как запросить семя, используемое random.random ()? - PullRequest
39 голосов
/ 16 февраля 2011

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

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

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

ОБНОВЛЕНИЕ: да, я имею в виду random.random ()! ошибка ... [название обновлено]

Ответы [ 7 ]

40 голосов
/ 16 февраля 2011

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

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

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

25 голосов
/ 16 февраля 2011

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

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

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

10 голосов
/ 10 января 2016

Вы можете создать подкласс 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 ()), будут равны:сохраните / скопируйте огромное начальное значение и попробуйте использовать его в другом сеансе, сгенерированное значение будет точно таким же.

3 голосов
/ 15 февраля 2016

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

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

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

3 голосов
/ 03 сентября 2015

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

SEED = int(time.time())
random.seed(SEED)
2 голосов
/ 30 марта 2018

Поскольку никто не упомянул, что обычно лучшая случайная выборка, которую вы можете получить на любом языке программирования, генерируется через операционную систему, я должен предоставить следующий код:

random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")

это криптографически безопасно.

Источник: https://www.quora.com/What-is-the-best-way-to-generate-random-seeds-in-python


со значением 8, по-видимому, примерно столько же, сколько для sys.maxsize для меня.

>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>
2 голосов
/ 16 февраля 2011

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

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

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

РЕДАКТИРОВАТЬ: Как отмечает ephemient, внутреннее состояние генератора случайных чисел может быть более сложным, чем начальное число, в зависимости от его реализации.

...