matlab线性同余发生器,线性同余法生成伪随机数

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,若要得到最大周期,需要满足:

$B, M$互质;

$M$的所有质因数都能整除$A-1$;

若$M$是4的倍数,$A-1$也是;

$A,B,X_0$都比$M$小;

$A,B$是正整数。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值