2010-10-15 4 views
12

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

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

+4

Имея семена функции рандомизации является совсем не редкость - вы должны сделать то же самое с твистером Мерсен. –

+1

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

+1

Существует прекрасное обсуждение этой темы в главе 6 книги Джулиана Бакналла «Tomes of Delphi: алгоритмы и структуры данных» (www.boyet.com) –

ответ

6

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

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

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

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

4

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

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

16

alt text

я не мог сопротивляться.

+2

Мне нравится юмор. Но это ** должно быть CW! –

+1

Nah, no CW, это прекрасно иллюстрирует, что то, что мы можем воспринимать как неслучайное, на самом деле может быть совершенно случайным. В конце концов, случайный не является отсутствием шаблона ... –

+1

Каждый раз, когда вы чувствуете склонность ставить «я не удержался» в вашем «ответе», вы должны быть склонны сделать это CW. Это вопрос степени, но в этом случае прямого ответа на ОП не было. – Argalatyr

20

PRNG Delphi, как и почти все языки программирования RTL PRNG, является linear congruential generator.

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

2

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

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

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

2

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

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

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

3

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

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

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

-1

Вернуться хаотически 0..9

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

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

+1

Рекомендуемый вызов для генерации случайного целого числа в диапазоне от 0 до 9 является «случайным (10)». Использование floattostr является умным, но указанное выражение иногда терпит неудачу. Рассмотрим: «randseed: = -1498392781; X: = StrToInt (копия (FloatToStr (Random), 4,1));" В этом случае random вернет ровно 0,5, floattostr вернет «0.5», так как нет четвертого символа, копия вернет пустую строку, а StrToInt завершится с исключением. –

+0

Идея заключалась в том, чтобы привести пример с большей дисперсией (см. [Link] (http://stackoverflow.com/a/3947122/636542)). Так вы можете свободно улучшать этот алгоритм согласно вашим потребностям ... – DejanR

Смежные вопросы