Внедрение обычных случайных чисел в симуляции
Я создаю небольшое симуляцию в Python, и я бы хотел использовать Common Random Numbers для уменьшения вариации. Я знаю, что для достижения CRN я должен добиться синхронизации:
CRN требует синхронизации потоков случайных чисел, что гарантирует, что в дополнение к использованию одних и тех же случайных чисел для имитации всех конфигураций конкретное случайное число, используемое для определенной цели в одной конфигурации, используется для одной и той же цели во всех других конфигурации.
Мне было интересно, действительно ли способ, которым я хотел его реализовать в моей симуляции, или если я должен использовать другой подход.
Мое моделирование имеет три разных класса (ClassA, ClassB, ClassC) и объекты ClassA имеют случайное время в пути, объекты ClassB имеют случайное время обслуживания и случайные ставки использования, а объекты ClassC имеют случайное время обслуживания. Конечно, может быть несколько экземпляров каждого класса объекта.
В начале моделирования я указываю одно случайное числовое семя (replication_seed
), чтобы я мог использовать другое семя для каждой репликации моделирования.
import numpy.random as npr
rep_rnd_strm = npr.RandomState().seed(replication_seed)
Затем в конструкторе для каждого класса я использую rep_rnd_strm
для генерации семени, которое используется для инициализации потока случайных чисел для экземпляра класса:
self.class_rnd_strm = npr.RandomState().seed(rep_rnd_strm.randint(10000000))
Затем я использую self.class_rnd_strm
для генерации семени для каждого потока случайных чисел, необходимого для экземпляра класса. Например, конструктор ClassA имеет:
self.travel_time_strm = npr.RandomState().seed(self.class_rnd_strm.randint(10000000))
в то время как конструктор класса B имеет:
self.service_time_strm = npr.RandomState().seed(self.class_rnd_strm.randint(10000000))
self.usage_rate_strm = npr.RandomState().seed(self.class_rnd_strm.randint(10000000))
Являюсь ли я здесь действующим подходом к работе с синхронизацией или мне нужно делать что-то по-другому?
Ответы
Ответ 1
Да. Это действительный подход, чтобы сделать его реплицируемым , но только если вы можете гарантировать, что в порядке, в котором экземпляры различных экземпляров различных экземпляров не имеют случайности, нет случайности.
Это потому, что если они создаются в другом порядке, тогда они получат другое семя для своего генератора случайных чисел.
Ответ 2
Если я правильно понял вопрос, вы посеяли случайное число (псевдо), поэтому вы не синхронизируете свой CRN.
Рассмотрим:
self.travel_time_strm = npr.RandomState().seed(seed=self.seed)
self.service_time_strm = npr.RandomState().seed(seed=self.seed)
self.usage_rate_strm = npr.RandomState().seed(seed=self.seed)
Где self.seed - это переменная экземпляра для каждого класса, возможно, из аргумента ключевого слова.
def __init__(self, *args, **kwargs):
self.seed = None
if kwargs.get('seed'):
self.seed = kwargs.get('seed')
Ответ 3
Одна начальная настройка семени в начале запуска симуляции хороша для воспроизводимых случайных чисел, позволяющих воспроизводить любой заданный имитационный запуск точно, повторно используя его семя.
Не делайте ничего в своих классах, кроме вызовов на случайный случай. [метод по вашему выбору], чтобы получить ваши начальные случайные числа. Не трогайте семена в прогон симуляции.
Пока ваша случайность использует случайный пакет, и вы избегаете сброса семян во время прогона, это должно дать вам поведение, в котором вы нуждаетесь.