廣度優先搜尋尋找最優路徑 以及雙向廣度搜尋演算法

2021-05-23 02:20:32 字數 1935 閱讀 1119

這裡是poj1915上的一道在棋盤上搜尋走步路徑的題目:

**如下(使用bfs):

通過這道題目我有如下的幾點總結:

1、一開始我通過struct結構來表示每一步到達的座標位置,其中設定了乙個struct* parent的指標,而不是改進後的int parent; 但是在實際的除錯過程中,出現了非常奇怪的現象,被壓入到queue佇列中的節點的parent指標域不斷地變動,最後發現原來是curr節點每次都變動的問題,而tmp節點的parent指標始終指向的是curr節點的。

~~~~~~~所以最後乾脆使用int parent,省去指標的隱蔽錯誤!!~~~~~~~~~~~~~~~~~

2、一開始發生錯誤的時候,不要急著直接按原問題的規模來除錯,可以先用小規模問題來測試,這樣往往更容易發現程式到底錯在**。

3、上面程式可能存在的不足就是nodetable占用了比較大的空間,不過也不會很大,因為一旦搜尋到目標節點就停止了。這裡使用陣列其實主要是起到還原路徑的作用。

4、在上面的程式中:

宣告了:

pnode nodetable[maxsize*maxsize]=;  //儲存節點的表

而在實際向表中插入資料的時候,必須先通過new操作符建立記憶體空間,然後進行賦值:

nodetable[id]=new node();       //注意一定要先new分配記憶體空間,再進行賦值

*nodetable[id]=start;

不能直接用: *nodetable[id]=start;

雙向廣度搜尋演算法:

主要的演算法思想是這樣的:

有些問題按照廣度優先搜尋法則擴充套件結點的規則,既適合順序,也適合逆序,於是我們考慮在尋找目標結點或路徑的搜尋過程中,初始結點向目標結點和目標結點向初始結點同時進行擴充套件—,直至在兩個擴充套件方向上出現同乙個子結點,搜尋結束,這就是雙向搜尋過程。出現的這個同一子結點,我們稱為相交點,如果確實存在一條從初始結點到目標結點的最佳路徑,那麼按雙向搜尋進行搜尋必然會在某層出現「相交」,即有相交點,初始結點一相交點一目標結點所形成的一條路徑即是所求路徑。

理論上雙向bfs可以在時間和空間上做到單向bfs的 1/2 次方。所以速度比單向的bfs快一點。

下面是poj1915的另乙個程式版本:雙向廣度搜尋

下面總結一些雙向廣度搜尋的特點:

1、因為是在兩個方向上,同時逆向的搜尋,所以需要維護兩個資料結構是兩個個open表和close表.因為每個方向上的搜尋都要對搜尋過程進行記錄。這裡open表就是一般bfs中的佇列資料結構,具有先進先出的特點,而closed列表就相當於對已檢測節點做標記的記錄陣列。

2、在雙向廣度搜尋中,可以交替的擴充套件每乙個搜尋方向上的節點,當然如果進一步優化:可以選擇擴充套件節點個數較少的方向。

3、在擴充套件過程中對訪問陣列使用1、2進行標記兩個不同方向上搜尋到的節點,另外每次擴充套件的時候,都是把當前層的節點全部擴充套件完,這樣再遞增搜尋深度的變數你n1、n2,這樣最後總的搜尋最優步數就是 n1+n2 。如果要還原路徑,只要在兩個方向上分別記錄相交節點half1、half2就可以了。

下面是poj2046 gap的題目,主要的方法還是使用廣度優先搜尋,下面用三種方法進行了實現:第一種使用set容器進行狀態的判重,第二種方法使用hash進行判重,第三種方法使用a*演算法+hash進行判重。

這裡體現了乙個搜尋優化的方法:將局面的狀態轉化為字串進行狀態判重。另外這裡比較巧妙的是使用set容器進行狀態的判重,set在這裡就是hash表的作用。

使用hash表進行狀態判重。主要注意的獲得hash值函式的寫法(字串hash法)。

這裡的特點是,通過在hash表單元的狀態empty、active來方便hash表插入元素是否重複的判斷。

使用a*演算法要注意不應該將已經進入關閉列表的元素再次加入到開放列表中。而這一般可以通過把hash表作為關閉列表來使用。(但是由於hash存在衝突的可能性,可能會把已經進入關閉列表的元素又加入到開放列表中,所以使用set容器就避免了這一點)。

最優乘車(廣度優先搜尋)

description h城是乙個旅遊勝地,每年都有成千上萬的人前來觀光。為方便遊客,巴士公司在各個旅遊景點及賓館,飯店等地都設定了巴士站並開通了一些單程巴上線路。每條單程巴士線路從某個巴士站出發,依次途經若干個巴士站,最終到達終點巴士站。一名旅客最近到h城旅遊,他很想去s公園遊玩,但如果從他所在的...

雙端佇列廣度優先搜尋

在乙個邊權只有0 1的無向圖中搜尋最短路徑可以使用雙端佇列進行bfs。其原理是當前可以擴充套件到的點的權重為0時,將其加入隊首 權重為1時,將其加入隊尾。達達是來自異世界的魔女,她在漫無目的地四處漂流的時候,遇到了善良的少女翰翰,從而被收留在地球上。翰翰的家裡有一輛飛行車。有一天飛行車的電路板突然出...

迷宮路徑問題廣度優先搜尋模板

總時間限制 1000ms 記憶體限制 65536kb 描述定義乙個二維陣列 int maze 5 5 它表示乙個迷宮,其中的1表示牆壁,0表示可以走的路,只能橫著走或豎著走,不能斜著走,要求程式設計序找出從左上角到右下角的最短路線。輸入乙個5 5的二維陣列,表示乙個迷宮。資料保證有唯一解。輸出左上角...