題目大意:乙個3*3的棋盤上有8個格仔寫著1~8的數字,還有乙個空格,給定局面,要求給出乙個空格的移動序列,使得達到目標狀態:
1 2 3
4 5 6
7 8 x(空格)
做法:大名鼎鼎的八數碼問題...學習了a*演算法後,今天特意去試做了了下,居然過了,資料好水啊...
題目中的狀態可以用0~8的全排列表示,可以將其與1~9!的數字來進行對映,這就需要用到一種叫做康托展開的優秀的雜湊演算法。具體過程就不再贅述了,網上很容易可以找到過程。
然後就是設計估價函式。f=g+h,其中g為從起始狀態走到當前狀態的步數,h為每乙個數字的位置與其在目標狀態中位置的曼哈頓距離之和。然後就可以進行搜尋了。
據說好像有比裸搜更快捷的判定無解的方法...然而我看的資料裡的方法是錯的,有待學習有待學習...
以下是本人**:
#include #include #include #include #include #include using namespace std;
struct state a,t;
struct statement
for(int k=1;k<=9;k++) if (fx.s[k]==0)
if (x1-x2==3) route[j]='d';
if (x1-x2==-3) route[j]='u';
if (x1-x2==1) route[j]='r';
if (x1-x2==-1) route[j]='l';
i=fa[i];
} for(int i=1;i<=g;i++) printf("%c",route[i]);
}void astar()
state st=q_cantor(now.s);
int x;
for(int i=1;i<=9;i++) if (st.s[i]==0)
if (x-3>0)
{ swap(st.s[x],st.s[x-3]);
next.s=cantor(st),next.g=now.g+1,next.h=calc_h(st);
if (next.g+next.h
poj 1077 Eight A 解八數碼問題
題意 經典的八數碼問題。分析 搜尋演算法的區別是如何重排open表,關鍵是如何編碼狀態和定義狀態的值。對搜尋過程中任意狀態s,a 演算法以g s h s 重排open表,也就是說g s h s 是排列open中狀態的依據,其中g s 是初始狀態到s的消耗,h s 是s到目標狀態的估計。我重排open...
poj1077 康托展開 bfs 記憶路徑
題意 就是說,給出乙個三行三列的陣列,其中元素為1 8和x,例如 1 2 3 現在,需要你把它變成 1 2 3 要的最少步數的移動方案。可以右移r,左移l,上移u,下移d x 4 6 4 5 6 7 5 8 7 8 x有的人說,廣搜不能記錄路徑?這是錯誤的,廣搜只要你清楚的記錄這個狀態的上個狀態是什...
poj 1077 八數碼難題
終於自己ac了這道八數碼難題,用的方法是最最普通的單項bfs hash,這裡主要的難點在於如何儲存狀態,其實,在八數碼裡所有的狀態共有9!種 362880種,所以在每個轉台節點,我需要乙個char state 3 3 來記錄當前棋盤的狀態,用乙個int x,y來記錄當前x的位置,用char oper...