用試探回溯法解決N皇后問題

2021-07-01 19:31:17 字數 2064 閱讀 7339

學校資料結構的課程實驗之一。

資料結構:(其實只用了乙個二維陣列)

演算法:深度優先搜尋,試探回溯

需求分析:

設計乙個在控制台視窗執行的「n皇后問題」解決方案生成器,要求實現以下功能:

由n*n個方塊排成n行n列的正方形稱為n元棋盤。如果兩個皇后位於n元棋盤上的同一行、同一列或同一對角線上,則稱它們在互相攻擊。現要找出使棋盤上n個皇后互不攻擊的布局。

編制程式解決上述問題,以n=6執行程式,輸出結果。

演算法解釋:

首先試探當前行第乙個可用的位置(列、對角線沒有被占領),擺放皇后之後,試探下一行的第乙個可用位置;如果遇到此行沒有可用位置,則返回上一行,移除上一行的皇后,試探此行的下乙個可用位置,直至n個皇后全部擺放好,生成一種方案。

主函式:

int main()

/*pre: the user enters a valid board size.

post: all solutions to the n-queens puzzle for the selected board size

are printed.

uses: the class queens and the recursive functionsolve from. */

cout

<< endl << "would you like to continue? [y/n]"

<< endl;

//回車符的消去

fflush(stdin);

while ((enter = cin.get()) == '\n')

cin.putback(enter);

cin >> choice;//移植了計算器的**

}return

0;}

輔助函式(計算出所有解決方案)(參考了經典教材」data structures and program design in c++」 robert l. kruse, alexander j. ryba 高等教育出版社-影印版)

int

sum = 0;//記錄解決方案個數

int solve_from(queens &configuration)//通過遞迴、回溯找到所有解決方案並列印

/*pre: the queens configuration represents a partially completed

arrangement of nonattacking queens on a chessboard.

post: all n-queens solutions that extend the given configuration are

printed. the configuration is restored to its initial state.

uses: the class queens and the function solve_from, recursively.*/

return

sum;

}

注:

每次回溯其實有兩種可能:「擺放滿了n個皇后」或者「此行沒有可放的位置」,二者都會返回上一行去試探下一種可能,只不過擺滿n個皇后的情況會生成一種方案(被if截獲,回到上一層迴圈),生成後還是回到倒數第二行再進行試探。因此一次深度優先搜尋(呼叫一次solve_from函式)可以將所有方案全部輸出。

「皇后」類的定義

const

int max_board = 15;//最大棋盤階數

using namespace std;

class queens

;

執行截圖

注: 當輸入的棋盤階數比較大(如:8)時,命令列視窗的緩衝區預設300行可能會不夠顯示,所以要在屬性修改「高度」,使所有結果都顯示出來。

試探回溯法(N皇后問題)

然後影響速度的主要是函式中的checkout函式,我使用的是遍歷棧中所有皇后元素與當前皇后元素比對的方式,在棧中資料量龐大是時候似乎效率略低,這樣導致我的函式在計算n 9,10之類的方格時已需要數秒時間。然而鄧公的dsacpp中用的是vector繼承的find函式,相對來說速度比我的快一點,不過基本...

回溯法解決n皇后問題

回溯法的基本行為是搜尋,搜尋過程使用剪枝函式來為了避免無效的搜尋。剪枝函式包括兩類 1.使用約束函式,剪去不滿足約束條件的路徑 2.使用限界函式,剪去不能得到最優解的路徑。1 針對所給問題,確定問題的解空間 首先應明確定義問題的解空間,問題的解空間應至少包含問題的乙個 最優 解。2 確定結點的擴充套...

回溯法解決N皇后問題

在棋盤上放置8個皇后,使得它們互不攻擊,此時每個皇后的攻擊範圍為同行同列和同對角線,要求找出所有解。遞迴函式將不再遞迴呼叫它自身,而是返回上一層呼叫,這種現象稱為回溯 backtracking 當把問題分成若干步驟並遞迴求解時,如果當前步驟沒有合法選擇,則函式將返回上一級遞迴呼叫,這種現象稱為回溯。...