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

拉斯维加斯算法求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[n]<<"]"<<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 }
复制代码
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值