Детерминированные потоки случайных чисел в C ++ STL - PullRequest
6 голосов
/ 16 марта 2009

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

В основном мой вопрос: в C ++, если я использую rand(), но поставлю srand() с заданным пользователем начальным числом, а не текущим временем, я смогу генерировать такой же поток случайных чисел на любом компьютер

Ответы [ 7 ]

7 голосов
/ 16 марта 2009

Десятки PRNG доступны в виде библиотек. Выбери один. Я склонен использовать Mersenne Twister .

Используя внешнюю библиотеку, вы исключаете риск странной или ошибочной реализации библиотеки вашего языка rand(). Пока все ваши платформы соответствуют одной и той же математической семантике, вы получите согласованные результаты.

МТ - мой любимый, потому что я физик, и я использую эти вещи для Монте-Карло, где важна гарантия равномерного распределения в больших измерениях. Но не использует MT как криптографический PRNG!

5 голосов
/ 16 марта 2009

srand() & rand() не являются частью STL. Они на самом деле являются частью C времени выполнения. Да, они будут давать те же результаты, если это та же реализация srand()/rand().

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

4 голосов
/ 16 марта 2009

Предполагая, что реализации rand() одинаковы, да.

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

1 голос
/ 16 марта 2009

Нет, стандарт ANSI C only указывает, что rand() должен генерировать поток случайных целых чисел от 0 до RAND_MAX, который должен быть не менее 32767 ( source ). Этот поток должен быть детерминированным только в том смысле, что для данной реализации на данном компьютере он должен создавать один и тот же целочисленный поток с тем же начальным числом.

Вы хотите портативный PRNG. Mersenne Twister (многие реализации, связанные внизу) довольно переносимы, как и доморощенный PRNG Бена Пфаффа, совместимый с C99. Boost.Random тоже должно быть в порядке; когда вы пишете свой код на C ++, использование Boost не сильно ограничивает ваш выбор платформ (хотя у некоторых «меньших» (то есть несовместимых) компиляторов могут возникнуть проблемы с интенсивным использованием шаблонного метапрограммирования). Это действительно проблема только для встраиваемых платформ малого объема и, возможно, новых исследовательских архитектур, поэтому, если под «любым компьютером» вы подразумеваете «любую платформу x86 / PPC / ARM / SPARC / Alpha / и т. Д., На которую ориентируется GCC», любую из выше должно быть просто отлично.

1 голос
/ 16 марта 2009

Напишите свою собственную подпрограмму псевдослучайных чисел. В Интернете задокументировано множество алгоритмов, и у них есть ряд приложений, в которых rand недостаточно хорош (например, Perlin Noise ).

Попробуйте эти ссылки для начала:

http://en.wikipedia.org/wiki/Linear_congruential_generator

http://en.wikipedia.org/wiki/Pseudorandom_number_generator

0 голосов
/ 16 марта 2009

Да. Для данного семени (начального значения) последовательность чисел, которую возвращает rand (), всегда будет одинаковой.

0 голосов
/ 16 марта 2009

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

...