Я делал некоторое тестирование на Случайном классе, и я использовал следующий код:
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% времени, которое я получаю в этом среднем диапазоне. Я не думаю, что мы можем назвать его близко к тому, чтобы быть Случайным.
Что я могу сделать для получения довольно случайного числа.
Вы не тестируете на циклы. Вы проверяете, сколько времени требуется для получения случайного числа, которое у вас уже было. Это совершенно другое. Ваши цифры точно соответствуют тому, сколько времени требуется для получения случайного числа, которое было у вас раньше. Посмотрите в Википедии в разделе "парадокс дня рождения" график вероятности получения коллизии после определенного числа итераций.
По совпадению, на прошлой неделе я написал статью в блоге именно на эту тему. Она выйдет в свет 22 марта; подробности смотрите в моем блоге тогда.
Если вы хотите проверить длину цикла генератора псевдослучайных чисел, то вам нужно искать не число, которое у вас уже было, а скорее длинную точную последовательность чисел, которые у вас уже были. Есть несколько интересных способов сделать это, но мне, наверное, проще просто сказать вам: длина цикла Random составляет несколько миллиардов, поэтому вы вряд ли сможете написать программу, которая обнаружит этот факт. Вам пришлось бы хранить много чисел.
Однако длина цикла - не единственная мера качества генератора псевдослучайных чисел. Помните, что ГПСЧ не случайны, они предсказуемы, и поэтому вы должны очень тщательно продумать, какова ваша метрика "случайности".
Дайте нам больше деталей: почему вас волнует, насколько "случайным" является Random? Для каких целей вы его используете, что вас так волнует? Какие аспекты случайности важны для вас?
Вы судите о случайности по повторяющимся парам, что не лучший тест на случайность. Повторения, которые вы видите, сродни парадоксу дня рождения: http://en.wikipedia.org/wiki/Birthday_problem , где повторение может произойти с небольшим размером выборки, если вы не ищете конкретный мероприятие.
Вы предполагаете, что случайность лучше, если числа не повторяются. Это не так.
У настоящей случайности нет памяти. Когда вы выбираете следующее число, шанс снова получить то же самое число так же высок, как и любое другое число в диапазоне.
Если вы бросаете игральную кость и выпадает шестерка, а затем бросаете кость снова, то шанс снова получить шестерку не меньше. Если вам выпадут две шестерки подряд, это не означает, что игральная кость сломана.
Случайность в классе Random, конечно, не идеальна, но ваш тест показывает не это. Он просто показывает феномен, который вы получаете с каждым генератором рандомных чисел, даже если он действительно создает настоящие случайные числа, а не просто псевдослучайные.
Согласно документации на http://msdn.microsoft.com/en-us/library/system.random.aspx
Для генерации криптографически безопасного случайное число, подходящее для создания случайного пароля, например, используйте класс, производный от System.Security.Cryptography...::.RandomNumberGenerator , например System.Security.Cryptography...::.RNGCryptoServiceProvider.
Компьютер не может сгенерировать реальное случайное число. если вам нужно реальное случайное число (Дэвид дал вам лучший вариант из точки net framework) вам нужен внешний случайный источник.