一般我们用到的随机算法都是伪随机算法,什么叫伪随机算法呢?伪随机算法意思是假如知道第一个随机种子和随机算法的话就可以推算出下一个随机数。通常我们程序里都是通过当前时间作为随机函数的第一个随机种子,然后将随机函数返回的值作为下一个种子,随机函数是一个公用函数,每个用户的请求都会触发一个新的随机种子,所以说是随机的。很多公司都有自己的一套随机算法。
常用的快速随机数产生算法是线性同余算法和梅森旋转算法。平均分布的伪随机算法都是周期性的,在一个周期内各个数字的分布概率相等。Windows和Linux的C运行库都采用线性同余算法,Window C运行库的随机序列周期是65536,Linux的C运行库是2^31,在一个周期内一个数字只出现一次。而设置随机数种子就相当于设置当前的a[n],下一个随机数从这里开始计算产生。
一、线性同余法
古老的LCG(linear congruential generator)代表了最好的伪随机数产生器算法。主要原因是容易理解,容易实现,而且速度快。这种算法数学上基于X(n+1) = (a * X(n) + c) % m这样的公式,其中:
模m, m > 0
系数a, 0 < a < m
增量c, 0 <= c < m
原始值(种子) 0 <= X(0) < m
其中参数c, m, a比较敏感,或者说直接影响了伪随机数产生的质量。
一般而言,高LCG的m是2的指数次幂(一般2^32或者2^64),因为这样取模操作截断最右的32或64位就可以了。
多数编译器的库中使用了该理论实现其伪随机数发生器rand()。下面是部分编译器使用的各个参数值:
Source m a c rand() / Random(L)的种子位
Numerical Recipes
2^32
Borland C/C++
2^32 1 位30..16 in rand(), 30..0 in lrand()
glibc (used by GCC)
2^32 12345 位30..0
ANSI C: Watcom, Digital Mars, CodeWarrior, IBM VisualAge C/C++
2^32 12345 位30..16
Borland Delphi, Virtual Pascal
2^32 1 位63..32 of (seed * L)
Microsoft Visual/Quick C/C++
2^32 位30..16
Apple CarbonLib
2^31-1 16807 0 见Park–Miller随机数发生器

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/25544.html