【问题标题】:Efficient Xorshift skip ahead高效的 Xorshift 跳过
【发布时间】:2012-07-27 17:34:09
【问题描述】:

我需要一个快速的随机数生成器,它允许我在随机数序列的不同位置随机访问数字。我选择了 Xorshift,因为它快速且易于实施。

为了从序列中获取特定的随机数,我实现了如下方法(mPos保存下一个随机数的位置):

void XorshiftRandomGenerator::skipTo(unsigned int pos)
{
    // Reset if we passed the position
    if (mPos>pos)
        reset();

    // Generate random numbers until we're done
    while (mPos<pos)
        random();
}

随后的random() 将返回所需的数字,但这种方法非常昂贵。有没有办法用 Xorshift 跳过大量随机数,而不计算其间的每个随机数?

作为替代方案,我可以使用另一个随机数生成器。你能推荐一个可以快速跳过的吗?

【问题讨论】:

  • 我认为线性同余生成器应该可以让您相当轻松地向前跳过(即在对数时间内)。

标签: c++ algorithm random


【解决方案1】:

Forest B. Brown 在 1994 年发表了一篇名为 Random Number Generation with Arbitrary Strides 的论文,广泛讨论了这个主题。

正如 Nabb 在 cmets 中所述,Linear Congruential Generator 可用于高效跳过。当然,通常的advantages and disadvantages LNG 也适用:事情简单且速度极快,但伪随机数的质量不是很高。公式在here详细解释。

【讨论】:

    【解决方案2】:

    你当然可以跳入 xorshift,过程描述为 here,但我自己没有读过,所以我不知道它有多容易。

    或者,您可以查看PCG,它通过使用底层 LCG(与 @Daerst 的答案相同)提供跳转功能,但对其进行后处理以改善其统计属性,或者描述 @987654323 的一些可拆分生成器@。例如,SplitMix 生成器只有一个常数的循环加法,因此要跳跃任意距离,您只需将跳跃距离乘以常数并加上(here 是一个显然通过 BigCrush 的 SplitMix 导数) .

    【讨论】:

      【解决方案3】:

      您可以使用随机数生成器的层次结构。 IE。您使用生成器 A 生成的每个数字都用作生成器 B 的种子,生成器 B 在从 A 获取下一个数字重新初始化自身并生成接下来的 100 个数字等之前生成 100 个数字。这样您可以逐步向前跳过100. 你当然可以将它级联成生成器树。

      【讨论】:

      • 很好的提示,谢谢!不过,我想知道是否有使用 Xorshift 跳过的数学方法,或者设计用于快速跳过的 RNG。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 1970-01-01
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多