人类的随机数生成能力是出了名的差。我希望能快速生成 "足够随机 "的数字。我并不追求多么伟大的东西,我只希望能在半分钟内生成随机数字。经过一番搜索,我找到了 George Marsaglia 在 usenet 上发表的一篇文章:

选择一个两位数,比如 23,作为你的 "种子"。

组成一个新的两位数:10 的个位数加上单位个位数的 6 倍。

示例序列为 23 -> 20 -> 02 -> 12 -> 13 -> 19 -> 55 -> 35 -> ...

其周期是乘数 6 在相对于模数 10 的素数组中的阶数(本例中为 59)。

马萨利亚最有名的作品是 "死硬派 "的 RNG 测试套件,所以他很了解自己的东西。我很好奇为什么这个方法有效,为什么他选择了 6。

我们将使用小精灵的语言 Raku。我会解释我在下拉菜单中使用的所有奇怪功能,以防你也是个小精灵。

这个序列是周期性的,也就是说,如果我们反复应用它,最终会得到相同的元素。让我们从产生整个序列的函数("子程序")开始:

解释:拉库语是一种极其古怪的语言,但我会尽量简单明了。

调查属性

如果 RNG 是均匀的,那么每个数字在序列中出现的次数应该是相同的。我们可以将最后几位数字转换成一个多集合或 "包 "来验证这一点。

[Raku 子程序的代码片段]

这似乎是一个足够均匀的分布,不过我得到 0 或 9 的可能性要小一些。

我的下一个想法来自顽固派测试。来自维基:

重叠排列:分析五个连续随机数的序列。在统计上,120 种可能的排序出现的概率应该相等。

数据集中只有 54 个 5 位数序列,因此我将把它应用于 2 位数的 "转换"。例如,序列包括 28 -> 50 的转换,没有其他 X8 -> Y0 形式的转换,因此单元格(8,0)应为 1。

从表中我们可以看出,有些转换是不可能的。如果我产生一个 0,就不可能马上得到一个 6。这显然不是一个好的 RNG,但无论如何,我的期望值还是很低的。

如果我不把最后一位数乘以 6,而是乘以 4 呢?

我不知道,我挺喜欢 RNG 的,它永远不会给我 3。不同的序列称为轨道,其长度称为周期。让我们看看用 4 作为乘数能得到的所有可能的轨道: