Как обеспечить уникальные семена для ГСЧ при последующих запусках процесса? - PullRequest
4 голосов
/ 27 июля 2011

Краткое описание: Мне нужен простой автономный способ для заполнения моего ГСЧ, чтобы при каждом запуске программы начальное значение различалось.

Детали:

Мне часто приходится запускать одну и ту же программу (которая выполняет вычисления со случайными числами, например, моделирование по методу Монте-Карло и т. Д.), Чтобы получить хорошую статистику по результату. В этом случае важно, чтобы генератор случайных чисел имел разное начальное число при каждом запуске.

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

Обратите внимание, что использование time(0) в качестве начального числа не является хорошим решением, поскольку разрешение таймера плохое: если несколько процессов запускаются параллельно, они, вероятно, получат одно и то же начальное число из time(0).

Требования:

  • максимально просто
  • кроссплатформенный (в настоящее время он мне нужен для работы только в Windows и Linux, x86 и x64).
  • автономный: не следует полагаться на специальный способ запуска программы (передача начального числа в качестве параметра из сценария запуска - слишком большая проблема).
  • Я хотел бы обернуть все это в небольшую библиотеку, которую я могу включить в любой новый проект с минимальными усилиями и просто сделать что-то вроде SeedMyRNG(getSeed());

РЕДАКТИРОВАТЬ:

Хотя мой главный вопрос был о том, как сделать это на C (или C ++), основываясь на указателях, приведенных в ответе, я нашел os.urandom() в качестве решения Python (что также полезно для меня).

Соответствующий соответствующий вопрос: Как использовать / dev / random или urandom в C?

Ответы [ 4 ]

4 голосов
/ 27 июля 2011

«Кроссплатформенность» - это субъективный термин. Вы имеете в виду «любую платформу» (вы можете столкнуться в будущем) или «каждую платформу» (в вашем списке поддерживаемых платформ)? Вот прагматичный подход, который я обычно использую:

  1. Проверьте, есть ли у вас /dev/urandom; если да, семя оттуда.

  2. В Windows используйте CryptGenRandom().

  3. Если ничего не помогает, начните с time().

1 голос
/ 28 июля 2011

Выезд RandomLib это библиотека случайных чисел C ++ с хорошей поддержкой для семян. В частности

Random r;
r.Reseed();

заставляет r быть засеянным с вектором чисел (от вызова к RandomSeed :: SeedVector ()), который почти наверняка уникален. это включает время, микросекунды, pid, hostid, год.

Менее оптимально, вы также можете посеять с помощью RandomSeed :: SeedWord (), которая читает из / dev / urandom, если это возможно. Тем не менее, вы, как правило, получите Начальное столкновение после 2 ^ 16 запускается с одним 32-битным словом в качестве начального числа. Итак, если ваше приложение запускается много раз, вам лучше использовать большее начальное пространство, предлагаемое вектором.

Конечно, это предполагает, что вы используете генератор случайных чисел который может использовать векторное семя. RandomLib предлагает MT19937 и SFMT19937, в котором используются векторные семена.

1 голос
/ 27 июля 2011

Вы можете использовать dev random в Linux и crypto api в Windows.Напишите небольшую библиотеку, чтобы представить независимый от платформы интерфейс, и он должен делать именно то, что вы хотите.

0 голосов
/ 05 августа 2014

Обновление 2014-08-04:

Boost теперь имеет кроссплатформенную реализацию, random_device. Вот пример для заполнения псевдослучайного генератора от повышения с использованием непредсказуемого начального числа:

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/random_device.hpp>

boost::random::mt11213b rng( (boost::random_device())() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...