學校資料結構的課程實驗之一。
資料結構:(其實只用了乙個二維陣列)
演算法:深度優先搜尋,試探回溯
需求分析:
設計乙個在控制台視窗執行的「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 當把問題分成若干步驟並遞迴求解時,如果當前步驟沒有合法選擇,則函式將返回上一級遞迴呼叫,這種現象稱為回溯。...