FW:0到1之间的随机数是怎么产生的

0到1之间的随机数是怎么产生的

http://www.matrixq.net/2011/10/10365.html

在很多编程语言中都有这样一个函数,生成0-1之间的随机数,比如Matlab和C中的rand()。其实这个过程就是在均匀分布(0,1)上的取样算法(Sampling algorithm),生成其他分布的随机数,比如高斯分布、指数分布都是建立在这个算法之上。这个0-1之间的随机数是怎么生成的呢?

对于”随机”有很多定义,在自然界中也有很多人类无法预测的随机现象,但是用机器生成的数,肯定不是真正的随机数,因为他是通过某种算法得到的,所以它又被称为”伪随机数”。最早研究随机数生成方法的是美国数学家Lehmer,在1945年左右他通过当时世界的第一台计算机ENIAC做了很多数论(number theory)方面的研究,其中就包括伪随机数的生成。Lehmer的生成随机数算法中包含3个整形参数,a,c,和m,以及一个被称为”种子(seed)”的初始值x_0。这样生成的下一个随机数就可以通过如下式子得到:

(1) \begin{equation*} x_{k+1}=(ax_k+c) \ mod \ m \end{equation*}

其中mod是取余数的运算。例如取 a=13, c=0, m=31以及 x_0=1, 生成的数列就成为:

  \[ 1,13, 14, 27, 10, 6, 16,22, 7, 29, 5, 3,... \]

这些数看起来是随机,下一个值是多少?由于我们已经有初始值了,所以很容易计算(3 \times 13)\ mod \ 31 = 8。同时也可以看出这是一个1到30之间的周期数列,它总是在重复1-30之间的数,如果把这个数列除以m,我们就可以得到[0,1]之间的浮点数了,即

  \[ 0.0323, 0.4194, 0.4516, 0.8710, 0.3226, 0.1935, 0.5161, .... \]

这系列数中只有30个不同的值,最小的是1/31, 最大的是30/31。

1960年,作为当时的主流计算机厂商IBM发布了名为RND的随机数生成计算机,他选的参数是a=2^{16}+3=65539,c=0,m=2^{31},它的周期范围很大,这些参数看起来让产生的数是真正的随机数了,可是不久就被人发现,它产生的数之间有很密切的关系,即

(2) \begin{equation*} x_{k+2}=6x_{k+1}-9 x_k \end{equation*}

犯了这么一个低级的错误,这无疑让当时的巨人脸上很没面子。现在Matlab的rand函数中使用的参数是

  \[ a=7^{5}=16807 \]

  \[ c=0 \]

  \[ m=2^{31}-1=2147483647 \]

是Park 和 Miller在1988年他们的一篇论文中推荐的。用这些参数产生的随机数范围是0.00000000046566 到 0.99999999953434,所以它仍然是伪随机数。当然在1995年matlab5之后,matlab就使用了一种全新的随机数生成算法,叫做Marsaglia’s generator。它的运算中没有取余,速度更快,直接产生浮点数,周期是2^{1430},”随机”的貌似已经很让人满意了。具体请参照大牛论文 G. Marsaglia, “Random numbers fall mainly in the planes”, Proc. Natl. Acad. Sci. 61(1), 25–28 (1968).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值