概率算法

 我们为什么要研究概率算法呢?其实在实际中我们会发现,有时候随机选择结果比花费时间去做最优选择的结果要好的多(即概率算法的期望时间非常的可观);且有时利用确定性算法求不出问题的解,而利用随机算法则总是可以求得问题的近似解,例如我们求f(x)=sin2((100)!πx),f(x)在[0,1]上的积分。所以概率算法也称随机决策算法,是基于概率论、统计学理论基础的。概率算法对同一输入实例的不同次执行会给出不同的解,即解的结果不可再现。所以可能会出现最坏的可能性,但是对于期望时间来说概率算法却具有重要意义。

总得来说其特点是:1)期望时间可观;2)结果不可再现性; 3)基于概率论、数理统计等;

概率算法包括:(1)Numerical概率算法;(2)Sherwood算法;(3)Las Vegas算法;4)Monte Carlo算法;

以下在讲完随机数产生原理后我们再详细探讨这每一种算法的特点及应用。我们利用在C中rand()是怎么产生一个个不同的数的呢,这些数字是否有一定的规律呢?其实,是有的。因为现实中不可能真正的随机数发生器,因此我们用就通过一个数(来作为种子)利用某个公式来产生一个数,而这个新产生的数又会作为输入通过公式产生另一个数,如此,每次新产的的数都会作为下次计算的种子,从而产生新的数。所以,如果每次都采用相同的数作为种子的话,那么每次产生的新数就会一样。对于种子的选择在加密算法中要求较高,这里就不探讨了。

uniform(a,b){//////随机产生a~b之间的一个数 

      srand(time(NULL));

      return ((b-a)*rand()/(double)RAND_MAX+a);

}

(一)Numerical概率算法

数字概率算法得到的是数字问题的近似解,但是随着算法执行时间的增加,解的精度就越高误差越小。不过也不可能无限执行,因为长时间运行会导致硬件产生错误。应用如;求积分;求集合大小(势);矩阵相乘、求逆、特征值和特征向量等等。

eg、集合X={x1,x2,.........,xn};求集合X的大小n值?(在X中随机均匀独立的取元素,直到第一次出现重复之前所选的元素为止,此时已选出的元素数为k,则有n=2*k*k/π)。

        Count (X) {

                   k ← 0; S ← Ф;

                   a ← uniform(X);

                  do {

                         k++;

                         S ← S{a}; 

                        a ← uniform(X);

                   } while (a不在集合S中)

                  return 2*k*k/π;

        }

(二)Sherwood算法

Sherwood算法就是在某一确定性算法中引入随机性的一种算法。为什么要在确定算法中引入随机性呢?目的有两个:一是引入随机性可以实现对数据的隐藏、保密等;二是引入随机性可以消除输入实例和算法最坏行为的联系(注意此处是消除不是避免);其特点如下:

(1)该算法总能得到正确的解;

(2)在确定算法平均时间比最坏时间小的多时,可以利用sherwood算法来减少或消除好坏实例之间的差别;

(3)其性能并不一定优于相应确定算法的平均性能;

确定算法是如何通过引入随机性变换成Sherwood算法的呢?首先是通过某一个函数u()将确定算法的输入实例x转换为一个随机实例y;然后根据确定算法提供的函数f()求解f(y);最后通过另一函数v()将求得的关于y的解转换为关于x的解即可完成转换。

eg、对一组元素Arr[N]进行洗牌。

        ReSort(Arr){

                 n=该数组元素个数N;

                 for i=1 to n-1

                 {

                        j=uniform(i.....n);

                        swap(Arr[i],Arr[j]);/////将前i-1个和后i....n个元素交换

                  }

        }

eg、求离散对数算法。 设 a=gx mod p,记logg,pa=x,称xa(g为底模除p)对数。从p,g,a计算x称为离散对数问题。

        ModularExponent(g,r,p){//求幂模b=gr mod p

            s=1;

           while(r>0){

                 if(r是奇数) s=s*g;

                 g=g*g;

                 r=r/2; 

             }

             return s;

        }

        dlogRH(g, a, p) { //  Sherwood算法求x=logg,p a ,a = gx mod p,求x

            r ← uniform(0..p-2);

            b ← ModularExponent(g, r, p); 

            c ← b*a mod p; 

            y ← logg,pc; // 使用确定性算法求logp,gc, y=r+x

            return (y-r) mod (p-1); // x

        }

 

(三)Las Vegas算法

Las Vegas(拉斯维加斯)是世界著名的赌城,赌博业的盈利主要靠统计和概率,其设计大量的随机性,所以人们常用赌城名字来命名一类随机算法。Las Vegas算法就是一种随机算法。为方便一下简写Las Vegas为LV。

     对于LV算法有时可能找不到解,但是若能找到解则该解一定是正确解。当找不到解就会陷入僵局,而此时再次使用相同实例运行该算法则可能有机会求出解(因为该算法的没次调用是彼此独立的)。也就是说求解问题的任一实例,通过LV算法反复调用足够多次数,使得算法以高概率找到问题的解即失效概率任意小。

       LV算法一般形式:LV(x,y,success);x为输入实例;y为返回解;success=true表示成功,否则失败;我们假设p(x)表示算法成功的概率;s(x)表示算法成功的期望时间;e(x)表示算法失败的期望时间;对如下算法调用其找到一正确解的期望时间为t(x):

        Obstinate(x) {
                repeat
                         LV(x, y, success);
                until success;
                return y; 
        }

可知t(x)=p(x)(s(x)+(1-p(x))(e(x)+t(x)),化简得t(x)=s(x)+[1-p(x)]*e(x)/p(x);LV算法经典的应用是8皇后问题,即使用LV算法+回溯法求8皇后的解。思想是这样的:首先使用LV算法随机放置k(1=<k<8)个皇后(具体放置多少个最好呢?根据实验研究结果的出一半放着一半略少的皇后数较好),然后使用回溯法放置余下的皇后。(具体算法代码见:链接:http://pan.baidu.com/share/link?shareid=3448300892&uk=4265476249 密码:a42g)

(四)Monte Carlo算法

Monte Carlo算法是1945年由J.Von Neumann进行核武模拟提出的,Monte Carlo是一种近似数值算法,即采用概率模型模拟近似的数值计算;采用伪随机数模拟真正的随机变量样本。所以Monte Carlo算法是以概率统计为基础,以随机抽样为主要手段,利用计算机来进行数值计算的。故同Las Vegas算法的命名其命名来源于摩纳哥的一座赌城——蒙特卡洛市,该城以赌博业闻名。

Monte Carlo算法不像LV和Sherwood算法,它总是能返回一个解,但是对于该解的正确性其本身并不能给予保证。显然Monte Carlo算法也是会出错的,不过可喜的是Monte Carlo算法对于任何实例均能够以高概率返回正确的解。其应用领域较为广泛,如:金融工程、经济学、物理学等等。

分析研究Monte Carlo算法首先介绍两个小概念:p-正确算法和有偏算法;

1)对实数p,有1/2<p<1,若某一算法MC(X)以不小于p的概率返回正确解,则称该算法为p-正确算法。

2)有偏包括偏真和偏假,这里仅介绍偏真(偏假和偏真定义道理相同)。若某一算法MC(X)对任意x,当返回true时得到的解总是正确的,而返回false时才有可能产生错误的解,则称该算法为偏真算法。

下面我们就来看看其如何应用:

eg、利用Monte Carlo算法求解主元素问题?(主元素即一组书中其个数超过总数一半的数)

///判断元素x是否为ARR的主元素

        maj(ARR[n]){

              i=uniform(1...n);

              x=ARR[i];//在ARR中随机选择一个数判断是否为主元素

               k=0;

               for j=1 to n

                    if  ARR[j]==x   then

                         k++;//有和x相等的则计数+1

              return  (k>n/2);

        }

显然上述算法返回true时一定含有主元素,但返回false并不能说明没有主元素,因为随机选择的x可能不是主元素。假设ARR中含有主元素,那么随机选择到x是主元素的概率>1/2,不是主元素的概率小于1/2,所以该maj(ARR[n])算法是偏真的、1/2-正确的算法。

显然通过以上分析可知,要是该算法出错概率小于某个数ε(ε>0),对于p-正确算法使得ε任意小,则需要重复调用该算法k次,那么就有ε=(1-p)的k次幂。对上述maj(ARR[n]),有ε=(1/2)的k次幂。显然k=lg(1/ε),即算法需要调用lg(1/ε)次。进而有如下改进:

        maj_MC(ε,ARR[n]){

            k=lg(1/ε);

            for i=1 to k///////////////////////调用maj(ARR[n])k次

                  if  maj(ARR[n])  then

                      return true;

           return false;

       }

eg、利用Monte Carlo算法进行矩阵乘法的验证?(设A、B、C均为n阶矩阵,试判定A*B=C?)

如果用传统方法一个个乘加再比较则时间复杂度为n*n*n,而用Monte Carlo验证则n*n时间内即可解决。首先利用长为n的而二值向量[0/1]X,将判定改为计算(X*A)*B==XC。

        Metrix_pf(A,B,C,n){

              for i=1 to n

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

             if (X*A)*B==XC  then

                  return true;

             else

                  return false;

        }

显然算法Metrix_pf(A,B,C,n)也是一个有偏算法,那么是偏真呢还是偏假呢?由(X*A)*B==XC可知偏真还是偏假取决于X,X不等于0时判断正确,而但X=0时判断显然具有迷惑性(不能判断A*B=C),故而它是一个偏假的,1/2-正确算法。当反复调用该算法k次后可使得算法出错的概率小于某个数ε(ε>0),即有ε=(1/2)的k次幂。显然k=lg(1/ε)。同样对上述算法改进如下:

        Metrix_pf_MC(A,B,C,,n,ε){

             k=lg(1/ε);

             for i=1 to k

                  if  Metrix_pf(A,B,C,n)==false   then

                       return false;

             return true;

        }

你可能感兴趣的:(Monte,Las,概率算法,Vegas算法,Carlo算法,Sherwood算法,Numerical概率算法)