雙向廣度優先搜尋演算法框架及八數碼問題例程

2021-06-04 07:13:40 字數 3018 閱讀 2630

雙向廣度優先搜尋演算法是對廣度優先演算法的一種擴充套件。廣度優先演算法從起始節點以廣度優先的順序不斷擴充套件,

直到遇到目的節點;而雙向廣度優先演算法從兩個方向以廣度優先的順序同時擴充套件,乙個是從起始節點開始擴充套件,另

乙個是從目的節點擴充套件,直到乙個擴充套件佇列中出現另外乙個佇列中已經擴充套件的節點,也就相當於兩個擴充套件方向出現了

交點,那麼可以認為我們找到了一條路徑。雙向廣度優先演算法相對於廣度優先演算法來說,由於採用了從兩個跟開始擴充套件

的方式,搜尋樹的深度得到了明顯的減少,所以在演算法的時間複雜度和空間複雜度上都有較大的優勢!雙向廣度優先算

法特別適合於給出了起始節點和目的節點,要求他們之間的最短路徑的問題。另外需要說明的是,廣度優先的順序能夠保證

找到的路徑就是最短路徑!

基於以上思想,我們給出雙向廣度優先演算法程式設計的基本框架如下:

資料結構:

queue q1, q2; //兩個佇列分別用於兩個方向的擴充套件(注意在一般的廣度優先演算法中,只需要乙個佇列)

int head[2], tail[2]; //兩個佇列的頭指標和尾指標

演算法流程:

一、主控函式:

void solve()

二、擴充套件函式:

int expand(i) //其中i為佇列的編號(表示q0或者q1)

三、判斷新節點是否在同乙個佇列中重複的函式

int isduplicate(i, j) //i為佇列編號,j為當前節點在佇列中的指標

四、判斷當前擴充套件出的節點是否在另外乙個佇列出現,也就是判斷相交的函式:

int isintersect(i,j) //i為佇列編號,j為當前節點在佇列中的指標

以上為雙向廣度優先搜尋演算法的基本思路,下面給出使用上面的演算法框架編寫的八數碼問題的**:

問題描述:

給定 3 x 3 的矩陣如下:

2     3     4

1     5      x

7     6     8

程式每次可以交換"x"和它上下左右的數字,

經過多次移動後得到如下狀態:

1      2     3

4      5     6

7      8      x

輸出在最少移動步數的情況下的移動路徑[每次移動的方向上下左右依次表示為'u', 'd', 'l', 'r']

例如:如果過輸入:【將矩陣放到一行輸出】

2  3  4 1  5  x  7  6  8

則輸出:

ullddrurdllurdruldr

原題見acm pku 1077

/** author: puresky

* date: 2010.01.12

* purpose: solve eigth number problem!*/

#include

#include

#include

#define maxn 1000000

#define swap(a, b)

typedef struct _node node;

struct _node;

int head[2], tail[2];

node queue[2][maxn];// two queues for double directoin bfs

//shift of moving up, down, left ,right

int shift[4][2] = , , , };

//for output direction!

char dir[4][2] = , , , };

//test case

char start[10] = "23415x768";

char end[10] = "12345678x";

//read a tile 3 by 3

void readtile()

start[9] = '\0';}

//print result

void print_backward(int i)

}void print_forward(int j)

}void print_result(int i, int j)

//init the queue

void init(int qi, const char* state)

//check if there are duplicates in the queue

//time comlexity:o(n)

//we can optimise this function using hashtable

int isduplicate(int qi)

}return 0;}

//check if the current node is in another queue!

//time comlexity:o(n)

//we can optimise this function using hashtable

int isintersect(int qi)}

return -1;}

//expand nodes

int expand(int qi)

else

else

return 1;}}

}}return 0;}

//call expand to generate queues

int solve()

else

}while(head[0] <= tail[0]) if(expand(0)) return 1;

while(head[1] <= tail[1]) if(expand(1)) return 1;

return 0;}

int main(int argc, char** argv)

//system("pause"); //pause

return 0;}

acm judge online: 372k 記憶體, 938ms 時間

使用hashtable優化後的版本見:《八數碼問題hashtable優化查詢後的版本》

雙向廣度優先搜尋演算法

首先是廣度優先搜尋演算法 初始化visited陣列,將所有點的值設為false visited陣列用來儲存所有點的訪問情況 visited start true start為起始點 queuesearch 用來儲存待搜尋點的佇列 search.push start while search.empt...

廣度優先搜尋演算法

廣度優先搜尋 bfs 這個是第乙個研究的課題,廣度優先搜尋也叫寬度優先搜尋,英文為breadth first searth,開始看的時候一頭霧水,基本也能懂大致意思,但是還不是真正的理解,今天又仔細看看,大致理解上又更深了一層吧。下面來總結下,自己的一些體會,以及對它的獨到的理解。大的方面來說它是一...

廣度優先搜尋演算法

在深度優先搜尋中,深度越大的結點越先得到擴充套件。如果把它改為深度越小的結點越先得到擴充套件,就是廣度優先搜尋法。廣度優先搜尋演算法的基本思想 1 建立乙個空的狀態佇列ss 2 建立乙個空的狀態庫sb 3 把初始狀態s 0 存入佇列ss中 4 若佇列狀態是目標狀態,則搜尋成功,演算法執行中止。如該狀...