問題如下:有乙個n×n
n\times n
n×n的棋盤,要求在上面放置n個皇后,這些皇后之間不能在一條直線或斜線上(45度),求乙個符合要求的放置方案。
拉斯維加斯演算法隨機產生乙個解,但是這個解不一定符合題設要求(即拉斯維加斯演算法可能找不到問題的解)。例如n皇后問題中,隨機產生的擺放位置可能符合
「n個皇后相互不在一條直線或斜線上」這一規則,也可能不符合
。因此,可以通過迴圈呼叫此演算法,直到找到乙個解為此。
完全使用拉斯維加斯演算法可能複雜度太高,長時間得不到解,故,
以下演示的程式中,前t個皇后的位置由拉斯維斯演算法產生,後n - t個由回溯法產生。
執行結果如下,1表示擺放的位置:
**如下:
#include
#include
"random.h"
#include
#define max_v 100
using
namespace std;
/* 判斷某行放置皇后是否合法
* i : 即將放置的行數
* j : 即將放置的列數
* */
bool
place
(int map[max_v]
[max_v]
,int n,
int i,
int j)
int l = j - b;
int r = j + b;
//判斷兩個斜線方向
if(l >=
0&& map[a]
[l]==1)
if(r < n && map[a]
[r]==1)
}return
true;}
/* 回溯剩下的皇后位置
* t : 回溯開始的位置
* */
bool
recall
(int map[max_v]
[max_v]
,int n,
int t)
for(
int i =
0; i < n; i++
) map[t]
[i]=1;
if(recall
(map, n, t+1)
) map[t]
[i]=0;
}return
false;}
/* n 皇后問題
* map : 棋盤
* n : 棋盤大小
* t : 使用拉斯維加斯演算法的層次數
* */
void
nqueen
(int map[max_v]
[max_v]
,int n,
int t)
for(
int j =
0; j < n; j++
) map[i]
[randpos]=1
;}if(i == t &&
recall
(map, n, t))}
}int
main()
;nqueen
(map,10,
7);for
(int i =
0; i <
10; i++
) cout << endl;
}return0;
}
拉斯維加斯演算法與N皇后問題
拉斯維加斯演算法 拉斯維加斯演算法不會得到不正確的解。一旦用拉斯維加斯演算法找到乙個解,這個解就一定是正確解。但有時用拉斯維加斯演算法找不到解。與蒙特卡羅演算法類似,拉斯維加斯演算法找到正確解的概率隨著它所用的計算時間的增加而提高。對於所求解問題的任一例項,用同一拉斯維加斯演算法反覆對該例項求解足夠...
回溯法解N皇后問題
回溯法解n皇后問題,要求就不說了,直接說思路和上 回溯法解n皇后問題 使用乙個一維陣列表示皇后的位置 其中陣列的下標表示皇后所在的行 陣列元素的值表示皇后所在的列 這樣設計的棋盤,所有皇后必定不在同一行 假設前n 1行的皇后已經按照規則排列好 那麼可以使用回溯法逐個試出第n行皇后的合法位置 所有皇后...
回溯法解n皇后問題
n皇后問題 在n n格的棋盤上放置彼此不受攻擊的n個皇后。按照西洋棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。n皇后問題等價於在n n格的棋盤上放置n個皇后,任何2個皇后不放在同一行或同一列或同一斜線上。輸出可行的棋盤排布,以及可行解的個數。用回溯法解n皇后問題,以下給出遞迴回溯...