一、背景
我们在日常生活中会遇到许许多多的随机事件,最典型的例子就是抛硬币或者骰子。在生活中,我们想要得到一个随机结果的方式很简单,直接拿一枚硬币或者一个骰子就可得到一个比较随机的结果。
对于这里为什么要用“比较”这个词是因为如果能知道事物的一切信息的话,“随机”也就不再是随机了。这里有点类似“上帝会不会掷骰子”的问题。在这里就不对这点进行深入讨论了。以下内容均是在我们相信不可能得到关于事物的一切信息,即“随机性”存在的基础上进行讨论的。
计算机编程中我们想要生成一个随机数,通常会使用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)
给定, 考虑下面这个线性同余
用这种方法会生成的序列就是在
上的均匀分布。
因为做线性同余运算会产生周期性, 事实上这个周期:
事实上,我们有这样一个定理说明上式 (2) 什么时候取到等号:
Thm 2.1: LCG的周期是m,当且仅当:
<1> b与m互素;
<2>m的每一个素因子可以被a-1整除;
<3>如果m|4,则(a-1)|4
很容易给出一个例子(读者可自行验证)