關於八皇后問題的解法

2021-05-24 10:13:39 字數 2262 閱讀 9594

八皇后問題是十九世紀著名的數學家高斯

1850

年提出:在

8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。

八皇后問題不是只用於這個有點無聊的數學問題上,不然就沒什麼研究意義了。在景觀設計,道路布局,城市規劃等方面有應用價值。比如布置景觀時,要讓

n個景觀互相不遮擋視線。

方案一

暴力法

最容易實現的,

8層迴圈巢狀

當然ok

,但它的複雜度驚人,

o(nn),n

為行列數

為了減少迴圈次數,針對該問題,最外層迴圈從第一列開始,向內層依次加

1,最內層迴圈就從第八列開始了。

方案二

回溯法

八皇后問題是回溯法經典的例子

回溯法基本的思想是採用遞迴,並且分步解決問題

首先擺第一行的皇后(都是從第一列開始擺)

然後擺第二行的皇后,擺在第一列,發現不行;擺第二列,也不行;擺第三列,行了。

接下來再擺第三行,都是從第一列開始擺,如果不行就依次往後挪。

以此類推,對於某一行,如果這一行每列都不行,那麼就得退回到上一行,(說明上一行的位置就已經不對了),上一行的皇后得往後再挪一格,如果已經是最後一格了,那就再退到上上一行……

如果擺到了最後一行,並且出現了乙個解,那麼將這個解輸出後,同樣再退回到上一行,將上一行的皇后往後挪一格……看看還有沒有其他解,直到不可能再出現其他解為止。

棋盤資訊,為了減少每次棋子調整帶來的

cost

,我們可以用四個一維陣列來表示。(傳統上用乙個二維陣列表示的話,每次棋子調整要改變陣列中很多個元素的值,而且相當混亂)

因為每個皇后的控制範圍為一行、一列再加對角線,所以與之對應的,我們把棋盤分成8行、

8列、15個左下斜對角線和

15個右下斜對角線,每一項都用乙個一維陣列表示。每次擺乙個皇后的時候,只需改變將與之對應的行、列、左下斜對角線和右下斜對角線陣列中元素(說明此行、列、對角線上不能再放其他皇后了),也就是只需改變

4個元素,而且這

4個元素的在它們的陣列中的下標與該皇后的橫縱座標有關(具體可以自己推算一下)。

類宣告如下(

cpp)

class chessboard

;關鍵方法的實現

void chessboard::putqueen(int row) }

}其實用回溯法的話,也窮盡了每一種情況,也是

exhaustive search

,而且它的效率還不如暴力法,因為用了遞迴。

方案三

best-first search

由於我們最初的問題是求所有的擺法,所以不管怎樣它一定是乙個

exhaustive search

問題了。如果我們把問題改一下,對任意一種棋盤狀態(八行裡每行都只有乙個皇后),怎樣才能最快的調整為乙個滿足條件的狀態。那這樣的話,就不能再像之前那樣盲目的去搜尋了,得採用一定的策略了,就是

informed search

。best-first search、a*

、hill climbing

和tabu search

等都能很好的解決該問題,我們以最基礎的

best-first search

來講述。

為了簡化問題,我們先來看乙個

4x4的棋盤。

給定乙個初始狀態,我們每次都對它挪動乙個棋子(也就是擴充套件後繼節點)。第一張圖中,第一行的棋子能朝左或右挪一格,第二行只能朝右挪一格,第三行第四行都能朝左或右挪一格。圖中

h表示深度,也就是調整的次數;

g表示當前的

conflicts

數,就是不符合的行、列和對角線總數。(圖中可能h和

g畫反了,真正的

h應該代表當前節點離目標節點的

cost

,也就是圖中的

g;真正的

g應該代表初始節點到當前節點的

cost

,也就是圖中的h)

根據best-first search

演算法,每次都將當前最好節點的所有後繼節點都插入

open list

中,每次都選擇

open list

中最好的節點進行擴充套件,直到選出的節點即為目標節點(圖中的

g=0)。每次都沿著當前最好的節點延伸,很快就能找到目標節點。

關於八皇后問題的研究 回溯演算法

今天從早上開始就在弄回溯法,都說回溯的經典問題是八皇后問題,於是就好好看了一下八皇后的問題。找出所有的情況可能有點難,但是找出一條路來感覺應該挺簡單的。我一直都不怎麼會用遞迴,這個程式依然沒有遞迴。這個演算法主要解決八皇后問題 public class huisu02 xx yy 判斷反對角線 xx...

關於八皇后問題的研究 回溯演算法

今天從早上開始就在弄回溯法,都說回溯的經典問題是八皇后問題,於是就好好看了一下八皇后的問題。找出所有的情況可能有點難,但是找出一條路來感覺應該挺簡單的。我一直都不怎麼會用遞迴,這個程式依然沒有遞迴。這個演算法主要解決八皇后問題 public class huisu02 xx yy 判斷反對角線 xx...

八皇后問題詳細解法

問題描述 在 8 8的棋盤上,放置8個 皇后 棋子 使兩兩之 間互不攻擊。所謂互不攻擊是說任何兩個皇后都要滿足 1 不在棋盤的同一行 2 不在棋盤的同一列 3 不在棋盤的同一對角線上。求 這8個皇后中的每乙個 應該擺放在哪一列。演算法分析 陣列 column down up 分別用來標記衝突,col...