寬搜(BFS)————真·笨法師演算法
阿新 • • 發佈:2020-10-07
①.所謂寬度優先搜尋
寬度優先搜尋演算法(又稱廣度優先搜尋)是很麻煩最簡便的圖的搜尋演算法之一,這一演算法也是很多重要的圖的演算法的原型。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜尋整張圖,直到找到結果為止。
翻譯過來就是:
寬度優先搜尋是一種粗暴的演算法,就像走迷宮時,dfs是一個人在走迷宮,而bfs是一群人在走迷宮,而且每個人都有一部手機(既然有手機那為什麼不sos?,那麼就可以分成幾隊,同時朝不同方向展開搜尋,如果遇到岔路繼續分隊,直到找到出口位置
dfs注重於深度,也就是一條路走到頭,而bfs注重寬度,也就是說什麼也不管,先把這條路上所有岔路口都佔了
bfs常用於求最短路徑,路徑總數等
bfs建立在佇列的基礎上
dfs建立在遞迴的基礎上
兩者都需要用到樹
如圖
dfs路徑是
1——2——1——3——5——6——5——8——5——3——7——9——7——3——1——4
而bfs的路徑是
1——2——3——4(只有3有岔路口——3——5——7——6——8——9
因為bfs不需要回溯,所以步驟比dfs短些
——————————————————————————————————————————————————————————————————————————
②演算法過程
1 void bfs() 2 { 3 f=r=1;//佇列初始化為空4 que[r]=初始狀態 //隊尾插入初始狀態 5 while(f<=r){ 6 //當佇列非空時做,其中f和r分別表示佇列的頭指標和尾指標 7 if(找到目標狀態) 8 做相應處理(如退出迴圈輸出解、輸出當前解、比較解的優劣) 9 else{ 10 獲取頭結點資訊; 11 拓展頭結點; 12 if(拓展出當新結點沒有出現過){ 13 r++; 14 將新結點插到隊尾;15 } 16 } 17 f++;//取下一結點 18 } 19 }
③例題
迷宮問題(一本通):http://ybt.ssoier.cn:8088/problem_show.php?pid=1255
程式碼:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int mp[10][10]; 4 int f,r; 5 struct group{ 6 int x; 7 int y; 8 int father; 9 }que[100]; 10 int father[100],b; 11 int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; 12 void pr(int p){ 13 if(p==0)return ; 14 pr(que[p].father); 15 cout<<"("<<que[p].x<<", "<<que[p].y<<")"<<endl; 16 } 17 void pr2() 18 { 19 for(int i=f; i ; i=que[i].father) 20 cout<<"("<<que[i].x<<", "<<que[i].y<<")"<<endl; 21 } 22 void bfs(){ 23 f=r=1; 24 que[r].x=0; 25 que[r].y=0; 26 que[r].father=0; 27 mp[0][0]=1; 28 while(f<=r){ 29 group t; 30 t.x=que[f].x; 31 t.y=que[f].y; 32 if(t.x==4&&t.y==4){ 33 pr(f); 34 } 35 for(int i=0;i<4;i++){ 36 int lx=t.x+next[i][0]; 37 int ly=t.y+next[i][1]; 38 if(lx>=0 && lx<5 && ly>=0 && ly<5 && mp[lx][ly]==0){ 39 mp[lx][ly]=1; 40 r++; 41 que[r].x=lx; 42 que[r].y=ly; 43 que[r].father=f; 44 45 } 46 } 47 f++; 48 } 49 } 50 int main(){ 51 for(int i=0;i<5;i++){ 52 for(int j=0;j<5;j++){ 53 cin>>mp[i][j]; 54 } 55 } 56 bfs(); 57 return 0; 58 }