科普向-计算机如何生成随机数?(第一期)

一、背景

我们在日常生活中会遇到许许多多的随机事件,最典型的例子就是抛硬币或者骰子。在生活中,我们想要得到一个随机结果的方式很简单,直接拿一枚硬币或者一个骰子就可得到一个比较随机的结果。

对于这里为什么要用“比较”这个词是因为如果能知道事物的一切信息的话,“随机”也就不再是随机了。这里有点类似“上帝会不会掷骰子”的问题。在这里就不对这点进行深入讨论了。以下内容均是在我们相信不可能得到关于事物的一切信息,即“随机性”存在的基础上进行讨论的。

计算机编程中我们想要生成一个随机数,通常会使用random函数,比如下面这段python代码:

import random
# 生成一个0到1之间的随机浮点数
random_float = random.random()
# 使用random.choice()随机选择一个元素
selected_number = random.choice([1,2])

但是你是否想过这样的问题?计算机的程序都是人们设置好的,那如果是人们提前设置好的程序,怎么会存在”随机“呢?换句话说,计算机是如何生成随机数的?所生成的随机数真的是随机的么?我们如果要用计算机生成随机数就要给计算机定义这些“随机”,但是这样是不是就会变成“确定”而不是“随机”了?

我们接下来就来回答:计算机是用什么方法产生这些随机数以及随机分布的。

二、生成区间[0,1]上的均匀分布

1、NOISE

最容易想到的就是基于Noise的生成方法,这里的噪声指的是计算机的电噪声和热噪声,这些噪声本身具有随机性,因此会产生随机。但这种方式存在的一个重大问题是不可控以及无法重复。事实上我们没办法精准控制每次计算的电噪声以及热噪声。而这种不可重复性使得很多结果不具备可信性。想象一下一篇文章里的数据不同人用不同的电脑算出来的结果和原文差距很大且各不相同,自然就无法验证结论的可靠性。

2、伪随机数生成(PRNG: Pseudo-Random Number Generate)

a)利用线性同余生成(LCG:Linear Congruence Generate)

给定a,\,b,\,m,\,X_0, 考虑下面这个线性同余

X_{n+1}\equiv aX_n+b\,\,\,\,\,\,(mod\,\,\, m) \quad \quad \quad \quad \quad (1)

用这种方法会生成的序列{\frac{X_n}{m}}就是在[0,1]上的均匀分布。

因为做线性同余运算会产生周期性, 事实上这个周期:

Period\,\leqslant\, m\quad \quad \quad \quad \quad \quad \quad \quad \quad \quad\quad\quad (2)

事实上,我们有这样一个定理说明上式 (2) 什么时候取到等号:

Thm 2.1: LCG的周期是m,当且仅当:

<1> b与m互素;

<2>m的每一个素因子可以被a-1整除;

<3>如果m|4,则(a-1)|4

很容易给出一个例子(读者可自行验证)

m=2^k,\,a=4c+1,\,b \text{ is odd number}

当然LCG还有更一般的形式:

X_{n+1}\equiv a_0X_n+a_1X_{n-1}+...+a_jX_{n-j}+b\,\,\,\,\,\,(mod\,\,\, m) \quad \quad \quad \quad \quad (3)

但是这样得到的周期 \tau 最大并不能取到 m^{j+1}-1\tau 的大小是由a_j,b\,\,and \,\,m决定的

关于LCG的一个重要事实是,它显示了s元组即向量(X_n,X_{n-1},...,X_{n+s-1})的非常差的分布.

Marsaglia在Random numbers fall mainly in the planes. Proc. Nat. Acad. Sci. USA, 61:25, 1968.中证明了这一重要事实:

Thm 2.2: 一个通过(1)式得到的s元组(X_n,X_{n-1},...,X_{n+s-1})位于一个s维超平面(0,1)^s上的等距平行线上,其最大值为(s!m)^\frac{1}{s}

可以看出当s较大时,相对于均匀分布的偏差是明显的。
尽管LCG有这个缺点,但它仍然是实践中应用最广泛的伪随机数生成器。

(b)线性反馈移位寄存器(LFSR: Linear Feedback Shift Register)

再简单介绍另一种方法LFSR,生成方式如下:

对于一个二进制数字X_k=(a_n,a_{n-1},...,a_1)_B可以生成

X_{k+1}=(b_n,b_{n-1},...,b_2,b_1)_B

其中   b_j=a_{j-1}\,\,\,j\in[2,n],  b_1=\sum_{k=1}^{n-1}w_ka_k+a_n\quad(mod\,2)

三、逆变换法

a) 一个例子

