C ++ 11引入了允许生成非常随机数的类,它还创建了随机数的均匀分布。还有实现生成种子(用于使随机数生成器更随机的数字)。
我正在尝试创建一个在最小值和最大值之间生成随机数的函数,但我遇到了麻烦。该函数仅生成种子和随机数一次。换句话说,当我调用该函数时,它将继续给我相同的数字。
下面是代码,我尝试生成一堆种子,随机选择其中一个种子,将该种子用于RNG并最终生成一个随机数。
int Utils::GenerateSuperRandomNum(int min, int max)
{
//Seed a the RNG
int randNum;
int randIndex;
seed_seq seq{ 1, 2, 3, 4, 5 };
vector<int> seeds(5 * max);
uniform_int_distribution<int> rngDistribution(min, max); //Generates number in the range min to max.
//Generate our seed numbers.
seq.generate(seeds.begin(), seeds.end());
//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));
randIndex = rand() % seeds.size();
//Seed the RNG with a random seed from our vector.
mt19937 rngGenerator(seeds.at(randIndex));
//Get a random number.
randNum = rngDistribution(rngGenerator);
return randNum;
}
答案 0 :(得分:6)
seed_seq seq{ 1, 2, 3, 4, 5 };
vector<int> seeds(5 * max);
uniform_int_distribution<int> rngDistribution(min, max); //Generates number in the range min to max.
//Generate our seed numbers.
seq.generate(seeds.begin(), seeds.end());
seq
始终输入相同的输入{1,2,3,4,5}
,因此始终具有相同的状态。由于它具有相同的状态,seeds.at(0)
始终是相同的值。
//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));
由于srand
每次都以相同的值播种,因此每次都以相同的状态开始。由于它每次都接收相同的值,因此它始终以相同的状态开始。 rand
使用的相同状态。
randIndex = rand() % seeds.size();
由于rand
始终具有与srand
相同的状态,因此每次都会生成相同的第一个数字。
mt19937 rngGenerator(seeds.at(randIndex));
由于randIndex
始终是相同的值,因此seeds.at(randIndex)
始终是相同的值。由于rngGenerator
总是以相同的值播种,因此它始终具有相同的状态。
randNum = rngDistribution(rngGenerator);
由于rngDistribution
始终具有相同的状态,因此它始终生成相同的值。
这显然是个问题。简单的解决方法是根据CPU温度,时间或经常更改的其他值来播种。
<小时/> 基本上,你已经认真地推翻了这一点。它的设计使用方式如下:
int Utils::GenerateSuperRandomNum(int min, int max) {
static mt19937 rngGenerator(std::random_device{}());
std::uniform_int_distribution<int> rngDistribution(min, max);
return rngDistribution(rngGenerator);
}
std::random_device{}()
根据魔法产生一个模糊的随机数,希望是硬件,就像CPU温度或其他东西一样。它可能很慢或有其他问题,因此每个程序只应使用一次。即,播种更快/更好的发电机。
static mt19937 rngGenerator(
创建一个单独的全局生成器,在第一次调用该函数时播种,并且永远不再播种。这是完美的,因为我们希望它被初始化一次,然后从那时起就做它的魔力。其他生成器(如rand
)的使用不会添加任何熵,所以不要这样做。我们也不想重新播种它,因为这可能会意外地降低随机性,而不是增加它。
std::uniform_int_distribution<int> rngDistribution(min, max);
和rngDistribution(rngGenerator)
。他们使用生成器在该分布中给出随机数。完成交易。
答案 1 :(得分:1)
种子不使(伪)随机数生成器更随机。它为生成可重现的随机数序列提供了一个起点。
这意味着,如果您提供完全相同的种子,您将获得完全相同的结果。
答案 2 :(得分:0)
通过使用它来生成自己的种子,使随机数生成器更“随机”有点像试图通过拉动引导带来提升自己。如果这只是为了好玩,时间是一个足够随机的种子,如果你正在做超级间谍加密h / w设备提供真正的随机事件是你需要的。
您可以尝试使用此服务,我不知道它是否有效或只是NSA试图欺骗您。 https://www.random.org