c_cpp 拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时用拉斯维加斯算法找不到解。与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时用拉斯维加斯算法找不到解。与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时相关的知识,希望对你有一定的参考价值。

#include"time.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);
}
//随机化算法 拉斯维加斯算法 n后问题
#include "stdafx.h"
#include "RandomNumber.h"
#include <cmath>
#include <iostream>
using namespace std;
 
class Queen
{
	friend bool nQueen(int);
	private:
		bool Place(int k);					//测试皇后k置于第x[k]的合法性
		bool Backtrack(int t);				//解n后问题的回溯法
		bool QueensLV(int stopVegas);		//随机放置n个皇后拉斯维加斯算法
		int n,*x,*y;
};
 
//测试皇后k置于第x[k]列的合法性
bool Queen::Place(int 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;
}
 
//解n后问题的回溯法
bool Queen::Backtrack(int t)
{
	if(t>n)
	{
		for(int i=1; i<=n; i++)
		{
			y[i] = x[i];//问题的解
		}
		return true;
	}
	else
	{
		for(int i=1; i<=n; i++)
		{
			x[t] = i;
			if(Place(t)&&Backtrack(t+1))
			{
				return true;
			}
		}
	}
	return false;
}
 
 
//随机放置n个皇后拉斯维加斯算法
bool Queen::QueensLV(int stopVegas)
{
	RandomNumber rnd;		//随机数产生器
	int k = 1;
	int count = 1;
 
	//1<=stopVegas<=n
	while((k<=stopVegas)&&(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表示放置成功
}
 
//与回溯法相结合的解n后问题的拉斯维加斯算法
bool nQueen(int n)
{
	Queen X;
	
	//初始化X
	X.n = n;
 
	int *p = new int[n+1];
	int *q = new int[n+1];
 
	for(int i=0; i<=n; i++)
	{
		p[i] = 0;
		q[i] = 0;
	}
 
	X.y = p;
	X.x = q;
 
	int stop = 3;
	if(n>15)
	{
		stop = n-15;
	}
 
	bool found = false;
	while(!X.QueensLV(stop));
 
	//算法的回溯搜索部分
	if(X.Backtrack(stop+1))
	{
		for(int i=1; i<=n; i++)
		{
			cout<<p[i]<<" ";
		}
		found = true;
		cout<<endl;
	}
	
	delete []p;
	delete []q;
	return found;
}
 
int main()
{
	int n=8;  
    cout<<n<<"皇后问题的解为:"<<endl;  
    while(!nQueen(n));  
    return 0;  
}
//随机化算法 拉斯维加斯算法 n后问题
#include "stdafx.h"
#include "RandomNumber.h"
#include <cmath>
#include <iostream>
using namespace std;
 
class Queen
{
	friend void nQueen(int);
	private:
		bool Place(int k);		//测试皇后k置于第x[k]列的合法性
		bool QueensLv(void);	//随机放置n个皇后拉斯维加斯算法
		int n;					//皇后个数
		int *x,*y;				//解向量
};
 
//测试皇后k置于第x[k]列的合法性
bool Queen::Place(int 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;
}
 
//随机放置n个皇后的拉斯维加斯算法
bool Queen::QueensLv(void)
{
	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 表示放置成功
}
 
//解n后问题的拉斯维加斯算法
void nQueen(int n)
{
	Queen X;
	X.n = n;
 
	int *p = new int[n+1];
	for(int i=0; i<=n; i++)
	{
		p[i] = 0;
	}
	X.x = p;
	X.y = new int[n+1];
 
	//反复调用随机放置n个皇后的拉斯维加斯算法,直到放置成功
	while(!X.QueensLv());
 
	for(int i=1; i<=n; i++)
	{
		cout<<p[i]<<" ";
	}
	cout<<endl;
	delete []p;
}
 
int main()
{
	int n=8;  
    cout<<n<<"皇后问题的解为:"<<endl;  
    nQueen(n);  
    return 0;  
}

以上是关于c_cpp 拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时用拉斯维加斯算法找不到解。与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 【随机化算法】n后问题【7.4.1】拉斯维加斯(Las Vegas)算法

迪杰斯克拉算法是怎样的?

随机化思想导论

常用算法

常用算法

Luogu P3959 宝藏