廣度優先搜尋的優化與技巧

2022-06-20 20:30:10 字數 1627 閱讀 6046

例題:p1397 八數碼難題

普通bfs

雙向bfs

所謂雙向廣度優先搜尋指的是搜尋沿兩個方向同時進行

正向搜尋:從初始點向目標點搜尋;

逆向搜尋:從目標點向初始點搜尋;

從正反兩個方向搜尋,理論上可以節省二分之一的搜尋量,從而提高搜尋速度,節約記憶體空間。

從初始狀態和目標狀態向兩個方向同時進行擴充套件,如果兩顆解答樹在某個節點發生一次重合,即可終止此搜尋過程,則該節點所連線的兩條路徑所拼成的路徑就是最優解

●雙向廣度優先搜尋通常有兩種搜尋方法:

①、兩個方向交替擴充套件;

②、選擇結點個數較少的那個方向先擴充套件;

●實現方法:

建立兩個佇列分別拓展兩個方向出發的狀態。

每次while迴圈時只擴充套件正反兩個方向中節點數目較少的乙個,可以使兩邊的發展速度保持一定的平衡,從而減少總擴充套件節點的個數,加快搜尋速度。

例題**

#include#include#include#includeusing namespace std;

mapma,mb;

struct nod

;queueqa,qb;

int dx[4] = ;

int dy[4] = ;

int main()

for (int i = 0; i < 9;i++));}

qb.push();

ma[a] = mb[aim] = 0;

while(!qa.empty()||!qb.empty())

ma[b] = ma[temp] + 1;

qa.push();}}

else

mb[b] = mb[temp] + 1;

qb.push();}}

}return 0;

}

p4667 [balticoi 2011 day1]switch the lamp on

類似優先佇列優化的d j最短路,每次用未被標記最小的值去更新其他點。

邊權只有0、1,可用雙端佇列代替優先佇列

邊權為0,插到隊頭;邊權為1,插入隊尾,這樣就省去了排序操作,保證隊首最小

例題**

#include#include#includeusing namespace std;

struct nod

;char sq[505][505];

dequeq;

int dx[4] = ;

int dy[4] = ;

int rx[4] = ;

int ry[4] = ;

char ch[5] = "\\//\\";

bool vis[505][505];

int dist[505][505];

int n, m;

void bfs()

); dist[0][0] = 0;

while(!q.empty())

bfs();

if(dist[n][m]==0x3f3f3f3f)

cout << "no solution"<

else

cout << dist[n][m]<

return 0;

}

深度優先搜尋與廣度優先搜尋

深度優先遍歷的主要思想就是 首先以乙個未被訪問過的頂點作為起始頂點,沿當前頂點的邊走到未訪問過的頂點 當沒有未訪問過的頂點時,則回到上乙個頂點,繼續試探訪問別的頂點,直到所有的頂點都被訪問。沿著某條路徑遍歷直到末端,然後回溯,再沿著另一條進行同樣的遍歷,直到所有的頂點都被訪問過為止。通過上面的圖例可...

廣度優先搜尋與深度優先搜尋

廣度優先搜尋使用的是步步為營的策略,每執行一步迴圈就會把所有可能的情況加入佇列,直到調出迴圈。適用於求最短的問題。深度優先搜尋則是依次遍歷每一種情況,直至找到問題的解。深度優先搜尋和廣度優先搜尋都屬於窮竭法。在執行記憶體空間上面,廣度優先搜尋與情況數成正比,而深度優先搜尋與遞迴深度成正比。inclu...

深度優先搜尋與廣度優先搜尋

首先我們以鍊錶的形式儲存乙個圖 struct edge vectorg2 maxvex int source 6 3 表示從頂點0到頂點1的邊的權值為10。以鄰接鍊錶形式生成該圖 void genedge 首先以乙個未被訪問過的頂點作為起始頂點,沿著當前頂點的邊走到未訪問過的頂點 當沒有未訪問過的頂...