【问题标题】:Boost random numbers inside a class as static member将类中的随机数提升为静态成员
【发布时间】:2015-12-19 05:14:19
【问题描述】:

我正在模拟“Foo”对象。每个 Foo 必须有一个随机的“类型”t。我想通过(静态)成员函数将随机数生成封装到类中:

#include <boost/random.hpp>

class Foo {
public:
    static void set_seed(int seed);
    Foo();
    void print() { std::cout << t << std::endl; };
private:
    double t;
    static boost::mt19937 rng;
    static boost::uniform_01<> unif;
    static boost::variate_generator<boost::mt19937, boost::uniform_01<> > type;
};

Foo::Foo() {
    // create a new friend with random parameters
    double t = type();
};

void Foo::set_seed(int seed) {
    rng = boost::mt19937(seed);
}

boost::mt19937 Foo::rng; //reserve storage
// boost::uniform_01<> Foo::unif = boost::uniform_01<>(); // apparently not necessary
boost::variate_generator<boost::mt19937, boost::uniform_01<> > Foo::type(rng, unif); // initialize

int main() {
    Foo::set_seed(1);
    Foo f;
    f.print();
    Foo g;
    g.print();
    return 0;
}

代码编译(在 RHEL 6.7 上由 g++ -I/usr/include/boost148/ test.cpp 编译),但结果看起来不像 uniform(0,1) randoms。 (类似于 6.95301e-310 和 0。)

谁能告诉我:

  1. 这是 MC 模拟的合理方法吗?我必须并行创建大量的 Foo,但并行化是在更高级别(在 R 中)完成的,每个 MPI 工作人员将加载相应的编译代码(在共享和非共享内存 cpu 上)。我认为静态成员在这个意义上是“mpi-parallel-safe”,但如果我错了,请告诉我。
  2. 如何正确初始化随机数?

我也会对 C++11 保持清醒,因为代码必须在使用最新版本软件的集群上运行。

【问题讨论】:

  • t inside print() 未初始化。

标签: c++ boost random static-members


【解决方案1】:

这个坏了:

Foo::Foo() {
    // create a new friend with random parameters
    double t = type();
};

你想要:

Foo::Foo() {
    // create a new friend with random parameters
    t = type();
}

按照你的方式,你用一个全新的变量“遮蔽”t,它的生命周期只是构造函数的生命周期。您未初始化类中的“真实”t

Even better would be to use an initialization list:

Foo::Foo()
: t(type())
{
}

【讨论】:

  • 太棒了,谢谢你们!我在 boost::random 中苦苦挣扎,并没有注意到这样一个微不足道的错误...... :-( 但是,我仍然很乐意听到更多关于这种方法的通用 cmets。
  • @OttToomet:其余部分看起来还不错。请注意您是如何设置种子的——我们无法告诉您每个进程是否需要不同的种子(例如,基于 MPI 进程 ID)等。
猜你喜欢
  • 2010-10-14
  • 2019-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多