Что является подходящей заменой для rand ()? - PullRequest
1 голос
/ 14 сентября 2011

Насколько я знаю, rand () не генерирует равномерное случайное распределение.Какая функция / алгоритм позволит мне сделать это?Мне не нужна криптографическая случайность, только равномерное случайное распределение.И наконец, какие библиотеки предоставляют эти функции?Спасибо!

Ответы [ 4 ]

2 голосов
/ 14 сентября 2011

rand() генерирует равномерное (псевдо) случайное распределение.

Фактическое требование из C стандарта (3,7 МБ PDF), раздел 7.20.2.1, составляет:

Функция rand вычисляет последовательность псевдослучайных чисел в диапазон от 0 до RAND_MAX .

где RAND_MAX, по крайней мере, 32767. Это, по общему признанию, расплывчато, но намерение состоит в том, что он дает вам равномерное распределение - и на практике это то, что на самом деле делают реализации.

Стандарт предоставляет пример реализации, но реализации C не требуют его использования.

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

Одна проблема заключается в том, что rand() дает вам равномерно распределенные числа в фиксированном диапазоне. Если вы хотите, чтобы числа находились в другом диапазоне, вам нужно проделать дополнительную работу. Например, если RAND_MAX равен 32767, то rand() может выдавать 32768 различных значений; вы не можете получить случайные числа в диапазоне 0,9 без отбрасывания некоторых значений, поскольку нет способа равномерно распределить эти 32768 различных значений в 10 сегментов одинакового размера.

Другие PRNG, вероятно, дадут вам лучшие результаты, чем rand(), но они, вероятно, будут подвержены тем же проблемам.

Как обычно, comp.lang.c FAQ отвечает на этот вопрос лучше, чем я; см. вопросы с 13.15 по 13.21.

2 голосов
/ 14 сентября 2011

Вот статья и автономный генератор случайных чисел , написанный на C #. Код очень маленький и легко переносимый на C ++ и т. Д.

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

Алгоритм в этой статье принадлежит Джорджу Марсалья, ведущему специалисту по генерации случайных чисел. Хотя код крошечный, метод хорошо выдерживает стандартные тесты.

2 голосов
/ 14 сентября 2011

Функция BSD random() (включенная в опцию XSI POSIX / SUS) почти повсеместно доступна и намного лучше, чем rand в большинстве систем (за исключением некоторых, где rand фактически использует random, и поэтому они 'оба довольно хороши).

Если вы предпочитаете выходить за пределы системных библиотек, вот некоторая полезная информация о вашем выборе:

http://guru.multimedia.cx/category/pseudo-random-number-generators/

(От Михаэля Нидермайераславы FFmpeg.)

...