【问题标题】:Pseudo-random number generator伪随机数发生器
【发布时间】:2009-02-25 03:08:27
【问题描述】:

创建最佳伪随机数生成器的最佳方法是什么? (任何语言都可以)

【问题讨论】:

  • 这是一个重要的研究领域,没有公认的最佳指标……您想达到什么目标?
  • 您想要真正的随机性,还是想要可以重复的类随机系列?
  • @Robert Gould:他指定了伪随机。如果他在寻找真正的随机性,他确实是在找错树……
  • 来自将被删除的答案:Hardware random number generator

标签: language-agnostic random


【解决方案1】:

这完全取决于应用程序。例如,创建“最随机”数字的生成器可能不是最快或最节省内存的生成器。

Mersenne Twister 算法是一种流行的、相当快速的伪随机数生成器,可以产生非常好的结果。它有一个巨大的周期,但也有一个相对巨大的状态(2.5 kB)。但是,它对于加密应用程序来说还不够好。

更新:自从编写了这个答案后,PCG family of algorithms 的发布似乎在大多数方面(速度、内存、随机性和周期)都优于现有的非加密算法,使其成为出色的全方位选择but cryptography

如果你在做加密,我的回答仍然是:不要自己动手。

【讨论】:

  • MT 还具有在 n*[0-1)-空间上均匀绘制 n 元组的优点,用于大 n。不是每个 PRNG 都能做到的。这是它在许多领域的蒙特卡洛研究中非常受欢迎的原因。
  • “它被认为不足以用于加密应用程序”:不,MT 绝对禁止用于加密,因为 MT 的 624 个输出数字序列可以让您预测它的全部未来输出!捕获正确加密 RNG 的输出序列不会提供有关其未来输出的任何信息。
  • “捕获正确加密 RNG 的输出序列不会提供有关其未来输出的任何信息。”错了,有资料。未来的输出只需要难以计算即可。
【解决方案2】:
【解决方案3】:

德国杂志 C't 在 2/2009 期中测试了许多软件和硬件生成器,并通过各种统计测试运行了结果。

我扫描了结果here

我不会费心自己写。文章提到,即使是唐纳德·高德纳 (Donald Knuth) 的“超级随机数生成器”也失败了,毕竟它并不是那么随机。获得一个通过所有测试的结果(所有列中的结果 > 0)。他们还使用带有硬件 RNG 的 VIA EPIA M10000 主板测试了设置。对于需要具有高吞吐量的强大随机数服务器的商业或半商业设置,我喜欢此选项。

当然,除非你只是在玩,在这种情况下this 可能就足够了。

【讨论】:

  • 如果您特别需要 PRNG,则硬件 RNG 是不可行的,即。 e.具有可重复输出的东西,这是在模拟中使用的一个非常重要的特征。
【解决方案4】:

最好的方法是不要。

Pseudo-random number generators 是一个非常复杂的主题,因此最好使用对该主题有很好理解的人制作的实现。

【讨论】:

  • 我投了反对票,因为“不要重新发明轮子”是一个糟糕的答案,更糟糕的是因为它不断被无能的程序员传播。永远不应该告诉你不要做某事。
  • 我同意@Krythic 的评论。你永远不应该劝阻一个人,或者一个初学者说这​​太复杂了。这停止了​​学习过程,是错误的。 -1
  • 出于某种原因,这种类型的答案让我很困扰,如果初学者真的想将其作为练习来实现,那么不要阻止他们这样做。类似于初学者在人们说“使用beautifulsoup”之前询问“如何实现HTML解析器作为练习”。同意@Krythic
  • @expressjs123 我现在正在用我正在制作的颜色选择器重新发明轮子。我可以使用现有的颜色选择器吗?大概。但我想自己做。重新发明轮子是你学习新事物的方式,我永远不会告诉任何人不要这样做。这是我的项目的图片:imgur.com/a/A6hnv8F
