0

我的问题与这个问题完全相反。

这是我的测试文件的摘录

f1 = open('seed1234','r')
f2 = open('seed7883','r')
s1 = eval(f1.read())
s2 = eval(f2.read())
f1.close()
f2.close()
####
test_sampler1.random_inst.setstate(s1)
out1 = test_sampler1.run()
self.assertEqual(out1,self.out1_regress) # this is fine and passes

test_sampler2.random_inst.setstate(s2)
out2 = test_sampler2.run()
self.assertEqual(out2,self.out2_regress) # this FAILS

一些信息——

test_sampler1并且test_sampler2是执行一些随机采样的类中的 2 个对象。该类有一个属性random_inst,它是 type 的对象random.Random()。该文件seed1234包含一个TestSampler'srandom_inst的状态,random.getstate()当它被给予种子时返回1234,你可以猜出它是什么seed7883。我所做的是我TestSampler在终端中创建了一个,给它一个随机种子1234,获取状态rand_inst.getstate()并将其保存到一个文件中。然后我重新创建回归测试,我总是得到相同的输出。

然而

与上述相同的程序不起作用test_sampler2- 无论我没有得到相同的随机数字序列。我正在使用 python 的random模块,我没有在其他任何地方导入它,但我确实numpy在某些地方使用(但不是numpy.random)。

test_sampler1和之间的唯一区别test_sampler2是它们是从 2 个不同的文件创建的。我知道这是一件大事,它完全取决于我编写的代码,但我也不能简单地在这里粘贴大约 800 行代码,我只是在寻找一些关于我可能会搞砸的一般概念......

什么可能会扰乱 的test_sampler2随机数生成器的状态?

解决方案

我的代码有两个单独的问题:

1

我的脚本是一个命令行脚本,在我将它重构为使用 python 的optparse库之后,我发现我正在使用类似的东西为我的采样器设置种子,seed = sys.argv[1]这意味着我将种子设置为 a str,而不是int-seed可以采用任何哈希值对象,我发现它很难。这就解释了为什么如果我使用相同的种子我会得到 2 个不同的序列 - 如果我从命令行运行我的脚本 sth likepython sample 1234 #seed is 1234和从我的文件运行我的unit_tests.py文件,当我创建一个对象实例时test_sampler1 = TestSampler(seed=1234)

2

我有一个从这里借来的离散分布抽样函数(看看接受的答案)。那里的代码缺少一些基本的东西:它仍然是不确定的,如果你给它相同的值和概率数组,但是通过一个排列(比如 values ['a','b']and probs[0.1,0.9]和 values ['b','a']and probabilities [0.9,0.1])转换并且种子被设置并且您将通过 PRNG 获得相同的随机样本,例如0.3,但由于您的概率间隔不同,在一种情况下您将获得 ab和在一种情况下获得 an a。为了解决这个问题,我只是将值和概率压缩在一起,按概率和 tadaa 排序——我现在总是得到相同的概率区间。

解决这两个问题后,代码按预期工作,即 out2 开始确定性地运行。

4

1 回答 1

1

唯一可以改变实例状态的(除了内部 Python 错误)random.Random是调用该实例上的方法。所以问题在于你没有向我们展示的东西。这是一个小测试程序:

from random import Random

r1 = Random()
r2 = Random()

for _ in range(100):
    r1.random()
for _ in range(200):
    r2.random()

r1state = r1.getstate()
r2state = r2.getstate()

with open("r1state", "w") as f:
    print >> f, r1state
with open("r2state", "w") as f:
    print >> f, r2state


for _ in range(100):
    with open("r1state") as f:
        r1.setstate(eval(f.read()))
    with open("r2state") as f:
        r2.setstate(eval(f.read()))
    assert r1state == r1.getstate()
    assert r2state == r2.getstate()

我一整天都没有运行它,但我敢打赌我可以而且永远不会看到失败的断言;-)

顺便说一句,这种事情当然更常见pickle,但这并不能解决你的真正问题。问题不在于获取或设置状态。问题是您还没有找到在您的random.Random实例上调用方法的东西。

虽然这样做很麻烦,但您可以尝试添加打印语句来random.py找出它在做什么。有更聪明的方法可以做到这一点,但最好保持简单,这样您就不会最终实际调试调试代码。

于 2013-12-10T00:49:41.450 回答