八皇后問題 遞迴,回溯演算法

2021-07-11 02:36:45 字數 2257 閱讀 7422

八皇后

問題,是乙個古老而著名的問題,是

回溯演算法

的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於2023年提出:在8×8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。 

高斯認為有76種方案。2023年在柏林的象棋雜誌上不同的作者發表了40種不同的解,後來有人用圖論的方法解出92種結果。計算機發明後,有多種計算機語言可以解決此問題。

基本思路如上面分析一致,我們採用逐步試探的方式,先從乙個方向往前走,能進則進,不能進則退,嘗試另外的路徑。首先我們來分析一下西洋棋的規則,這些規則能夠限制我們的前進,也就是我們前進途中的障礙物。乙個皇后q(x,y)能被滿足以下條件的皇后q(row,col)吃掉

1)x=row(在縱向不能有兩個皇后)

2)  y=col(橫向)

3)col + row = y+x;(斜向正方向)

4)  col - row = y-x;(斜向反方向)

遇到上述問題之一的時候,說明我們已經遇到了障礙,不能繼續向前了。我們需要退回來,嘗試其他路徑。

我們將棋盤看作是乙個8*8的陣列,這樣可以使用一種蠻幹的思路去解決這個問題,這樣我們就是在8*8=64個格仔中取出8個的組合,c(64,80) = 4426165368,顯然這個數非常大,在蠻幹的基礎上我們可以增加回溯,從第0列開始,我們逐列進行,從第0行到第7行找到乙個不受任何已經現有皇后攻擊的位置,而第五列,我們會發現找不到皇后的安全位置了,前面四列的擺放如下:

第五列的時候,擺放任何行都會上圖所示已經存在的皇后的攻擊,這時候我們認為我們撞了南牆了,是回頭的時候了,我們後退一列,將原來擺放在第四列的皇后(3,4)拿走,從(3,4)這個位置開始,我們再第四列中尋找下乙個安全位置為(7,4),再繼續到第五列,發現第五列仍然沒有安全位置,回溯到第四列,此時第四列也是乙個死胡同了,我們再回溯到第三列,這樣前進幾步,回退一步,最終直到在第8列上找到乙個安全位置(成功)或者第一列已經是死胡同,但是第8列仍然沒有找到安全位置為止

總結一下,用回溯的方法解決8皇后問題的步驟為:

1)從第一列開始,為皇后找到安全位置,然後跳到下一列

2)如果在第n列出現死胡同,如果該列為第一列,棋局失敗,否則後退到上一列,在進行回溯

3)如果在第8列上找到了安全位置,則棋局成功。

8個皇后都找到了安全位置代表棋局的成功,用乙個長度為8的整數陣列queenlist代表成功擺放的8個皇后,陣列索引代表棋盤的col向量,而陣列的值為棋盤的row向

量,所以(row,col)的皇后可以表示為(queenlist[col],col),如上圖中的幾個皇后可表示為:

queenlist[0] = 0;  queenlist[1] = 3;   queenlist[2] = 1;  queenlist[3] = 4;   queenlist = 2;

geightqueen[8]  為每個皇后的位置 , 這裡寫演算法就把它設為a[8]
eightqueen(index)     # 查詢道歉位置皇后的可能值  

a [ index ] ---> (0,7) 

check_pos_valid( index , a [ index ])

ok :    a [ index ]  =

index

index == 7         # 這裡代表已經是找到了第八個皇后的位置

輸出陣列的值。

return

eightqueen(index + 1)   #   查詢下乙個皇后的可能的位置

a [ index ]  = 0           

整個過程,相當的巧妙。

#includeusing namespace std;

static int geightqueen[8] = , gcount = 0;

void print()//輸出每一種情況下棋盤中皇后的擺放情況

cout <

}int check_pos_valid(int loop, int value)//檢查是否存在有多個皇后在同一行/列/對角線的情況

return 1;

}

void eight_queen(int index)

eight_queen(index + 1);

geightqueen[index] = 0;}}

}

int main(int argc, char*argv)

八皇后問題 遞迴(回溯演算法)

國際西洋棋棋手馬克斯貝瑟爾於1848年提出 在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處在同一行 同一列或者同一斜線上,問有多少種擺法 92 1.第乙個皇后先放在第一行第一列 2.第二個皇后放在第二行第一列,然後判斷是否ok,如果不ok,繼續放在第二列 第三列,找合適的...

八皇后問題(遞迴,回溯演算法)

問題介紹 八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1884年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即 任意兩個皇后都不能處於同一行同一列或者同一直線上問有多少種擺法。1.第乙個皇后先放在第一列 2.第二個皇后放在第二行第一...

八皇后問題(遞迴,回溯)

八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當 n 1 或...