c++ rand() 和来自 boost 的 RNG 生成相同的数字(在发布模式下),即使使用 srand(0)
c++ rand() and RNG from boost generating the same numbers(in release mode) even with srand(0)
我正在使用 运行d() 在一个函数中生成一些 运行dom 数字来填充一些数组,但是当我 运行 该程序时,我注意到它总是给出同一行生成的数字。数组中填充了同一行生成的数字,可以全为 0 或一行中有不同的数字,但这种数字模式在每个数组中都是相同的。
所以我使用 debug 一步一步地 运行 程序并且它起作用了,运行d() 为每个数组生成了不同的数字..
在此之后我决定尝试另一种方法来生成 运行dom 数字。我找到了一种使用 Boost 库来执行此操作的方法。
这是我现在使用的代码:
int main(){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( 1, 6);
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
for(int i=0;i<10;i++){
std::cout<<dice()<<std::endl;
}
}
如果我在 main() 函数上使用此代码,一切顺利,它会给我 10 个 运行dom 数字。
但是,如果我将这段代码放在一个函数中,以便在我需要时调用它 returns 相同的数字。总是 55555555,或 0000000..
有趣的是,如果我使用调试并在该函数处设置断点并 运行 一步一步,它会再次运行,给我总是不同的数字。
所以我不知道我在这里错过了什么..
edit:当我使用 运行d() 时,我使用的是 s运行d((unsigned int)time(空));
更新 1:
int random(int begin,int end){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( begin , end );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
return dice();
}
int main() {
for(int i=0; i<10; i++)
cout<<random(0,6)<<endl;
}
如果我使用这种方法,它会给我相同的序列。如果我 运行 它一步一步调试它会工作并给我不同的数字。
您在每个函数调用中为 rng 播种,因此您总是从种子开始得到一个随机序列(长度为 1)。由于您使用 time(NULL)
作为种子,一秒钟内的所有调用都将获得相同的种子,因此序列相同。
因为您不想重复使用相同的序列,所以您不应该在调用 random
之间为 rng 播种,而是继续上一次调用的序列,就像您在完全在 main
内。这要求您在调用之间维护生成器对象的状态,而不是每次都构造一个新对象。
找到另一种方法,现在可以了。
如果有人需要我会把代码放在这里
boost::random::mt19937 gen;
int random(int begin, int end)
{
boost::random::uniform_int_distribution<> dist(begin, end);
return dist(gen);
}
int main(){
for(int i=0;i<10;i++)
std::cout << random(0,20) << std::endl;
}
我正在使用 运行d() 在一个函数中生成一些 运行dom 数字来填充一些数组,但是当我 运行 该程序时,我注意到它总是给出同一行生成的数字。数组中填充了同一行生成的数字,可以全为 0 或一行中有不同的数字,但这种数字模式在每个数组中都是相同的。
所以我使用 debug 一步一步地 运行 程序并且它起作用了,运行d() 为每个数组生成了不同的数字..
在此之后我决定尝试另一种方法来生成 运行dom 数字。我找到了一种使用 Boost 库来执行此操作的方法。
这是我现在使用的代码:
int main(){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( 1, 6);
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
for(int i=0;i<10;i++){
std::cout<<dice()<<std::endl;
}
}
如果我在 main() 函数上使用此代码,一切顺利,它会给我 10 个 运行dom 数字。 但是,如果我将这段代码放在一个函数中,以便在我需要时调用它 returns 相同的数字。总是 55555555,或 0000000.. 有趣的是,如果我使用调试并在该函数处设置断点并 运行 一步一步,它会再次运行,给我总是不同的数字。 所以我不知道我在这里错过了什么..
edit:当我使用 运行d() 时,我使用的是 s运行d((unsigned int)time(空));
更新 1:
int random(int begin,int end){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( begin , end );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
return dice();
}
int main() {
for(int i=0; i<10; i++)
cout<<random(0,6)<<endl;
}
如果我使用这种方法,它会给我相同的序列。如果我 运行 它一步一步调试它会工作并给我不同的数字。
您在每个函数调用中为 rng 播种,因此您总是从种子开始得到一个随机序列(长度为 1)。由于您使用 time(NULL)
作为种子,一秒钟内的所有调用都将获得相同的种子,因此序列相同。
因为您不想重复使用相同的序列,所以您不应该在调用 random
之间为 rng 播种,而是继续上一次调用的序列,就像您在完全在 main
内。这要求您在调用之间维护生成器对象的状态,而不是每次都构造一个新对象。
找到另一种方法,现在可以了。
如果有人需要我会把代码放在这里
boost::random::mt19937 gen;
int random(int begin, int end)
{
boost::random::uniform_int_distribution<> dist(begin, end);
return dist(gen);
}
int main(){
for(int i=0;i<10;i++)
std::cout << random(0,20) << std::endl;
}