廣度優先搜尋 八數碼問題

2021-07-24 07:13:26 字數 2076 閱讀 1377

給定乙個一幅圖和乙個起點s,回答「從s到給定的頂點v是否存在一條路徑?如果有,找出其中最短的那條(所含邊數最少)。「

邊數最少,很自然想到從從經過1條邊能到達的節點有哪些?然後經過這些邊再到達的節點有哪些?這樣我不就能夠想出來最短的路徑了嗎?沒錯,這是非常簡單的想法,然而真正的廣度優先演算法也是這樣,簡單而有效。

上面這幅圖我要找到從1到12的最短路徑,則我會從1經過1條邊可以到達的節點(2 3 4)搜尋,發現沒有,接下來搜尋節點(2 3 4)通過1條邊能夠到達的頂點(5 6 7 8),發現沒有,接下來搜尋節點(5 6 7 8),發現沒有,接下來搜尋節點(5 6 7 8)通過1條邊能夠到達的節點(9 10 11 12),搜尋到最後乙個,發現搜尋到了。如果你每次經過一條邊則記錄加1,則現在經過了三條邊,即最短路徑是3條邊,

當已經理解了演算法思想,接下來就應該實現了。最重要的一步是思考使用什麼樣的資料結構,想想這裡的搜尋乙個集合,那自然就是遍歷他們,接下來還要遍歷他們通過一條邊能夠到達節點,普通的想法是先判斷他們,如果沒有,則再遍歷他們,然後生成的所有節點再加入乙個新的集合當中。

問題:發現了沒,這裡遍歷了兩遍集合。還有就是新的節點加入乙個新的集合,每次都要宣告新的陣列嗎?這是有多麻煩。

解決方案:這裡遍歷了兩遍,其實我先生成新的節點和後生成新的節點只是多占用一點空間而已,我要是在遍歷第乙個節點如果判斷不是就直接生成新的節點也可以,這樣就不用遍歷第二遍了,加入新的集合解決起來有點棘手,如果我可以仍然放在集合裡面繼續遍歷就好了,對!就是這樣,所以在集合裡會有順序的關係,不能我先遍歷第乙個節點,接著直接遍歷新的節點,所以說我們的資料就要有順序之分,所以想想有什麼樣的資料儲存方式能夠有順序,常見的陣列就夠了,如果稍微學過資料結構,鍊錶也可以。

程式設計的思路:遍歷陣列,從第乙個節點開始,如果不是,則生成新節點加入到陣列的最後乙個節點後面,所以如果是c語言,一定要將陣列宣告大一些。然後不斷遍歷即可,直到找到。

八數碼問題也稱為九宮問題。在3×3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是:給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟。所謂問題的乙個狀態就是棋子在棋盤上的一種擺法。解八數碼問題實際上就是找出從初始狀態到達目標狀態所經過的一系列中間過渡狀態。

移動棋子最少,當然是使用廣度優先搜尋來解決。所以這裡的每個節點就要是乙個3

*3的矩陣。如果在c語言中,可以使用結構體。

//找出0的位置

int loction(int num)

//進行標記

long

long sign(int num)

void mobile(int num)

; if (loc / 3 != 2 && stand != 3)

if (loc % 3 != 0 && stand != 0)

if (loc % 3 != 2 && stand != 2)

}void display(int num)

}int search()

if (sign(i) == sign(101))

mobile(i);

i++;

}}int main()

//測試用例

/*2 8 3

1 6 4

7 0 5

1 2 3

7 8 4

0 6 5

*/

八數碼問題(bfs廣度優先搜尋)

最近在學bfs,覺得這個題不錯,自己沒做出來,去網上搜了一下,又結合了我自己的想法,ac了 這個看起來用dfs比較好做,但是會超時好像,所以肯定用bfs了。問題描述 在九宮格裡放在1到8共8個數字還有乙個是x,與x相鄰的數字可以移動到x的位置,問給定的狀態最少需要幾步能到達目標狀態 1 2 3 4 ...

廣度優先搜尋解決八數碼問題

程式描述 基於盲目搜尋策略的寬度優先搜尋方法 include include include include include include include using namespace std define n 9 九宮格總數字 陣列定義 0 9階乘定義 const int jc n 1 0 9...

八數碼問題 廣度優先搜尋 列舉判重

const maxn 500000 type atp record s string time longint end var que array 0.maxn of atp head,tail,x longint now string 儲存進行操作後的字串 procedure print 判斷是否...