【发布时间】:2012-03-26 10:32:57
【问题描述】:
我在我的应用程序中使用 c++11 新的 <random> 标头,并且在一个类中以不同的方法使用不同的随机数和不同的分布。我只是将一个随机引擎std::default_random_engine 作为类成员在类构造函数中用std::random_device 播种它,并在我的方法中将它用于不同的分布。以这种方式使用随机引擎是否可以,或者我应该为我使用的每个发行版声明不同的引擎。
【问题讨论】:
我在我的应用程序中使用 c++11 新的 <random> 标头,并且在一个类中以不同的方法使用不同的随机数和不同的分布。我只是将一个随机引擎std::default_random_engine 作为类成员在类构造函数中用std::random_device 播种它,并在我的方法中将它用于不同的分布。以这种方式使用随机引擎是否可以,或者我应该为我使用的每个发行版声明不同的引擎。
【问题讨论】:
没关系。
不共享生成器的原因:
随机序列的确定性:
如果您希望能够(用于测试/寻找错误)控制生成的确切序列,那么通过隔离使用的 RNG 可能会减少麻烦,尤其是在并非所有 RNG 消耗都是确定性的情况下。
【讨论】:
在为不同的随机变量使用一个伪随机数生成器时应该小心,因为这样做它们会变得相关。
这是一个示例:如果您想在二维(例如 x 和 y)中模拟布朗运动,您需要在两个维度上都具有随机性。如果您从一个生成器(noise())中获取随机数并连续分配它们
while(simulating)
x = x + noise()
y = y + noise()
然后变量 x 和 y 变得相关,因为伪数生成器的算法只会说明它们有多好,如果你获取每个生成的数字,而不是像本例中那样仅每秒生成一个数字。在这里,布朗粒子可能会以比负方向更高的概率移动到正 x 和 y 方向,从而引入人为漂移。
关于使用不同生成器的另外两个原因,请查看sehe's 答案。
【讨论】:
MosteM 的回答不正确。只要您希望分布中的抽取是独立的,这样做是正确的。如果由于某种原因您需要完全相同的随机输入来绘制不同分布的图形,那么您可能需要不同的 RNG。如果您想要两个随机变量之间的相关性,最好使用数学原理从一个公共随机变量开始构建它们:例如,如果 A、B 是独立的正态(0,1),那么 A 和 aA +sqrt(1-a* *2)B 是正常的(0,1),具有相关性 a。
编辑:我在 C++11 随机库上找到了一个很棒的 resource,它可能对你有用。
【讨论】:
没有理由不这样做。根据您使用的随机生成器,周期非常大(在 Mersenne-Twister 的情况下为 2^19937),因此在大多数情况下,您甚至不会在程序执行期间到达一个周期的末尾。即使没有这么说,达到所有分布都使用同一个生成器的周期比让 3 个生成器每个执行其周期的 1/3 更糟糕。
在我的程序中,我为每个线程使用一个生成器,它工作正常。我认为这是他们在 C++11 中拆分生成器和发行版的主要原因,因为如果您不允许这样做,那么将生成器和发行版分开将没有任何好处,如果需要一个生成器无论如何,每个发行版。
【讨论】: