将类内的随机数提升为静态成员

Boost random numbers inside a class as static member

本文关键字:静态成员 随机数      更新时间:2023-10-16

我正在运行"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编译),但结果看起来不像统一的(0,1)随机数。(类似于6.95301e-310和0。)

有人能告诉我吗:

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

我也会远离C++11,因为代码必须在一个比最新软件更少的集群上运行。

这是坏的:

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未初始化。

更好的方法是使用初始化列表:

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