我有一个应用程序对某个实验进行 1000 次(多线程,以便同时进行多个实验)。每个实验都需要 appr。 50.000 次 random.random() 调用。
真正随机化的最佳方法是什么。我可以将一个随机对象复制到每个实验中,然后进行 50.000 * expid 的跳跃。文档表明 jumpahead(1) 已经扰乱了状态,但这是真的吗?
或者是否有另一种“最佳方式”做到这一点的方法?
(不,随机数不是用于安全性,而是用于 metropolis hasting 算法。唯一的要求是实验是独立的,而不是随机序列是否可预测)
最佳答案
I could copy a random object to every experiment and do than a jumpahead of 50.000 * expid.
大致正确。每个线程都有自己的 Random
实例。
将它们全部播种到相同的种子值。使用一个常量来测试,当你“运行记录”时使用/dev/random。
编辑。在 Python 之外和较旧的实现中,使用 jumpahead( 50000 * expid )
来避免两个生成器以并行值序列结束的情况。在任何当前(2.3 后)的 Python 中,jumpahead
不再是线性的并且使用 expid
足以打乱状态。
您不能简单地在每个线程中执行 jumpahead(1)
,因为那样可以确保它们同步。使用 jumpahead( expid )
确保每个线程都被明确地扰乱。
The documentation suggests that jumpahead(1) already scrambles the state, but is that really true?
是的,jumpahead 确实“扰乱”了状态。回想一下,对于给定的种子,您会得到一个很长但固定的伪随机数序列。你在这个序列中向前跳跃。要通过随机性测试,您必须从这个一个序列中获取所有值。
编辑。曾几何时,jumpahead(1) 受到限制。现在 jumpahead(1) 确实进行了更大的加扰。然而,加扰是确定性的。您不能简单地在每个线程中执行 jumpahead(1)
。
如果您有多个具有不同种子的生成器,您就违反了“一个种子的一个序列”假设,并且您的数字不会像从单个序列中获得它们那样随机。
如果您只使用 jumphead 1,您可能会得到类似的并行序列。 [这种相似性可能检测不到; 理论上,有相似之处。]
当你跳到 50,000 时,你确保你遵循 1-sequence-1-seed 前提。您还要确保在两个实验中不会有相邻的数字序列。
最后,您还具有可重复性。对于给定的种子,您可以获得一致的结果。
同样的跳跃:不好。
>>> y=random.Random( 1 )
>>> z=random.Random( 1 )
>>> y.jumpahead(1)
>>> z.jumpahead(1)
>>> [ y.random() for i in range(5) ]
[0.99510321786951772, 0.92436920169905545, 0.21932404923057958, 0.20867489035315723, 0.91525579001682567]
>>> [ z.random() for i in range(5) ]
[0.99510321786951772, 0.92436920169905545, 0.21932404923057958, 0.20867489035315723, 0.91525579001682567]
关于python - 我应该如何在 Python 中使用 random.jumpahead,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2546039/