Делаем повторяющуюся серию «случайных» чисел в C#
Класс Random может генерировать ряд псевдослучайных чисел. Их называют «псевдослучайными», а не «случайными», потому что цифры генерируются математическим алгоритмом, а не каким-то совершенно непредсказуемым процессом, например наблюдением за источником радиоактивного распада или статическими в радиоволнах. Учитывая достаточную информацию об алгоритме, используемом классом и текущем состоянии объекта Random , вы можете предсказать следующее число (фактически все следующие числа) в последовательности.
Однако класс Random создает номера, которые выглядят достаточно случайными для большинства приложений. В настоящее время класс использует алгоритм генератора децитивных случайных чисел Дональда Кнута, описанный в его книге «Искусство компьютерного программирования», том 2: «Полукоммерческие алгоритмы» , Addison-Wesley, 1981. Посмотрите на него более подробно.
Очевидное время, когда класс Random не является «достаточно случайным», заключается в криптографии важной информации. Если вам нужно зашифровать финансовую информацию, пароли или другую действительно чувствительную информацию, используйте криптографическую библиотеку вместо Random .
Генерирование псевдослучайных чисел часто полезно в программах, но иногда полезно иметь возможность генерировать один и тот же псевдослучайный набор чисел. Например, предположим, что вы хотите, чтобы демонстрационная программа отображала график некоторых псевдослучайных данных. Если может показаться странным, если каждый раз, когда вы запускаете программу, отображается другой график.
Для другого примера предположим, что у вас есть программа, которая использует методы рандомизации для поиска хорошего решения сложной проблемы, такой как проблема с перемещающимся продавцом (TSP). Теперь предположим, что в программе есть ошибка. Очень сложно найти такую ошибку, потому что каждый раз, когда вы запускаете программу, вы получаете другую серию псевдослучайных чисел, поэтому ошибка может возникать в другом месте или вообще не происходит.
К счастью, легко создать повторяемую серию псевдослучайных чисел. Просто передайте конструктору класса Random целочисленное начальное значение, котороебудет использоваться при инициализации алгоритма генерации псевдослучайных чисел. Если вы опустите это число, объект использует время системы для инициализации генератора, поэтому, если вы снова запустите программу позже в другое время, вы получите другую последовательность чисел.
Это вызывает важную проблему: если вы создаете два случайных объекта примерно в одно и то же время, время системы может не измениться, так что вы можете в конечном итоге с двумя объектами, инициализированными одним и тем же начальным значением, и, следовательно, с получением тех же псевдослучайных чисел. Чтобы этого избежать, создайте единый случайный объект, а затем используйте его, когда вам нужно генерировать псевдослучайные числа.
В этом примере используется следующий код для добавления 100 псевдослучайных чисел в ListBox .
// Инициализируем генератор случайных чисел и генерируем некоторые числа. private void GenerateNumbers(TextBox seed_textbox, ListBox lst) { // Get the seed. int seed = int.Parse(seed_textbox.Text); // Initialize the random number generator. Random Rand = new Random(seed); // Generate numbers. lst.Items.Clear(); for (int i = 1; i < 100; i++) { lst.Items.Add(Rand.Next(0, 10000)); } }
Код принимает в качестве параметров TextBox, содержащий начальное значение, и ListBox, где он должен помещать псевдослучайные числа. Он анализирует значение семени и использует его для инициализации нового объекта Random . Затем он очищает ListBox и использует объект Random, чтобы заполнить его 100 псевдослучайными номерами от 0 до 9999.
Запустите программу, введите начальные значения в элементах управления TextBox нажмите кнопки «Создать». Если два значения семени совпадают, в списках будут отображаться одни и те же псевдослучайные числа. Если значения семян разные, даже в незначительной сумме, значения будут сильно отличаться.