Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Заполнение массивов случайными числами

#c_sharp


Есть отдельный класс матрица, в конструкторе по умолчанию инициализируется и заполняется
случайными числами двумерный массив:    

mas = new int[3, 3];
Random rand = new Random();
for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
        mas[i, j] = rand.Next(-1, +9);


Проблема в том, что когда в основной программе создаю 2 объекта класса моей матрицы,
оба массива получаются с одинаковыми числами.

Как сделать, что бы числа были разными?
    


Ответы

Ответ 1



Можно ещё инициализировать Random чем-то быстро меняющимся или заведомо различным. Например: var rand = new Random((int)Stopwatch.GetTimestamp()); GetTimestamp() меняется с частотой порядка нескольких МГц на современных компах, ваш же цикл выполняется несколько микросекунд. У меня за это время GetTimestamp() вырастает примерно на 15 тактов, т.е. seed будет разный. В общем, вряд ли найдётся такой комп, у которого GetTimestamp() не изменится за время заполнения массива. Разве что совсем-совсем старый какой-нибудь, у которого Stopwatch.IsHighResolution == false. var rand = new Random(Guid.NewGuid().GetHashCode()); Guid.NewGuid() всегда возвращает разные значения: To a very high degree of certainty, this function returns a unique value – no other invocation, on the same or any other system (networked or not), should return the same value. (из MSDN по функции CoCreateGuid).

Ответ 2



Дело в том, что ваша программа бежит быстро. Random генерирует псевдослучайные числа, высчитывая каждое новое число из предыдущего. В качестве начального значения используется текущее время. Но если ваша программа бежит быстро, то при заполнении второй матрицы начальный момент времени тот же! Ведь время «тикает» достаточно редко по сравнению с несколькими микросекундами, расходуемыми на ваш цикл. Вот и последовательность «случайных» чисел получается точно такая же. Обычное решение этой проблемы — не пересоздавайте объект Random, используйте тот же самый, сохранив его в статическую переменную. Если ваша программа многопоточная, вам придётся в каждом из потоков заводить по экземпляру Random, так как эти объекты не потокобезопасны. (Да, это глобальное решение локальной проблемы. Сорри.)

Комментариев нет:

Отправить комментарий