考虑下面的分布,F(x)是概率分布函数,f(x)是概率密度函数,如何让计算机生成下面的分布呢?

事实上,对于如上图所示的分布:

X\sim p(x)d(x),\quad\quad F(x)=\mathbb{P}(X\leq x) ,\quad F(x)\in [0,1]\\\\F(x)=\int_{-\infty}^{x}p(x)dx,\quad\quad p(x)=\frac{dF}{dx}

可以把其看成是Y轴上的均匀分布\mathcal{U}[0,1],通过F^{-1}(y)映射到x轴:

x\doteq F^{-1}(y),\quad\quad y\sim \mathcal{U}[0,1]

根据定义以及y\sim \mathcal{U}[0,1]

\mathbb{P}(X\leq x)=\mathbb{P}(F^{-1}(y)\leq x)=\mathbb{P}(y\leq F(x))=F(x)

因此这样产生的x符合:

X\sim p(x)d(x),\quad\quad F(x)=\mathbb{P}(X\leq x) ,\quad F(x)\in [0,1]

所以用这种逆变换法也可以产生我们需要的分布。

b) 另一个例子:指数分布的生成

对于指数分布exp(\lambda ), 其概率密度函数:

p(x)=\left\{\begin{matrix} \lambda e^{-\lambda x}& x\geq 0 \\ 0& x< 0 \end{matrix}\right.

图像如下:

我们很容易可以得到其分布函数:

F(x)=\int_{0}^{x}p(t)dt=-e^{-\lambda t}|_0^x=1-e^{-\lambda x}\doteq y \quad\quad y \in [0,1)

可以反解出:

x=-\lambda^{-1}log(1-y)

所以我们可以利用前面讲到的生成 \mathcal{U}[0,1] 的方法生成 Y_n \sim\mathcal{U}[0,1]\quad i.i.d, 之后利用上面的式子可以得到:

X_n=-\lambda^{-1}log(1-Y_n), \quad\quad where\,\,Y_n \sim\mathcal{U}[0,1]\quad i.i.d

c) 如何生成[a,b]上的均匀分布\mathcal{U}[a,b]

(i)平移拉伸

对于LCG生成的X_n做下面变换即可:

Y_n=(X_n+a)(b-a), \quad\quad\quad X_n \sim\mathcal{U}[0,1]\quad i.i.d

因此就得到了Y_n \sim\mathcal{U}[a,b]\quad i.i.d

这里就回答了我们一开始的问题,计算机是如何生成随机数的问题。实际上对于给定区间的随机数,就转换成了生成在这个区间的均匀分布问题,我们只需要按上述方法生成一个数即可。这个数就是服从在这个给定区间均匀分布的数,而这个均匀分布本身就代表了随机性。 

(ii)逆变换法

考虑分布函数F(x)=(b-a)^{-1}(x-a)=y,\quad\quad\quad where\,\, y\sim\mathcal{U}[0,1]\quad i.i.d

我们只需要生成y\sim\mathcal{U}[0,1]\quad i.i.d,随后根据 x=F^{-1}(y) 即可得到 x\sim\mathcal{U}[a,b]\quad i.i.d

d)生成两点分布或者多点分布

(i)两点分布

如果要生成[0,1]上的两点分布,我们只需要给定一个阈值 p, 随后生成[0,1]上的均匀分布x\sim\mathcal{U}[0,1],之后再加上条件判断:

if\left\{\begin{matrix} y=1 & x\leq p \\ y=0&x>p \end{matrix}\right.

这样生成的y就服从y \sim \mathcal{B}(p)

(ii)多点分布

类似于两点分布,只需要多加入几个分点(阈值)即可,这里就不过多赘述啦。

这样就回答了计算机如何在给定的数中进行随意选取的问题。比如给了k个数,那么可以生成 [0,1] 上的均匀分布,之后利用(k-1)个分点把 [0,1] 分成k段,如果生成的随机数在第i个区间,那么就输出给定的数中得第i个数。

e) 局限性

当然我们会注意到使用逆变换法对F(x)的要求十分严格,通常需要没有跳跃间断点并且不存在一个区间[m,n]使得 F(x)\equiv C\quad\quad x\in[m,n]其中C为一个常数。当然对于F(x)也需要F^{-1}(x)是可以求出来的,这也是使用逆变换法的根本。

四、结语

这期讲了一些简单的例子,当然我们平常遇到的最常见的分布函数(比如正态分布),以及一些更为一般的分布函数计算机要怎么生成相应的分布呢?会在下一期里同大家分享~

上面内容只是作为科普,仅代表个人的一些理解,如果有不严谨或者错误的地方欢迎各位大佬指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值