【解决方案5】:

PRNG 算法很复杂,获取正确的熵源以使其正常工作也是如此。这不是你想自己做的事情。每种现代语言都有一个几乎可以肯定适合您使用的 PRNG 库。

【讨论】:

    【解决方案6】:

    哎呀,这会让 VEEEEEERY 变得复杂!似乎有许多指标可以衡量随机数生成器的“随机性”,因此很难衡量哪些是“最好的”。我将从Numerical Recipes in C(或任何你能找到的语言)开始举几个例子。我从那里给出的例子中编写了我的第一个简单的代码。

    编辑:首先确定您需要的随机数生成器有多复杂也很重要。我记得几年前我在 C 中的一个粗鲁的觉醒,当时我发现默认随机数生成器的周期约为 32,767,这意味着它在生成那么多数字后往往会周期性地重复自身!如果你需要几个骰子,那很好。但当您需要为模拟生成数百万个“随机”值时则不然。

    【讨论】:

    • 数字食谱是一个危险的领域,因为除非您为每个用户购买许可证,否则它们不允许您使用代码。这是我们在大学模拟框架中遇到的一个陷阱,它造成了很大的麻烦。而对于 C RNG,周期通常在 2^32 左右,它只发出 15 位
    【解决方案7】:

    请参阅此链接了解 TestU01 测试套件,其中包括几组测试。

    http://www.iro.umontreal.ca/~simardr/testu01/tu01.html

    在论文中,作者展示了在各种现有 RNG 上的测试结果,但不是 .NET System.Random(据我所知)。虽然他确实测试了 VB6 的生成器。

    很少有人通过所有测试...

    【讨论】:

      【解决方案8】:

      从 knuth 半数字中窃取一个。 它质量高且易于实施。 它使用一对数组、加法和几个 if。 如果我没记错的话,便宜,有效,而且很长一段时间 2^55。

      【讨论】:

      • 我依稀记得一本名著中的 RNG 非常糟糕,但因为它出现在一本名著中而被广泛使用。不过,我再也找不到关于这个的任何信息了。这很可能是另一本不同的书。不过,在将其用于任何关键目的之前,请务必检查一下。
      【解决方案9】:

      如果您打算使用 C++ 工作,Boost 有一组 PRNG,我比标准库中的任何东西都更信任这些 PRNG。 documentation 可能有助于挑选一个。与往常一样,PRNG 的好坏取决于您使用它的目的。

      【讨论】:

        【解决方案10】:

        https://github.com/fsssosei/Pure_PRNG 用于通过统计测试的 PRNG 算法的 Python 库

        【讨论】:

        • 您不能直接添加指向某个存储库的链接。该存储库可能会在某个时间点被弃用,人们不会得到问题的解决方案。相反,请解释这如何解决了 OP 提出的问题。
        • 好的。我的建议是:如果您不是该领域的专家,请不要创建自己的“PRNG”。使用现成的库,例如 Numpy 中的 PRNG
        【解决方案11】:

        在生产代码中,利用已建立的库绝对更安全,但从教育的角度来看,了解伪随机数生成器的工作原理并编写自己的库会很有趣且值得。

        有许多不同的技术,但一种直接的方法是基于逻辑图。即

        x = r * x * (1 - x)
        

        如果r 的值正确,x 的值会表现出混乱和不可预测的行为。您可以在下面的参考资料中了解一些需要注意的陷阱。


        参考文献

        1. https://tim.cogan.dev/random-num/
        2. https://scholar.google.com/scholar?hl=en&as_sdt=0%2C44&q=Logistic+map%3A+A+possible+random-number+generator&btnG=

        【讨论】:

          【解决方案12】:

          【讨论】:

            猜你喜欢
            • 2010-11-18
            • 1970-01-01
            • 2014-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-07
            • 1970-01-01
            • 2012-12-16
            相关资源
            最近更新 更多