【问题标题】:Should I seed the random number generator?我应该播种随机数生成器吗?
【发布时间】:2013-10-03 18:42:36
【问题描述】:

From the docs:

random.seed(a=None, version=2) 初始化随机数生成器。

如果a被省略或None,则使用当前系统时间。如果 随机源由操作系统提供,它们用于 而不是系统时间(有关详细信息,请参阅 os.urandom() 函数 可用性)。

但是……如果它真的是随机的……(我以为我读到它使用梅森,所以它非常随机)……播种有什么意义?无论哪种方式,结果都是不可预测的……对吧?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    当您导入模块时,模块实际上是生成器的种子(如果可能,使用来自urandom 的操作系统提供的随机数据,否则使用当前日期和时间),因此无需手动调用seed()

    (这在 Python 2.7 文档中提到,但由于某种原因,3.x 文档中没有提到。但是,我在 3.x 源代码中确认它仍然完成。)

    如果没有自动播种,每次启动程序时都会得到相同的数字序列,就像每次手动使用相同的种子一样。

    【讨论】:

      【解决方案2】:

      如果您希望每次运行都使用不同的随机数,则默认值可能是最好的。如果出于某种原因您需要可重复随机数,例如在测试中,请使用种子。

      【讨论】:

        【解决方案3】:

        但是……如果它真的是随机的

        不,它是伪随机的。如果它使用 Mersenne Twister,那也是 PRNG

        它基本上是一种算法,可以从给定的种子中生成完全相同的伪随机数序列。生成真正的随机数需要特殊的硬件支持,这不是纯算法可以做到的。

        您可能不需要播种,因为它会在首次使用时自行播种,除非您有其他或更好的方式来提供种子,而不是基于时间的方式。

        如果您将随机数用于与安全无关的事物,则基于时间的种子通常没问题。如果您将 if 用于安全/加密,请注意文档所说的内容:“并且完全不适合加密目的”

        【讨论】:

        • 哦,好吧,是的,我知道这是伪随机的。但我没有想到,你可能想要重复给定的序列。
        • @Aerovistae:这基本上是伪随机的定义 ;-)
        【解决方案4】:

        如果你想重现你的结果,你可以用一个已知的值给生成器做种子,这样你每次都会得到相同的序列。

        【讨论】:

          【解决方案5】:

          Python 使用的随机数生成器 Mersenne twister 在可能的平台(Unixen、Windows)上默认由操作系统提供随机数提供种子;但是在其他平台上,种子默认为系统时间,这意味着如果系统时间的精度很差,则值非常可重复。因此,在这样的系统上,用已知的更好随机值播种是有益的。请注意,特别是在 Python 3 上,如果使用版本 2,您可以传入任何 strbytesbytearray 来为生成器播种;从而更好地利用梅森捻线器的大状态。

          使用种子值的另一个原因确实是为了保证您一次又一次地获得相同的随机数序列 - 通过重用已知种子。引用docs

          有时能够重现由下式给出的序列很有用 一个伪随机数生成器。通过重用种子值,同样 序列应该可以重复运行,只要多个 线程没有运行。

          大多数随机模块的算法和种子函数都是 可能会在 Python 版本之间发生变化,但有两个方面是 保证不变:

          • 如果添加了新的播种方法,则会提供向后兼容的播种器。
          • 当兼容的播种机被赋予相同的种子时,生成器的 random() 方法将继续产生相同的序列。

          但是,为此,您主要希望使用 random.Random 实例而不是使用模块全局方法(多线程问题等)。

          最后还要注意梅森捻线器产生的随机数不适合加密使用;尽管它们看起来非常随机,但可以通过仅观察生成器的数百个值来完全恢复随机生成器的内部状态。对于加密算法,您想使用SystemRandom class

          【讨论】:

            【解决方案6】:

            在大多数情况下,我会说没有必要关心。但是,如果有人真的愿意做一些有线的事情并且(s)他可以粗略地计算出您的代码运行时的系统时间,他们可能能够暴力重播您的随机数并查看哪个系列适合。但我会说在大多数情况下这不太可能。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-03-14
              • 2019-07-16
              • 2016-07-22
              • 1970-01-01
              • 2013-09-24
              • 1970-01-01
              • 2010-10-05
              • 2010-09-30
              相关资源
              最近更新 更多