伪随机数算法(一)

  伪随机数概念在我大学一年级接触C语言基础的时候就听说过,并熟练掌握C语言中rand()函数的使用方法。不过,当时我对伪随机数的认识基本也就停留在百度百科那种小白水平,最多就知道老师说我们用的随机数是假的,是通过某种算法实现的。最近学习计算物理学讲到Monte Carlo方法时,通过课本和互联网才算真正意义上理解了什么是伪随机数。借此文好好总结一下吧!

一、随机数的分类

  在计算物理学中,随机数被准确地分成了三类:真随机数、准随机数、伪随机数。那么这三种的区别是什么呢?拷贝一段书上的定义(我觉得写的挺好的⊙﹏⊙,其实是懒得想别的表述方式):

  1)真随机数:产生的数不可预计,也不可能重复产生两个相同的真随机数序列。真随机数只能通过某些随机的物理过程来产生,如放射性衰变、电子设备的热噪声等。

  2)准随机数:其随机数序列不具备随机性质,仅仅是用它来处理问题能够得到正确的结果。(老实说,准随机数我目前也没准确理解,读者有好的例子请@我)

  3)伪随机数:通过某种数学公式或者算法产生的数值序列。虽然在数学意义上伪随机数是不随机的,但是如果能够通过统计检验,可以当成真随机数使用。

二、伪随机数算法

  伪随机数产生的方法有个逼格挺高的名字---伪随机数发生器。伪随机数产生器中最最最基础的思想是均匀分布(当然这不是唯一的思路)。一般来说,只敢说"一般来说",因为我也不敢百分百肯定,如今主流的编程语言中使用的随机数函数基本采用这种均匀分布思想,而其中最常用的算法就是"线性同余法"(有着很多的别名,不过我喜欢用这个名字,原因你懂的→_→)。不BB别的算法,直接介绍线性同余法。

  1. 什么是线性同余法?

  对于计算机科学专业的学生来说,八成会接触一门课,叫作《离散数学》。里面有一章专门介绍初等数论,而线性同余法作为产生均匀型伪随机数的算法,有大概一页的论述(真是一个悲剧(-_-メ))。当然,可能很多人在初中或者之后的数学竞赛中学过初等数论,线性同余法当然也一定是有过接触的。

  线性同余法基于如下线性同余方程组

  用于产生均匀型伪随机数的线性同余产生器(与上面的方程符号没有对应关系)

                                             

  其中,a为"乘数",b为"增量",m为"模数",x0为"种子数"。

  如果产生的是区间实在(0,1)之间的,则只需要每个数都除以m即可,即取

                                                    

  2. 线性同余法产生均匀型伪随机数需要注意什么?

   2.1)种子数是在计算时随机给出的。比如C语言中用srand(time(NULL))函数进行随机数种子初始化。

     2.2)决定伪随机数质量的是其余的三个参数,即a,b,m决定生成伪随机数的质量(质量指的是伪随机数序列的周期性)

     2.3)一般b不为0。如果b为零,线性同余法变成了乘同余法,也是最常用的均匀型伪随机数发生器。

  3. 高性能线性同余法参数取值要求?

   3.1)一般选取方法:乘数a满足a=4p+1;增量b满足b=2q+1。其中p,q为正整数。 PS:不要问我为什么,我只是搬运工,没有深入研究过这个问题。

     3.2)m值得话最好是选择大的,因为m值直接影响伪随机数序列的周期长短。记得Java中是取得32位2进制数吧。

     3.3)a和b的值越大,产生的伪随机数约均匀

   3.4)a和m如果互质,产生随机数效果比不互质好。

三、伪随机数代码实现

  本文采用Java代码实现伪随机数算法(当然不是调用Java库函数,也不是抄它的代码)。产生序列的均匀性可以通过Matlab或者导入Excel作图直观检验。

 1 package monteCarlo;
 2
 3 public class MonteCarlo {
 4     private static final int MAXN = 2 << 20;
 5     private int[] x;
 6
 7     public MonteCarlo() {
 8         x = new int[MAXN];
 9     }
10
11     public void rand() {
12         x[0] = (int)(Math.random()*100 + 1);  // 随机种子(可以用日期产生)
13         /* 保证m与a互质 */
14         int m = MAXN;
15         int a = 9;  // a = 4p + 1
16         int b = 7;  // b = 2q + 1
17
18         System.out.println(x[0]);
19         /* 取前1w个数*/
20         for(int i = 1; i < 10000; ++i) {
21             x[i] = ( a * x[i-1] + b ) % m;
22             System.out.println(x[i]);
23         }
24     }
25
26     public static void main(String[] args) {
27         MonteCarlo mc = new MonteCarlo();
28         mc.rand();
29     }
30 }

 

