rand()生成相同的数字 - 即使我的主要是srand(time(NULL))!

Nic*_*eet 14 c++ random srand

所以,我正在尝试创建一个随机向量(想想几何,而不是一个可扩展的数组),每当我调用我的随机向量函数时,我得到相同的x值,尽管y和z是不同的.

int main () {
    srand ( (unsigned)time(NULL));
    Vector<double> a;
    a.randvec();
    cout << a << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用该功能

//random Vector
template <class T>
void Vector<T>::randvec()
{
    const int min=-10, max=10;
    int randx, randy, randz;

    const int bucket_size = RAND_MAX/(max-min);

    do randx = (rand()/bucket_size)+min;
    while (randx <= min && randx >= max);
    x = randx;

    do randy = (rand()/bucket_size)+min;
    while (randy <= min && randy >= max);
    y = randy;

    do randz = (rand()/bucket_size)+min;
    while (randz <= min && randz >= max);
    z = randz;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,randx将始终返回8,而其他数字似乎完全遵循(伪)随机性.但是,如果我在randx之前将调用定义为randy,那么randy将始终返回8.

为什么我的第一个随机数总是8?我播种不正确吗?

小智 8

问题是随机数生成器的种子值非常接近 - 程序的每次运行只会将time()的返回值改变一小部分 - 可能是1秒,甚至可能没有!然后,相当差的标准随机数发生器使用这些相似的种子值来生成明显相同的初始随机数.基本上,你需要一个比time()更好的初始种子生成器和一个比rand()更好的随机数生成器.

我认为使用的实际循环算法是从Accelerated C++中提取的,旨在产生比所需的范围更好的数字扩展,而不是使用mod运算符.但它无法弥补总是(有效地)给予相同的种子.

  • 你是对的 - 它直接来自Accelerated C++.但是,我不确定你是否正确将种子价值放在一起.我在同一分钟内多次运行程序(比如20秒内10次),每次我仍然得到8作为我的第一个随机数.我每次运行rand时得到的第一个数字是:2046680223610024096 20471340121436194148 2047251661855022070 20473356961746421126 20474533451699427348 20475205731980895774 20476046081258989483这似乎正在做它的工作,对吧? (2认同)

Jus*_*ini 5

我没有看到你的任何问题srand(),当我尝试运行非常相似的代码时,我没有重复获得与第一个相同的数字rand().但是,我确实注意到另一个可能的问题.

do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);
Run Code Online (Sandbox Code Playgroud)

这条线可能不符合你的意图.只要min < max(并且它应该是),就不可能randx小于或等于min,大于或等于max.另外,您根本不需要循环.相反,您可以使用以下方法获取介于最小值和最大值之间的值:

randx = rand() % (max - min) + min;
Run Code Online (Sandbox Code Playgroud)

  • 无害,除了它没有做到它预期的 - 并且有人瞥了一眼代码(而不是太仔细看)会看到它检查边界,当它实际上没有. (3认同)
  • 虽然这是事实,但它根本没有回答这个问题. (2认同)
  • 你的公式错了:应该是`randx = rand()%(max - min)+ min`. (2认同)