Насколько случайным является Random.Next ()? - PullRequest
9 голосов
/ 25 февраля 2010

Я проводил некоторые тесты в классе Random и использовал следующий код:

while (x++ <= 5000000)
       {
           y = rnd.Next(1, 5000000);
           if (!data.Contains(y))
               data.Add(y);
           else
           {
               Console.WriteLine("Cycle {2}: Repetation found for number {0} after {1} iteration", y, x, i);
               break;
           }
       }

Я продолжал изменять максимальный предел rnd (то есть 5000000), менял количество итераций и получал следующий результат:

1) if y = rnd.Next(1, 5000) : The average is between 80 to 110 iterations
2) if y = rnd.Next(1, 5000000) : The average is between 2000 to 4000 iterations
3) if y = rnd.Next(1, int.MaxValue) : The average is between 40,000 to 80,000 iterations.

Почему я получаю эти средние значения, то есть из 10 раз, когда я проверял каждое значение, 80% времени я получаю в этом среднем диапазоне. Я не думаю, что мы можем назвать это почти случайно.

Что я могу сделать, чтобы получить довольно случайное число.

Ответы [ 5 ]

30 голосов
/ 25 февраля 2010

Вы не тестируете циклы. Вы проверяете, сколько времени занимает получение случайного числа, которое у вас было раньше. Это совершенно другой . Ваши цифры позволяют определить, сколько времени потребуется, чтобы получить случайное число, которое у вас было раньше. Посмотрите в википедии под «парадоксом дня рождения» график вероятности столкновения после определенного числа итераций.

По совпадению, на прошлой неделе я написал статью в блоге на эту тему. Это будет жить 22 марта; см. Мой блог тогда для деталей.

Если вы хотите проверить, является ли длина цикла генератора псевдослучайных чисел, тогда вам нужно искать не число , которое вы имели раньше, а скорее длительность Точная последовательность чисел, которые у вас были раньше. Есть несколько интересных способов сделать это, но мне, вероятно, проще сказать вам: длина цикла Random составляет несколько миллиардов, так что вы вряд ли сможете написать программу, которая обнаружит этот факт. Вам нужно будет хранить лот чисел.

Однако длина цикла - не единственная мера качества генератора псевдослучайных чисел. Помните, что PRNG являются не случайными , они предсказуемы , и поэтому вы должны очень тщательно продумать, какова ваша метрика для "случайности".

Дайте нам более подробную информацию: почему вас волнует, как "случайный" случайный? Какое приложение вы используете для того, что вас волнует? Какие аспекты случайности важны для вас?

16 голосов
/ 25 февраля 2010

Вы предполагаете, что случайность лучше, если числа не повторяются. Это не правда.

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

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

Случайность в классе Random, конечно, не идеальна, но это не то, что показывает ваш тест. Он просто показывает пеномен, который вы получаете с каждым генератором чисел, даже если на самом деле создаются реальные случайные числа, а не только псевдослучайные числа.

3 голосов
/ 25 февраля 2010

Вы оцениваете случайность по повторяющимся парам, что не лучший тест на случайность. Повторения, которые вы видите, похожи на парадокс дня рождения: http://en.wikipedia.org/wiki/Birthday_problem,, где событие повтора может произойти с небольшим размером выборки, если вы не ищете конкретное событие.

2 голосов
/ 25 февраля 2010

Компьютер не может генерировать реальное случайное число. если вам нужно реальное случайное число (Дэвид дал вам лучший вариант из структуры dot net) вам нужен внешний случайный источник.

2 голосов
/ 25 февраля 2010

Согласно документации на http://msdn.microsoft.com/en-us/library/system.random.aspx

Для создания криптографически безопасного случайное число, подходящее для создания случайный пароль, например, используйте класс, полученный из System.Security.Cryptography .. ::. RandomNumberGenerator такие как System.Security.Cryptography .. ::. RNGCryptoServiceProvider.

...