算法分析与设计学习笔记-概率算法_2

ch4 Las Vegas 算法

特点:有找不到解的风险,智慧返回正确的解,成功的概率随着执行时间的增加而增加

与sherwood算法比较:sherwood算法的平均性能不一定而且可以计算出一个给定实例的执行上界

lv算法更有效率,但是时间的上界可能不存在

形式 LV(x,y,success)输入实例,返回参数,是否成功

4.1 八皇后问题

回溯法:

i=j=1;

while i<8 do {//当前行号i<=8

检查当前行i:从当前列j起向后逐列试探,寻找安全列号;

if 找到安全的列号 then{

放置皇后,将列号记入栈内,将下一行置为当前行i++

j=1;//当前列置为1

}else{

退栈回到上一行,i--;

移去该行已经放置的黄根后,以该皇后所在列的下一列为当前列;

}

}


LV算法:

try[i]表示第i个皇后放在(i,try[i])位置上

安全位置:try[i]-try[j] != {i-j,0,j=i}//无行冲突,列冲突以及对角线冲突

Queen(success){//贪心的lv算法,所有的皇后都是随机放置

//如果success=true, 则try[1..8]包含8后问题的一个解

col,diag45,diag135=空;//列以及两个对角线集合对的初值为空

k=0;//行号

repeat//已经放置好k个皇后,考虑放第k+1个皇后

nb=0;//计数器,nb值为(k+1)个皇后的open位置总数

for i=1 to 8 do{//i为列号,试探(k+1,i)是否安全

if (i not in col) and (i-k-1 not in diag45) and (i+k+1 not in diag135) then{

//i列对与k+1皇后可用的,但是不着急把皇后放在第i列

nb=nb+1;

if uniform(1..nb)=1 then//或许放在第i列

j=i//注意第一次uniform一定返回1,则j一定有值i

}//end if

}//end for,在nb个安全位置上随机选择1个位置j放置

if(nb>0) then{

k=k+1;

try[k]=j;

col =col+{j};

diag45=diag45+{j-k};

diag135=diag135+{j+k};

}//end if

until (nb==0) or (k==8)


success=(nb>0);

}

LV算法改进:

将最后两行改为:

until nb=0 or k=stepVegas;

if(nb>0) then//已经随机放好stepVegas个皇后

backtrace(k,col,diag45,diag135,success);

else

 success = false

ps:一般来说一半使用随机,一半使用回溯法是比较好的


4.2 模p平方根

4.3 整数的因数分解

MC算法可以用来判定n是否为素数

split(n) -> n为合数时找到n的一个非平凡的因数

1)朴素的split算法

split(n){

//n为素数,返回1,否则返回找到的n的最小非平凡因数

for i=2 to 根号n的下整数 do {

if (n mod i)=0 then

 return i;//i>=2

}

return 1;//返回平凡因数

}

2)Dixon因数分解算法

基本思想:找到两个与n互素的整数a,b,使a^2=b^2(mod n)

n|(a^2-b^2)  n|(a+b)(a-b)

如果n不满足n|(a+b),n|(a-b),则存在n的一个非平凡因子x满足

x|(a+b),(n/x)|(a-b)

则n和a+b的最大共因子是n的一个非平凡因子


Dixon(n,x,success){//找到合数n的某一个非平凡因子

if n is even then{

x=2;

success=true;

}else{

for i=2 to log(3)n do

if n^(1/i)为整数then{

x=n^(1/i);

success=true;

return;

}//n为合数且为奇数,并且至少有2个不同的奇素数因子

a,b 为是a^2=b^2(mod n)的整数

if a==+-b(mod n) then success=false

else{

x=gcd(a+b,n);

success=true;

}

}

}

第一步:在1到n-1之间随机选择x

第二步:在k+1个灯饰中找到一个非空子集,使相应的因数分解的积中前k个素数的指数均为偶数

第三步:在第二步中找到线性相关的行之后另a为相应xj的乘积,b为yj的乘积开平方,然后求a+b与n的最大公因子



ch5 Monte Carlo算法

MC算法偶然会犯错,但它对于任何实例都能以高概率找到正确的解

MC算法是p-正确的:以不小于p的概率返回正确的解(1/2<p<1),算法优势为p-1/2

若MC算法对同一实例绝不给出两个不同的正确解,则为相容的或者一致的

可以通过多次调用同一个算法,选择次数出现最多的解

eg

MC(x)为一个一致的,0.75-正确的算法

MC3(x){

t=MC(x);

u=MC(x);

v=MC(x);

if t=u or t=v then return t;

else return v;

}//该算法为0.84-正确


偏真算法:MC(x)返回true时答案总是正确的,当返回false的时候才有可能产生错误的解

5.1 主元素问题

数组T中等于x的元素大于n/2,则x称为T的主元素

maj(T){

i=uniform(1..n);

x=T[i];

k=0;

for j=1 to n do {

if(T[j]==x) then k=k+1;

}

return k>n;

}

如果算法返回true,一定为正确,算法是一个偏真的1/2正确的算法

//调整后为0.75正确的算法

maj2(T){

if maj(T)then

return Ture;//success one time

else

return maj(T);

}

//MC算法改进

majMC(T,e){

k=lg(1/e);

//e=2^-k;

for i=1 to k do{

if maj(T) then return true;

}

return false;

}


5.2判断一个整数是否为素数

//简单算法

prime(n){

d=uniform(2..根号n)

return (n mod d)!=0;

}

//偏假的测定

Fermat(n){

a=uniform(1..n-1);

if a^n-1 mod n==1 then

return true;

else return false;

}

//Fermat测试改进

Btest(a,n){//n为计数,2<=a<=n-2,返回真说明n为强伪素数或者素数

s=0;

t=n-1;//t is even

repeat {s++:t=t/2}

until t mod 2=1;

x=a^t mod n;

if x=1 or x=n-1 then return true;

for i=1 to s-1 do{

x=x^2 mod n;

if x=n-1 then return true;

}

return false;

}


5.3 矩阵乘法验证

判定AB=C? 转换为判定XAB=XC?(X为一个长度为n的二值01向量)

goodproduct(A,B,C,n){//偏假的1/2-正确算法

for i=1 to n do{

x[i]=uniform(0..1);

}

if (XA)B=XC then

return true;

}


//改进

RepeatGoodProduct(A,B,C,n,k){

for i=1 to k do{

if goodproduct(A,B,C,n)=false then return false;

}

return true;

}//偏假的1-2^-k 正确算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值