如何“隐藏”随机状态生成器状态

时间:2019-11-16 20:10:43

标签: python random random-seed

我正在为随机数生成器植入种子,以产生可重复的结果:

import random

SEED = 32412542
random.seed(SEED)

我想让它只对程序的一部分返回“不可重现”的随机值,如:

import random

SEED = 32412542
random.seed(SEED)

my_list = [1, 2, 3, 4, 5]

res = random.sample(my_list, len(my_list))  # I would like result of this to be the same between runs of the program.

# Do some reproducible calculations, such as training neural network.
print(res)  # E.g. prints [3, 2, 4, 1, 5]

# What to do here?
res = random.sample(my_list, len(my_list))  # I would like result of this to be different between runs.

# Do some non-reproducible calculations, such as picking neural network parameters randomly.
print(res)  # Prints some random order.

res = random.sample(my_list, len(my_list))  # I would like result of this to be the same between runs of the program.

# Do some reproducible calculations, such as training neural network.
print(res)  # E.g. prints [2, 3, 1, 4, 5]

到目前为止,我想出的是在我不希望其变得不可复制之前,先不带参数地进行播种,然后再使用SEED值重新进行播种:

import random

SEED = 32412542
random.seed(SEED)

my_list = [1, 2, 3, 4, 5]

res = random.sample(my_list, len(my_list))
print(res)  # Prints: [3, 2, 4, 1, 5]

random.seed()
res = random.sample(my_list, len(my_list))
print(res)  # Prints some random order.

random.seed(SEED)
res = random.sample(my_list, len(my_list))
print(res)  # Prints: [3, 2, 4, 1, 5], so exactly what has been printed before.

问题在于重新播种后,会产生完全相同的一组随机值(很明显-最终目的是使用特定值进行播种),我不想发生这种情况。我想以某种方式恢复随机发生器的先前状态。有可能吗?

1 个答案:

答案 0 :(得分:2)

您不能使用random函数来执行此操作,但是可以通过创建Random类的实例来做到这一点。 As the documentation states:

  

如果要使用其他类Random,也可以将其子类化   您自己设计的基本生成器:在这种情况下,请覆盖   random()seed() getstate()setstate()方法。 (可选)   新的生成器可以提供getrandbits()方法-这允许   randrange()产生任意大范围的选择。

示例:

>>> import random
>>> r = random.Random()
>>> r.randint(1, 1000)
545
>>> r.randint(1, 1000)
349
>>> r.randint(1, 1000)
745
>>> r.randint(1, 1000)
792
>>> state = r.getstate()
>>> r.randint(1, 1000)
52
>>> r.randint(1, 1000)
799
>>> r.randint(1, 1000)
586
>>> r.randint(1, 1000)
581
>>> r.setstate(state)
>>> r.randint(1,1000)
52
>>> r.randint(1,1000)
799
>>> r.randint(1,1000)
586
>>> r.randint(1,1000)
581

实际上you can even using the functions from the random module,我的坏事:

  

random.getstate()返回捕获当前内部对象的对象   发电机的状态。该对象可以传递给setstate()   恢复状态。

     

random.setstate(state)状态应该是从先前的状态获得的   调用getstate(),然后setstate()恢复   生成getstate()时的生成器。