C++ 为什么在我';你给发电机设定了时间种子?
我不明白为什么我已经用C++ 为什么在我';你给发电机设定了时间种子?,c++,C++,我不明白为什么我已经用time(0)(C++初级读本告诉我使用time(0))为default\u random\u引擎)播种了一个time(0),却一直得到相同的第一位数字。这是我电脑的问题吗?(Ubuntu,C++11) 我试过一个在线编译器,有趣的是,我用gcc得到了相同的第一位数字,而不用clang++ 代码: #包括 #包括 #包括 使用名称空间std; int main(){ 自动t=时间(0); cout您正在为随机生成器设置非常相似的初始状态。根据生成器的质量,这可能会或可能不
time(0)
(C++初级读本告诉我使用time(0)
)为default\u random\u引擎
)播种了一个time(0)
,却一直得到相同的第一位数字。这是我电脑的问题吗?(Ubuntu,C++11)
我试过一个在线编译器,有趣的是,我用gcc
得到了相同的第一位数字,而不用clang++
代码:
#包括
#包括
#包括
使用名称空间std;
int main(){
自动t=时间(0);
cout您正在为随机生成器设置非常相似的初始状态。根据生成器的质量,这可能会或可能不会导致类似的输出。为了说明,我将您的示例扩展为(a)仅打印第一个序列,因为这是我们关心的,以及(b)打印不同分辨率的多个结果:
int main(){
auto t = time(0);
cout << "time: " << t << endl;
default_random_engine e(t);
default_random_engine e2(t);
default_random_engine e3(t);
default_random_engine e4(t);
uniform_int_distribution<int> uniform_dist(0, 9);
uniform_int_distribution<int> uniform_dist2(0,999);
uniform_int_distribution<int> uniform_dist3(0,99999);
uniform_int_distribution<int> uniform_dist4(0,9999999);
cout << "sequence: ";
cout << uniform_dist(e) << " " << uniform_dist2(e2) << " " << uniform_dist3(e3) << " " << uniform_dist4(e4);
cout << endl;
return 0;
}
虽然我不知道这个随机生成器实现到底在做什么,但您可以很容易地看到,它正在执行一个非常简单的转换,将种子转换为状态,并将状态转换为输出值。正如其他评论所建议的,有更好的随机生成器和更好的种子。另外请注意,实现之间的质量有所不同选项;Visual Studio 2017没有表现出这种行为。正如评论中所建议的,与time()
相比,将提供更优质的种子材料来源
但是,如果需要使用带有线性同余生成器的小种子,则可以扩展种子值以生成更好的初始值设定项。线性生成器在重新分配种子值中的位时速度较慢,因此微小的差异将导致初始的几个值彼此接近
标准库提供了将小种子扩展为更好初始值的函数:
seed_seq seed({t});
default_random_engine e(seed);
这是问题之一,尤其是在可供选择的数字有限的情况下。您可能可以通过使用更好的引擎(如mt19937
)来改进它。我还建议您查看。使用时间(0)
与使用std::random\u设备不同,种子值没有那么大的不同。如果您仍然想使用time(0)
可以调用e.discard(n)
其中n
是要提升生成器状态的步数。如果有效,则丢弃初始n
值。如果std::default_random_引擎
实现为rand
,则时间(0)
不会产生完全不同的种子,这将导致一个接近最后一个种子的随机序列。远离std::default\u random\u engine
,因为你不知道它是什么。除非你真的需要性能,否则我会默认使用std::mt19937
作为你去PRNG的工具,不一样,但很接近。1541162550
与1541162552
没有太大区别,后者可能与坏的PRNGIt有很大关系。这实际上取决于生成器。可以想象,种子的最高有效位对生成器的初始状态有更大的影响。我的建议是,使用更好的种子,如std::random_设备
,或者使用光盘ard()
在使用前“预热”发电机。伙计,这个实验非常聪明和简单。非常全面,谢谢。作为一个小小的改进,时间(0)可以输入std::mt19937(编辑:我现在看到几乎所有其他人都已经推荐了这个).在x86_64上的g++和clang++中,std::default_random_引擎
是std::linear_conformential_引擎
的类型定义。
$ ./a.out
time: 1541162210
sequence: 7 704 70457 7070079
$ ./a.out
time: 1541162211
sequence: 7 704 70457 7070157
$ ./a.out
time: 1541162212
sequence: 7 704 70458 7070236
$ ./a.out
time: 1541162213
sequence: 7 704 70459 7070315
$ ./a.out
time: 1541162214
sequence: 7 704 70460 7070393
$ ./a.out
time: 1541162215
sequence: 7 704 70461 7070472
$ ./a.out
time: 1541162216
sequence: 7 704 70461 7070550
$ ./a.out
time: 1541162217
sequence: 7 704 70462 7070629
$ ./a.out
time: 1541162218
sequence: 7 704 70463 7070707
$ ./a.out
time: 1541162219
sequence: 7 704 70464 7070786
seed_seq seed({t});
default_random_engine e(seed);