城市路徑問題—廣度優先搜算(BFS)

例題:
已知若干個城市的地圖,求從一個城市到另一個城市的路徑,要求該路徑經過的城市最少。
城市路線圖如下:
在這裏插入圖片描述
算法分析:
圖的廣度優先搜索類似於樹的層次遍歷,逐層搜索正好可以儘快找到一個結點與另一個結點相對與而言最直接的路徑。所以此問題適應廣度優先搜索。下面通過分許一個例子來進行算法設計:
(1)設置鄰接矩陣以“1”可以走,“0”不能走。
(2)設置鄰接矩陣:
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200606191431350.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_
(3)
①將城市A(編號1)人隊,隊首指針qh置爲0,隊尾指針qe置爲1。
②將隊首指針所指城市的所有可直通的城市人隊,當然如果這個城市在隊中出現過就不人隊,然後將隊首指針加1,得到新的隊首城市。重複以上步驟,直到城市H(編號爲8)入隊爲止。當搜索到城市H時,搜索結束。
③輸出經過最少城市線路。

數據結構設計:
考慮到算法的可讀性,用線性數組a作爲活結點隊的存儲空間。爲了方便輸出路徑,隊列的每個結點有兩個成員,sq[i].city記錄人隊的城市,sq[i].pre記錄該城市的前趨城市在隊列中的下標,這樣通過sq[i].pre就可以倒推出最短線路。也就是說活結點隊同時又是記錄所求路徑的空間。因此,數組隊並不能做成循環隊列,所謂“出隊”只是隊首指針向後移動,其空間中存儲的內容並不能被覆蓋。同時和廣度優先算法框架一樣,設置數組visited[]記錄已搜索過的城市。


代碼如下:


#include<stdio.h>

int jz[9][9]= {{0,0,0,0,0,0,0,0,0},{0,0,1,1,1,0,1,0,0},{0,1,0,0,0,0,1,0,0},
               {0,1,0,0,1,1,0,0,0},{0,1,0,1,0,0,0,1,0},{0,0,0,1,0,0,0,1,1},
               {0,1,1,0,0,0,0,0,1},{0,0,0,0,1,1,0,0,1},{0,0,0,0,0,1,1,1,0}};
          //1可以走,0不能走
          //因爲代碼中是從一開始的來方便城市的辨別,
          所以我們需要在下標爲0的地方也要創建爲0(即不可到達)的線路

struct sq
{
    int city;
    int pre;
} sq[100];

int qh,qe,i,visited[100];
int n=8;

void out()        //輸出路徑/
{
    printf("可以走的路程的路徑爲(數字代表城市的編號): \n\n");
    printf("%d ",sq[qe].city);
    while(sq[qe].pre!=0)
    {
        qe=sq[qe].pre;
        printf("-- %d ",sq[qe].city);
    }
    printf("\n\n");
}

void search()
{
    qh=0;
    qe=1;
    sq[1].city=1;
    sq[1].pre=0;
    visited[1]=1;
    while(qh!=qe)//當隊不空//  
    {
        qh++;                         //結點出隊/
        for(i=1; i<=n; i++) //擴展結點/
            if(jz[sq[qh].city][i] == 1 && visited[i]==0)
            {
                qe++;                    //結點入隊/
                sq[qe].city=i;
                sq[qe].pre=qh;
                visited[i]=1;
                if (sq[qe].city == 8)
                {
                    out();
                    return;
                }
            }
    }
    printf("沒有可以走的路!/n");
}

int main()
{
    int i;
    for(i=1; i<=n; i++) //初始化visit[]
    {
        visited[i]=0;
    }
    search();
    return 0;
}

總結:
①圖的存儲空間和搜索時需要用到“隊列”的存儲空間
②該題目要求的是城市A-城市H的最短路徑,但輸出的從城市H-到城市A的最短路徑。大家可以進行改進使它正序輸出。
③該文中的代碼引用了 “呂國英”的 《算法設計與分析》 清華大學出版社中的代碼。之後會發出我已改進的城市路徑問題的代碼,大家可以一起探討。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章