n皇后問題

2021-07-04 13:37:24 字數 1605 閱讀 8599

8皇后問題和由他推廣得到的n皇后問題**於西洋棋的玩法,因為皇后所在的位置可以縱向、橫向、兩個斜向四個方向的「捕捉」,所以8皇后問題就是要求如何布置8個皇后在8*8的棋盤上而使他們互相無法「捕捉」。也就是說不存在兩個皇后同行或同列,或在同一斜線上。而n皇后問題就是如何布置n個皇后在n*n棋盤裡使不存在兩個皇后在同行同列和同一斜線上。因為8皇后問題可以歸為n皇后問題,所以下面按照n皇后問題來進行討論。

回溯法的基本思想:確定了解空間的組織結構後,回溯法就從開始結點(根結點)出發,以深度優先的方式搜尋整個解空間。這個開始結點就成為乙個活結點,同時也成為當前的擴充套件結點。在當前的擴充套件結點處,搜尋向縱深方向移至乙個新結點。這個新結點就成為乙個新的活結點,並成為當前擴充套件結點。如果在當前的擴充套件結點處不能再向縱深方向移動,則當前擴充套件結點就成為死結點。換句話說,這個結點不再是乙個活結點。此時,應往回移動(回溯)至最近的乙個活結點處,並使這個活結點成為當前的擴充套件結點。回溯法即以這種工作方式遞迴地在解空間中搜尋,直至找到所要求的解或解空間中已沒有活結點時為止。

運用回溯法解題通常包含以下三個步驟:

(1)針對所給問題,定義問題的解空間;

(2)確定易於搜尋的解空間結構;

(3)以深度優先的方式搜尋解空間,並且在搜尋過程中用剪枝函式避免無效搜尋;

一般回溯法可用遞迴來實現,下面是從網上找來的乙個非常典型的遞迴程式結構。

procedure try(i:integer);

varbegin

if i>n then 輸出結果

else   for j:=下界 to 上界 do

begin

x[i]:=h[j];

if 可行 then begin 置值;try(i+1); end;

end;

end;

說明:i是遞迴深度; 

n是深度控制,即解空間樹的的高度;

可行性判斷有兩方面的內容:不滿約束條件則剪去相應子樹;若限界函式越界,也剪去相應子樹;兩者均滿足則進入下一層,直到最後的葉子輸出結果。

回到n皇后問題的解決來,看看如何用回溯法解。首先找出解空間:給棋盤的行和列都編上1到n的號碼,皇后也給編上1到n的號碼。由於乙個皇后應在不同的行上,為不失一般性,可以假定第i個皇后將放在第i行上的某列。因此n皇后問題的解空間可以用乙個n元組(x1,x2,.....xn)來表示,其中xi是放置皇后i所在的列號。這意味著所有的解都是n元組(1,2,3,.......,n)的置換。解空間大小為n!。其次我們看約束條件:因為解空間已經給我們排除了不在同一行(因為每個皇后分別已經對應不同的行號)的約束條件。我們要判斷的是不在同一列和不在同一斜線的約束。因為xi表示皇后所在的列號,所以如果存在x(k)=x(i)那麼肯定存在第k個皇后和第i個皇后同列。所以不同列的判段條件是x(k)!=x(i),1程式設計基本思路:x(j)表示乙個解的空間,j表示行數,裡面的值表示可以放置在的列數,抽象約束條件得到能放置乙個皇后的約束條件(1)x(i)!=x(k);(2)abs(x(i)-x(k))!=abs(i-k)。應用回溯法,當可以放置皇后時就繼續到下一行,不行的話就返回到第一行,重新檢驗要放的列數,如此反覆,直到將所有解解出。

#include

#include

/*檢查可不可以放置乙個新的皇后*/

bool place(int k, int *x)

N皇后問題

include define maxqueens 20 define minqueens 4 enum bool typedef struct queendata queendata queendata queens maxqueens 1 int ncount init int init chec...

N皇后問題

採用遞迴回溯法 執行結果 輸入8 對於n皇后解的個數,參考 當n 16時,構造法給出解,參考poj 3239 一 當n mod 6 2 且 n mod 6 3時,有乙個解為 2,4,6,8,n,1,3,5,7,n 1 n為偶數 2,4,6,8,n 1,1,3,5,7,n n為奇數 上面序列第i個數為...

N皇后問題

問題 題目 於西洋棋的玩法,因為皇后所在的位置可以縱向 橫向 兩個斜向四個方向的 捕捉 所以8皇后問題就是要求如何布置8個皇后在8 8的棋盤上而使他們互相無法 捕捉 也就是說不存在兩個皇后同行或同列,或在同一斜線上。而n皇后問題就是如何布置n個皇后在n n棋盤裡使不存在兩個皇后在同行同列和同一斜線上...