c_cpp 【随机化算法】n后问题【7.4.1】拉斯维加斯(Las Vegas)算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 【随机化算法】n后问题【7.4.1】拉斯维加斯(Las Vegas)算法相关的知识,希望对你有一定的参考价值。
//随机化算法 拉斯维加斯算法 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;
}
#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);
}
以上是关于c_cpp 【随机化算法】n后问题【7.4.1】拉斯维加斯(Las Vegas)算法的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 【随机化算法】计算定积分【7.2.2】
c_cpp 【随机化算法】计算π值【7.2.1】
c_cpp 【随机化算法】跳跃表【7.3.3】舍伍德(舍伍德)算法
c_cpp 【随机化算法】线性时间选择算法【7.3.1】舍伍德(舍伍德)算法
c_cpp 【随机化算法】素数测试【7.5.3】蒙特卡罗(Monte Carlo)算法
c_cpp 【随机化算法】搜索有序表【7.3.2】舍伍德(舍伍德)算法