⑴ 求各种产生随机数的算法
多的很呀!别撤消呀,千万! 不过几乎都是伪随机数。 随机序列的算法 找到了两个算法, 第一个很简单, 但可惜不是随机的, 第二个是典型的伪随机数算法, 可惜要用到2的几百万次方这样巨大的整数, 真痛苦 要是有UNIX上计算密码的源代码就好了 第一种做法: f(k) = (k*F(N-1)) mod F(N)其中, k是一个序列号, 就是要取的那个数的顺序号 F(N)是这样一个序列 F(0) = 0, F(1) = 1, F(N+2) = F(N+1)+F(N) (for N>=0)第二种做法V = ( ( V * 2 ) + B .xor. B ... )(Mod 2^n)N+1 N 0 2V是要取的随机数, B是个种子, n是随机数的最大个数 原来这个问题, 很高难, 不少数学高手都为解决这个问题写了论文, 咳咳, 偶真是个白痴 呵呵, 效果肯定是不错啦, 因为用不到很大的表. 至于应用是这样的, 比如, 你要给每个用户在注册的时候一个ID但有不希望用户在看到自己的ID的时候能知道其他用户的ID, 如果用SEQUENCE来生成ID的话, 一个用户只要把自己的ID减1就能得到其它用户的ID了. 所以要用随机数来做ID, 这样用户很难猜到其他用户的ID了. 当然主要的问题是, 随机数可能重复. 因此希望使用一个随机数做种子用它来确定一组"无规律"的自然数序列, 并且在这个序列中不会出现重复的自然数. 在这里使用的方法生成的序列并不是没有规律的, 只不过这个轨律很难被发现就是了. Xn+1 = (aXn + b) mod c (其中, abc通常是质数)是一种被广泛使用的最简单的随机数发生算法, 有研究表表明这个算法生成的随机数基本上符合统计规律, JAVA, BORLAND C等用的都是这个方法, 一般只要保证第一个种子是真正的随机数就行了, 下面来说一下重复的问题, 上述方法会有可能出现重复, 因为当(aXn + b)有可能是同样的数或者说余数相同的数, 因此要想不重复就得变形 偶想到的方法是 Xn=(a*n + b) mod c n是一个在1到c之间的整数, a*n + b就是一个线性公式了, 且若n不同则a*n + b也不同, 它们除上质数c得到的余数也肯定不同, 因为 若不考虑a和b而只有n的时候, 每次的结果都是n,而线性公式, 只不过移动了这条直线的位置和斜率而已, 每个结果仍然不会相同的, 为了增加不可预计性, 偶又为上面那个公式设计了, 随机数种子, 于是就变成了这个样子 F(N)=(随机数*(N+随机数))MOD 一个质数 这样就能够产生 1到选定质数之间的一个"无规律"的自然数序列了, 只要改变随机数就能改变序列的次序 在应用的时候, 要把随机数种子和最后用到的序列号保存到一个表里, 每此使用的时候取出来算好, 再把序列号更新一下就可以了 具体地说, 就是可以建一个表来保存每个序列的随机数种子, 然后再为这个序列建一个SEQUENCE就行了然后就SELECT MOD(序列控制表.随机数*(SEQ.NEXTVAL+序列控制表.随机数)),序列控制表.质数) FROM 序列控制表 WHERE 序列控制表.序列ID=XX就OK了注意 序列控制表.质数 决定了序列的范围
⑵ 如何评价一个伪随机数生成算法的优劣
1 相同序列的概率非常低
2 符合统计学的平均性,比如所有数字出现概率应该相同,卡方检验应该能通过,超长游程长度概略应该非常小,自相关应该只有一个尖峰,任何长度的同一数字之后别的数字出现概率应该仍然是相等的等等
3 不应该能够从一段序列猜测出随机数发生器的工作状态或者下一个随机数
4 不应该从随机数发生器的状态能猜测出随机数发生器以前的工作状态
一般用的随机数发生器至少要符合K1和K2,而用于加密等应用的随机数发生器应该符合K3和K4。
⑶ 请问C++的rand随机数发生器产生的随机数到底是什么分布呢
是随机分布的。不过其实它是按固定算法算出来的。。。也就是说每次产生前我们需要给它一个启始数(就是种子【srand就是定义种子的】),然后它就会会用这种子进行运算,产生随机数,而且下一次运算的启始就是上一次的运算的结果,这样就产生了一大串数。因为这函数的结果产生的数是均匀的。所以只要启始数也就是种子是个随机数就可以了。(例如时间)。因为时间是在不断变化的所以每次启始数都不一样,也就得到了不一样的随机数。但是如果种子是一样的话,就会得到上次一样的结果。所以归根结底是一种算法算出来的伪随机数,机器本身是没有不确定性,也就是无法产生真正意义上的随机数的
⑷ 计算机产生伪随机数的周期是多少算法是什么
为追求真正的随机序列,人们曾采用很多种原始的物理方法用于生成一定范围内满足精度(位数)的均匀分布序列,其缺点在于:速度慢、效率低、需占用大量存储空间且不可重现等。为满足计算机模拟研究的需求,人们转而研究用算法生成模拟各种概率分布的伪随机序列。伪随机数是指用数学递推公式所产生的随机数。从实用的角度看,获取这种数的最简单和最自然的方法是利用计算机语言的函数库提供的随机数发生器。典型情况下,它会输出一个均匀分布在0和1区间内的伪随机变量的值。其中应用的最为广泛、研究最彻底的一个算法即线性同余法。
线性同余法LCG(Linear Congruence Generator)
选取足够大的正整数M和任意自然数n0,a,b,由递推公式:
ni+1=(af(ni)+b)mod M i=0,1,…,M-1
生成的数值序列称为是同余序列。当函数f(n)为线性函数时,即得到线性同余序列:
ni+1=(a*ni+b)mod M i=0,1,…,M-1
以下是线性同余法生成伪随机数的伪代码:
Random(n,m,seed,a,b)
{
r0 = seed;
for (i = 1;i<=n;i++)
ri = (a*ri-1 + b) mod m
}
其中种子参数seed可以任意选择,常常将它设为计算机当前的日期或者时间;m是一个较大数,可以把它取为2w,w是计算机的字长;a可以是0.01w和0.99w之间的任何整数。
应用递推公式产生均匀分布随机数时,式中参数n0,a,b,M的选取十分重要。
例如,选取M=10,a=b =n0=7,生成的随机序列为{6,9,0,7,6,9,……},周期为4。
取M=16,a=5,b =3,n0=7,生成的随机序列为{6,1,8,11,10,5,12,15,14,9,0,3,2,13,4,7,6,1……},周期为16。
取M=8,a=5,b =1,n0=1,生成的随机序列为{6,7,4,5,2,3,0,1,6,7……},周期为8。
Visual C++中伪随机数生成机制
用VC产生随机数有两个函数,分别为rand(void)和srand(seed)。rand()产生的随机整数是在0~RAND_MAX之间平均分布的,RAND_MAX是一个常量(定义为:#define RAND_MAX 0x7fff)。它是short型数据的最大值,如果要产生一个浮点型的随机数,可以将rand()/1000.0,这样就得到一个0~32.767之间平均分布的随机浮点数。如果要使得范围大一点,那么可以通过产生几个随机数的线性组合来实现任意范围内的平均分布的随机数。
其用法是先调用srand函数,如
srand( (unsigned)time( NULL ) )
这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。也可以使用srand函数来人为指定种子数分析以下两个程序段,
程序段1:
//包含头文件
void main() {
int count=0;
for (int i=0;i<10;i++){
srand((unsigned)time(NULL));
count++;
cout<<"No"<
//包含头文件
void main() {
int count=0;
srand((unsigned)time(NULL));
for (int i=0;i<10;i++){
count++;
cout<<"No"<
No1=9694 No2=9694 No3=9694 No4=9694 No5=9694
No6=9694 No7=9694 No8=9694 No9=9694 No10=9694
程序段2的运行结果为:
No1=10351 No2=444 No3=11351 No4=3074 No5=21497
No6=30426 No7=6246 No8=24614 No9=22089 No10=21498
可以发现,以上两个程序段由于随机数生成时选择的种子的不同,运行的结果也不一样。rand()函数返回随机数序列中的下一个数(实际上是一个伪随机数序列,序列中的每一个数是由对其前面的数字进行复杂变换得到的)。为了模仿真正的随机性,首先要调用srand()函数给序列设置一个种子。为了更好地满足随机性,使用了时间函数time(),以便取到一个随时间变化的值,使每次运行rand()函数时从srand()函数所得到的种子值不相同。伪随机数生成器将作为"种子"的数当作初始整数传给函数。这粒种子会使这个球(生成伪随机数)一直滚下去。
程序段1中由于将srand()函数放在循环体内,而程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的,因此产生的随机数也是一样的。而程序段2中第1次产生的随机数要用到随机种子,以后的每次产生随机数都是利用递推关系得到的。 基于MFC的随机校验码生成
Web应用程序中经常要利用到随机校验码,校验码的主要作用是防止黑客利用工具软件在线破译用户登录密码,校验码、用户名、密码三者配合组成了进入Web应用系统的钥匙。在利用VC开发的基于客户机/浏览器(Client/Server)模式的应用软件系统中,为了防止非法用户入侵系统,通常也要运用随机校验码生成技术。
⑸ 随机算法原理
展开专栏
登录
企鹅号小编
5.7K 篇文章
关注
详解各种随机算法
2018-02-06阅读 1.4K0
转自:JarvisChu
之前将的算法都是确定的,即对于相同的输入总对应着相同的输出。但实际中也常常用到不确定的算法,比如随机数生成算法,算法的结果是不确定的,我们称这种算法为(随机)概率算法,分为如下四类:
1、数值概率算法
用于数值问题的求解,通常是近似解
2、蒙特卡洛算法Monte Carlo
能得到问题的一个解,但不一定是正确解,正确的概率依赖于算法运行的时间,算法所用的时间越多,正确的概率也越高。求问题的准确解;
3、拉斯维加斯算法 Las Vegas
不断调用随机算法求解,直到求得正确解或调用次数达到某个阈值。所以,如果能得到解,一定是正确解。
4、舍伍德算法 Sherwood
利用随机算法改造已有算法,使得算法的性能尽量与输入数据无关,即平滑算法的性能。它总能求得问题的一个解,且求得的解总是正确的。
随机数
概述
计算机产生的随机数都是伪随机数,通过线性同余法得到。
方法:产生随机序列
d称为种子;m取值越大越好;m,b互质,常取b为质数;
⑹ 计算机的随机数是怎么产生的
楼主您好!
在统计学的不同技术中需要使用随机数,比如在从统计总体中抽取有代表性的样本的时候,或者在将实验动物分配到不同的试验组的过程中,或者在进行蒙特卡罗模拟法计算的时候等等。
产生随机数有多种不同的方法。这些方法被称为随机数发生器。随机数最重要的特性是它在产生是后面的那个数与前面的那个数毫无关系。
真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。
在实际应用中往往使用伪随机数就足够了。这些数列是“似乎”随机的数,实际上它们是通过一个固定的、可以重复的计算方法产生的。它们不真正地随机,因为它们实际上是可以计算出来的,但是它们具有类似于随机数的统计特征。这样的发生器叫做伪随机数发生器。
在真正关键性的应用中,比如在密码术中,人们一般使用真正的随机数。
⑺ 蒙特卡罗发生器
蒙特卡罗算法简介蒙特卡罗也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。蒙特卡罗方法的名字来源于摩纳哥的一个城市蒙地卡罗,该城市以赌博业闻名,而蒙特·罗方法正是以概率为基础的方法。与它对应的是确定性算法。 蒙特卡罗方法在金融工程学,宏观经济学,计算物理学(如粒子输运计算、量子热力学计算、空气动力学计算)等领域应用广泛。 基本思想当所求解问题是某种随机事件出现的概率,或者是某个随机变量的期望值时,通过某种“实验”的方法,以这种事件出现的频率估计这一随机事件的概率,或者得到这个随机变量的某些数字特征,并将其作为问题的解。 有一个例子可以使你比较直观地了解蒙特卡罗方法:假设我们要计算一个不规则图形的面积,那么图形的不规则程度和分析性计算(比如,积分)的复杂程度是成正比的。蒙特卡罗方法是怎么计算的呢?假想你有一袋豆子,把豆子均匀地朝这个图形上撒,然后数这个图形之中有多少颗豆子,这个豆子的数目就是图形的面积。当你的豆子越小,撒的越多的时候,结果就越精确。在这里我们要假定豆子都在一个平面上,相互之间没有重叠。 工作过程在解决实际问题的时候应用蒙特卡罗方法主要有两部分工作: 用蒙特卡罗方法模拟某一过程时,需要产生各种概率分布的随机变量。 用统计方法把模型的数字特征估计出来,从而得到实际问题的数值解。 计算步骤使用蒙特卡罗方法进行分子模拟计算是按照以下步骤进行的: ① 使用随机数发生器产生一个随机的分子构型。 ②对此分子构型的其中粒子坐标做无规则的改变,产生一个新的分子构型。 ③计算新的分子构型的能量。 ④比较新的分子构型于改变前的分子构型的能量变化,判断是否接受该构型。 若新的分子构型能量低于原分子构型的能量,则接受新的构型,使用这个构型重复再做下一次迭代。 若新的分子构型能量高于原分子构型的能量,则计算玻尔兹曼常数,同时产生一个随机数。 若这个随机数大于所计算出的玻尔兹曼因子,则放弃这个构型,重新计算。 若这个随机数小于所计算出的玻尔兹曼因子,则接受这个构型,使用这个构型重复再做下一次迭代。 ⑤如此进行迭代计算,直至最后搜索出低于所给能量条件的分子构型结束。 在数学中的应用通常蒙特·卡罗方法通过构造符合一定规则的随机数来解决数学上的各种问题。对于那些由于计算过于复杂而难以得到解析解或者根本没有解析解的问题,蒙特·卡罗方法是一种有效的求出数值解的方法。一般蒙特·卡罗方法在数学中最常见的应用就是蒙特·卡罗积分。 积分非权重蒙特卡罗积分,也称确定性抽样,是对被积函数变量区间进行随机均匀抽样,然后对被抽样点的函数值求平均,从而可以得到函数积分的近似值。此种方法的正确性是基于概率论的中心极限定理。当抽样点数为m时,使用此种方法所得近似解的统计误差恒为,不随积分维数的改变而改变。因此当积分维度较高时,蒙特卡罗方法相对于其他数值解法更优。 解题三个主要步骤:构造或描述概率过程: 对于本身就具有随机性质的问题,如粒子输运问题,主要是正确描述和模拟这个概率过程,对于本来不是随机性质的确定性问题,比如计算定积分,就必须事先构造一个人为的概率过程,它的某些参量正好是所要求问题的解。即要将不具有随机性质的问题转化为随机性质的问题。 实现从已知概率分布抽样: 构造了概率模型以后,由于各种概率模型都可以看作是由各种各样的概率分布构成的,因此产生已知概率分布的随机变量(或随机向量),就成为实现蒙特卡罗方法模拟实验的基本手段,这也是蒙特卡罗方法被称为随机抽样的原因。最简单、最基本、最重要的一个概率分布是(0,1)上的均匀分布(或称矩形分布)。随机数就是具有这种均匀分布的随机变量。随机数序列就是具有这种分布的总体的一个简单子样,也就是一个具有这种分布的相互独立的随机变数序列。产生随机数的问题,就是从这个分布的抽样问题。在计算机上,可以用物理方法产生随机数,但价格昂贵,不能重复,使用不便。另一种方法是用数学递推公式产生。这样产生的序列,与真正的随机数序列不同,所以称为伪随机数,或伪随机数序列。不过,经过多种统计检验表明,它与真正的随机数,或随机数序列具有相近的性质,因此可把它作为真正的随机数来使用。由已知分布随机抽样有各种方法,与从(0,1)上均匀分布抽样不同,这些方法都是借助于随机序列来实现的,也就是说,都是以产生随机数为前提的。由此可见,随机数是我们实现蒙特卡罗模拟的基本工具。 建立各种估计量: 一般说来,构造了概率模型并能从中抽样后,即实现模拟实验后,我们就要确定一个随机变量,作为所要求的问题的解,我们称它为无偏估计。 建立各种估计量,相当于对模拟实验的结果进行考察和登记,从中得到问题的解。 例如:检验产品的正品率问题,我们可以用1表示正品,0表示次品,于是对每个产品检验可以定义如下的随机变数Ti,作为正品率的估计量: 于是,在N次实验后,正品个数为: 显然,正品率p为: 不难看出,Ti为无偏估计。当然,还可以引入其它类型的估计,如最大似然估计,渐进有偏估计等。但是,在蒙特卡罗计算中,使用最多的是无偏估计。 用比较抽象的概率语言描述蒙特卡罗方法解题的手续如下:构造一个概率空间(W ,A,P),其中,W 是一个事件集合,A是集合W 的子集的s 体,P是在A上建立的某个概率测度;在这个概率空间中,选取一个随机变量q (w ),w Î W ,使得这个随机变量的期望值 正好是所要求的解Q ,然后用q (w )的简单子样的算术平均值作为Q 的近似值。 特点:直接追踪粒子,物理思路清晰,易于理解。 · 采用随机抽样的方法,较真切的模拟粒子输运的过程,反映了统计涨落的规律。 · 不受系统多维、多因素等复杂性的限制,是解决复杂系统粒子输运问题的好方法。 · MC程序结构清晰简单。 · 研究人员采用MC方法编写程序来解决粒子输运问题,比较容易得到自己想得到的任意中间结果,应用灵活性强。 · MC方法主要弱点是收敛速度较慢和误差的概率性质,其概率误差正比于,如果单纯以增大抽样粒子个数N来减小误差,就要增加很大的计算量。 计算程序:关于蒙特卡罗方法的计算程序已经有很多,如:EGS4、FLUKA、ETRAN、ITS、MCNP、GEANT等。这些程序大多经过了多年的发展,花费了几百人年的工作量。除欧洲核子研究中心(CERN)发行的GEANT主要用于高能物理探测器响应和粒子径迹的模拟外,其它程序都深入到低能领域,并被广泛应用。就电子和光子输运的模拟而言,这些程序可被分为两个系列: 1.EGS4、FLUKA、GRANT 2.ETRAN、ITS、MCNP 这两个系列的区别在于:对于电子输运过程的模拟根据不同的理论采用了不同的算法。 EGS4和ETRAN分别为两个系列的基础,其它程序都采用了它们的核心算法。 ETRAN(for Electron Transport)由美国国家标准局辐射研究中心开发,主要模拟光子和电子,能量范围可从1KeV到1GeV。 ITS(The integrated TIGER Series of Coupled Electron/Photon Monte Carlo Transport Codes )是由美国圣地亚哥(Sandia)国家实验室在ETRAN的基础上开发的一系列模拟计算程序,包括TIGER 、CYLTRAN 、ACCEPT等,它们的主要差别在于几何模型的不同。 TIGER研究的是一维多层的问题,CYLTRAN研究的是粒子在圆柱形介质中的输运问题,ACCEPT是解决粒子在三维空间输运的通用程序。 NCNP(Monte Carlo Neutron and Photo Transport Code)由美国橡树林国家实验室(Oak Ridge National Laboratory)开发的一套模拟中子、光子和电子在物质中输运过程的通用MC 计算程序,在它早期的版本中并不包含对电子输运过程的模拟,只模拟中子和光子,较新的版本(如MCNP4A)则引进了ETRAN,加入了对电子的模拟。 FLUKA 是一个可以模拟包括中子、电子、光子和质子等30余种粒子的大型MC计算程序,它把EGS4容纳进来以完成对光子和电子输运过程的模拟,并且对低能电子的输运算法进行了改进。
⑻ C语言怎样产生一定范围的随机数
编译环境为:vs2013
产生1到3的整型随机数的代码如下:
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define max 3 //这个函数的意义为:随机生成最大的数为3
#define min 1 //这个函数的意义为:随机生成最小的数为1
int main()
{
int num;
srand(time(0));
num = rand() % (max - min) + min; // 这里的意义,“%”为模运算
printf("随机数为:%d
", num);
system("pause"); //这个代码可以让弹出的黑框不会一下就消失
return 0;
}
(8)随机发生器算法扩展阅读:
根据密码学原理,随机数的随机性检验可以分为三个标准:
条件一、统计学伪随机性。统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等。类似的标准被称为统计学随机性。满足这类要求的数字在人类“一眼看上去”是随机的。
条件二、密码学安全伪随机性。其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分。
条件三、真随机性。其定义为随机样本不可重现。实际上只要给定边界条件,真随机数并不存在,可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数。
随机数分为三类:
①伪随机数:满足第一个条件的随机数。
②密码学安全的伪随机数:同时满足前两个条件的随机数。可以通过密码学安全伪随机数生成器
计算得出。
③真随机数:同时满足三个条件的随机数。
⑼ python中的随机数是怎么实现的
PYTHON中的伪随机数发生器用的是梅森旋转算法。
梅森旋转算法(Mersenne twister)是一个伪随机数发生算法。由松本真和西村拓士在1997年开发,基于有限二进制字段上的矩阵线性递归。可以快速产生高质量的伪随机数,修正了古典随机数发生算法的很多缺陷。
梅森旋转算法是R、Python、Ruby、IDL、Free Pascal、PHP、Maple、Matlab、GNU多重精度运算库和GSL的默认伪随机数产生器。从C++11开始,C++也可以使用这种算法。
整个算法主要分为三个阶段:获得基础的梅森旋转链;对于旋转链进行旋转算法;对于旋转算法所得的结果进行处理。
算法实现的过程中,参数的选取取决于梅森素数,故此得名。
梅森素数由梅森数而来。所谓梅森数,是指形如2↑p-1的一类数,其中指数p是素数,常记为Mp 。如果梅森数是素数,就称为梅森素数。
例如4-1=3,8-1=7,16-1=15(不是素数),32-1=31,64-1=63(不是素数)等等。