Насколько надежна случайная функция в Delphi

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

Мне интересно, является ли случайная функция (после вызова randomize) достаточно случайной для статистических тестов или нужен Mersenne twister? Кто-нибудь имеет представление о фактической реализации random, которая может сказать мне, как это важно?

9 ответов


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

сказав это, я написал несколько частей кода Delphi, которые должны делать правильную статистику, и использовали Random например, для получения различных нулевого распределения, данные псевдо-повторений и resamplings. До сих пор я не сталкивался ни с одним случаем в моем собственном коде, где Random дали бы предвзятые или ненадежные результаты, или результаты что исключило бы его использование для предполагаемого статистического теста. Но то, что относится к моему коду, не обязательно должно относиться к вашему.

если вы сомневаетесь, вы можете, конечно, статистически проанализировать результаты вызовов Random (например, в R, SPSS и т. д.) и проверьте, нарушает ли распределение результатов требования к распределению для вашего конкретного статистического теста(ов). - "Если ты настоящий ученый, это то, что ты должен сделать в любом случае.]

если вы нужны другие PRNGs - например,TPMath библиотека содержит некоторые. (Для более сложных вещей есть также возможность вызова сложных статистических функций из R через Delphi.)


PRNG Delphi, как и почти все языки программирования RTL PRNGs, является линейный конгруэнтный генератор.

Это достаточно хорошо для большинства мелких вещей, но есть вещи, которых нужно остерегаться. В частности, следите за битами низкого порядка: шаблон умножения и добавления означает, что биты низкого порядка не очень случайны. Но это обычно относится только к большим 32-битным значениям, вытащенным, а затем усеченным с помощью mod или аналогичные. Используя Random(10) ощипывать значение от 0 до 9 внутренне использует умножение по всему 32-разрядному диапазону, а не mod операции.


alt text

Я не мог устоять.


Если вы ищете способ гарантировать уникальность случайных чисел с самым быстрым временем выполнения,About.com создал вызов на Самый Быстрый Уникальный Генератор Случайных Чисел и реализация Патрика ван Логчема был избран победителем.


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

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


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

среди этих функций также есть криптографически надежный генератор случайных чисел!--2-->. Это, безусловно, лучшая случайность, которую вы получите в программном обеспечении, потому что она зарождается на основе очень длинного списка факторов. Я не уверен, но подозреваю, что так и будет. даже используйте аппаратный генератор случайных чисел, если он у вас есть.

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


с веб-сайта Embarcadero:

_lrand-функция генератора длинных случайных чисел. _rand использует мультипликативный конгруэнтный генератор случайных чисел с периодом 2^64 и возвращает очередное псевдослучайное число в диапазоне от 0 до 2^31 - 1.

генератор повторно инициализируется вызовом srand со значением аргумента 1. Его можно установить в новую начальную точку, вызвав srand с заданным номером семени.


если они не изменили реализацию, так как я ее проанализировал(Delphi 4 IIRC), Delphi PRNG реализован следующим образом:

Randseed:=int32(Randseed*088405)+1
result:=Randseed*Range shr 32

(псевдокод / предположим, что умножения на произвольно больших целых числах)


вернуть случайный между 0..9

StrToInt(copy(FloatToStr(Random),4,1))

Примечание: проверьте длину FloatToStr (Random) перед использованием или использовать любую другую цифру из десятичной части...