澄清称呼

时间:2019-05-28 11:12:29

标签: c++ c++11

我想知道为什么在程序开始时对srand进行播种而不是在哪里使用是有利的。

我在程序开始时植入srand时会生成伪随机数,但是当我在调用生成数字的函数中植入srand时我会得到相同的数字

#include <iostream>
#include <ctime>
using namespace std;

int rng()
{
    const int SIZE = 10;
    int rng[10];
  srand(time(NULL));
    for (int i = 0; i < 10; i++)
    {
        rng[i] = rand() % 128 + 1;
        return rng[i];
    }

}

int main()
{
    int array;
  //srand(time(NULL)); If i put it here i get actual random numbers
    cout << "Welcome to the program";
    cout << "\nthis is your rng\n";
    for (int i = 0; i < 10; i++)
    {
        array = rng();
        cout << array << endl;
    }

    return 0;
}

当我运行程序时,所有数字都是相同的,但是当我从rng函数中删除种子并取消注释主模块中的色号时,这些数字就是我想要的伪随机数。我想知道为什么。我调查了一下,听说即时播种了时间,当我运行该函数时,循环是如此之快,以至于所有数字都是用相同的种子值生成的,所以它们都是一样的,但是我想知道与它有什么区别,并在主目录中使用srand(time(NULL)),因为这两种方法都不会以如此快的速度生成数字,无论如何它们将处于相同的种子值?由于输出不同,它没有出现这种方式,但我很好奇,为什么?

1 个答案:

答案 0 :(得分:2)

time返回自1970年1月1日以来的秒数,因此在一秒内重复调用它实际上将返回相同的值。只要将srand放在所有rand调用之前,将它放在什么位置都没关系,并且 每个程序仅应被调用一次,因为它是全局的,并且显然会重置随机顺序。因此,如果仅在需要的地方使用它,则冒着风险,当代码的其他部分也需要它并再次调用srand时,它将干扰您的rand调用。完全没有必要调用它,但是种子将始终相同。调试时可以选择确定性地设置种子。

也就是说,不要使用它,就是不要。

如您所见,time不是一个好的种子生成器,rand甚至不是一个好的随机数生成器,对于floatsx mod n来说肯定不是。使用<random>库。它具有std::random_device,可以生成真正的随机数=好的种子。可悲的是它不是必需的。 std::mt19937成为RNG,它与std::XX_YY_distribution s一起满足所有需求,但对随机性的最极端需求除外。它也是线程安全的,因为您可以控制对生成器的访问及其使用方式。