随机数生成算法的研究.doc_第1页
随机数生成算法的研究.doc_第2页
随机数生成算法的研究.doc_第3页
随机数生成算法的研究.doc_第4页
随机数生成算法的研究.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

随机数生成算法的研究在数据结构、算法分析与设计、科学模拟等方面都需要用到随机数。由于在数学上,整数是离散型的,实数是连续型的,而在某一具体的工程技术应用中,可能还有数据值的范围性和是否可重复性的要求。因此,我们就整数随机数和实数随机数,以及它们的数据值的范围性和是否可重复性,分别对其算法加以分析和设计。以下以visual basic 语言为工具,对整数随机数生成问题加以阐述,而对于实数随机数生成问题,只要稍加修改就可转化为整数随机数生成问题。根据整数随机数范围性和是否可重复性,可分为:1 某范围内可重复。2 某范围内不可重复。3 枚举可重复。4 枚举不可重复。所谓范围,是指在两个数n1和n2之间。例如,在100和200之间这个范围,那么,只要产生的整数随机数n满足100n200,都符合要求。所谓枚举,是指有限的、已知的、若干个不连续的整数。例如,34、20、123、5、800这5个整数就是一种枚举数,也就是单独可以一个个确定下来。某范围内可重复在visual basic 语言中,有一个随机数函数rnd。语法:rnd(number)。参数number 可选,number 的值决定了 rnd 生成随机数的方式。rnd 函数返回小于 1 但大于或等于 0 的值。如果 number 为rnd 生成小于零每次都相同的数字,并将 number 用作种子。大于零序列中的下一个随机数。等于零最近生成的数字。未提供序列中的下一个随机数。在调用 rnd 之前,先使用无参数的 randomize 语句初始化随机数生成器,该生成器具有一个基于系统计时器的种子。若要生成某给定范围内的随机整数,可使用以下公式:int(upperbound - lowerbound + 1) * rnd + lowerbound)这里,upperbound 是此范围的上限,而 lowerbound 是范围的下限。程序流程图:程序例程:下面是一个生成10个1020之间随机数的例子。private sub command1_click() lowerbound = 10 upperbound = 20 randomize for i = 1 to 10 random = int(upperbound - lowerbound + 1) * rnd + lowerbound) debug.print random; next debug.printend sub运行结果:12 10 20 20 17 17 18 14 12 20某范围内不可重复要产生一定范围内不可重复的随机数,按通常的设计是把曾经生成的随机数保存起来作为历史数据。产生一个新的随机数后在历史数据搜索,若找到就重新产生一个新的再重复数据搜索;否则就认为已经找到了一个新的不同随机数。例如,要由计算机随机产生10个101200之间互不相同的数。程序: private sub command2_click() dim random(10) as integer lowerbound = 101 upperbound = 200 randomize for i = 1 to 10 do r = int(upperbound - lowerbound + 1) * rnd + lowerbound) yes = 0 for j = 1 to i - 1 if r = random(j) then yes = 1: exit for next loop while yes = 1 random(i) = r debug.print r; next debug.printend sub运行结果:199 174 147 126 120 190 192 146 122 111粗看起来,上面的程序似乎没有什么问题,在执行过程中程序也能够通过。但,仔细分析我们就会发现问题出在一个新产生的随机数是否已经存在的判定上。既然是随机数,那么从数学的角度来说在概率上,每次产生的随机数 r就有可能相同,尽管这种可能性很小,但确是一个逻辑性与正确性的问题。因此,每次产生的新的随机数r都有可能是数组random的前i-1个数中的某一个,也就是说程序在运行过程中由此可能会导致死循环,那么,能否找到一个不在数组random中的随机数r的工作就变得不确定了。从算法的角度来讲,在理论上,程序失去了有穷性、有效性和确定性。什么是算法?通常人们将算法定义为一个有穷的指令集,这些指令为解决某一特定任务规定了一个运算序列。一个算法应当具有以下特征:5 输入:一个算法必须有0个或多个输入。它们是算法开始运算前给予算法的量。这些输入取自于特定的对象的集合。它们可以使用输入语句由外部提供,也可以使用置初值语句或赋值语句在算法内提供。6 输出:一个算法应有1个或多个输出,输出的量是算法计算的结果。7 确定性:算法的每一步都应确切地、无歧义地定义。对于每一种情况,需要执行的动作都应严格地、清晰地规定。8 有穷性:一个算法无论在什么情况下,都应在执行有穷步后结束。9 有效性:算法中每一条运算都必须是足够基本的。就是说,它们原则上都能精确地执行,甚至人们只用纸和笔做有限次运算就能完成。一般来说,我们所编写的程序都是在特定算法基础上设计出来的,程序常常与算法是相互对应的,在没有特殊的情况下,程序也应当具有以上五个特征。但,也有一些程序在设计中,人们由于疏忽会想当然地认为,程序只要编写出来一般都会自然地符合算法的五个特征,这是应当引为注意的。那么,应该如何对其进行改进,使其符合算法的五个特征呢?仍然以上述由计算机随机产生10个101200之间互不相同的数为例进行阐述。首先,把要产生的所有数放到一个数组a中。令upperbound 是此范围的上限,而 lowerbound 是范围的下限。第二,每次随机生成数组a的一个下标subscript,然后取出它所对应的数据,将数组a的最后一个数放到下标subscript的位置,同时将数组a长度减1。尽管前若干次生成的下标subscript随机数有可能相同,但,因为每一次都把最后一个数填到取出的位置,因此,相同下标subscript对应的数却绝不会相同,每一次取出的数都不会一样,这样,就保证了算法的确定性、有效性、有穷性。程序流程图:程序:private sub command3_click() dim a(10), b(100) as integer lowerbound = 101 upperbound = 200 for i = 1 to upperbound - lowerbound + 1 b(i) = lowerbound + i - 1 next randomize length = upperbound - lowerbound + 1 for i = 1 to 10 subscript = int(length * rnd + 1) r = b(subscript) b(script) = b(length) length = length - i a(i) = r debug.print a(i); next debug.printend sub运行结果:195 153 148 183 149 101 137 172 126 110枚举可重复这种随机数的生成比较简单,只要把各个枚举数放入一个数组中保存起来,然后随机生成数组的下标,最后取出对应下标下的数组的值即可。流程图和程序可参考前面的论述。枚举不可重复首先把各个枚举数放入一个数组中保存起来,其它的处理方法完全类似于某范围内不可重复随机数的方法。结束语上述算法具有很高的应用价值与理论价值。在计算机数据结构、算法分析与设计、科学模拟等方面需要随机数的应用中,都可使用该算法。参考文献:1 visual basic程序设计教程北京:机械工业出版社,2002.2.12 严蔚敏数据结构(第二版)北京:清华大学出版社,1999 关于一定范围内不重复随机数的讨论:1)问题:在11000产生n个随机数(n为用户指定, n大于0,不大于1000),产生出来的数,不能重复,如n3时,结果可以是1,202,454;但不能为34,43,43。 我现在的实现是,如果n1000时,顺序产生全部的11000。 如果n 1000,则随机产生数,同时进行重复数过滤。 现在问题是当900 n 1000,特别是995 n 1000时,程序总是不停的产生数并判断该数已经产生过,然后继续重复上述步骤。 想请教如何改变算法,让产生过程更快。2)讨论:以下示例假设n=1000 用一个列表,把1到1000的数存起来,随机从所有数中取出一个,后面的数前移,列表的元素数量减1,如此重复。3)讨论:给你写了个,速度还可以,一秒钟不到,就出来了。 #include #include #include int find(int *a,int num,int data); void main() int a1000=0,temp,n; int i,j,k; printf( please input zhe number of data: ); scanf( %d ,&n); for(i=0;i n;i+) srand(time(null); temp=rand()%(1000-i)+1; for(j=0,k=0;j temp;) if(ak+=0) j+; ak-1=1; for(i=1;i =1000;i+) if(ai-1=1) printf( %4d ,i); 程序的思想是这样的: 用一个标志数组a1000,加入产生的数为123,则将a122置为1,产生n个数后,把下一个随机数(假设为next)的范围定为1000-n,由于此时数组a还有1000-n元素没有置为1,此时可以把next对应的空位置为1,这样一直循环,直到产生所需数为止。 最后扫描整个数组a,把值为1的元素位置输出即可。4)讨论:用洗牌算法 定义一个数组,里面是顺序排好的自然数 把随机一个数组元素和第一个元素交换 把随机一个数组元素和第二个元素交换 把随机一个数组元素和第三个元素交换 把随机一个数组元素和第n个元素交换 这里n为需要生成的不重复随机数个数5)讨论:随机洗牌算法。 代码: /* ëæ»ï´åæë㠳컾³: vc6.0 */ #include #include #include using namespace std; void random_shuffle( int n ) int list1000; int i; for( i=0; i 1000; +i ) listi=i+1; srand(time(null); int j; for( i=0; i 1000; +i ) j=rand()%1000; swap( listi, listj ); for( i=0; i n; +i ) cout listi ; cout endl; int main( ) int n; cout çëêäèën (n n; random_shuffle( n ); return 0; 粗心了。 我的代码中random_shuffle()中的第二个for循环,只需要执行n次。 应该改为: for( i=0; i n; +i ) j=rand()%1000; swap( listi, listj ); 6)讨论:995 n 1000 是5/1000的几率!虽然总能排带!但是太慢了 不如直接对1000个数的数组进行随机排序! 用洗牌算法(我自己的思路,大家不要笑) 随机2个数a 和b,将数组中index=a 到index=b之间的所有数一起放到数组的前面或者后面! 循环多次就行了关于真随机数生成器/blog/199943有关如何产生随机数的理论有许多,如果要详细地讨论,需要厚厚的一本书的篇幅。有限状态机不能产生真正的随机数的,所以在现在的计算机中并没有一个真正的随机数生成算法,现有的随机数生成算法生产的随机数只不过因为重复的周期比较大,可以做到使产生的数字重复率很低,这样看起来好象是真正的随机数,一般称作叫伪随机数发生器。真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。真随机数生产效率没有伪随机数高,还有就是信息熵的信息量如果很有限的话,就不是一定是真的随机数了。还有人质疑真正的随机数的存在,这是哲学问题,不在此涉及。查了下现有的真随机数生成器,比如puttygen的随机数是让用户移动鼠标达到一定的长度,之后把鼠标的运动轨迹转化为种子;intel通过电阻和振荡器来生成热噪声作为信息熵资源;unix/linux的dev/random和/dev/urandom采用硬件噪音生成随机数;(待补充)基于特定intel芯片组中random number generator(rng)单元的真随机数生成器.在intel 815e芯片组的个人电脑上安装intel security driver(isd)后,可以通过编程读取寄存器获取rng中的随机数.有人在bbs上提到:rsa的书上介绍过一种随机数发生器,根据的是劣质内存芯片工作在高温下,其数据是不可预测的,读取这里面的数据,就会得到难以预测的随机数。有采用这种技术制作随机数发生器板卡。关于linux系统的真随机数生成器在linux内核设计与实现一书的附录b中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论