随机算法的数学基础就是概率论的知识,比如大学本科阶段学习的独立性,互斥、样本期望以及各种分布的知识。在这里默认大家都了解了概率论的知识的前提下,对随机算法进行初步的介绍。在学习C、JAVA的时候,我们其实也经常用到随机产生函数random()等等,但是本文将侧重于介绍随机算法的理论。
一、随机算法
随机算法为使用随机函数发生器的算法,算法中的一些判断依赖于随机函数产生器的输出,因为任何随机函数产生器的输出随着运行过程改变。随机算法可以分成2类:
第一类:对相同的输入总是产生相同(正确)的输出的算法,拉斯维加斯算法(Las Vegas);
拉斯维加斯算法的执行时间依赖于随机函数产生器的输出,可以描述为一个随机变量;
第二类:对于相同的输入,其输出可能随运行过程的不同而不同的算法‘蒙特卡罗算法(Monte Carlo);
具有一个随机函数产生器输出的随机算法不同于具有不同的随机函数产生器输出的相同算法,因而随机算法可以看成是一族算法。与此相关的有高概率、误差概率等概念,在此不详述这些理论。下面给出两个随机算法的例子。
二、例子1:识别重复元素-拉斯维加斯类型
1、问题描述:考虑一个有n个数字的数组a[ ],当中(n/2)个是不同元素,而其余元素是另一个元素的拷贝,也就是说数组中共有(n/2)+1个不同的元素,现在需要设计算法来识别这个重复的元素。
2、思路:任何确定性算法至少需要(n/2)+2个时间步。说明如下:假设一个智者,他知道所用算法的所有知识,掌握算法的输入选择,确保算法选择的前(n/2)+1个元素都是不同的,此时还需要再查看一个就能得到结果。
如果采用拉斯维加斯算法,只需要花费O(log N)的时间,随机选择2个数组元素,并检查它们是否来源于不同的数组位置并且拥有相同的值,如果是,则发现了重复元素,如果不是,则继续采样。
-----------------------------------------------------------------------------------
int RepeatedElement(Type a[ ], int n)
{
while(1)
{
int i =random()%n +1;
int j =random()%n +1;
if ( ( i != j)&&(a[i]==a[j]) )
return (i);
}
}
------------------------------------------------------------------------------------
三、例子2:素数测试-蒙特卡罗算法
1、问题描述:确定一个整数是否是素数。
2、解决方案:解决此问题需要数论中的2个定理为支柱。
定理1:【Fermat】:若n为素数,那么对任何整数a<n,,有a^(n-1)模n余1;(著名的费尔马小定理)
定理2:若n为素数,等式x^2模n余1,有2个解,即1和n-1;(二次探测定理)
根据以上两个定理,如到Miller-Rabin算法的一般步骤:
0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
1、随机取一个b,2<=b
2、计算v=b^m mod n
3、如果v==1,通过测试,返回
4、令i=1
5、如果v=n-1,通过测试,返回
6、如果i==j,非素数,结束
7、v=v^2 mod n,i=i+1
8、循环到5