在c ++中生成超级随机数

时间:2015-03-19 22:40:33

标签: c++ c++11 random vector random-seed

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;
}

3 个答案:

答案 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