拉斯维加斯算法的一个显著特征就是它所做的随机性决策有可能导致算法找不到所需的解。因此常用一个bool型函数表示拉斯维加斯算法。找到解就返回true,否则返回false。
n后问题典型的有回溯法(n后问题这里不多说),但是也是拉斯维加斯算法的一个很好的例子。(这里用八皇后实例,n后都是可行的)
拉斯维加斯算法的思想如下:在棋盘上相继的各行中随机地放置皇后,并注意放置的合法性,直至n个皇后都相容的放好。
#include<iostream.h>
#include<time.h>
#include<math.h>
//随机数类
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;
class RandomNumber
{
private:
//当前种子
unsigned long randSeed;
public:
RandomNumber(unsigned long s=0); //构造函数,默认值0表示由系统自动生成种子
unsigned short Random(unsigned long n); //产生0到n-1之间的随机数
double fRandom(void); //产生[0,1)之间的随机数
};
RandomNumber::RandomNumber(unsigned long s) //产生种子
{
if(s==0)
randSeed=time(0); //用系统时间产生种子
else
randSeed=s; //由用户提供种子
}
unsigned short RandomNumber::Random(unsigned long n) //产生0到n-1之间的随机整数
{
randSeed=multiplier*randSeed+adder;
return(unsigned short)((randSeed>>16)%n);
}
double RandomNumber::fRandom(void) //产生[0,1)之间的随机数
{
return Random(maxshort)/double(maxshort);
}
//---------------------------------------------------------------------------------
class Queen
{
public:
friend void nQueen(int);
bool Place(int k); //测试皇后k放到第x[k]列的合法性
bool QueensLV(void); //随机放置n个皇后拉斯维加斯算法
private:
int n,x[9],y[9]; //n-皇后个数 x,y-解向量,从x[1][y1]开始
};
bool Queen::Place(int k)
{
//测试皇后k放到第x[k]列的合法性
for(int j=1;j<k;j++)
if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
return false;
return true;
}
bool Queen::QueensLV(void)
{
//随机放置n个皇后的拉斯维加斯算法
RandomNumber rnd; //随机数产生器
int k=1;
int count=1;
while((k<=n)&&(count>0))
{
count=0;
for(int i=1;i<=n;i++)
{
x[k]=i;
if(Place(k)) y[count++]=i;
}
if(count>0) x[k++]=y[rnd.Random(count)]; //位置随机
}
return (count>0); //count>0表示放置成功
}
void nQueen(int n)
{
//解n后问题的拉斯维加斯算法
Queen X;
//初始化X
X.n=n;
//反复调用随机放置n个皇后的拉斯维加斯算法,直至放置成功
while(!X.QueensLV());
for(int i=1;i<=n;i++) cout<<X.x[i]<<" ";
cout<<endl<<endl;
//直观的表示
int view[9][9]; //初始化"棋盘"
int a,b;
for(a=1;a<=8;a++)
for(b=1;b<=8;b++)
view[a][b]=0;
for(i=1;i<=n;i++)
view[i][X.x[i]]=1; //1代表有皇后
for(a=1;a<=8;a++)
{
for(b=1;b<=8;b++)
cout<<view[a][b]<<" ";
cout<<endl;
}
cout<<endl;
}
int main()
{
int n=8;
nQueen(n);
return 0;
}