在这里随机学习模块,一开始就有簿记功能,据我所知,设置一个特定的种子是为了确保获得相同的随机数.
但是,getstate()和setsate()?link
在文档中,它没有介绍这个状态的含义,如果我不知道它意味着什么,我怎么能正确设置它?
random.getstate()
返回捕获生成器当前内部状态的对象.可以将此对象传递给setstate()以恢复状态.
random.setstate(状态)
state应该是从之前调用getstate()获得的,而setstate()将生成器的内部状态恢复到调用getstate()时的状态.
谢谢,
Python的默认生成器是一个Mersenne Twister,其状态空间为19937位,远大于您认为的种子.
您可以在概念上将其视为三个功能:
当您使用种子值开始时random.seed(),它使用函数f()一次生成19937位的完整状态值.每次使用生成器时,它都会使用g()前进到下一个19937位状态,并通过使用h()将更新后的状态折叠为单个整数来返回找到的输出.
通常,您实际上并未看到位于发电机核心的内部状态.getstate()绕过折叠函数h(),并setstate()绕过播种函数f(),这样您就可以从任何点重现序列,而不必一直回到开头,并将整个序列重现到该点.
大多数人不需要(也不应该)使用get/setstate功能,但它可以用于提取一些聪明的数学技巧来减少蒙特卡罗估计的可变性.
为什么不尝试一下呢?
import random
random.seed(42)
print(random.sample(range(20),k=10))
st = random.getstate() # remeber this state
print(random.sample(range(20),k=20)) # print 20
random.setstate(st) # restore state
print(random.sample(range(20),k=10)) #print same first 10
Run Code Online (Sandbox Code Playgroud)
输出:
[12, 0, 4, 3, 11, 10, 19, 1, 5, 18]
[4, 9, 0, 3, 10, 8, 16, 7, 18, 17, 14, 6, 2, 1, 5, 11, 15, 13, 19, 12]
[4, 9, 0, 3, 10, 8, 16, 7, 18, 17]
Run Code Online (Sandbox Code Playgroud)
显然,如果您获得状态并恢复它,您可以返回并一遍又一遍地重现相同的值。
但您不能在两者之间使用不同的随机数,否则您会改变状态。
random.setstate(st) # go back again
print(random.sample(range(99),k=2)) # do something different
print(random.sample(range(20),k=18))
Run Code Online (Sandbox Code Playgroud)
输出:
[21, 50] # something different after setting state
[0, 3, 11, 9, 18, 8, 17, 19, 16, 7, 15, 1, 10, 2, 12, 5, 13, 14] # changed values
Run Code Online (Sandbox Code Playgroud)
import random
import timeit
t1 = timeit.timeit(stmt = """random.seed(42)
random.randint(1,10)""",number=10000,setup="import random")
t2 = timeit.timeit(stmt = """
random.randint(1,10)
random.setstate(s)""",number=10000,setup="""import random
s = random.getstate()""")
print(t1,t2)
Run Code Online (Sandbox Code Playgroud)
输出:
# seed() time setstate() time
0.5621587821914207 0.49502014443357545
Run Code Online (Sandbox Code Playgroud)