我不确定出了什么问题(还!),但您仍然可以按如下方式按时间初始化,而不会遇到问题(借自here http://www.cplusplus.com/reference/random/linear_congruential_engine/linear_congruential_engine/).
#include <ctime>
#include <iostream>
#include <random>
#include <chrono>
using namespace std;
unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count();
default_random_engine gen(seed1); //gen(time(NULL));
uniform_int_distribution<int> dist(10,200);
int main()
{
for(int i = 0; i < 5; i++)
cout<<dist(gen)<<endl;
return 0;
}
您还可以使用随机设备,它是不确定的(它从您的击键、鼠标移动和其他来源窃取计时信息,以生成不可预测的数字)。这是您可以选择的最强种子,但如果您不需要强有力的保证,则计算机时钟是更好的选择,因为如果您经常使用计算机,则计算机可能会耗尽“随机性”(需要多次击键和鼠标)运动以生成单个真正的随机数)。
std::random_device rd;
default_random_engine gen(rd());
Running
cout<<time(NULL)<<endl;
cout<<std::chrono::system_clock::now().time_since_epoch().count()<<endl;
cout<<rd()<<endl;
在我的机器上生成
1413844318
1413844318131372773
3523898368
so the chrono
库提供的数字明显大于且变化更快的数字(以纳秒为单位)ctime
图书馆。这random_device
正在产生遍布地图的不确定数字。所以看起来好像种子ctime
生产是否可能以某种方式过于接近,从而部分映射到相同的内部状态?
我制作了另一个程序,如下所示:
#include <iostream>
#include <random>
using namespace std;
int main(){
int oldval = -1;
unsigned int oldseed = -1;
cout<<"Seed\tValue\tSeed Difference"<<endl;
for(unsigned int seed=0;seed<time(NULL);seed++){
default_random_engine gen(seed);
uniform_int_distribution<int> dist(10,200);
int val = dist(gen);
if(val!=oldval){
cout<<seed<<"\t"<<val<<"\t"<<(seed-oldseed)<<endl;
oldval = val;
oldseed = seed;
}
}
}
正如您所看到的,这只是打印出截至当前时间的每个可能的随机种子的第一个输出值,以及具有相同值的种子和先前种子的数量。输出的摘录如下所示:
Seed Value Seed Difference
0 10 1
669 11 669
1338 12 669
2007 13 669
2676 14 669
3345 15 669
4014 16 669
4683 17 669
5352 18 669
6021 19 669
6690 20 669
7359 21 669
8028 22 669
8697 23 669
9366 24 669
10035 25 669
10704 26 669
11373 27 669
12042 28 669
12711 29 669
13380 30 669
14049 31 669
因此,对于每个新的第一个数字,都有 669 个种子给出该第一个数字。因为第二个和第三个数字不同,我们仍然生成独特的内部状态。我认为我们必须更多地了解default_random_engine
为了理解 669 的特殊之处(它可以因式分解为 3 和 223)。
鉴于此,很明显为什么chrono
and random_device
库工作得更好:它们生成的种子总是相距 669 以上。请记住,即使第一个数字相同,在许多程序中重要的是由不同生成的数字序列。