Насколько надежна функция Random в Delphi? - PullRequest
12 голосов
/ 16 октября 2010

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

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

Ответы [ 9 ]

20 голосов
/ 16 октября 2010

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

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

16 голосов
/ 16 октября 2010

alt text

Не удержался.

6 голосов
/ 16 октября 2010

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

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

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

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

6 голосов
/ 16 октября 2010

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

4 голосов
/ 16 октября 2010

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

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

3 голосов
/ 17 октября 2010

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

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

А если этого недостаточно, вы также можете попробовать зарегистрироваться в службе квантового генератора случайных битов для получения некоторых ДЕЙСТВИТЕЛЬНО случайных значений.

2 голосов
/ 17 октября 2010

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

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

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

2 голосов
/ 17 октября 2010

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

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

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

0 голосов
/ 11 сентября 2012

Возврат случайного числа от 0,9

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

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

...