我想知道为什么在程序开始时对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)),因为这两种方法都不会以如此快的速度生成数字,无论如何它们将处于相同的种子值?由于输出不同,它没有出现这种方式,但我很好奇,为什么?
答案 0 :(得分:2)
time
返回自1970年1月1日以来的秒数,因此在一秒内重复调用它实际上将返回相同的值。只要将srand
放在所有rand
调用之前,将它放在什么位置都没关系,并且 每个程序仅应被调用一次,因为它是全局的,并且显然会重置随机顺序。因此,如果仅在需要的地方使用它,则冒着风险,当代码的其他部分也需要它并再次调用srand
时,它将干扰您的rand
调用。完全没有必要调用它,但是种子将始终相同。调试时可以选择确定性地设置种子。
也就是说,不要使用它,就是不要。
如您所见,time
不是一个好的种子生成器,rand
甚至不是一个好的随机数生成器,对于floats
和x mod n
来说肯定不是。使用<random>
库。它具有std::random_device
,可以生成真正的随机数=好的种子。可悲的是它不是必需的。 std::mt19937
成为RNG,它与std::XX_YY_distribution
s一起满足所有需求,但对随机性的最极端需求除外。它也是线程安全的,因为您可以控制对生成器的访问及其使用方式。