当前位置:文档之家› 随机数原理

随机数原理

Dor = Int((upperbound - lowerbound + 1) * Rnd + lowerbound)yes = 0For j = 1 To i - 1If r = random(j) Then yes = 1: Exit ForNextLoop While yes = 1random(i) = rDebug.Print r;NextDebug.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个101~200之间互不相同的数为例进行阐述。

首先,把要产生的所有数放到一个数组a中。

令upperbound 是此范围的上限,而lowerbound 是范围的下限。

第二,每次随机生成数组a的一个下标subscript,然后取出它所对应的数据,将数组a的最后一个数放到下标subscript的位置,同时将数组a长度减1。

尽管前若干次生成的下标subscript随机数有可能相同,但,因为每一次都把最后一个数填到取出的位置,因此,相同下标subscript对应的数却绝不会相同,每一次取出的数都不会一样,这样,就保证了算法的确定性、有效性、有穷性。

程序流程图:程序:Private Sub Command3_Click()Dim a(10), b(100) As Integerlowerbound = 101upperbound = 200For i = 1 To upperbound - lowerbound + 1b(i) = lowerbound + i - 1NextRandomizelength = upperbound - lowerbound +1For i = 1 To 10subscript = Int(length * Rnd + 1)r = b(subscript)b(script) = b(length)length = length - ia(i) = rDebug.Print a(i);NextDebug.PrintEnd Sub运行结果:195 153 148 183 149 101 137 172 126 110枚举可重复这种随机数的生成比较简单,只要把各个枚举数放入一个数组中保存起来,然后随机生成数组的下标,最后取出对应下标下的数组的值即可。

流程图和程序可参考前面的论述。

枚举不可重复首先把各个枚举数放入一个数组中保存起来,其它的处理方法完全类似于某范围内不可重复随机数的方法。

结束语上述算法具有很高的应用价值与理论价值。

在计算机数据结构、算法分析与设计、科学模拟等方面需要随机数的应用中,都可使用该算法。

参考文献:[1]《Visual Basic程序设计教程》北京:机械工业出版社,2002.2.1[2]严蔚敏《数据结构》(第二版)北京:清华大学出版社,1999关于一定范围内不重复随机数的讨论:1)问题:在1~1000产生N个随机数(N为用户指定, N大于0,不大于1000),产生出来的数,不能重复,如N=3时,结果可以是1,202,454;但不能为34,43,43。

我现在的实现是,如果N=1000时,顺序产生全部的1~1000。

如果N <1000,则随机产生数,同时进行重复数过滤。

现在问题是当900 <N <1000,特别是995 <N <1000时,程序总是不停的产生数并判断该数已经产生过,然后继续重复上述步骤。

想请教如何改变算法,让产生过程更快。

以下示例假设N=1000用一个列表,把1到1000的数存起来,随机从所有数中取出一个,后面的数前移,列表的元素数量减1,如此重复。

3)讨论:给你写了个,速度还可以,一秒钟不到,就出来了。

#include <time.h>#include <stdio.h>#include <stdlib.h>int find(int *a,int num,int data);void main(){int a[1000]={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(a[k++]==0)j++;}a[k-1]=1;}for(i=1;i <=1000;i++)if(a[i-1]==1)printf( "%4d ",i);}程序的思想是这样的:用一个标志数组a[1000],加入产生的数为123,则将a[122]置为1,产生n个数后,把下一个随机数(假设为next)的范围定为1000-n,由于此时数组a还有1000-n元素没有置为1,此时可以把next对应的空位置为1,这样一直循环,直到产生所需数为止。

最后扫描整个数组a,把值为1的元素位置输出即可。

4)讨论:定义一个数组,里面是顺序排好的自然数把随机一个数组元素和第一个元素交换把随机一个数组元素和第二个元素交换把随机一个数组元素和第三个元素交换……把随机一个数组元素和第N个元素交换这里N为需要生成的不重复随机数个数5)讨论:随机洗牌算法。

代码:/*&Euml;&aelig;&raquo;ú&Iuml;&acute;&Aring;&AElig;&Euml;&atilde;·¨±à&sup3;&Igrave;&raquo;·&frac34;&sup3;: VC6.0*/#include <iostream>#include <ctime>#include <cstdlib>using namespace std;void Random_Shuffle( int n ){int list[1000];int i;for( i=0; i <1000; ++i )list[i]=i+1;srand(time(NULL));int j;for( i=0; i <1000; ++i ){j=rand()%1000;swap( list[i], list[j] );}for( i=0; i <n; ++i )cout < <list[i] < < " ";cout < <endl;}int main( ){int n;cout < < "&Ccedil;&euml;&Ecirc;&auml;&Egrave;&euml;N (N <1000) : ";cin> > n;Random_Shuffle( n );return 0;}粗心了。

我的代码中Random_Shuffle()中的第二个for循环,只需要执行n次。

应该改为:for( i=0; i <n; ++i ){j=rand()%1000;swap( list[i], list[j] );}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的书上介绍过一种随机数发生器,根据的是劣质内存芯片工作在高温下,其数据是不可预测的,读取这里面的数据,就会得到难以预测的随机数。

相关主题