八數碼是乙個經典的人工智慧難題,因為好的演算法在八數碼問題中將搜尋的幾種經典方法體現的淋漓盡致,經過幾種演算法的比較,我發現用迭帶加深的啟發示演算法的效率最好,而且求得解為最優解.
開始實現時老是在查詢cloesd表時耗費時間,因此好多case都要算很長時間,最長竟達30分鐘,後來將cloesd儲存在乙個100000000大小的 字元陣列中,這樣,陣列中每乙個元素對應乙個狀態序列,有點類似雜湊儲存,別看這摸簡單的雜湊函式,它可是其中的英雄!,有了它判重的時間複雜度變為o(1),於是就使八數碼的30多萬的狀態空間能在30秒中搜尋完畢!下面是該函式:
public
long
gethashvalue(state s)
...
判重函式:
public
bool
exist(state s)
...}
public
intmin
=100
;public
const
intmax =9
;public
const
intn =3
;public
arraylist opened
=new
arraylist();
public
arraylist closed
=new
arraylist();
/**/
//////
當前節點是否是目標狀態
//////
///public
bool
isanswer(state s)
...else
return
false;}
/**/
//////
搜尋當前節點的子狀態
//////
//////
public
arraylist searchnextstate(state s,
intp)
...}}if
(row
1) ...}}if (col >0) ...}}if (col 1) ...} }icomparer mycomparer =new myreverserclass(); ar.sort(mycomparer); return ar;} /**/ ////// 搜尋八數碼 ////// ///public state search(state s) ...int perms =0 ;for (inti = 0; i < 9; i++) ...} if(perms %2 !=0 )... s.depth =1 ;s.hashvalue =gethashvalue(s); opened.add(s); state t; while (depth < 100) ...arraylist tar =searchnextstate(t, t.index); foreach (state t intar) ...} depth++; }return null;} /**/ ////// 判斷closed表是否已存在 ////// ///public bool exist(state s) ...; string strar =str.split(c); for( inti =0 ; i < strar.length; i++) ...} }s.a =a; bashuma.search(s); console.readline(); }} } 這是一種很奇特的演算法。當然理解了以後就不那麼奇特了。直接看題 在3 3 的棋盤上,擺有八個棋子,每個棋子上標有1至 8的某一數字。棋盤中留有乙個空格,空格用 0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 為了使題目簡單 設目標狀態為 1238047... 八數碼遊戲就是通過移動空格把數字從給定的狀態移動到目標狀態,例如 初始狀態為 目標狀態為 2 8 3 1 2 3 1 6 4 8 4 7 5 7 6 5 程式中用0表示空格,提供了兩套狀態。eightnums.rb class eightnums 常量定義 up 1 down 1 left 2 ri... 八數碼遊戲就是通過移動空格把數字從給定的狀態移動到目標狀態,例如 初始狀態為 目標狀態為 2 8 3 1 2 3 1 6 4 8 4 7 5 7 6 5 程式中用0表示空格,提供了兩套狀態。eightnums.rb class eightnums 常量定義 up 1 down 1 left 2 ri...八數碼問題(迭代加深)
八數碼遊戲的Ruby實現
八數碼遊戲的Ruby實現