八數碼問題的幾種解法

2021-10-04 01:46:16 字數 2750 閱讀 4792

1. 用雙向bfs解決八數碼問題

2. 用迭代加深搜的a*演算法解決八數碼問題

注:本實驗我採用的都是從283104765到123804765的最短步數

首先,雙向bfs指的是從初始狀態和目標狀態同時開始搜尋,廣度優先搜尋是每次先搜尋周圍,然後再向外擴充套件,(這裡我們把矩陣轉化為數字序列,更方便)我將用乙個佇列先把初始序列和目標序列依次放入佇列q,分別為第乙個和第二個,然後根據bfs的先進先出的特性,將會按順序一層一層的搜尋,當從初始序列開始後,會移動空格(這裡用0表示)並交換位置,然後把交換位置,之後的序列依次入隊,初始狀態序列bfs完後,就輪到第二個目標狀態序列了,同樣會產生交換位置之後的序列,這樣的話就可以實現從初始狀態和目標狀態兩頭同時進行bfs搜尋,會大大加快速度,終止條件就是當兩頭出現相交時,為結束。

//雙向bfs,從起點和終點兩個方向開始搜尋,

//如果某乙個狀態下出現相交的情況,那麼就出現了答案

#include

#include

#define ll long long int

using

namespace std;

//這裡我們把矩陣轉化為數字序列,更方便

int start, target =

123804765

;//start表示開始序列,target表示目標序列

int a[4]

[4], fx, fy, nx, ny;

int dx[4]

=;//代表四個移動方向

int dy[4]

=;queue<

int> q;

map<

int,

int> ans;

//ans用來記錄步數

map<

int,

int> v;

//v用來記錄狀態,是否順序和逆序訪問過

void

solve()

q.push

(start)

;//起始狀態和終止狀態依次入隊

q.push

(target)

; ans[start]=0

;//ans記錄步數

ans[target]=1

; v[start]=1

;//狀態1表示順序訪問過,即從起點開始搜尋

v[target]=2

;//狀態2表示逆序訪問過,即從終點開始搜尋

while

(!q.

empty()

)}}for

(int i =

0; i <

4; i++)}

if(v[now]

== v[cur])if

(v[now]

+ v[cur]==3

) ans[now]

= ans[cur]+1

; v[now]

= v[cur]

;//與上一狀態的方向保持一致

q.push

(now)

;//把的移動後的序列入隊

swap

(a[fx]

[fy]

, a[nx]

[ny]);

// 移動完了之後還要還原}}

}int

main()

結果:

由於迭代加深搜的a演算法裡面其實包含了深度優先搜尋,所以我就不再另外寫dfs演算法了,其實ida演算法就是廣度優先搜尋和深度優先搜尋和a*演算法三者的結合,可以通過自己設定,最大深度maxdep,逐步加大搜尋深度來獲得最優解,而如果使用dfs搜尋策略的話,就需要對整個搜尋空間進行搜尋,採用估值函式,剪掉f(n)>maxdep的路徑,通過剪枝去掉重複的路徑,可以大大減小時間複雜度。

#include

using

namespace std;

int dis[9]

[9]=

,//即從該點到其它8個點需要移動的步數,,

,,,,

,};int yuan[9]

=;//每個數字的目標狀態的位置

int chu[3]

[3];

//儲存當前狀態

char k;

int sx, sy;

int ax[4]

=;int ay[4]

=;//這兩個陣列一定要對稱寫,使搜尋時不會返回上一狀態

bool flag;

inth()

return ans;

}void

dfs(

int ceng,

int dep,

int f,

int x,

int y)

for(

int i =

0; i <

4; i++)}

intmain()

}}if(

!h()

) flag =0;

int maxdep;

//預期深度

for(maxdep =1;

; maxdep++)}

return0;

}

結果:

HDOJ 1043 八數碼問題(A 解法)

簡介 乙個九宮格中有八個數字,一位空格,每次只能移動相鄰的兩個格仔,現要求把九宮格變為 12345678x 的樣子 x代表空格 sample input 2 3 4 1 5 x 7 6 8 sample output ullddrurdllurdruldr 這裡我們要用到康拓展開,具體介紹如下 康拓...

八數碼問題

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

八數碼問題

2 6 4 1 3 7 0 5 8 8 1 5 7 3 6 4 0 2 樣例輸出 還有就是重判的問題,如何重判呢?第一種方法 把排列變成整數,然後只開乙個一維陣列,也就是說設計一套排列的編碼和解碼函式,把0 8的全排列和0 362879的整數意義一一對應起來。時間效率高,但編碼解碼法適用範圍並不大,...