四、均匀性检验结果

  统计运算太麻烦了,直观上图。反正这图我没有发现明显的规律。因此这种伪随机数在一定条件下是可以满足随机性性质的。而以前我取a=5,b=1时有部分点在一条斜线上分布,这就不满足咯。

  (⊙o⊙)总算完成了伪随机数算法(一)线性同余法,舒了一口气。文章构思原创,当然知识点...你懂的,不过转载还是希望尊重一下我劳动的小成果。

  

  

  

  

  

  

  

时间: 2024-12-30 06:40:00

伪随机数算法(一)的相关文章

伪随机数算法--线性同余法

1 Static Function rand() 2 x = (x * 37 + 27) Mod 1000 3 rand = x 4 End Function VB代码 伪随机数算法--线性同余法

伪随机数算法

Random 转载内容,有更改,感谢原作者() Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术的3.2.1节) 如果两个Random实例使用相同的种子,并且调用同样的函数,那么生成的sequence是相同的 也可以调用Math.random()生成随机数 Random实例是线程安全的,但是并发使用Random实例会影响效率,可以考虑使用ThreadLocal

Redis源码中看伪随机数生成算法

导读 --------------------------------------------------------------------------------------------------------------------------------------------------------------         Redis源码中有一个rand.c的源文件,很明显这是一个和(伪)随机数有关的文件.细看该文件代码只有寥寥50行,不过涉及到的算法原理却不简单,读起来虽然有些晦

加密算法与随机数生成算法

使用安全可靠的加密算法和随机数生成算法 密钥管理 在密码学里有个基本原则:密码系统的安全性应该依赖于密钥的复杂性,而不是算法的保密性. 在安全领域里,选择一个足够安全的加密算法不是困难的事,难的是密钥管理.在密钥管理中常见的错误是,将密钥硬编码在代码里.硬编码的密钥容易泄露: ① 代码被广泛传播(开源软件,商业软件的二进制文件,逆向工程反编译).安全方案:通过 Diffie-Hellman 交换密钥体系,生成公私密钥来完成密钥的分发. ② 软件开发团队的成员都能看到代码,从而获知密钥,如果人员流

基于粒子滤波器的目标跟踪算法及实现

代码实现: 运行方式:按P停止,在前景窗口鼠标点击目标,会自动生成外接矩形,再次按P,对该选定目标进行跟踪. [cpp] view plaincopy // TwoLevel.cpp : 定义控制台应用程序的入口点. // /************************************************************************/ /*参考文献real-time Multiple Objects Tracking with Occlusion Handli

c#笔试基础(转载)

技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”.回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以

进击的雨燕--------------协议

详情转自:http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html 协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性.类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能.任意能够满足协议要求的类型被称为遵循(conform)这个协议. 除了遵循协议的类型必须实现那些指定的规定以外,还可以对协议进行扩展,实现一些特殊的规定或者一些附加的功能,使得遵循的类型能够收益. 协议

随机数是骗人的,.Net、Java、C为我作证

差点儿全部编程语言中都提供了"生成一个随机数"的方法,也就是调用这种方法会生成一个数,我们事先也不知道它生成什么数.比方在.Net中编写以下的代码: Random rand = newRandom(); Console.WriteLine(rand.Next()); 执行后结果例如以下: Next()方法用来返回一个随机数.相同的代码你执行和我的结果非常可能不一样,并且我多次执行的结果也非常可能不一样,这就是随机数. 一.陷阱 看似非常easy的东西,使用的时候有陷阱.我编写以下的代码

小白日记34:kali渗透测试之Web渗透-扫描工具-Burpsuite(二)

扫描工具-Burpsuite 公共模块 0.Spider 爬网 手动爬网 先禁用截断功能 手动将页面中点击所有连接,对提交数据的地方,都进行提交[无论内容] 自动爬网[参数设置] 指定爬网路径,否则其他子目录也会被爬到[右键,Add Scope] #爬网参数设置 ###爬到页面中仍需要身份认证的页面,需重复输入,也可以忽略. #可导出 #################################################################### burpsuite支持两