我们如何模拟随机性?

How do we simulate randomness?

我在 Python 中遇到了这个函数 randint() ,它从整数列表中给你一个随机整数。我无法消化的是我们如何才能真正模拟随机性。我如何才能真正判断可能使用任何编程语言的随机函数不会给出有偏差的结果?贝尔曲线?

我们如何模拟像随机性这样自然的东西?我们可以只计算一个结果可以出现的概率。但永远不知道这是如何工作的。

为了模拟某些东西,我们需要对主题有完整的了解,不是吗?

快速回答:


熵被引入计算机算法以启动由聪明的计算机算法生成的确定性数字序列,然后拟合到用户要求的分布曲线,例如rand(1,10) could internally produce numbers from 0.0 to 0.9999 but needs to map to 1 through 10.。因为很难 知道 那个熵是什么,它使得确定数字更加困难,因此伪随机生成器描述。在统计学中,我们了解到抛硬币 100 次可能不会得到 50 次正面和 50 次反面,也不应该,因为抛硬币不是这样的。然而,这是一个很好的例子。假设沿着均匀分布进行无限次迭代,概率就起作用了。 Heads 可能会连续显示 100 次、1000 次、10,000 次。 可能,不太可能,但有可能。如果 0 在可能答案列表中,则模拟随机性的算法没有义务确保返回 0。它只需要确保它是可能的。

一般答案


大多数计算机生成的随机数都是伪随机数。

正如您在问题中所回避的那样,计算机无法模拟真正的随机性;所有随机算法都确定性地生成随机数;这意味着如果知道算法的初始种子、算法使用的熵以及算法在哪一次迭代中,就可以确定 'random' 数。真正的随机性只能通过观察随机事件的结果来实现,这可能是计算机组件或其他现象的物理性质。

有人可能会争辩说,自然随机性实际上并不是随机的,而只是一系列未知的事件。不是不可知的(即熵),但只是目前未知。它只是未知的(随机的),因为我们目前无法解释或预测它,由于技术或知识的进步不足。确实存在混沌熵,但除非我们谈论的是量子计算机,否则这无关紧要。对于大多数适用的软件应用程序来说,一个非常好的伪随机数生成器就足够了。

给定 1,000 年前的一段时间,我们可以说海洋很容易发生随机海啸。现在我们有了更先进的技术和理解,我们可以创建预测模型。随着我们输入有关所有可能导致海啸的事件的更多信息,这些预测模型变得更加准确。

计算机难以模拟的部分是熵。熵,简单来说,就是随机性。当生成素数元组时,用于创建一系列随机数的算法通常会从外部来源收集熵;移动鼠标、电子噪音、'noise' 从内置 WiFi 或蓝牙等天线收集。熵是创建一组好的模拟随机数的关键。

即使我们在收集熵方面取得了所有进步,仍然可以诱导机器生成一组特定的熵,然后攻击者可以准确预测生成的数字。如果算法从麦克风收集噪音,它们可以在正确的时间产生响亮且可预测的噪音,以影响稍后生成的数字序列。所有其他收集熵的形式也是如此。

获得真正随机性的一个简单方法是使用 Random.org.

The randomness comes from atmospheric noise, which for many purposes is better than the pseudo-random number algorithms typically used in computer programs.

由于您要模拟 随机性,您将最终使用伪随机数生成器。该主题涵盖广泛。 PRNG.

Python 的 random() 已经使用了 Mersenne twister。我的猜测是您不想要比这更好的东西,除非您正在使用某种加密工具。

现在,如果您想获得真正随机的信号,它必须具有物理性质(例如盖革计数器)。但在大多数情况下,您不需要走这么远。

您问题的答案在很大程度上取决于应用程序中随机性的目的。

