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

Kat*_*nie -5 c++ random vector c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

Moo*_*uck 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());
Run Code Online (Sandbox Code Playgroud)

seq始终输入相同的输入,{1,2,3,4,5}因此始终具有相同的状态.由于它具有相同的状态,seeds.at(0)因此总是相同的值.

//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));
Run Code Online (Sandbox Code Playgroud)

由于srand每次都以相同的值播种,因此每次都以相同的状态开始.由于它每次都接收相同的值,因此它始终以相同的状态开始.rand使用的状态相同.

randIndex = rand() % seeds.size(); 
Run Code Online (Sandbox Code Playgroud)

由于rand始终具有相同的状态,因此每次srand都会始终生成相同的第一个数字.

 mt19937 rngGenerator(seeds.at(randIndex)); 
Run Code Online (Sandbox Code Playgroud)

由于randIndex始终是相同的值,seeds.at(randIndex)因此始终是相同的值.由于rngGenerator总是以相同的值播种,因此它始终具有相同的状态.

randNum = rngDistribution(rngGenerator);
Run Code Online (Sandbox Code Playgroud)

由于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);
}
Run Code Online (Sandbox Code Playgroud)

std::random_device{}()根据魔法产生一个模糊的随机数,希望是硬件,就像CPU温度或其他东西一样.它可能很慢或有其他问题,因此每个程序只应使用一次.即,播种更快/更好的发电机.

static mt19937 rngGenerator(创建一个单一的全局生成器,在第一次调用该函数时播种,并且永远不再播种.这是完美的,因为我们希望它被初始化一次,然后从那时起就做它的魔力.其他生成器的使用rand不添加任何熵,所以不要这样做.我们也不想重新播种它,因为这可能会意外地降低随机性,而不是增加它.

std::uniform_int_distribution<int> rngDistribution(min, max);rngDistribution(rngGenerator)你似乎明白了.他们使用生成器在该分布中给出随机数.木已成舟.

  • `seeds.at(0)`并不总是1.它始终是`seed_seq`算法产生的一些固定数. (3认同)