【问题标题】:Reproducibility of random numbers (Python 2/random)随机数的再现性(Python 2/random)
【发布时间】:2016-12-19 17:25:23
【问题描述】:

Python 2 documentation of the random.seed() 函数中我发现了一个警告:

如果给定一个可散列的对象,则只有确定性的结果才能得到保证 当 PYTHONHASHSEED 被禁用时。

https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED我推断解释器的-R开关可能和PYTHONHASHSEED有类似的效果。

我已经通过经验验证,以小整数为种子的随机数似乎是可重现的。小整数的哈希也是如此。

但是,int 是可散列的。是否在任何受信任的来源中明确声明,将其用作可重现的随机数序列的种子是安全的?

Reproducibility of python pseudo-random numbers across systems and versions? 相比,在同一系统和解释器中的可重复性就足够了。

【问题讨论】:

  • 我认为这是一个文档缺陷;它应该说整数和长整数没有散列。无论如何,此时 Python 2 的实现不太可能发生变化,Python 3 documentation 提到直接使用 int(Python 2 长整数)。

标签: python python-2.7 random deterministic reproducible-research


【解决方案1】:

不是一个完整的答案,但random_seed (in C) 的源代码将是相关的:

if (PyInt_Check(arg) || PyLong_Check(arg))
    n = PyNumber_Absolute(arg);
else {
    long hash = PyObject_Hash(arg);
    if (hash == -1)
        goto Done;
    n = PyLong_FromUnsignedLong((unsigned long)hash);
}

这表明除了long (int) 以外的任何东西都直接使用哈希值作为种子,只要:

  1. hash(int) 给出一致的结果并且
  2. 您正在使用种子的这种实现(可能与 Jython 等不同)

那么我希望seed(int) 产生一致的结果。

也就是说,我不能代表其中任何一个条件保持不变,因此除非其他人可以验证它们,否则这并不能真正给出明确的答案。

【讨论】:

  • 这看起来像 Python 3 源代码。 Python 2 code 会更相关。
  • @user2357112 好的,但除了检查它是int 还是long 而不是long,相关部分几乎相同吗?
  • @TadhgMcDonald-Jensen 我同意 user2357112。这与int/long 的区别无关。问题是关于 Python 2,所以 Python 2.7 源代码似乎更合适
【解决方案2】:

文档确认了它在 Python 2.6 中的安全性:

如果 x 不是 None 或 int 或 long,则使用 hash(x) 代替。如果 x 是 int 或 long,则直接使用 x。

(来自https://docs.python.org/2.6/library/random.html#random.seed

[编辑]

2.7 的文档已更新为:

如果 a 不是 None 或 int 或 long,则使用 hash(a) 代替。请注意,启用 PYTHONHASHSEED 时,某些类型的哈希值是不确定的。

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2018-02-06
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2011-03-11
    相关资源
    最近更新 更多