正确播种随机数发生器(Mersenne twister)c ++

时间:2012-10-31 19:20:37

标签: c++ random srand

除了作为一名垃圾程序员,我的行话还没有达到标准。我会尽力解释自己。 我使用randomlib实现了Merssene twister随机数生成器。 不可否认,我对Visual 8 C ++的随机数生成器的工作原理并不太熟悉,但我发现我可以在srand(time(NULL))main()播种一次,我可以安全地在其他类中使用rand()。 我有一个Merssene twister需要创建一个对象,然后播种该对象。

#include <RandomLib/Random.hpp>
RandomLib::Random r;        // create random number object
r.Reseed();                 // seed with a "unique" seed
float d = r.FloatN();   // a random in [0,1] rounded to the nearest double

如果我想在类中生成一个随机数,我怎么做,而不必每次都定义一个对象。我只是担心如果我使用计算机时钟,我将每次运行使用相同的种子(每秒只更改一次)。

我是否正确地解释了自己?

提前致谢

1 个答案:

答案 0 :(得分:1)

Random对象本质上是您需要保留的状态信息。您可以使用所有常规技术:您可以将其作为全局变量或作为参数传递。如果某个特定类需要随机数,您可以将Random对象保留为类成员,以便为该类提供随机性。


C ++ <random>库的相似之处在于它需要构造一个对象作为随机性/ RNG状态的来源。这是一个很好的设计,因为它允许程序控制对状态的访问,例如,保证多线程的良好行为。 C ++ <random>库甚至包括mersenne twister算法。

这是一个示例,显示将RNG状态保存为类成员(使用std::mt19937而不是Random

#include <random> // for mt19937
#include <algorithm> // for std::shuffle
#include <vector>

struct Deck {
    std::vector<Cards> m_cards;
    std::mt19937 eng; // save RNG state as class member so we don't have to keep creating one

    void shuffle() {
        std::shuffle(std::begin(m_cards), std::end(m_cards), eng);
    }
};

int main() {
    Deck d;
    d.shuffle();
    d.shuffle(); // this reuses the RNG state as it was at the end of the first shuffle, no reseeding
}