установить случайную начальную программу в Python

83

У меня довольно большая программа, в которой я использую функции из randomмодуля в разных файлах. Я хотел бы иметь возможность установить случайное начальное число один раз в одном месте, чтобы программа всегда возвращала одни и те же результаты. Можно ли этого достичь python?

Миша Обрехт
источник

Ответы:

121

Основной запущенный модуль python должен import randomвызывать и вызывать random.seed(n)- он распределяется между всеми другими импортируемыми объектами до randomтех пор, пока где-то еще не сбрасывается семя.

Джон Клементс
источник
3
Могу ли я сбросить сид где-нибудь, не зная об этом? потому что установка семени один раз в главном файле не помогает
Миша Обрехт
1
@MischaObrecht, я так думаю - семя инициализируется только при первом импорте случайного модуля - если он импортирован более одного раза, он не будет выполнять инициализацию и сбрасывать семя - поэтому где-то в вашем коде должен быть явный вызов
Джон Клементс
3
Если вы вызываете методы из randomкода уровня модуля, который вы импортируете в main, до того, как вы random.seed(n)перейдете в main, то эти вызовы будут выполняться перед семенем, поэтому они будут отсортированы по времени и фактически не воспроизводятся случайный.
Рассел Борогов
13
Если выясняется, что какой-то сторонний код повторно заполняет ГСЧ (маловероятно, но возможно), обратите внимание, что вы можете создать дополнительные генераторы случайных чисел с независимым состоянием через random.Random()конструктор и использовать их, когда важна строгая воспроизводимость.
Рассел Борогов
У меня это не работает. И у меня нет воспроизводимого кода. Полагаю, мне придется проверить документацию по всем импортированным библиотекам ... (см. Stackoverflow.com/questions/37886997/…
B Furtado
36

Комментарий zss должен быть выделен как фактический ответ:

Еще одна вещь, о которой следует остерегаться: если вы используете numpy.random, то вам нужно использовать numpy.random.seed()для установки семени. Использование random.seed()не установит начальное число для случайных чисел, сгенерированных из numpy.random. Это меня на время смутило. -zss

Сида Чжоу
источник
Абсолютно верно, если где-то в вашем приложении вы используете случайные числа из random module, скажем, функции, random.choices()а затем в какой-то другой точке numpyгенератора случайных чисел, скажем, np.random.normal()вам нужно установить начальное число для обоих модулей. Что я обычно делаю, так это добавляю пару строк в мои main.pyлайки random.seed(my_seed)и np.random.seed(my_seed). Kudos to zss
Aenaon
У Sage аналогичная проблема, поскольку его PRNG отличается от Python и numpy. Используйте set_random_seed()для Sage.
Брент Баккала
8

В начале вызова приложения random.seed(x)убедитесь, что x всегда одинаково. Это гарантирует, что последовательность псевдослучайных чисел будет одинаковой при каждом запуске приложения.

Химера
источник
3

Джон Клементс в значительной степени отвечает на мой вопрос. Однако это не было реальной проблемой: оказалось, что причиной случайности моего кода был SVD numpy.linalg, потому что он не всегда дает одинаковые результаты для плохо подготовленных матриц !!

Поэтому обязательно проверьте это в своем коде, если у вас такие же проблемы!

Миша Обрехт
источник
23
Еще одна вещь, о которой следует остерегаться: если вы используете numpy.random, вам нужно использовать numpy.random.seed () для установки семени. Использование random.seed () не устанавливает начальное число для случайных чисел, сгенерированных из numpy.random. Это меня на время смутило.
zss
1

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

Я думал: « Ну, я установил свои семена так, чтобы они всегда были одинаковыми, и у меня нет изменяющихся / внешних зависимостей, поэтому путь выполнения моего кода всегда должен быть одинаковым », но это было неправильно.

Пример, который меня укусил, был list(set(...)), где итоговый порядок может отличаться.

JBSnorro
источник
Хорошая мысль, это раньше меня сжигало. Также такие вещи, как получение результатов из базы данных, они также возвращаются не по порядку (случайным образом), если вы не укажете иное,
Джастин Фурунесс
0

Одно важное предостережение заключается в том, что для версий python до 3.7 ключи словаря не являются детерминированными. Это может привести к случайности в программе или даже к иному порядку, в котором генерируются случайные числа и, следовательно, недетерминированным случайным числам. Вывод обновления питона.

Давуд Тагави-Нежад
источник
-14

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

Просто выберите три больших простых числа (если это не криптографическое приложение) и вставьте их в a, b и c: a = ((a * b)% c) Это дает систему обратной связи, которая производит довольно случайные данные. Обратите внимание, что не все простые числа работают одинаково хорошо, но если вы просто проводите моделирование, это не имеет значения - все, что вам действительно нужно для большинства симуляций, - это беспорядок чисел с достаточно сложным шаблоном (псевдослучайным, помните), чтобы он каким-то образом не соответствует вашему приложению.

Кнут говорит об этом.

user1277476
источник
10
Сворачивать свои собственные нет необходимости, потому что Python имеет отличные средства случайных чисел в своей стандартной библиотеке, и очень легко создать действительно плохой генератор, если вы не знаете, что делаете.
Рассел Борогов
6
Я согласен, что это довольно плохое решение: в моделировании Монте-Карло (какова моя программа), где обычно собираются миллионы образцов, коррелированные случайные числа (происходящие из плохого генератора) могут легко испортить ваши результаты !!
Mischa Obrecht
Вы имеете в виду, Кнут все время об этом говорит? Даже сейчас?
означает-к-значению