您的位置:首页 > 其它

拉斯维加斯算法求n皇后问题

2013-06-24 11:36 447 查看


拉斯维加斯算法求n皇后问题

#include <cstdlib>
#include <iostream>

using namespace std;

bool place(int x[],int k);
void queen(int n,int x[]);
void Output(int n,int x[]);
int main(int argc, char *argv[])
{
cout<<"请输入皇后的个数\n";
int n;
cin>>n;
int x[n+1];
x[0]=0;
cout<<"解向量是----\n";
queen(n,x);
system("PAUSE");
return EXIT_SUCCESS;
}
bool place(int x[],int k)
{
for(int i=1;i<k;i++)
if((x[i]==x[k])||(abs(x[i]-x[k])==abs(i-k)))
return 0;
return 1;
}
void queen(int n,int x[])
{
int k=1;
long num=0;
x[1]=0;
while(k>0)
{
x[k]+=1;
while((x[k]<=n)&&(!place(x,k)))
x[k]+=1;
if(x[k]<=n)
if(k==n)
{
num++;
Output(n,x);
}
else
x[++k]=0;
else
x[k--]=0;
}
system("PAUSE");
cout<<"一共有"<<num<<"种情况\n";
return;
}
void Output(int n,int x[])
{
cout<<"[";
for(int i=1;i<n;i++)
cout<<x[i]<<",";
cout<<x
<<"]"<<endl;
return;
}


一. 特征:

确定性算法的每一个计算步骤都是确定的,而随机算法允许算法在执行过程中随机地选择下一个计算步骤。在很多情况下,当算法在执行过程中面临一个选择时,随机性选择常比最优选择省时。因此随机算法可在很大程度上降低算法度。

拉斯维加斯算法不会得到不正确的解,但是有时找不到解。求得正确解的概率也依赖于算法所用的时间。

蒙特卡罗算法可求问题的精确解,但这个解不一定是正确的,求得正确解的概率也依赖于算法所用的时间。

二.原理

A.拉斯维加斯算法

通常采用bool型方法来表示拉斯维加斯算法。当算法找到一个解时返回true,否则false.

当返回false时,说明未得到解,那么可再次独立调用该算法,在时间允许的情况一直运算到出解为止。

B.蒙特卡罗算法

设P是一个实数,且0.5<p<1。如果蒙特卡罗算法对于问题的任一实例得到正确解的概率不小于P,则称该算法是p正确的。对于统一实例,蒙特卡罗算法不会给出两个不同的正确解答,则称该算法是一致的。而对于一个一致的p正确的蒙特卡罗算法,要提高获得正确解的概率,只要执行该算法若干次,并选择出现频率最高的解即可。

下面是用拉斯维加斯算法求解n皇后的程序



1 #include<iostream>
2 using namespace std;
3 class Queen{
4    friend bool nQueen(int);
5 private:
6    bool Place(int k);              //测试皇后K置于x[k]列的合法性
7    bool Backtrack(int t);          //解n后问题的回溯法
8    bool QueenLV(int stopVegas);    //随机放置n个皇后的拉斯维加斯算法
9    int n,*x,*y;
10 };
11 bool Queen::Place(int k){
12     for(int j=1;j<k;j++)//第k个皇后是否跟前面的皇后冲突
13         if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
14         return false;
15     return true;
16 }
17 bool Queen::Backtrack(int t){
18     if(t>n){//存放皇后放置的位置
19         for(int i=1;i<=n;i++)
20         y[i]=x[i];
21         return true;
22     }
23     else{
24         for(int i=1;i<=n;i++){
25             x[t]=i;//t皇后放在第i列
26             if(Place(t)&&Backtrack(t+1))
27             return true;
28         }
29     }
30     return false;
31 }
32 bool Queen::QueenLV(int stopVegas){
33     //随机放置n个皇后的拉斯维加斯算法
34
35     int k=1;//随机数产生器
36     int count=1;
37     //1<=stopVagas=<n表示允许随机放置的皇后数
38     while((k<=stopVegas)&&(count>0)){
39         count=0;
40         for(int i=1;i<=n;i++){
41             x[k]=i;
42             if(Place(k))
43             y[count++]=i;
44         }
45         if(count>0) //如果能放置,则在这么多个能放置第k个皇后的位置中选择一个位置
46         x[k++]=y[rand()%count];
47     }
48     return(count>0);//count>0表示放置成功
49 }
50 bool nQueen(int n){
51     //与回溯法相结合的接n后问题的拉斯维加斯算法
52     Queen X;
53     X.n=n;
54     int *p=new int[n+1];
55     int *q=new int[n+1];
56     for(int i=0;i<=n;i++){
57         p[i]=0;
58         q[i]=0;
59     }
60     X.y=p;
61     X.x=q;
62     int stop=5;
63     if(n>15)
64       stop=n-15;
65     bool found=false;
66     while(!X.QueenLV(stop));//直到能放置
67     //算法的回溯搜索部分
68     if(X.Backtrack(stop+1)){
69         for(int i=1;i<=n;i++)
70         cout<<p[i]<<"  ";
71         found=true;
72     }
73     cout<<endl;
74     delete []p;
75     delete []q;
76     return found;
77 }
78 int main(){
79     int n;
80     cout<<"n:";cin>>n;
81     if(!nQueen(n))
82       cout<<"无解"<<endl;
83     return 0;
84 }


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: