【问题标题】:Do std::random_device and std::mt19937 follow an uniform distribution?std::random_device 和 std::mt19937 是否遵循均匀分布?
【发布时间】:2016-11-17 00:04:45
【问题描述】:

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

关注randpermdocumentation

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

randpage:

rand 返回单个均匀分布的随机数

所以rand 遵循均匀分布。我的 C++ 代码基于:

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

我的问题是:上面的代码遵循均匀分布?如果没有,怎么办?

【问题讨论】:

  • 至少std::mt19937 应该是统一的,if you trust the original authors' paper title。而std::random_device 只是用来播种 Mersenne Twister,所以它实际上不必以任何方式保持一致。
  • @mindriot 感谢您的回答。和上面描述的std::uniform_int_distribution相比有什么区别?
  • mt19937 是一个随机数 engine,它产生“原始”随机数(32 位或 64 位),并且这些随机数应尽可能统一。 uniform_int_distribution 将随机输入转化为与特定分布匹配的东西(例如,在 {1, ..., 6} 上均匀分布)。
  • shuffle 在内部构造自己的分布,它只需要一个随机源:引擎。 mt19937 是标准库中最好的。

标签: c++ matlab random uniform-distribution


【解决方案1】:

C++ random number library 中的不同类大致工作如下:

  • 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,根据文档,

    对给定范围[first, last) 中的元素重新排序,以使这些元素的每个可能排列具有相同的出现概率。

在您的代码示例中,您使用std::mt19937 PRNG 来提供std::shuffle。所以,std::mt19937 是统一的,std::shuffle 的行为也应该是统一的。所以,一切都尽可能统一。

【讨论】:

    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 2018-05-21
    • 1970-01-01
    • 2016-02-07
    相关资源
    最近更新 更多