Python 在编写自己的RNG时,如何操纵种子以便不断生成新的数字?
我必须用python(3.x)为赋值实现Wichmann-Hill随机数生成算法。该算法需要使用三个随机数进行播种 我试着用Python 在编写自己的RNG时,如何操纵种子以便不断生成新的数字?,python,random,time,seed,Python,Random,Time,Seed,我必须用python(3.x)为赋值实现Wichmann-Hill随机数生成算法。该算法需要使用三个随机数进行播种 我试着用time.time\u ns()为它设定种子,但是如果我连续多次尝试生成一个新的数字(我必须能够连续生成至少100000个),我会得到大量重复,因为时间显然还没有改变 Wichmann Hill的算法如下: i1 = (170 * i1) % 30323 i2 = (171 * i2) % 30269 i3 = (172 * i3) % 30307
time.time\u ns()
为它设定种子,但是如果我连续多次尝试生成一个新的数字(我必须能够连续生成至少100000个),我会得到大量重复,因为时间显然还没有改变
Wichmann Hill的算法如下:
i1 = (170 * i1) % 30323
i2 = (171 * i2) % 30269
i3 = (172 * i3) % 30307
i1 = i1 / 30323.0
i2 = i2 / 30269.0
i3 = i3 / 30307.0
return (i1 + i2 + i3) % 1.0
其中i1、i2和i3应为种子
我一直在寻找一种方法,为下一次需要一个数字时为算法播种。非常感谢您的建议。如果您可以使用0到2**31-1范围内的种子,您可以使用numpys
random.randint(低、高、大小)
:
我没有检查碰撞:
gen seeds of length:100000 in time:0.0024sec
wh of length:100000 in time:1.1818sec
基于,您的实现应该如下所示
class WHGen:
def __init__(self):
# Initialize the seeds with "random" numbers between 1 and 30,000.
# Note: if you don't actually have nanosecond precision, you'll want
# to divide time.time_ns() by some power of 10 first to discard
# any low-order zeros.
self.i1 = time.time_ns() % 30000 + 1
self.i2 = time.time_ns() % 30000 + 1
self.i3 = time.time_ns() % 30000 + 1
# If you want to "cheat", you can just random.randint(1,30000) instead.
def __iter__(self):
while True:
# The new seed is just the remainder, not the result of
# the division used to compute the next number in the sequence.
self.i1 = (171 * self.i1) % 30369
self.i2 = (172 * self.i2) % 30307
self.i3 = (170 * self.i3) % 30323
# Do *not* reset the seeds themselves to these results.
# I.e., not self.i1 /= 30269
x = self.i1 / 30269
y = self.i2 / 30307
z = self.i3 / 30323
yield (x + y + z) % 1.0
# 10 random numbers
gen = WHGen()
nums = list(islice(gen, 10))
你如何准确地初始化
i1
、i2
和i3
,连续三次调用time.time
?我不认为你应该根据–Hill设置i1/=30323
,等等。谢谢你的帮助,但我不允许使用任何内置的RNG来播种我的值。什么是__(self)
do?我想这会让函数变得更易使用,但我以前从未见过。此外,我将无法使用randint,因为我不允许使用任何内置RNG(将添加到问题描述中).在我的例子中,你在这里写的东西,我的三个种子都是一样的,但我想它应该可以工作,因为它们被修改和分割等等。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。
class WHGen:
def __init__(self):
# Initialize the seeds with "random" numbers between 1 and 30,000.
# Note: if you don't actually have nanosecond precision, you'll want
# to divide time.time_ns() by some power of 10 first to discard
# any low-order zeros.
self.i1 = time.time_ns() % 30000 + 1
self.i2 = time.time_ns() % 30000 + 1
self.i3 = time.time_ns() % 30000 + 1
# If you want to "cheat", you can just random.randint(1,30000) instead.
def __iter__(self):
while True:
# The new seed is just the remainder, not the result of
# the division used to compute the next number in the sequence.
self.i1 = (171 * self.i1) % 30369
self.i2 = (172 * self.i2) % 30307
self.i3 = (170 * self.i3) % 30323
# Do *not* reset the seeds themselves to these results.
# I.e., not self.i1 /= 30269
x = self.i1 / 30269
y = self.i2 / 30307
z = self.i3 / 30323
yield (x + y + z) % 1.0
# 10 random numbers
gen = WHGen()
nums = list(islice(gen, 10))