算導4(8皇后 回溯問題)

2021-06-17 21:59:28 字數 1735 閱讀 6845

solve the 8-queenproblem using back-trackingalgorithm.

解題思路:

這道題目可以使用回溯演算法。這種方法的思想是:為了求得問題的解,先選擇某一種可能情況向前探索,如果發現是錯誤的,則退回一步重新選擇,繼續向前探索,如此反覆進行,直至得到解或者證明無解。要解決n皇后問題,其實就是要解決好怎麼放置這n個皇后,每乙個皇后與前面的所有皇后不能在同一行、同一列、同一對角線,在這裡我們可以以行優先,就是說皇后的行號按順序遞增,只考慮第i個皇后放置在第i行的哪一列,所以在放置第i個皇后的時候,可以從第1列判斷起,如果可以放置在第1個位置,則跳到下一行放置下乙個皇后。如果不能,則跳到下一列...直到最後一列,如果最後一列也不能放置,則說明此時放置方法出錯,則回到上乙個皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。當第n個皇后放置成功後,即得到乙個可行解,此時再回到上乙個皇后重新放置尋找下乙個可行解...如此後,即可找出乙個n皇后問題的所有可行解。 

複雜度分析:

複雜度小於n^3。棋盤是n行n列的,但是在每列選擇可否放置的比較上又做了一次迴圈。但不是迴圈到n,而是根據皇后i的取值而變化的。所以複雜度應該是1/3n^3左右。

這是迭代的方法:

#include

#include

#include

#define n 8

int x[n+1];//放置的列數

//int final[n+1][n+1];

using namespace std;

void print(int x)

i++;

cout << endl; }

cout<< endl;

//memset(final, 0,sizeof(final));//這個絕對不能加,每次memset要浪費很多時間 

} bool place(int k)

returntrue;

} int nquees(int num)

if(x[k] <= n)//搜尋到合適的位置

else//如果沒有到達最後一行,則行數k加1。並且從第一列開始嘗試。 

}else k = k -1;//不能搜尋到合適的位置則說明上面的步驟有問題,則回溯到上一行重新比對。 

}returnnum; }

int main(int argc, char *argv)

這是遞迴的方法:

#include

#include

#define n 8

using namespace std;

int final[n+1][n+1];

int x[n+1];

int sum = 0;

void print()

cout << endl; }

} bool place(int k)

return true; }

int quees(int k)

else  }}

returnsum; }

int main(int argc, char *argv)

迭代回溯和遞迴回溯差不多。遞迴回溯存在乙個潛在的問題,即當n增大時,遞迴的複雜度也將是幾何級的增長,可能出現重複的情況。回溯法的解就是展開乙個樹。比如說這個n皇后問題,好像當n>60的時候,回溯法就不能完全地解決問題了,這時可以考慮用概率演算法來解決,它可以解決很大的基數,只不過結果不是很精確而已。

回溯 n皇后問題

思想 用回溯方法求解,首先要分析問題的求解空間。可用一棵n叉樹表示這個問題的求解空間,在回溯遍歷這個課二叉樹的過程中形成合理的解。對於這棵n叉樹,列序號i 0 n 1 是它的孩子,而每個孩子都有深度為n的子樹 包括自身 這些子樹的層次是n個皇后 也代表每個皇后的行序號,因為不同的皇后肯定不在同一行 ...

回溯 八皇后問題

八皇后問題 國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。分析 八皇后問題是回溯演算法的典型案例。我想我們在自己做的過程中,是這樣的 是先從 0,0 這個座標開始排放皇后,然後 1...

八皇后問題 回溯

在劉汝佳老師的書中對於8皇后問題的分析 我感覺非常經典 8皇后問題可行的解 92個 一共有3種思考的出發點 從64個格仔中選乙個子集,使得 子集中恰好有8個格仔,且任意兩個選出的格仔都不在同一行,同一列或同一對角線上 這正是子集的列舉問題。然而,64個格仔的子集有264個,太大了,這並不是乙個很好的...