拉斯維加斯算法的一個顯著特徵就是它所做的隨機性決策有可能導致算法找不到所需的解。因此常用一個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;
}