27 Mart 2014 Perşembe

Breadth First Search (BFS) Algoritması

#include <iostream>
#include <queue>
#include <conio.h>
#include <stdio.h>

using namespace std;

enum VertexName { A , B , C , D , E , F };

struct Vertex{

    VertexName name;

    int kaynak;
    int veri[6];
    int uzaklik;
    int Time;

};

queue<Vertex> dolasim;

void BFS ( Vertex [] , Vertex );

int main()

{
   
    // burada matrisi diziye atmak için tanımladık

    Vertex dizi[5];
   
    //dosya işlemlerinin okuması
   
    FILE *oku;
   
    oku=fopen("deneme.txt","r");
   
    int a,b,c,d,e;
   
    dizi[0].name = A;
    dizi[1].name = B;
    dizi[2].name = C;
    dizi[3].name = D;
    dizi[4].name = E;
   
    if(oku==NULL ){

  puts("Dosya açilmadi !\n"); return 0;
}

for(int i=0; i<5;i++){   //diziye elemanları atama işlemlerini yerine getirdik

    fscanf(oku,"%d %d %d %d %d\n",&a,&b,&c,&d,&e);
   
    dizi[i].veri[0] = a;  
    dizi[i].veri[1] = b;  
    dizi[i].veri[2] = c;  
    dizi[i].veri[3] = d;  
    dizi[i].veri[4] = e;  
}
 fclose(oku);
    //dosya sonu
   
    int secim,num;
   
    //sorunun b şıkkında dereceleri hakkında yorum yaptık
   
    /*  burada dikkat edilmesi gerekn husus soruya yönelik yaptığım için
   
    köşegenlerde olduğunda misal, dizi[i][i]x2 kuralını yerine  getirmedim, ancak
   
    bu örnek dışında dikkat etmemiz gereken husus olarak göze çarpar
   
    */
   
    printf("[0-4 ARASI] DERECESINI BULMAK İSTEDİGİNİZ GRAF NUMARASINI GİRİNİZ:");
    scanf("%d",&num);
   
    int top=0;
 
    for(int a=0;a<5;a++){
 
       if(num !=a){
             
            top=top+dizi[num].veri[a];
            }
       
        else{  // yukarıda anlattığım köşegen durumu
       
             top=top+2*dizi[num].veri[a];
       
            }
        }
       
        // C şıkkı dolaşma iiçin gerekli adımlar
       
    printf("\nGIRDIGINIZ GRAFIN DERECESI:%d\n",top);  
    printf("\n[0-4 ARASI] LUTFEN DOLASMAK ISTEDIGINIZ GRAF NUMARASINI GIRINIZ:\n");
    scanf("%d",&secim);
   
    //dolaşılması istenene node dan başlayıp hepsinden geçen yollar
   
    BFS( dizi , dizi[secim] ); //uygun fonksiyon
   
}
/* Bu fonksiyonun amacı dolaşılan node leri tutulan isimleri sırasında yazıp bunları

daha iyi görebilmek için hazırlanmıştır!

*/

void sonraki_yaz ( Vertex sonraki ){
   
    switch ( sonraki.name )
    {

    case A:
        printf("Isim : A ");
        break;

    case B:
        printf("Isim : B ");
        break;

    case C:
        printf("Isim : C ");
        break;

    case D:
        printf("Isim : D ");
        break;

    case E:
        printf("Isim : E ");
        break;

    }
   
    puts("");
   
    // ailelerini çocuklarını parentlerini görebilmek için adımları takibi kolaylaştıran fonksiyon
   
    switch ( sonraki.kaynak )
    {
    case -1:
        printf("Parent : NULL ");
        break;
    case 0:
        printf("Kaynak : A ");
        break;
    case 1:
        printf("Kaynak : B ");
        break;
    case 2:
        printf("Kaynak : C ");
        break;
    case 3:
        printf("Kaynak : D ");
        break;
    case 4:
        printf("Kaynak : E ");
        break;
    }
   
    puts("\n");
   
    getch();
   
}

/*
 
  asıl olayın hazırlandığı yer

  bu fonksiyonu hazırlarken C kütüphanelerinden faydalandık. bu kütüphaneye ait
 
  push()
 
  empty()
 
  front()
 
  pop()
 
  fonksiyonlarından <queue> kütüphanesi
 
  ile hazırladık.
 
  OLAYIN MANTIĞI
 
  Fonksiyona gönderilen node kuyruğa atılır.

  Kuyruk boşalıncaya kadar döngü sürdürülür.

  Sıradaki node kuyruktan çıkarılır.

  Çıkarılan node daha önce gezilmemiş ise, gezildi işareti konur
 
  ve gezilmemiş komşuları kuyruğa konur

*/


void BFS ( Vertex all[5] , Vertex a )  //diziyi ve kullanıcıdan alınan node başlangıcı
{
    int simdiki_deger; //deger tutumu
   
    Vertex yeniVertex; //tutulacak deger tanımlama
   
    for ( int i = 0 ; i < 5 ; i++ )
    {
        if ( all[i].name != a.name ) //girilen degerin adı değilse yapılan işlemler
        {
            all[i].uzaklik = 9999999;
            all[i].kaynak = -1;
        }
    }
   
    a.uzaklik = 0;
    a.kaynak = -1;
   
    dolasim.push(a);  //yığın görevi
   
    while ( !dolasim.empty() ) // doluluk kontrolu
    {
        yeniVertex = dolasim.front();
       
        for ( int i = 0 ; i < 5 ; i++ )
        {
            if ( yeniVertex.name ==  i )
            {
                all[i] = yeniVertex;
                simdiki_deger = i;
                break;
            }
        }
       
        dolasim.pop(); //boşaltım,çıkarım
               
        for ( int j = 0 ; j < 5 ; j++ )
        {
            if ( yeniVertex.veri[j] == 1 && all[j].uzaklik == 9999999 )
            {
               
                all[j].uzaklik = yeniVertex.uzaklik + 1;
               
                all[j].kaynak = yeniVertex.name;
               
                dolasim.push(all[j]); //tekrar boşaltılan yerlerin dolması, koyması
           
            }
        }

       sonraki_yaz( yeniVertex );

    }
}

Hiç yorum yok:

Yorum Gönder