我正在使用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)
然后在每个Class的构造函数中,我使用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))
而ClassB的构造函数有:
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))
我在这里做的是一种有效的方法来实现同步,还是我应该以不同的方式做事?
答案 0 :(得分:2)
是。这是一种使其可复制的有效方法,但仅当您可以保证时,各种类的各种实例的实例化顺序中没有随机性。 这是因为如果它们以不同的顺序实例化,那么它们将为其随机数生成器获得不同的种子。
答案 1 :(得分:0)
如果我正确理解了这个问题,那么您正在使用(伪)随机数播种,因此您不会同步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')
答案 2 :(得分:0)
在模拟运行开始时种子的一个初始设置有利于可重现的随机数,允许您通过重新使用其种子来准确再现任何给定的模拟运行。
除了使用随机调用[您选择的方法]以获取初始随机数之外,您的课程中不执行任何操作。在模拟运行中不要再次触摸种子。
只要您的所有随机性都使用随机包并且您在运行期间避免重置种子,这应该会为您提供所需的行为。