八數碼 (poj1077)
八數碼問題是人工智慧中的經典問題
有乙個3*3的棋盤,其中有0-8共9個數字,0表示空格,
其他的數字可以和0交換位置。求由初始狀態
到達目標狀態
1 2 3
4 5 6
7 8 0
的步數最少的解
給定排列求序號:
整數 1,2…k的乙個排列:
a1 a2 a3 …ak
求其序號
基本思想:算出有多少個排列比給定排列小。
先算1到a1-1放在第1位,會有多少個排列: (a1-1)* ((k-1)!)
再算a1不變,1到a2-1 放在第2位(左邊出現過的不能再用),會有多少個排
列: (a2-1)* ((k-2)!)
再算a1,a2不變,1到a3-1 放在第3位,會有多少個排列
….全加起來。 時間複雜度:o(n 2 )
3241
1,2放在第一位,有 2*3! = 12 種
3在第一位,1放在第2位,有 2! = 2種
32? 1放在第3位,有 1種
=>前面共 12+2+1 = 15種。所以 3241是第16個排列
時間與空間的權衡
對於狀態數較小的問題,可以用最直接的方式編
碼以空間換時間
對於狀態數太大的問題,需要利用好的編碼方法
以時間換空間
八數碼問題有解性的判定
八數碼問題的乙個狀態實際上是0~8的乙個排列,對於任意給定的初始狀態和
目標,不一定有解,即從初始狀態不一定能到達目標狀態。
因為排列有奇排列和偶排列兩類,從奇排列不能轉化成偶排列或相反。
如果乙個數字0~8的隨機排列,用f(x) (x!=0)表示數字x前面比它小的數(不
包括0)的個數,全部數字的f(x)之和為y=∑(f(x)),如果y為奇數則稱該排列
是奇排列,如果y為偶數則稱該排列是偶排列。
871526340排列的 y=0+0+0+1+1+3+2+3=10,10是偶數,所以是偶排列。
871625340排列的y=0+0+0+1+1+2+2+3=9 9是奇數,所以是奇排列。
因此,可以在執行程式前檢查初始狀態和目標狀態的奇偶性是否相同,相
同則問題可解,應當能搜尋到路徑。否則無解。
#include
#include
#include
#include
#include
#include
using
namespace
std;
int goalstatus = 123456780; // 目標狀態
const
int maxs = 400000;
char result[maxs]; // 要輸出的移動方案
struct node
node()
};node myqueue[maxs]; // 狀態佇列,狀態總數362880
int qhead = 0; // 隊頭指標
int qtail = 1; // 隊尾指標
char moves = "udrl"; // 四種移動
int newstatus( int status, char move) // 返回空格的位置
switch( move)
break;
case
'd':
if( zeropos + 3 > 8 )
return -1; // 空格在第三行
else
break;
case
'l':
if( zeropos % 3 == 0)
return -1; // 空格在第一列
else
break;
case
'r':
if( zeropos % 3 == 2)
return -1; // 空格在第三列
else
break;
}return atoi(tmp);
}bool bfs(int status)
qhead ++;
}return
false;
}int main()
}line2[j] = 0; // 字串形式的初始狀態
if( bfs(atoi(line2))) while( pos); //pos = 0 說明已經回退到初始狀態了
for( int i = moves -1; i >= 0; i -- )
cout
<< result[i];
}else
cout
<< "unsolvable"
<< endl;
}}
** 郭煒 八數碼 廣搜)
時限 5000ms 記憶體限制 20000k 總時限 10000ms 描述在九宮格裡放在1到8共8個數字還有乙個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態 用0表示空格 1 2 3 4 5 6 7 8 0 輸入輸入乙個給定的狀態。輸出輸出到達目標狀態的最小步...
雙向廣搜 八數碼
雙向廣搜還是乙個很神奇的東西 判重更神奇 雙廣僅適用於有目標狀態的題目 include include include include include include include include include include using namespace std const int maxx...
八數碼問題(廣搜)
題目 描述 在九宮格裡放在1到8共8個數字還有乙個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態 用0表示空格 1 2 3 4 5 6 7 8 0 輸入 輸入乙個給定的狀態。輸出 輸出到達目標狀態的最小步數。不能到達時輸出 1。輸入樣例 1 2 3 4 0 6 ...