八數碼 單向廣搜

2021-08-24 23:30:08 字數 2531 閱讀 1431

八數碼 (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 ...