众所周知,Python 使用 Mersenne Twister (MT) 算法来处理其随机数。然而,尽管周期很长(~2^19937),但众所周知,当您对大于 2080 个元素的序列进行洗牌时(因为 !2081 > 2^19937),您无法达到每个随机排列。当我处理排列和统计属性对我来说很重要时,我试图找出将 Python 生成器与额外的随机源混合或重新播种以避免重复的最佳方法。
目前,我的概念是使用系统随机数生成器(SystemRandom)为MT生成器添加一个外部随机源。我可以想到两种方法来做到这一点:
- 将 SystemRandom 随机数与 MT 随机数异或
- 使用 SystemRandom 重新播种 MT
第一种方法由硬件随机数生成器以某种频率使用,以减少它们的偏差趋势。但是,它的效率非常低。在 Windows XP 机器上,SystemRandom 比标准 Python 随机函数慢 50 倍。当您的大部分功能都涉及改组时,这对性能造成了巨大的影响。鉴于此,使用 SystemRandom 重新播种 MT 应该会更加有效。
但是,这种方法也存在两个问题。首先,在运行期间重新播种 MT 可能会破坏其统计特性。我相当肯定,如果 MT 运行的时间足够长,这应该不是问题,因为每次运行的 MT 值都应该是格式正确的(无论起点如何)。然而,它确实表明在 MT 重新播种之间有一个相当长的时期是优选的。其次,有一个问题是什么是触发重新播种的最有效方法。处理此问题的最简单方法是使用计数器。然而,更有效的方法可能是可能的。
那么,关于这一点有三个问题:
- 有没有人读过任何关于在每 N 个样本后用随机值重新播种 MT 会改变其理想的统计特性的内容?
- 有没有人知道比增加计数器来触发重新播种更有效的方法?
- 最后,如果有人知道解决这个问题的一般更好的方法,我会全力以赴。