Что такое подходящая замена для rand ()?

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

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 ответы лучше, чем я; см. вопросы с 13.15 по 13.21.

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

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

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

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

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

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

(От Майкла Нидермайера от славы FFmpeg.)

Ну, вопрос о том, существует ли реальный псевдослучайный генератор, остается открытым . При этом быстрый поиск показывает, что могут быть несколько более легкие альтернативы .