Генератор случайных чисел: уровень класса или уровень метода? - PullRequest
2 голосов
/ 25 ноября 2008

При использовании генератора случайных чисел, который является лучшим способом использовать его для большей случайности нового значения:

  1. Есть метод, который каждый раз создает новый экземпляр ГСЧ, а затем возвращает значение?

  2. Есть экземпляр RNG на уровне класса, который создается один раз в конструкторе, и все последующие вызовы нового случайного значения с использованием существующего экземпляра?

Проблема в том, что может быть много вызовов случайного числа, часто в разных областях, не связанных друг с другом.

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

Ответы [ 3 ]

8 голосов
/ 25 ноября 2008

Вариант 1 не работает, на самом деле.

Вариант 2 - единственный выбор. Для RNG абсолютно необходимо, чтобы вы генерировали значения в последовательности из одного начального числа.

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

4 голосов
/ 25 ноября 2008

Я предлагаю вариант 3: использовать один ГСЧ во всей программе. Это требует блокировки или локального потока, если RNG не является потокобезопасным (например, в .NET), но это делает жизнь намного проще и вам не нужно беспокоиться о повторении.

См. на соответствующей странице MiscUtil для получения подробной информации о классе .NET StaticRandom, который я написал для этой цели. (Это невероятно просто - ничего умного.)

3 голосов
/ 25 ноября 2008

Редактировать: Я полагаю, я имею в виду вариант 3, как упомянуто в другом ответе, то есть глобальный случайный менеджер, хотя в пределах определенного класса вы можете делать то же самое.

Еще одним преимуществом использования варианта 2 является то, что если вам когда-либо потребуется функциональность «воспроизведения» в вашем программном обеспечении, вы можете просто сохранить начальное число, которое вы использовали для инициализации ГСЧ. В следующий раз вам нужно только заставить RNG использовать сохраненное начальное число, и вы получите точно такой же набор поведения, при условии, что нет других проблем, таких как параллелизм / многопоточность, которые могут изменить порядок выполнения .

Возможно, вы захотите сделать что-то подобное, если ваше программное обеспечение запускает эксперимент, который требует много случайности, но где вы можете повторить определенный прогон, чтобы продемонстрировать другим людям. Он также часто используется в компьютерных играх, где ИИ принимает решения на основе взвешивания возможных вариантов, но в конечном итоге случайное число «выбирает», какое действие они предпринимают.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...