使用qsrand,随机方法不是随机的

时间:2010-05-04 17:11:40

标签: qt random

我在这里遇到一个奇怪的问题,我无法找到一个好的解释,所以我想问你们:

考虑以下方法:

int MathUtility::randomize(int Min, int Max)
{
    qsrand(QTime::currentTime().msec());

    if (Min > Max)
    {
        int Temp = Min;
        Min = Max;
        Max = Temp;
    }
    return ((rand()%(Max-Min+1))+Min);
}

我不会向你解释这个方法实际上做了什么,我会解释我的问题:

我意识到当我在循环中调用此方法时,有时,我会一遍又一遍地得到相同的随机数...例如,这个片段......

for(int i=0; i<10; ++i)
{
    int Index = MathUtility::randomize(0, 1000);
    qDebug() << Index;
}

...会产生类似的东西:

567 567 567 567 ...等...

我也意识到,如果我不是每次都调用qsrand,而是在我的应用程序生命周期中只调用一次,那么它的工作正常...

我的问题:为什么?

7 个答案:

答案 0 :(得分:36)

因为如果你在毫秒内多次调用randomize(这很可能是当前的CPU时钟速度),那么你就会为RNG注入相同的值。这是保证从RNG产生相同的输出。

随机数生成器仅用于播种一次。多次播种不会使输出更加随机,事实上(正如你所发现的那样)可能会使更少随机。

答案 1 :(得分:2)

如果您足够快地拨打电话,QTime::currentTime().msec()的值不会改变,并且您基本上使用相同的种子重新播种qsrand,导致生成的下一个随机数相同作为前一个。

答案 2 :(得分:2)

如果调用qsrand Qt函数初始化种子,则必须调用qrand Qt函数生成随机数,而不是标准库中的rand函数。 rand函数的种子初始化是srand。 很抱歉挖掘。

答案 3 :(得分:1)

你看到的是伪随机性的影响。你用时间播种一次,它会生成一系列数字。由于您在相互之后非常快速地拉出一系列随机数,因此您将使用相同的数字重新播种随机数,直到下一毫秒。虽然毫秒似乎是一个短暂的时间,但请考虑您在那段时间内所做的计算量。

答案 4 :(得分:1)

现代Qt c ++ 11

#include <random>
#include "QDateTime"

int getRand(int min, int max){
    unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch());
    std::mt19937 gen(ms);
    std::uniform_int_distribution<> uid(min, max);    
    return uid(gen);
}

答案 5 :(得分:0)

两个问题:

1正如其他人所指出的那样,发电机多次出现种子。

2这不是在给定范围内生成随机数的非常好的方法。 (事实上​​,对于大多数发电机来说,它非常糟糕)

您假设发生器的低阶位均匀分布。大多数发电机都不是这种情况。在大多数发生器中,随机性发生在高阶位中。

通过使用除法后的余数,你实际上抛弃了随机性。

您应该使用乘法和除法进行缩放。不使用模运算符。 例如

my_number = start_required +(generator_output * range_required)/ generator_maximum;

如果generator_output在[0,generator_maximum]中 my_number将在[start_required,start_required + range_required]

答案 6 :(得分:0)

我找到了相同的操作,并使用rand()代替srand()解决了问题。

但我用它来检查我的申请。它只是在cicle中工作,所以我不需要寻找它的更新。

但如果你想做一些游戏之王,这不是一个好方法,因为你的随机化将是相同的。