例如这组数 1,35,5664,3,5,6,78,234,675,47
它们看起来是随意的,里面可能会重复.它们是一个随机数序列.这个序列的顺序是固定的,第1位是1,第2位是35.这个序列是手工写的.
显然,计算机要使用一种算法来自动生成这个序列,而不是用人工来写.
中方方法-随机数生成算法
冯诺依曼提出的中方方法 : 将一个n位数平方,结果表示为2n位数(不够左边补0),取其中间的n位数.这个数就是得到的随机数.
例如:1234这个数(n=4),平方后是1522756,表示为2n位数是 01522756,中间n位数是 5227 这个数就是由1234得到的随机数
将上例得到的5227继续采用中方方法会得到下一个随机数,一直这样下去,就产生了很多随机数.于是,通过算法得到了随机数序列.
这个方法的不足在于,计算出的下一个随机数,可能是0.这样以后的结果就都是0了.明显这是错误的.
线性同余法
同余法是说,如果两个整数a,b用m除,所得的余数相同,则称a,b对模m同余
使用此法计算随机数的 公式
X[n+1]=(A*X[n]+C) mod M
公式说明
用一个初始值Xn,乘以正整数A,加上正整数C.然后对正整数M取模.得到的值就是下一个随机数.
如何生成随机数
这两种算法生成的随机数,都有一个特点就是生成的随机序列是固定的,不管什么时候生成,随机数都是按固定的顺序出现.因为算法是固定的,种子值是固定的.算法无法生成真正的随机数.
中方方法有明显缺点,所以使用线性同余法.为了让随机数近似随机,关键是选定A,C,M的值.
研究线性同余法公式发现,随机数序列的产生有周期性.假设 2,5,6,1,5,2,5,6,1,5 这个随机序列,第6位开始,其实是一种重复.由于算法固定,这种重复一定会发生.至于在第几位发生,取决于ACM的选择.
经过前人的理论研究,用线性同余法产生随机数时.为了得到近似随机数(是为了得到最大周期).ACM的值如下选择.
- M尽可能的大(这样周期就大) 可以取系统位数,例如 32位系统,取2^32
- A与M互质
- C选0或者1 如果不为0,那么C与M互质.如果为0,那么M要选质数.
- A,C要比M小,ACM都是正整数
重复周期越长,随机性越好.如果需要每次都产生不一样的序列,那么每次要传入不同的种子.这样,近似随机数就实现了.
ACM选择示例:最小随机数生成器
A=16807 C=0 M=2147483647
nextRand = 16807 * seed % 2147483647
let seed = 2 // 种子为2
生成10个随机数如下
- 33614
- 564950498
- 1097816499
- 1969887316
- 140734213
- 940422544
- 202055088
- 768218109
- 770072199
- 1866991771