【发布时间】:2020-08-07 17:53:40
【问题描述】:
有谁知道以下代码中使用的两种随机数生成方法之间的区别?我怀疑第一种情况的计算成本可能更高,因为每次生成随机数时它都会从/dev/urandom 获得一个新种子。如果我在这些示例中正确生成随机数,也感谢任何 cmets。
我很困惑,因为uniform_int_distribution 指定了template<class URNG> result_type operator()(URNG& g);,在某些示例中,我看到传递的参数是default_random_engine 类型,而其他时候是random_device。这让 default_random_engine 的实际作用更加混乱。
比如我见过的方法一:
#include <iostream>
#include <random>
#include <map>
using namespace std;
int main()
{
random_device rd;
uniform_int_distribution<int> p{0,9};
map<int,int> m;
for (int i=0; i < 100; ++i) {
m[p(rd)]++;
}
for (map<int,int>::iterator it = m.begin();
it != m.end(); ++it)
cout << it->first << ", " << it->second << '\n';
return 0;
}
方法二,
#include <iostream>
#include <random>
#include <map>
using namespace std;
int main()
{
random_device rd;
default_random_engine gen(rd());
uniform_int_distribution<int> p{0,9};
map<int,int> m;
for (int i=0; i < 100; ++i) {
m[p(gen)]++;
}
for (map<int,int>::iterator it = m.begin();
it != m.end(); ++it)
cout << it->first << ", " << it->second << '\n';
return 0;
}
【问题讨论】:
-
第一种方法简直太糟糕了。你的硬件熵有限,你想这样浪费它吗?第二种方法可以使用优于
default_random_engine的 PRNG 进行改进,我认为这是实现定义的。 -
不要永远使用
default_random_engine。你不知道你会得到什么。您可能会得到一个线性同余生成器(或更糟)。明确地命名您想要的随机引擎 - 并正确seed它。如果您不知道为什么应该选择其他东西,mt19937_64是一个很好的默认选择。 -
像
default_random_engine这样的 PRNG 实际上在做什么?我在cplusplus.com/reference/random/linear_congruential_engine/… 上看到它使用x = (a*x + c) mod m,但不知道x, a,c, m是基于该页面描述的参数。