我先问随机是什么意思?这个词是 shorthand 表示 先验 不可预测的结果。您可以尝试使用 entropy 等度量来量化不可预测性的程度,但随机性本身是一种二元状态:事件要么可以确定地预测(熵 = 0),要么是随机的。钟形曲线(正态分布)或均匀分布等不同的概率分布具有不同的熵值,但它们都属于随机分布,因为它们的熵值不为零——您无法确定地预测结果。

大多数编程语言都实现了某种类型的伪随机数生成器 (PRNG)。这些是确定性算法,使用 chaotic behavior 来模拟随机性的不可预测性。如果您知道所应用的算法和初始状态,则可以绝对确定地预测 PRNG 的结果。然而,我们可以从 Alan Turing 的 "Imitation Game." 中获得灵感。想象一下,你有两个黑盒数字源,其中一个包含 PRNG(但你对它的初始状态一无所知),而另一个包含一个源"real" 随机性(不管是什么意思)。如果你被允许应用你能想到的任何测试,而你无法分辨哪个是你计划在你的计算机程序中使用的样本范围内的,那么你使用哪个重要吗?

如何判断 PRNG 是否可以使用?基本上它归结为相信设计算法的人知道他们在做什么,并且该实现能够很好​​地抵抗 tests specifically intended to catch PRNGs in identifiably non-random behavior, such as Marsaglia's Diehard tests or the more recent Dieharder suite, or those available from NIST.

的电池。

How can we simulate something that is so natural as randomness?

长话短说:

  • 通过了解是什么让某物起作用 "randomly",
  • 通过聪明地做出正确的简化假设,以免使问题变得太难,
  • 通过具有良好的先前收集的统计数据来知道统计模型是正确的,
  • 通过拥有足够好的 PRNG 来模拟该随机过程,并且
  • 通过一种算法将 PRNG 的输出映射到基础统计分布。

通过了解是什么让某事起作用 "randomly"
放射性衰变几乎完美地表现为泊松过程。不太完美的是,世界杯比赛中的进球可以建模为泊松过程。 (但这对拉斯维加斯来说已经足够赚钱了。)另一方面,抛硬币的结果是伯努利过程的一个例子。有许多不同种类的随机过程,这些不同的随机过程导致不同种类的随机分布。了解幕后发生的事情很重要。

通过聪明并做出正确的简化假设
建模者的技巧包中最有用的工具之一是中心极限定理。将很多很多随机影响加在一起,最终结果通常看起来是高斯分布的(问题中提到的 "Bell Curve")。假设高斯分布是一个很好的简化假设,但它会给人带来麻烦。一个人必须足够聪明,避免过于简单化假设。

通过之前收集的良好统计数据
人们花了一段时间才确定放射性衰变确实是一个泊松过程。他们通过拥有先前测量的良好历史记录来确定这一点。没有以前收集的统计数据,所有的人都只是猜测。猜测特别擅长在后面咬猜猜的人

通过拥有足够好的 PRNG
使用确定性伪随机数生成器的原因有很多。从 运行 #12345 的 Monte Carlo 模拟可以精确重复的意义上说,PRNG 不完全是 "random" 可能是一件好事。如果模拟车辆爆炸或模拟患者在 Monte Carlo 模拟的 运行 中死亡,任何理智的人都会想详细调查该案例。

幸运的是,那里有许多非常好的 PRNG。 Python 使用梅森扭曲器。虽然不是最好的,但是非常非常好。

通过将 PRNG 的输出映射到基础统计分布的算法*
如果无法将 Mersenne twister(或您使用的任何 PRNG)的结果转换为手头的分布,您就完蛋了。幸运的是,我们之前的人已经花费了大量时间来开发近似大量随机分布的算法。

这个问题被标记为 python,所以我不应该写关于 python 的随机包和 numpy 的随机包。后者甚至比作为标准 python 软件包免费获得的内置功能更好。它提供了大量算法,可将 Mersenne twister(例如)的整数输出转换为大量经常遇到的概率分布。 (在某些情况下,概率分布很少遇到。)