Default_random_engine 传递给函数给出可重复的结果
Default_random_engine passed into a function gives repeatable results
我有一个 class 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>
的优点?
您的 Permutation
构造函数按值接收引擎。所以,在这个循环中:
for (int i = 0; i < n; i++)
Permutation test(length, generator);
您一遍又一遍地传递同一引擎的副本,处于同一状态。所以你当然会得到相同的结果。改为通过引用传递引擎
Permutation::Permutation(int n, default_random_engine& generator)
这样它的状态将通过调用 std::shuffle
来修改。
正如我所想,这是一个幼稚的错误——我以错误的方式混合了针对类似问题的各种解决方案。
正如本杰明所指出的,我不能一遍又一遍地复制同一个引擎,因为它仍然是一样的。但这并不能解决问题,因为引擎被毫无意义地声明为 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);
我有一个 class 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>
的优点?
您的 Permutation
构造函数按值接收引擎。所以,在这个循环中:
for (int i = 0; i < n; i++)
Permutation test(length, generator);
您一遍又一遍地传递同一引擎的副本,处于同一状态。所以你当然会得到相同的结果。改为通过引用传递引擎
Permutation::Permutation(int n, default_random_engine& generator)
这样它的状态将通过调用 std::shuffle
来修改。
正如我所想,这是一个幼稚的错误——我以错误的方式混合了针对类似问题的各种解决方案。
正如本杰明所指出的,我不能一遍又一遍地复制同一个引擎,因为它仍然是一样的。但这并不能解决问题,因为引擎被毫无意义地声明为 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);