线性同余法生成伪随机数

备份自: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$是正整数。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 13,708评论 0 5
  • 最喜欢榛子蛋糕 细腻顺滑的奶油口感 淡淡的清香感 不属于甜腻的味道 真的是最爱呀 配一壶红茶或者玄米 清新清香的融...
    li_magazine阅读 2,629评论 0 0
  • 第十四章 评估的原则 评估是一个复杂、评价的过程,在订立治疗协议之前进行。 我们关注情感直至他在客体关系历史中的根...
    心理学工作者_张旭兰阅读 994评论 0 0
  • 又到周五啦,对的,我又休息了!什么叫又嘛?周五休息是定下来的!周周复周周啊,越长大越觉得时间的指针走的越快,那么,...
    行云流水畅遨游阅读 1,865评论 0 2
  • 1.几张图片看清缓冲机制 2.NSURLCache的7种常见用法 3.NSURLRequest的7种缓冲机制 4....
    煎饼侠拯救不快乐阅读 3,795评论 0 1