我得到一个在c ++中生成数万个随机数的任务。我已经在c ++中搜索了很多有关随机数的内容,并查找了c ++参考,但是现在我很困惑。
据我所知,random_device是不确定的随机数生成器,但是每次我重新运行程序时,random_device生成的随机数都是相同的。那么,当我重新启动程序时,如何为random_device设置种子以使随机数不同?
我读到“如果您尝试从中获取很多数字,std :: random_device可能会用尽熵。这可能会导致其阻塞,直到您移动鼠标或其他东西为止”。这意味着我的程序可能会在某些时候暂停。我如何避免这种情况发生?
答案 0 :(得分:1)
从here,您可以看到std::random_device
并不总是保证是不确定的:
std :: random_device可以根据实现定义的伪随机数引擎实现,如果不确定的源(例如,硬件设备)对实现不可用。在这种情况下,每个std :: random_device对象都可能生成相同的数字序列。
在Linux上,默认情况下,它根据here使用/dev/urandom
或RDRND
CPU指令:
libc ++和libstdc ++中的实现期望令牌是从中读取时会产生随机数的字符设备的名称,其默认值为“ / dev / urandom” ,尽管其中CPU指令RDRND可用,libstdc ++将其用作默认指令。
不会阻止。您可以使用方法here切换到安全的设备/dev/random
,但是如果没有足够的熵,该设备将被阻止。
在Windows上,我不确定这种设备,因此它可能会回退到需要某种种子的PRNG。
要跨平台解决问题,如@Binara所述,您可以使用std::rand
中的<cstdlib>
。此功能不会被阻止,您可以使用std::srand(somethingLikeCurrentTime)
使其具有不确定性。
如@ user1118321所述,如果您想使用更安全的PRNG,则可以考虑使用std::mersenne_twister_engine
并使用std::random_device
生成它的种子。建议使用这种方法here。
答案 1 :(得分:1)
假设您不需要加密安全的随机数生成,则可以使用std::mt19937
随机生成器。 Meresenne Twister随机生成器在重复之前要进行2 19937 次迭代。我过去曾经这样使用它:
std::array<int, std::mt19937::state_size> seedData;
std::random_device randDevice;
std::mt19937 eng;
std::uniform_real_distribution<double> randGen(0, 1);
std::generate_n(seedData.data(), seedData.size(), std::ref(randDevice));
std::seed_seq seq(std::begin(seedData), std::end(seedData));
eng.seed(seq);
这将创建一个包含适当大小的种子的数组。它创建一个随机设备来设置种子。然后,它创建一个mt19937
随机生成器引擎来生成数字。要使用它生成介于0和1之间的值,可以使用std::uniform_real_distribution
,如下所示:
double randVal = randGen(eng);
答案 2 :(得分:-3)
只需扩展上一个答案即可。如果要生成一定范围内的随机数。您可以使用
srand(time(NULL));
rand() % n + 1;
其中n是要生成的最大值。