2010-02-25 2 views
9

Я делал некоторые испытания на случайном классе, и я использовал следующий код:Насколько случайным является Random.Next()?

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% времени я получаю в этом среднем диапазоне. Я не думаю, что мы можем назвать его близким к случайному.

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

+4

Это называется случайным случайным образом. –

+4

случайный не означает «уникальный». – nos

+18

Поздравляем вас за открытие парадоксального дня рождения. (http://en.wikipedia.org/wiki/Birthday_problem) – kennytm

ответ

30

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

Кстати, на прошлой неделе я написал статью в блоге об этом точном предмете. Он выйдет в прямом эфире 22 марта; see my blog, то для деталей.

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

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

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

+0

+1 @ Эрик: Вы заполняете upp свой блог перед выпуском? Забавно. – Zano

+6

@ Zano: Да, я сразу пишу целую кучу статей, а затем настраиваю их на два раза в неделю. Я на два месяца вперед в любой момент. Раймонд Чен публикуется как пять или десять раз в неделю и имеет несколько * лет * в своей очереди; Я не знаю, как он это делает! –

+0

Хе-хе это смешно. Но не устаревают ли статьи, если вы делаете это за годы досрочно? Например, более новая версия .NET или C# будет вести себя по-другому и т. Д. –

2

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

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

2

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

+1

Мне нравится, как random.org использует шумы в атмосферных помехах. –

3

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

15

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

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

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

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

+0

+1 для сломанных кубиков –

+0

+1 очень хорошо объяснено – Bhaskar

+0

Это могло бы, на самом деле. У меня есть 10-сторонние кости, которые появляются чаще всего на 8,9,0 раз, чем другие цифры. Они отлично подходят для Marvel Super Heroes, но плохо для других игр, которые хотят более низких чисел. И.Е. Кость может быть сломана. – PRMan