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

时间:2014-08-18 09:37:42

标签: c++ class random singleton instance

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

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

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);
}

2 个答案:

答案 0 :(得分:2)

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

底线 - 除非您计划使用相关归纳策略来减少差异,并且您确实知道自己在做什么,否则应该使用单个PRNG。如果我没记错的话,MT19937会为相当大的k值生成顺序不相关的k元组,超过600。如果您的目标是生成独立样本,那么MT19937和其他类似的生成器就是通过单个生成器实例来模拟的。

* - 也有关于此的维基百科文章,但它目前编写得非常糟糕,因此我不建议将其用作资源。

答案 1 :(得分:1)

我无法根据您发布的代码来判断您的随机数生成器,但我可以根据哪种方法(实例化一些复制的生成器而不是一个全局的代码)来说明一些事情,最好:< / p>

  1. 如果内存很重要,显然单例方法是你喜欢的方法,因为你只需要分配一次内存
  2. 除非您的生成器支持您想要用于对象的任何花哨功能,例如能够在某个可自定义的分发中生成数字,我真的没有理由在这个生成器中有多个实例应用程序。
  3. 如果我想到你通常在应用程序中使用随机数生成器 - 你很少需要调用它 - 我会采用单例方法。
  4. 希望这会有所帮助...