关于c ++:使用随机数生成器:多个实例还是单例方法?

Using random number generator: multiple instances or singleton approach?

我创建了一个可用作随机数生成器的类,该类比标准rand()更好地工作。 下面,我为类添加了.cpp文件,其中包含类变量std :: mt19937 gen和std :: uniform_real_distribution distr。

我的问题是是否有必要创建我的数字生成器的多个实例。 例如,如果我有A类和B类,并且每个类都需要在[0,1]范围内采样随机数,那么,如果A和B都有自己的UniformNumberGenerator实例会更好,还是应该采用单例方法并使用 两个类都有一个实例?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
UniformNumberGenerator::UniformNumberGenerator(double min, double max)
{
    gen = CreateGenerator();
    distr = std::uniform_real_distribution<double>(min, max);
}

std::mt19937 UniformNumberGenerator::CreateGenerator()
{
    std::random_device rd;
    std::mt19937 result(rd());
    return result;
}

//Take a sample
double UniformNumberGenerator::operator()()
{
    return distr(gen);
}


使用伪随机数生成器(PRNG)的多个实例的一个合理原因是使用相关归纳策略提高两个系统之间差异的模拟估计的精度。其中最简单的是"通用随机数"(CRN)*。直观地,如果您在银行或杂货店有两种不同的安排,并且想要确定哪种配置最有效,则将它们与完全相同的客户和交易进行比较是有意义的。 CRN通过为两种情况生成完全相同的PRN序列来做到这一点,但是您必须非常小心,以使PRNG流保持同步。如果两个系统具有不同数量的永久实体(例如服务器),这将是一个真正的挑战。在这种情况下,每台服务器一个PRNG将是合适的,并且一个PRNG也可以为每个到达流生成特性。所有PRNG都将在运行中独立地植入种子(因此,服务器似乎彼此独立),并在运行之间相同地植入种子以产生运行级别同步。

底线-除非您打算使用相关归纳策略来减少方差,并且您确实确定自己知道自己在做什么,否则应该使用一个PRNG。 MT19937对于较大的k值会顺序生成不相关的k元组,如果我没记错的话,它会产生600多个。如果您的目标是生成独立的样本,那么MT19937和其他体面的生成器正是通过生成器的单个实例来模仿的。

*-也有一篇关于此的Wikipedia文章,但是目前写得很差,所以我不建议将其用作资源。


我无法根据您发布的代码来判断您的随机数生成器,但是我可以根据哪种方法(最好是复制生成器的一些副本与使用全局单生成器)来说明几件事:

  • 如果内存很重要,显然您更希望采用单例方法,因为您只需分配一次内存
  • 除非您的生成器支持您想要用于对象的任何精美功能,例如能够在某个可自定义的分布中生成数字,否则我真的看不出在应用程序中拥有多个此生成器实例的原因。
  • 如果我想到您通常如何在应用程序中使用随机数生成器-您几乎不需要调用它-我会选择单例方法。
  • 希望这可以帮助...