【问题标题】:Pseudo random number generator with > 64 bit seed for a 52 card deck shuffle具有 > 64 位种子的伪随机数生成器,用于 52 张牌洗牌
【发布时间】:2012-03-25 19:44:45
【问题描述】:

在编写洗牌算法时,我意识到有 52 个! ~= 2^225 可能发生的洗牌。鉴于此,在我看来,任何基于具有标准 32 位或 64 位种子的 PRNG 的洗牌算法都只能产生所有可能洗牌的子集。由于我的平台只有 32 位种子 PRNG(只有 POSIX srandom()/random() 函数),我想知道是否有任何方法可以创造性地使用它来创建能够产生任何结果的洗牌算法。如果没有,有没有人知道 PRNG 算法能够使用种子,种子是我可以自己实现的几个 32 位整数的组合?

【问题讨论】:

  • 有很多内部状态>226位的RNG。最受欢迎的可能是 Mersenne Twister 和 Marsaglia xorshift+。

标签: random shuffle


【解决方案1】:

如果你想使用当前的随机数生成器来解决你的问题,你只需要找到一种方法将所有可能的洗牌的参数空间分成几组。

例如,如果您有一个只能是 1 到 4 的随机种子,但参数空间有 12 种可能的排列,您将使用两个随机种子来求解:

(seed1) 定义您所在的参数组(1-4,5-8 或 9-12)
(seed2) 定义哪个元素是你的最终结果

(此参数集不必是种子大小的偶数倍。)

我将这种方法用于固态物理建模中非常大的复杂性问题。这是一个严格的数学解决方案,但它可能不是最优雅的软件解决方案。祝你好运。

【讨论】:

  • 可能一个完整的解释太长了,但我很好奇。为什么您的解决方案有效?您的解决方案与从同一生成器生成随机数对的错误解决方案有何不同?毕竟,使用两个不同的种子并不会降低生成器的确定性,不是吗? (我希望你是对的,但我有兴趣了解原因。)
  • 嗯,在物理学中,问题的参数空间很容易分组。在您的情况下,也许您会将每个单独的洗牌选项除以以下情况:卡 1 未置换,卡 2 未置换等。然后您生成一个未置换卡的随机数,然后生成一个真实随机数您想要该组中的哪个特定排列。我不相信这会使随机生成或多或少具有确定性。而且...如果是这样,那对我来说学习很重要。
  • 所以我想这在原则上是可能的。不过,对于洗牌问题,我将不得不考虑如何实际实施。
【解决方案2】:

有趣的问题。如果在 Linux 上,/dev/urandom 甚至 /dev/random 可能适合。这些设备依赖于一个“熵池”,由异步硬件事件的时间提供。

不过,还要研究 mrand48() 系列函数,无论是否在 Linux 上,它们都出现在 cstdlibstdlib.h 中。这让你得到 48 位,这更接近你想要的。

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多