需要为数组生成随机排列序列。当然,我们可以使用专门为此目的设计的STL功能,但我想手动完成如下操作:
问题>根据代码,在我看来,我们不应该在循环中放置std::default_random_engine generator;
。作为一般规则是真的吗?
// uniform_int_distribution
#include <iostream>
#include <random>
#include <utility>
void test1() // random result
{
int p[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::default_random_engine generator;
for (int i=0; i<=9; ++i) {
std::uniform_int_distribution<int> distribution(i,9);
int index = distribution(generator);
std::swap(p[index], p[i]);
std::cout << i << ": " << p[i] << std::endl;
}
}
void test2() // NOT random
{
int p[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i=0; i<=9; ++i) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(i,9);
int index = distribution(generator);
std::swap(p[index], p[i]);
std::cout << i << ": " << p[i] << std::endl;
}
}
int main()
{
test1();
std::cout << "*****************" << std::endl;
test2();
return 0;
}
/* output
0: 0
1: 2
2: 8
3: 6
4: 7
5: 3
6: 5
7: 9
8: 4
9: 1
*****************
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
*/
答案 0 :(得分:2)
随机生成器引擎在进入范围时会被播种。
在你的第一个函数中,你有这个基本结构:
void test1() // random result
{
std::default_random_engine generator;
for (int i=0; i<=9; ++i) {
// ...
}
}
当您输入test1()
时,随机数生成器会播种。每当你拨打test1()
时,你都会得到一个新的发电机,很可能是相同的排列。该生成器的范围是从声明点到test1()
的右括号。
在你的第二个函数中,你有这个替代结构:
void test2() // NOT random
{
for (int i=0; i<=9; ++i) {
std::default_random_engine generator;
// ...
}
}
此生成器在循环的每次迭代开始时进入范围,并在每次迭代结束时(在循环增量之前)超出范围。我相信,这将在每次迭代时为您提供相同的随机数序列。
如果你想要一个接种一次的随机序列,你需要只有一个生成器实例。要么使它成为全局变量,要么将对引擎的引用作为函数的参数传递。