Default_random_engine传入函数会产生可重复的结果

时间:2015-06-05 22:54:19

标签: c++ c++11 random shuffle

我有一个继承自Permutation的课程std::vector<int>。我创建了一个构造函数,使对象填充非重复数字。随机性应由<random>内容保证,因此声明如下:

/* Creates a random permutation of a given length
 * Input: n - length of permutation
 *        generator - engine that does the randomizing work */
Permutation(int n, default_random_engine generator);

函数本身看起来像这样(跳过了不可忽视的细节):

Permutation::Permutation(int n, default_random_engine generator):
vector<int>(n, 0)
{
    vector<int> someIntermediateStep(n, 0);
    iota(someIntermediateStep.begin(), someIntermediateStep.end(), 0); //0, 1, 2...

    shuffle(someIntermediateStep.begin(), someIntermediateStep.end(), 
            generator);

    // etc.
 }

在以下背景中调用:

auto seed = std::chrono::system_clock::now().time_since_epoch().count();
static std::default_random_engine generator(seed);

for (int i = 0; i < n; i++) 
    Permutation test(length, generator);

代码编译完全正常,但Permutation的所有实例都是相同的。如何强制定期生成随机数?我知道default_random_engine应绑定到分发对象,但是,我没有 - 我只在shuffle()使用引擎(至少目前)。

是否有任何解决方案或解决方法仍然使用<random>的优点?

2 个答案:

答案 0 :(得分:4)

您的Permutation构造函数按值获取引擎。所以,在这个循环中:

for (int i = 0; i < n; i++) 
    Permutation test(length, generator);

您正在一遍又一遍地传递相同状态的相同引擎的副本。所以你当然得到了相同的结果。通过引用传递引擎

Permutation::Permutation(int n, default_random_engine& generator)

这样,通过调用std::shuffle来修改其状态。

答案 1 :(得分:0)

这是一个幼稚的错误,就像我想的那样 - 我以错误的方式将各种解决方案混合到类似问题中。

正如本杰明指出的那样,我不能一遍又一遍地复制相同的引擎,因为它仍然是一样的。但仅凭这一点并没有解决问题,因为引擎毫无意义地被宣布static(谢谢,Zereges)。

为了清楚起见,更正的代码如下所示:

Permutation(int n, default_random_engine &generator);

// [...]

Permutation::Permutation(int n, default_random_engine generator):
vector<int>(n, 0)
{
    vector<int> someIntermediateStep(n, 0);
    iota(someIntermediateStep.begin(), someIntermediateStep.end(), 0); //0, 1, 2...

    shuffle(someIntermediateStep.begin(), someIntermediateStep.end(), 
        generator);

    // etc.
}

// [...]
// some function
auto seed = chrono::system_clock::now().time_since_epoch().count();
default_random_engine generator(seed);

for (int i = 0; i < n; i++) 
    Permutation test(length, generator);