美文网首页羽升笈
线性同余法生成伪随机数

线性同余法生成伪随机数

作者: 蛙声一爿 | 来源:发表于2015-08-27 23:33 被阅读2089次

备份自:http://blog.rainy.im/2015/08/21/lcg-random-number-generator/

SICP中1.2.6素数检验一节中采用概率算法,通过随机抽样的方法利用费马小定理测试来检验给出的整数是否为素数。这里需要用到随机数生成的方法(random n),即:随机返回0到n之间的任意整数,而我用的Calysto Scheme Kernel恰好没有相应的随机数生成方法的实现。之前有遇到Matlab进行随机模拟的时候,由于没有设定seed,导致运行了很久的程序一直在周期性地重复固定的“随机数”,刚好借此机会研究一下随机数生成的原理及方法。

计算机生成随机数的方法一般是采用数学法,即根据某一(递推)公式产生一个周期性足够大的数列,满足一定的均匀分布的特性,其优点在于可以迅速产生大量伪随机数,缺点是所产生的并非真正的随机数,只是近似随机。不同的公式能够产生性质不同的伪随机数(列),一种简单常用的方法称为线性同余发生器(Linear Congruence Generator, LCG),其公式如下:

$$
\begin{cases}
X_0 = SEED, & \text{设定初始值}\\X_n = (A * X_{n-1} + B) (Mod M)\\ R_n = X_n/M
\end{cases}
$$

显然LCG方法产生的随机数列周期小于$M$,同时在保证周期尽量大的情况下,还需要适时地重设初始值,一般以系统时间作为“种子”设定初始值。Scheme的实现如下,假设将常量设定为 $A = 3, B = 0, M = 5$:

;; random.scm
(define SEED 1)
(define (seed i) (set! SEED i))
(define A 3)
(define B 0)
(define M 5)

(define (LCG)
  (begin
   (seed (remainder (+ (* A SEED) B) M))
      SEED))
(define (random n)
  (round (* (/ (LCG) (- M 1)) n) ))

将初始值设定为系统时间后,检验10次$[0, 100]$随机数产生结果:

;; test your random
(define (test-rands n)
  (if (= n 0)
      (display "Done!")
      (begin
       (display (random 100))
       (newline)
       (test-rands (- n 1)))))
(seed (round (current-time)))
(test-rands 10)

;; 75
;; 100
;; 50
;; 25
;; 75
;; 100
;; 50
;; 25
;; 75
;; 100
;; Done!

可以发现,在$A = 3, B = 0, M = 5$的条件下,LCG产生的随机数列周期仅为4,若要得到最大周期,需要满足:

  1. $B, M$互质;
  2. $M$的所有质因数都能整除$A-1$;
  3. 若$M$是4的倍数,$A-1$也是;
  4. $A,B,X_0$都比$M$小;
  5. $A,B$是正整数。

参考

相关文章

  • python随机数生成算法

    python随机数生成算法# 现在程序中用的随机数,都是伪随机数算法生成的。例如线性同余法,平方取中法等。 1.梅...

  • LevelDB 随机数

    C语言中伪随机数生成算法实际上是采用的 "线性同余法":其中 A C M 都是常数(一般会取质数),当时,叫做乘同...

  • 线性同余法生成伪随机数

    备份自:http://blog.rainy.im/2015/08/21/lcg-random-number-gen...

  • rand()/srand()

    一、rand() rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由...

  • 转-java.util.Random 实现原理

    概述 该类的实例被用于生成伪随机数的流。该类使用一个 48 位的种子,它被一个线性同余公式所修改。如果 Rando...

  • java.util.Random 实现原理

    概述 该类的实例被用于生成伪随机数的流。该类使用一个 48 位的种子,它被一个线性同余公式所修改。如果 Rando...

  • 生成随机数

    两个C函数 rand()函数生成的随机数是伪随机数,所谓伪随机数,指的是程序每次运行,生成的随机数都是不变的,生成...

  • 多线程环境下生成随机数

    生成伪随机数据 Java里有伪随机型和安全型两种随机数生成器。伪随机生成器根据特定公式将seed转换成新的伪随机数...

  • python中random模块功能详解(python工程狮)

    random — 生成伪随机数,random模块为各种分布实现伪随机数的生成。 1.random.random()...

  • 无处不在的随机数

    目录: 什么是随机数 随机数分类 伪随机数生成器 真随机数生成器 各种语言中的随机数 使用系统时间作为种子是否安全...

网友评论

    本文标题:线性同余法生成伪随机数

    本文链接:https://www.haomeiwen.com/subject/atihcttx.html