八皇后 拉斯维加斯算法

拉斯维加斯算法的一个显著特征就是它所做的随机性决策有可能导致算法找不到所需的解。因此常用一个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;
}


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值