资源预览内容
第1页 / 共42页
第2页 / 共42页
第3页 / 共42页
第4页 / 共42页
第5页 / 共42页
第6页 / 共42页
第7页 / 共42页
第8页 / 共42页
第9页 / 共42页
第10页 / 共42页
亲,该文档总共42页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第7章 随机算法 学习要点了解随机算法的基本特征理解产生伪随机数的算法掌握数值随机化算法的设计思想 掌握舍伍德算法的设计思想掌握拉斯维加斯算法的设计思想掌握蒙特卡罗算法的设计思想随机算法的基本特征前面各章讨论的算法的每一个步骤都是确定的,而本章讨论的随机算法允许算法在执行过程中随机地选择一下计算步骤。在许多情况下,一般算法比较复杂,性能较差,很多具有很好平均运行时间的算法,在最坏的情况下,却具有很坏的性能。由于随机性选择比最优选择省时间,因此引入随机化算法可以在很大程度上降低算法的复杂度。随机算法的基本特征 随机算法对所求解问题的同一个实例用同一随机算法求解 两次可能得到完全不同的效果。这两次求解所需要的时间 ,甚至所得到的结果都可能会有相当大的差别。 包括 数值概率算法 蒙特卡罗(Monte Carlo)算法 拉斯维加斯(Las Vegas)算法 舍伍德(Sherwood)算法数值概率算法常用于数值问题的求解。将一个问题的计算与某个概率分布已经确定的事件联系起来,求问题的近似解。这类算法所得到的往往是近似解,且近似解的精度随计算时间的增加而不断提高。在许多情况下,要计算出问题的精确解是不可能或没有必要的,因此可以用数值随机化算法得到相当满意的解。蒙特卡罗算法用于求问题的准确解,但得到的解未必是正确的。蒙特卡罗算法以正的概率给出正解,求得正确解的概率依赖于算法所用的时间。算法所用的时间越多,得到正确解的概率就越高。一般给定执行步骤的上界,给定一个输入,算法都是在一个固定的步数内停止的。随机算法的分类舍伍德算法总能求得问题的一个解,且所求得的解总是正确的。当一个确定性算法在最坏情况下的计算复杂性与其在平均情况下的计算复杂性有较大差别时,可在这个确定性算法中引入随机性将它改造成一个舍伍德算法,消除或减少问题的好坏实例间的这种差别(精髓所在)。拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时可能找不到解。拉斯维加斯算法找到正确解的概率随着它所用的计算时间的增加而提高。对于所求解问题的任意实例,用同一拉斯维加斯算法反复对它求解,可以使求解失效的概率任意小。随机算法的分类7.1随机数7.1随机数随机数在随机化算法设计中扮演着十分重要的角色。在现实计 算机上无法产生真正的随机数,因此在随机化算法中使用的随 机数都是一定程度上随机的,即伪随机数。线性同余法是产生伪随机数的最常用的方法。由线性同余法产 生的随机序列a0,a1,an,满足:其中b0,c0,dm。d称为该随机序列的种子。如何选取该 方法中的常数b、c和m直接关系到所产生的随机序列的随机性 能。这是随机性理论研究的内容,已超出本书讨论的范围。从 直观上看,m应取得充分大,因此可取m为机器大数。为了在设计概率算法时便于产生所需的随机数,建立一个随机数类RandomNumber。该类包含一个需有用户初始化的种子randseed。给定初始种子后,即可产生与之相应的随机序列。种子seed 是一个无符号长整型数,可由用户选定也可用系统时间自动产生。函数Random的输入参数n65536是一个无符号整形数,返回0,n-1范围内的一个随机整数。函数fRandom()返回0,1内的一个随机实数。/随机数类 Const unsigned long maxshort = 64436L; Const unsigned long multiplier = 1194211693L; Const unsigned long adder = 12345L;class RandomNumberprivate:/当前种子unsigned long randSeed;public:/构造函数,默认值0表示由系统自动产生种子RandomNumber (unsigned long s = 0);/产生0到n-1之间的随机整数unsigned short Random (unsigned long n);/产生0,1)之间的随机实数double fRandom (void); 函数Random在每次计算时,用线性同余式计算新的种子randSeed。它的高16位的随机性较好。将randSeed右移16位得到一个065535间的随机整数,然后再将此随机整数映射到0(n-1)范围内。对于函数fRandom,先用函数Random(maxshort)产生一个0(maxshort-1)之间的整形随机序列,将每个整型随机数除以maxshort,就得到0,1)区间中的随机实数。/产生种子 RandomNumber: RandomNumber(unsigned long s) if (s = 0) randSeed = time (0); /用系统时间产生种子else randSeed = s; /由用户提供种子 /产生0n-1之间的随机数 Unsigned short RandomNumber: Random (unsigned long n) randSeed = multiplier * randSeed + adder;return (unsigned short) ( (randSeed 16) % n ); /产生0,1)之间的随机实数 Double RandomNumber: fRandom (void) return Random (maxshort) / double (maxshort);下面用计算机产生的伪随机数来模拟抛硬币实验。假设抛10次硬币构成一个事件。调用Random(2)返回一个二值结果。返回0表示抛硬币得到反面,返回1表示得到正面。下面的算法TossCoins模拟抛10次硬币这一事件50000次。用headi (0 i 10)记录这50000此模拟恰好得到i次正面的次数。最终输出模拟抛硬币事件得到正面事件的频率图,如下图所示:0 *1 *2 *3 *4 *5 *6 *7 * 8 *9 *10 *模拟抛硬币得到的正面事件频率图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 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 (low 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=pivot; /对子数组重复划分过程 if (j-l+1 void Shuffle (Type a, int n) /随机洗牌算法 static RandomNumber rnd; for (int i=0; i bool OrderedList :Search(Type x,int Type max = Small; int m = floor(sqrt(double(n); /随机抽取数组元素次数 for (int i=1; i void OrderedList :Insert(Type k) / 插入集合中指定元素 if ( (n=MaxLength) | (k=TailKey) ) return; int index; if (!Search(k,index) value+n = k; linkn =linkindex; linkindex = n; 对于插入运算,首先用Search函数确认待插入元素K不在当前集合中,然后将新插入的元素存储在valuen+1中,并修改相应的指针。删除元算首先用函数Search找到待删除元素K在当前集合中的位置,然后修改待删除元素K的前驱元素的link指针,使其只想待删除元素K的后继元素。被删除元素K在有序表中产生的空洞,由当前集合中的最大元素来补填。搜索当前集合中的最大元素的任务由函数SearchLast来完成。谢谢
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号