【问题标题】:using one random engine for multi distributions in c++11在 c++11 中使用一个随机引擎进行多分布
【发布时间】:2012-03-26 10:32:57
【问题描述】:

我在我的应用程序中使用 c++11 新的 <random> 标头,并且在一个类中以不同的方法使用不同的随机数和不同的分布。我只是将一个随机引擎std::default_random_engine 作为类成员在类构造函数中用std::random_device 播种它,并在我的方法中将它用于不同的分布。以这种方式使用随机引擎是否可以,或者我应该为我使用的每个发行版声明不同的引擎。

【问题讨论】:

    标签: c++ c++11 random


    【解决方案1】:

    没关系。

    不共享生成器的原因:

    • 线程(标准 RNG 实现不是线程安全的)
    • 随机序列的确定性:

      如果您希望能够(用于测试/寻找错误)控制生成的确切序列,那么通过隔离使用的 RNG 可能会减少麻烦,尤其是在并非所有 RNG 消耗都是确定性的情况下。

    【讨论】:

      【解决方案2】:

      在为不同的随机变量使用一个伪随机数生成器时应该小心,因为这样做它们会变得相关。

      这是一个示例:如果您想在二维(例如 x 和 y)中模拟布朗运动,您需要在两个维度上都具有随机性。如果您从一个生成器(noise())中获取随机数并连续分配它们

      while(simulating)
          x = x + noise()
          y = y + noise()
      

      然后变量 x 和 y 变得相关,因为伪数生成器的算法只会说明它们有多好,如果你获取每个生成的数字,而不是像本例中那样仅每秒生成一个数字。在这里,布朗粒子可能会以比负方向更高的概率移动到正 x 和 y 方向,从而引入人为漂移。

      关于使用不同生成器的另外两个原因,请查看sehe's 答案。

      【讨论】:

      • 我理解这个想法,但是绘制两次不相关的随机数怎么会导致相关?
      • @davidhigh 被“绘制”的数字不是真正的不相关随机数,它们是所谓的伪随机数,并以确定的方式计算。这通常比绘制真正的随机数要快得多,并且它的好处是可以通过再次使用相同的种子来重现。一个缺点是流中计算的数字并不是真正不相关的,应该使用从流中生成的每一个数字,以确保良好的随机性。
      【解决方案3】:

      MosteM 的回答不正确。只要您希望分布中的抽取是独立的,这样做是正确的。如果由于某种原因您需要完全相同的随机输入来绘制不同分布的图形,那么您可能需要不同的 RNG。如果您想要两个随机变量之间的相关性,最好使用数学原理从一个公共随机变量开始构建它们:例如,如果 A、B 是独立的正态(0,1),那么 A 和 aA +sqrt(1-a* *2)B 是正常的(0,1),具有相关性 a。

      编辑:我在 C++11 随机库上找到了一个很棒的 resource,它可能对你有用。

      【讨论】:

      • 回答“在为不同的随机变量使用一个伪随机数生成器时应该小心,因为这样做它们会变得相关。”有什么问题?问题中的任何地方都没有提到相关性。
      • 确实,这个问题没有提到相关性,但你的答案确实不太正确。来自给定种子的 PRN 序列应该在统计上模仿从真正 i.i.d 中提取的序列。顺序。 (这个效果好不好就看PRNG的质量了,C++11标准还不错)不同的seed可能会有重叠的序列,导致相关性,所以其实在使用不同的seed的时候要多加注意。事实上,根据你想要多少随机数,我会说你的 while 循环非常好,除非你想多线程。
      • @Plamen:我也有同样的反对意见(在阅读您的帖子之前),请参阅对 MosteMs 回答的评论。
      【解决方案4】:

      没有理由不这样做。根据您使用的随机生成器,周期非常大(在 Mersenne-Twister 的情况下为 2^19937),因此在大多数情况下,您甚至不会在程序执行期间到达一个周期的末尾。即使没有这么说,达到所有分布都使用同一个生成器的周期比让 3 个生成器每个执行其周期的 1/3 更糟糕。

      在我的程序中,我为每个线程使用一个生成器,它工作正常。我认为这是他们在 C++11 中拆分生成器和发行版的主要原因,因为如果您不允许这样做,那么将生成器和发行版分开将没有任何好处,如果需要一个生成器无论如何,每个发行版。

      【讨论】:

      • 实际上,即使每个发行版需要一个生成器,将两者分开也有明显的好处:关注点分离。如果我有 M 个生成器和 N 个分布,那么我需要 MxN 个组合类(哎呀!),添加 1 个生成器需要 N 个新的组合类。使用解耦方法,只要您尊重生成器的“概念”,添加一个生成器只是为该生成器编写代码,仅此而已。任何人都可以将它与任何其他发行版一起使用。可组合性带来重用。
      • 没错,我只是想到了“标准”生成器,它可能只是分布构造函数的一个参数,避免了 MxN 类。但你是对的,当涉及到自我实现的生成器时,这个概念就会被打破。
      猜你喜欢
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 2013-04-07
      • 2013-07-26
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多