资源预览内容
第1页 / 共48页
第2页 / 共48页
第3页 / 共48页
第4页 / 共48页
第5页 / 共48页
第6页 / 共48页
第7页 / 共48页
第8页 / 共48页
第9页 / 共48页
第10页 / 共48页
亲,该文档总共48页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1,第7章 随机算法,2,学习要点 了解随机算法的基本特征 理解产生伪随机数的算法 掌握数值随机化算法的设计思想 掌握舍伍德算法的设计思想 掌握拉斯维加斯算法的设计思想 掌握蒙特卡罗算法的设计思想,3,概述,前面各章讨论的算法的每一个步骤都是确定的,而本章讨论的随机算法允许算法在执行过程中随机地选择一下计算步骤。,在许多情况下,一般算法比较复杂,性能较差,很多具有很好平均运行时间的算法,在最坏的情况下,却具有很坏的性能。由于随机性选择比最优选择省时间,因此引入随机化算法可以在很大程度上降低算法的复杂度。,4,很早以前就被人们所发现和利用。17世纪,人们就知道用事件发生的“频率”来决定事件的“概率”。19世纪人们用投针试验的方法来决定。高速计算机的出现,使得用数学方法在计算机上大量模拟这样的试验成为可能。,5,从Buffon(蒲丰)投针问题谈起,6,7,8,概述,随机算法对所求解问题的同一个实例用同一随机算法求解两次可能得到完全不同的效果。这两次求解所需要的时间,甚至所得到的结果都可能会有相当大的差别。 包括 数值概率算法 蒙特卡罗(Monte Carlo)算法 拉斯维加斯(Las Vegas)算法 舍伍德(Sherwood)算法,9,数值概率算法常用于数值问题的求解。将一个问题的计算与某个概率分布已经确定的事件联系起来,求问题的近似解。这类算法所得到的往往是近似解,且近似解的精度随计算时间的增加而不断提高。在许多情况下,要计算出问题的精确解是不可能或没有必要的,因此可以用数值随机化算法得到相当满意的解。,蒙特卡罗算法用于求问题的准确解,但得到的解未必是正确的。蒙特卡罗算法以正的概率给出正解,求得正确解的概率依赖于算法所用的时间。算法所用的时间越多,得到正确解的概率就越高。一般给定执行步骤的上界,给定一个输入,算法都是在一个固定的步数内停止的。,随机算法的分类,10,舍伍德算法总能求得问题的一个解,且所求得的解总是正确的。当一个确定性算法在最坏情况下的计算复杂性与其在平均情况下的计算复杂性有较大差别时,可在这个确定性算法中引入随机性将它改造成一个舍伍德算法,消除或减少问题的好坏实例间的这种差别(精髓所在)。,拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时可能找不到解。拉斯维加斯算法找到正确解的概率随着它所用的计算时间的增加而提高。对于所求解问题的任意实例,用同一拉斯维加斯算法反复对它求解,可以使求解失效的概率任意小。,随机算法的分类,11,7.1随机数,12,7.1随机数,随机数在随机化算法设计中扮演着十分重要的角色。在现实计算机上无法产生真正的随机数,因此在随机化算法中使用的随机数都是一定程度上随机的,即伪随机数。 线性同余法是产生伪随机数的最常用的方法。由线性同余法产生的随机序列a0,a1,an,满足:(混合同余法) 其中b0,c0,dm。d称为该随机序列的种子。如何选取该方法中的常数b、c和m直接关系到所产生的随机序列的随机性能。这是随机性理论研究的内容,已超出本书讨论的范围。从直观上看,m应取得充分大,因此可取m为机器大数。,13,d = 1 种子 m= 11 b=6 c = 0 (1,6,3,7,9,10,5,8,4,2,1,6,3),14,复杂一些的生成器,Multiple recursive generator,15,算法实现,许多程序语言中都自带生成随机数的方法,如 c 中的 random() 函数,Matlab中的rand()函数等。 但这些生成器生成的随机数效果很不一样,比如 c 中的函数生成的随机数性质就比较差,如果用 c ,最好自己再编一个程序。Matlab 中的 rand() 函数,经过了很多优化。可以产生性质很好的随 机数,可以直接利用。,16,下面用计算机产生的伪随机数来模拟抛硬币实验。假设抛10次硬币构成一个事件。调用Random(2)返回一个二值结果。返回0表示抛硬币得到反面,返回1表示得到正面。下面的算法TossCoins模拟抛10次硬币这一事件50000次。用headi (0 i 10)记录这50000此模拟恰好得到i次正面的次数。最终输出模拟抛硬币事件得到正面事件的频率图,如下图所示:,17,0 * 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 *,模拟抛硬币得到的正面事件频率图,18,void main (void) / 模拟随机抛硬币事件 const int NCOINS = 10; const long NTOSSES = 50000L; / headsi是得到i次正面的次数 long i, headsNCOINS+1; int j, position; / 初始化数组heads for (j=0;j NCOIN+1; j+) headsj = 0; / 重复50000次模拟事件 for (i=0;i NTOSSES; i+) headsTossCoins(NCOINS)+; / 输出频率图 for (i=0;i=NCOINS; i+) position = int (float (headsi)/NTOSSES*72); coutsetw(6)i“ “; for (j=0;jposition-1;j+) cout“ “; cout“*“endl; ,int TossCoins (int numberCoins) /随机抛硬币 static RandomNumber coinToss; int i, tosses = 0; for (i = 0; i numberCoins; i+) / Random (2) = 1 表示正面 tosses += coinToss.Random (2); return tosses; ,int TossCoins (int numberCoins) /随机抛硬币 static RandomNumber coinToss; int i, tosses = 0; for (i = 0; i numberCoins; i+) / Random (2) = 1 表示正面 tosses += coinToss.Random (2); return tosses; ,19,7.2 数值随机化算法,20,7.2 数值随机化算法,7.2.1 用随机投点法计算值 设有一半径为r的圆及其外切四边形。向该正方形随机地投掷n个点。设落入圆内的点数为k。由于所投入的点在正方形上均匀分布,因而所投入的点落入圆内的概率为 。,所以当n足够大时,k与n之比就逼近这一概率。从而 。,21,在具体实现时,只要在第一象限计算即可: double Darts (int n) / 用随机投点法计算值 static RandomNumber dart; int k=0; for (int i=1;i =n;i+) double x=dart.fRandom(); double y=dart.fRandom(); if (x*x+y*y)=1) k+; return 4*k/double(n); ,22,7.2.2 计算定积分,(1)用随机投点法计算定积分 设f(x)是0,1上的连续函数,且0f(x)1。需要计算的积分 为 , 积分 I 等于图中的面积G。,在图所示单位正方形内均匀地作投点试 验,则随机点落在曲线下面的概率为:,假设向单位正方形内随机地投入n个 点(xi,yi),i = 1,2,n。随机点(xi,yi)落入G内,则yi f(xi)。 如果有m个点落入G内,则随机点落入G内的概率,即,23,double Darts (int n) / 用随机投点法计算定积分 static RandomNumber dart; int k=0; for (int i=1;i=n;i+) double x=dart.fRandom(); double y=dart.fRandom(); if (y=f(x) k+; return k/double(n) ,24,7.3 舍伍德算法,25,7.3 舍伍德算法,设A是一个确定性算法,当它的输入实例为x时所需的计算时间记为tA(x)。设Xn是算法A的输入规模为n的实例的全体,则当问题的输入规模为n时,算法A所需的平均时间为,这显然不能排除存在xXn使得 的可能性。希望获得一个随机化算法B,使得对问题的输入规模为n的每一个实例均有,这就是舍伍德算法设计的基本思想。当s(n)与 相比可忽略时,舍伍德算法可获得很好的平均性能。,26,7.3.1 随机快速算法 7.3.2 随机选择算法 7.3.2 搜索有序表,27,7.3.1 随机快速排序算法,随机快速排序算法 快速排序算法 算法的核心在于选择合适的划分基准 改变快速排序算法性能不稳定,即输入相关的问题,28,template void quicksort_random(Type A,int low,int high) random_seed(0); /* 选择系统当前时间作为随机数种子 */ r_quicksort(A,low,high); /* 递归调用随机快速排序算法 */ ,void r_quicksort(Type A,int low,int high) int k; if (lowhigh) k = random(low,high); /* 产生low到high之间的随机数k */ swap(Alow,Ak); /* 把元素Ak交换到数组的第一个位置*/ k = split(A,low,high); /* 按元素Alow把数组划分为两个 */ r_quicksort(A,low,k-1); /* 排序第一个子数组 */ r_quicksort(A,k+1,high); /* 排序第二个子数组 */ ,随机快速排序算法,29,最坏时间复杂度仍是:O(n2) 最坏情况:当随机数发生器第i次随机产生的枢点元素恰恰就是数组中第i大或第i小的元素时造成最坏情况 与输入无关 情况是微乎其微的 输入元素的任何排列顺序,都不可能使算法行为处于最坏的情况 期望运行时间是O(nlogn),30,7.3.2 随机选择算法,选择问题 给定线性序集中n个元素和一个整数1kn,要求找出这n个元素中第k小的元素,对选择问题而言,用中位数作为划分基准可以保证在最坏情况下用线性时间完成选择。如果只简单地用待划分数组的第一个元素作为划分基准,则算法的平均性能较好,而在最坏的情况下需要O(n2)计算时间。 舍伍德型选择算法则随机地一个数组元素作为划分基准。这样既能保证算法的线性时间平均性能又避免了计算拟中位数的麻烦。,31,template Type select(Type a,int l,int k) /计算al:r中第k小元素 static RandomNumber rnd; while (true) if( l =r) return al; int i = l, j=l + rnd.Random(r- l+1); /随机选择划分基准 swap(ai,aj); j=r+1; Type pivot=al; /以划分基准为轴作元素交换 while (true) while (a+ipivot); if (i=j) break; Swap (ai,aj); ,if (j-l+1=k) return pivot; al=aj; aj=pivo
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号