在python中回滚随机数生成器? [英] Rolling back the random number generator in python?

查看:203
本文介绍了在python中回滚随机数生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to 'rollback' the random number generator by a specified number of steps to a earlier state to get repeated random numbers?

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

I want to be able to do something like this:

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

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

My only current idea to accomplish this is to store all generated random numbers into a list to go back to. However, I would personally prefer a method that does not involve doing so because I plan on generating a pretty large amount of random numbers while this function won't be used that often.

推荐答案

您想看看 .将其与跟踪生成的项目数量结合起来,即可轻松完成所需的工作.

You want to take a look at random.getstate() and random.setstate(). Combine this with keeping track of the number of items generated and it's pretty simple to do what you want.

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

Note that you would have to be careful about other code using random if you relied on this, so I would suggest making a random.Random() instance to use to avoid this.

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

The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state.

(来自文档)

示例实现:

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

可以像这样使用:

random = RewindRandom()

>>> random()
0.31276818768213244
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random.rollback(2)
>>> random()
0.7031210824422215
>>> random()
0.7196351574136909
>>> random()
0.6582894948982371

这篇关于在python中回滚随机数生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