假设循环找到最后一个可用位置时 nb=k(k≥2,即共有 k 个可用位置),则选择第 k 个可用位置的概率显
然是 p(k)=1/k,下面计算 p(k-1),若要选择第 k-1 个可用位置必须满足两个条件;
①nb=k-1 时,uniform(1..nb)=1,第 k-1 次选第 k-1 个可用位置位置。
②nb=k 时 uniform(1..nb)≠1,第 k 次不选第 k 个可用位置则
P(k-1)=(1/(k-1))(1-p(k))=(1/(k-1))(1-1/k)=1/k;
计算 p(k-2),若要选择第 k-2 个可用位置必须满足三个条件:
①nb=k-2 时,uniform(1..nb)=1,第 k-2 次选第 k-2 个可用位置
②nb=k-1 时,uniform(1..nb)≠1,第 k-1 次不选第 k-1 个可用位置
③nb=k 时,uniform(1..nb)≠1,第 k 次不选第 k 个可用位置
P(k-2)=(1/(k-2))(1-p(k-1))(1-p(k))=(1/(k-2))(1-1/(k-1))(1-1/k)=1/k;
类似,可得 p(k-3)=p(k-4)=…=p(1) =1/k
命题得证。
EX08、写一算法,求 n=12~20 时最优的 StepVegas 值。
///////////////////////////////////Queen.h
class Queen
{
}
}
}
return false;
{
count = 0;
}
bool Queen::QueensLV(int stopVegas) //随机放置 n 个皇后的 Las Vegas 算法
{
int k = 1; //随机数产生器
int count = 1;
while( (k <= stopVegas) && (count > 0) )
friend bool nQueen(int, int);
friend bool nQueen(int n, int stopVegas,int &VistedNodes);
int getVistedNodes()
{
return vistedNodes;
}
private:
//测试皇后 k 置于第 x[k]列的合法性
bool Place(int k);
bool Backtrack(int t); //解 n 后问题的回溯法
bool QueensLV(int stopVegas); //随机放置 stopVegas 个皇后 LV 算法
int n;
int vistedNodes; //一次搜索成功或失败访问的节点数。
int *x;
int *y;
//皇后个数
//解向量
};
bool Queen::Place(int k)
{//测试皇后 k 置于第 x[k]列的合法性
for( int j=1; j n)
{
}
else
{
{
for(int i=1; i<=n; ++i)
{
y[i] = x[i];
}
return true;
for(int i=1; i<=n; ++i)
x[t] = i;
if( Place(t) && Backtrack(t+1) )
{
return true;
}
bool nQueen(int n, int stopVegas,int &vistedNodes)//算法:先 LV 后回溯法
{
for( int i = 1; i <= n; ++i)
{
x[k] = i;
if( Place(k))
{
y[count++] = i;
}
}
if( count > 0 )
{
x[k++] = y[rand()%count];
}
}
return (count>0);
//放置成功
Queen X;
X.n = n;
X.vistedNodes = 0;
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;
bool found = false;
while(!X.QueensLV(stopVegas));
if(X.Backtrack(stopVegas+1)) //回溯搜索
{
found = true;
}
delete[] p;
delete[] q;
vistedNodes = X.vistedNodes;
return found;
}
//////////////hh.cpp
#include
#include
#include
#include
#include
#include"Queen.h"
using namespace std;
void test()
{
for( int n=12; n<=20; ++n)
{
cout<<"皇后个数 n="<}else{
failVistedNodes += vistedNodes;
++failCount;
}
}
}
double p = 10.0/(10.0+failCount);
cout<
#include
#include
#include
using namespace std;
int q=0;
bool Btest(int a,int n)
{
int s=0,t=n-1;
int x;
do
{
s++;
t=t/2;
}while(t%2!=1);
for(int j=1;j<=t;j++)
x=(x*a)%n;
if(x==1||x==n-1)
{