【问题标题】:Avoiding Exact Repeats for Mersenne Twister in Python在 Python 中避免 Mersenne Twister 的精确重复
【发布时间】:2013-01-22 00:41:35
【问题描述】:

众所周知,Python 使用 Mersenne Twister (MT) 算法来处理其随机数。然而,尽管周期很长(~2^19937),但众所周知,当您对大于 2080 个元素的序列进行洗牌时(因为 !2081 > 2^19937),您无法达到每个随机排列。由于我正在处理排列并且统计属性对我来说很重要,因此我试图找出将 Python 生成器与额外的随机源混合或重新播种以避免重复的最佳方法。

目前,我的概念是使用系统随机数生成器(SystemRandom)为MT生成器添加一个外部随机源。我可以想到两种方法来做到这一点:

  1. 将 SystemRandom 随机数与 MT 随机数异或
  2. 使用 SystemRandom 重新播种 MT

硬件随机数生成器以某种频率使用第一种方法,以减少它们的偏差趋势。但是,它的效率非常低。在 Windows XP 机器上,SystemRandom 比标准 Python 随机函数慢 50 倍。当您的大部分功能都涉及改组时,这对性能造成了巨大的影响。鉴于此,使用 SystemRandom 重新播种 MT 应该会更加有效。

但是,这种方法也存在两个问题。首先,在运行期间重新播种 MT 可能会破坏其统计特性。我相当肯定,如果 MT 运行时间足够长,这应该不是问题,因为每次运行的 MT 值都应该是格式正确的(无论起点如何)。然而,它确实表明在 MT 重新播种之间有一个相当长的时期是优选的。其次,有一个问题是什么是触发重新播种的最有效方法。处理此问题的最简单方法是使用计数器。然而,更有效的方法可能是可能的。

那么,关于这一点有三个问题:

  1. 有没有人读到过在每 N 个样本后用随机值重新播种 MT 会改变其理想的统计特性的内容?
  2. 有没有人知道比增加计数器来触发重新种子更有效的方法?
  3. 最后,如果有人知道解决这个问题的一般更好的方法,我会全力以赴。

【问题讨论】:

  • 到目前为止,Charles 提出了一个观点,即由于 shuffle 函数的工作原理与混沌地图相似(前提是您不断对同一个列表进行混洗),您可能仍然会遇到所有排列(因为您的生成器的状态是 MT 和当前序列状态)。如果有人有证据支持或反对这一点,我会全神贯注。如果为真,重复洗牌可能会允许到达所有状态(因为序列的 # 个状态 == 排列的 # 个)。

标签: python random seeding mersenne-twister


【解决方案1】:

我意识到这是一年多以前的事了,但如果你回头看,有一个简单的解决方案:只需每 k 次从 MT RNG 获取一个新值从 SystemRandom 到 XOR足够大的 k, 而不是每次。例如。如果 SystemRandom 慢 50 倍并且您设置 k = 5000,那么您的新组合 RNG 应该只慢约 1%,并且(假设 SystemRandom 是“真正”随机的)在涉及超过 5000 个 RNG 调用的每次运行中都可以达到任何排列.

【讨论】:

    【解决方案2】:

    重新播种对您没有帮助。它只会跳入(非常非常)长的 MT 序列的其他地方。你确定洗牌你的数据会给你一个有偏见的结果吗?因为在宇宙的生命周期中,你永远不会有足够的时间来生成所有可能的序列。因此,即使您知道某些序列可能永远无法生成,但这并不意味着生成的序列会有偏差。我想你最好的选择就是直接使用 shuffle 命令。


    如果您查看numpy.random.shuffle source code(第 4376 行),这里基本上是使用的算法(为了清楚起见,我对其进行了简化):

    i = len(x) - 1
    while i > 0:
        j = randint(0, i)
        x[i], x[j] = x[j], x[i]
        i = i - 1
    

    换句话说,从末尾开始,它将值与数组中在它之前随机取的随机值交换,直到所有值都被交换。最终状态不仅取决于随机生成器,还取决于数组的初始状态。这意味着理论上,如果您执行足够的 shuffle,您应该能够访问所有排列。

    【讨论】:

    • 虽然绝对没有足够的时间来访问所有序列,但应该(至少在原则上)有可能到达每个序列。此外,我的直觉表明,根据洗牌的工作方式(Fisher-Yates 的一种变体),对位置的扰动可能会有所帮助。毕竟,如果我有一个周期为 3 的生成器(例如 [1,2,3])并且需要 6 个值,那么 [1,2,3,1,2,3] 与 [1,2, 3,3,1,2] 尽管我所做的只是跳到原始循环 3 中的不同位置。
    • 但是,话虽如此,我仍在考虑按原样使用它(并且已经将它逐字用于任何少于 2000 个元素的序列)。至于它是否给出有偏见的结果,我认为这将完全取决于数据。我不知道有任何研究表明当由于周期性而无法在随机播放中达到所有状态时,哪些排列会退出可能性范围,所以老实说,我不知道是否有人知道这些影响如何影响各种计算。但问也无妨。 :)
    • 我认为达到所有可能排列的理论条件取决于您的随机数保持随机性。由于循环重复,这些数字最终不是随机的——它们是重复的(从理论上的、渐近的角度来看)。显然,如果您正在生成相同初始状态的随机播放,您将在某个时候得到一个精确的重复而不是一个新的重复。反复改组相同的序列可能会回避这一点,但我还没有看到证明。然而,这似乎是合理的,因为它具有类似于混沌地图的形式。
    猜你喜欢
    • 2014-02-22
    • 2012-07-27
    • 2015-02-14
    • 1970-01-01
    • 2012-01-13
    • 2011-01-28
    • 2014-04-17
    • 2016-02-21
    • 2014-03-01
    相关资源
    最近更新 更多