回溯法求解N皇后問題。

2021-06-20 02:16:22 字數 1762 閱讀 7175

n皇后問題就是:不存在兩個皇后同行或同列,或在同一斜線上。如下圖所示。黑色塊表示其中乙個皇后放在了第二行,第三列。這時,只有綠色圈圈才能放其他的皇后。

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

看看如何用回溯法解n皇后問題。首先找出解空間:給棋盤的行和列都編上1到n的號碼,皇后也給編上1到n的號碼。由於乙個皇后應在不同的行上,為不失一般性,可以假定第i個皇后將放在第i行上的某列。因此n皇后問題的解空間可以用乙個n元組(x1,x2,.....xn)來表示,其中xi是放置皇后i所在的列號。這意味著所有的解都是n元組(1,2,3,.......,n)的置換。解空間大小為n!。其次我們看約束條件:因為解空間已經給我們排除了不在同一行(因為每個皇后分別已經對應不同的行號)的約束條件。我們要判斷的是不在同一列和不在同一斜線的約束。因為xi表示皇后所在的列號,所以第k個皇后和第i個皇后同列的判斷條件是x(k)=x(i)。所以不同列的判段條件是x(k)!=x(i),1第k個皇后和第i個皇后在同斜線的判斷條件是 i+x(i)=  k+x(k) 或 i-x(i) =k-x(k),兩式合併得 |x(i)-x(k)|=|i-k|  。

程式設計基本思路:x(j)表示乙個解的空間,j表示行數,裡面的值表示可以放置在的列數,抽象約束條件得到能放置乙個皇后的約束條件(1)x(i)!=x(k);(2)abs(x(i)-x(k))!=abs(i-k)。應用回溯法,當可以放置皇后時就繼續到下一行,不行的話就返回到第一行,重新檢驗要放的列數,如此反覆,直到將所有解解出。 

#include#includeusing namespace std;

#define n 60

int sum = 0; //可行解個數

int x[n]; //皇后放置的列數 (預留的空間)

bool isplaceable(int queenatrow)

else

}

} return sum;

}

/*功能: 求解放置n皇后方案的個數。

輸入: 皇后個數

返回: int:放置n皇后方案的個數

圖來自:

回溯法解析參考:

回溯法求解n皇后問題

皇后問題 由n n個方塊排成n行n列的正方形稱為 n元棋盤 如果兩個皇后位於棋盤上的同一行或同一列或同一對角線上,則稱她們為互相攻擊,現要求找使n元棋盤上的n個皇后互不攻擊的所有布局。假設棋盤上每一行放置乙個皇后,分別用自然數0,1,2,n 1。首先定義乙個長度為n的一維陣列q,其中每乙個元素去q ...

回溯法求解N皇后問題

原始出處 作者資訊和本宣告。否則將追究法律責任。回溯法 也稱為試探法,它並不考慮問題規模的大小,而是從問題的最明顯的最小規模開始逐步求解出可能的答案,並以此慢慢地擴大問題規模,迭代地逼近最終問題的解。這種迭代類似於窮舉並且是試探性的,因為當目前的可能答案被測試出不可能可以獲得最終解時,則撤銷當前的這...

使用回溯法求解N皇后問題

經典的n皇后問題描述為 在乙個n x n的棋盤上放置n個皇后,要求任意的兩個皇后都不在同一行 同一列或同一條對角線上,問在給定n的情況下有多少種放置的方法。求解n皇后最典型的方法是回溯法,此方法的思路可以概括為 在第一行佔據乙個位置,接著在下一行佔據乙個位置,判斷兩個位置之間是否存在衝突。如果不存在...