我在这里遇到一个奇怪的问题,我无法找到一个好的解释,所以我想问你们:
考虑以下方法:
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,而是在我的应用程序生命周期中只调用一次,那么它的工作正常...
我的问题:为什么?
答案 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中工作,所以我不需要寻找它的更新。
但如果你想做一些游戏之王,这不是一个好方法,因为你的随机化将是相同的。