在python中回滚随机数生成器?

Eri*_*ric 5 python random

是否有可能将随机数生成器按指定的步数"回滚"到较早的状态以获得重复的随机数?

我希望能够做到这样的事情:

print(random.random())
0.5112747213686085
print(random.random())
0.4049341374504143
print(random.random())
0.7837985890347726

random.rollback(2) #go back 2 steps

print(random.random())
0.4049341374504143
print(random.random())
0.7837985890347726
Run Code Online (Sandbox Code Playgroud)

我目前唯一想要实现的目的是将所有生成的随机数存储到列表中以便返回.但是,我个人更喜欢不涉及这样做的方法,因为我计划生成相当大量的随机数,而这个函数通常不会被使用.

Gar*_*tty 8

你想看看random.getstate()random.setstate().将此与记录生成的项目数量相结合,并且可以非常简单地执行您想要的操作.

请注意,random如果依赖于此,则必须小心使用其他代码,因此我建议random.Random()使用实例来避免这种情况.

该模块提供的函数实际上是random.Random类的隐藏实例的绑定方法.您可以实例化您自己的Random实例,以获取不共享状态的生成器.

(来自文档)

示例实现:

from itertools import islice
import collections
from random import Random

def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

class RewindRandom:
    def __init__(self):
        self._random = Random()
        self._state = self._random.getstate()
        self._count = 0

    def __iter__(self):
        while True:
            yield self._random.random()

    def __call__(self):
        self._count += 1
        return next(iter(self))

    def rollback(self, amount):
        self._random.setstate(self._state)
        consume(self, self._count-amount)
        self._count -= amount
Run Code Online (Sandbox Code Playgroud)

哪个可以这样使用:

random = RewindRandom()

>>> random()
0.31276818768213244
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random.rollback(2)
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random()
0.6582894948982371
Run Code Online (Sandbox Code Playgroud)