std::random_device和std::mt19937是否遵循均匀分布?

6

我正在尝试将这行matlab代码转换为C++代码:rp = randperm(p);

根据randperm文档

randperm使用与rand相同的随机数生成器。

而在rand 文档中:

rand返回一个符合均匀分布的单一随机数。

因此,rand遵循均匀分布。我的C++代码基于以下内容:

std::random_device rd;
std::mt19937 g(rd());
std::shuffle(... , ... ,g);

我的问题是:上面的代码遵循均匀分布吗?如果不是,怎么做到呢?

至少std::mt19937应该是均匀的,如果你信任原作者的论文标题。而std::random_device仅用于种子生成Mersenne Twister,因此它实际上不需要以任何方式均匀。 - mindriot
@mindriot,感谢您的回答。那么与上面描述的std::uniform_int_distribution相比有什么区别呢? - justHelloWorld
3
mt19937 是一个随机数引擎,它生成“原始”的随机数(32位或64位),这些随机数应尽可能均匀。 uniform_int_distribution 将该随机输入转换为与特定分布相匹配的内容(例如在 {1,……6} 上均匀分布)。 - mindriot
shuffle 构造其自身的分布,它只需要一个随机数生成器:engine。在标准库中,mt19937 是最好的。 - Revolver_Ocelot
如果您使用有偏生成器来提供shuffle,那么shuffle是否不会产生不同概率的不同排列呢?如果不是,那么当它不知道生成器的特征时,它如何构建均匀的排列概率呢?因此,生成器必须是均匀的,对吗? - mindriot
显示剩余2条评论
1个回答

16
不同的C++随机数库类大致工作如下:
  • std::random_device 是一个均匀分布的随机数生成器,可以访问您系统中的硬件设备,或者类似于 Linux 上的 /dev/random。通常仅用于种子伪随机生成器,因为底层设备很快就会耗尽熵。
  • std::mt19937 是一个快速的伪随机数生成器,使用 Mersenne Twister engine,根据原始作者的论文标题,也是均匀的。这将生成完全随机的32位或64位无符号整数。由于只使用 std::random_device 来种子此生成器,因此它本身不必是均匀的(例如,通常使用当前时间戳来种子生成器,这绝对不是均匀分布的)。
  • 通常,您使用像 std::mt19937 这样的生成器来提供特定的分布,例如 std::uniform_int_distributionstd::normal_distribution,然后采取所需的分布形状。
  • std::shuffle 根据文档,

    重新排列给定范围内的元素,以便这些元素的每个可能排列都有相等的出现概率。

在您的代码示例中,您使用std::mt19937 PRNG来提供std::shuffle。因此,std::mt19937是均匀的,std::shuffle也应该表现均匀。所以,一切都尽可能均匀。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接