Подтвердить что ты не робот

Как запросить семя, используемое random.random()?

Есть ли способ узнать, какое семя Python используется для засева его генератора случайных чисел?

Я знаю, что могу указать собственное семя, но я вполне доволен, что Python управляет им. Но, я хочу знать, какое семя оно использовало, так что, если мне нравятся результаты, которые я получаю в определенном запуске, я мог бы воспроизвести этот запуск позже. Если бы у меня было семя, которое было использовано, я бы мог.

Если ответ я не могу, то какой лучший способ генерировать семя? Я хочу, чтобы они всегда отличались от run to run --- Я просто хочу знать, что было использовано.

UPDATE: да, я имею в виду random.random()! ошибка... [название обновлено]

4b9b3361

Ответ 1

Невозможно получить автоматическое семя обратно от генератора. Обычно я генерирую такие семена:

seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)

Таким образом, это зависит от времени, поэтому каждый раз, когда вы запускаете script (вручную), он будет другим, но если вы используете несколько генераторов, у них не будет одинакового семени просто потому, что они были созданы почти одновременно.

Ответ 2

Состояние генератора случайных чисел не всегда является просто семенем. Например, безопасный PRNG обычно имеет энтропийный буфер, который представляет собой больший блок данных.

Однако вы можете сохранить и восстановить все состояние генератора числа randon, чтобы вы могли позже воспроизвести его результаты:

import random

old_state = random.getstate()
print random.random()

random.setstate(old_state)
print random.random()

# You can also restore the state into your own instance of the PRNG, to avoid
# thread-safety issues from using the default, global instance.
prng = random.Random()
prng.setstate(old_state)
print prng.random()

Результаты getstate могут, конечно, быть маринованными, если вы хотите сохранить их настойчиво.

http://docs.python.org/library/random.html#random.getstate

Ответ 3

Вы можете подклассифицировать random.Random, переписать метод seed() так же, как это делает python (v3.5 в этом примере), но сохранить начальное значение в переменной перед вызовом super():

    import random

    class Random(random.Random):
        def seed(self, a=None, version=2):
            from os import urandom as _urandom
            from hashlib import sha512 as _sha512
            if a is None:
                try:
                    # Seed with enough bytes to span the 19937 bit
                    # state space for the Mersenne Twister
                    a = int.from_bytes(_urandom(2500), 'big')
                except NotImplementedError:
                    import time
                    a = int(time.time() * 256) # use fractional seconds

            if version == 2:
                if isinstance(a, (str, bytes, bytearray)):
                    if isinstance(a, str):
                        a = a.encode()
                    a += _sha512(a).digest()
                    a = int.from_bytes(a, 'big')

            self._current_seed = a
            super().seed(a)

        def get_seed(self):
            return self._current_seed

Если вы проверите его, первое случайное значение, сгенерированное с новым семенем, и второе значение, сгенерированное с использованием одного и того же семени (с созданным методом get_seed()), будет равно:

    >>> rnd1 = Random()
    >>> seed = rnd1.get_seed()
    >>> v1 = rnd1.randint(1, 0x260)
    >>> rnd2 = Random(seed)
    >>> v2 = rnd2.randint(1, 0x260)
    >>> v1 == v2
    True

Если вы храните/копируете огромное начальное значение и пытаетесь использовать его в другом сеансе, генерируемое значение будет точно таким же.

Ответ 4

Семя - это внутренняя переменная в случайном пакете, которая используется для создания следующего случайного числа. Когда запрашивается новый номер, семя также обновляется.

Я бы просто использовал 0 в качестве семени, если вы хотите быть уверенным, что каждый раз должны иметь одинаковые случайные числа или настроить i.

В CorelDraw появился генератор случайных шаблонов, который был инициализирован семенем. Шаблоны сильно различались для разных семян, поэтому семена были важной конфигурационной информацией о шаблоне. Он должен быть частью параметров конфигурации для ваших прогонов.

EDIT: Как отмечено эфемерным, внутреннее состояние генератора случайных чисел может быть более сложным, чем семя, в зависимости от его реализации.

Ответ 5

Я хотел сделать то же самое, но я не мог получить семя. Итак, я думал, потому что семя генерируется со временем. Я создал свое семя, используя системное время, и использовал его как семя, поэтому теперь я знаю, какое семя было использовано.

SEED = int(time.time())
random.seed(SEED)

Ответ 6

Если вы "установите" семя с помощью random.seed(None), рандомизатор автоматически высевается как функция в системное время. Однако вы не можете получить доступ к этому значению, как вы заметили. Что я делаю, когда хочу рандомизировать, но все еще знаю, что это семя:

tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)

Примечание: причина, по которой я предпочитаю использовать time.time(), как это было предложено @Abdallah, заключается в том, что таким образом randseed читается человеком и сразу понятен, что часто имеет большие преимущества. Компоненты даты и даже микросегменты также могут быть добавлены по мере необходимости.