70

我使用以下代码来测试 C++<random>库。

为什么每次运行已编译的可执行文件都会得到完全相同的序列?rd()编译时确定吗?如何为每次运行获得不同的输出?

Windows 7 64 位上的 GCC 4.8.1。使用来自http://nuwen.net/mingw.html的MinGW 分发。

编辑:我用 Visual Studio 测试了相同的代码。没有问题。输出是不确定的。这可能是我使用的 mingw gcc 4.8.1 中的一个错误。

#include <iostream>
#include <random>
using namespace std;

int main(){
 random_device rd;
 mt19937 mt(rd());
 uniform_int_distribution<int> dist(0,99);
 for (int i = 0; i< 16; ++i){
    cout<<dist(mt)<<" ";
 }
 cout <<endl;
}
4

5 回答 5

34

来自http://en.cppreference.com/w/cpp/numeric/random/random_device

请注意,如果非确定性源(例如硬件设备)不可用于实现,则 std::random_device 可以根据伪随机数引擎来实现。

不过,我希望一个体面的实现至少可以为 RNG 播种。

编辑:我怀疑他们故意选择每次都提供相同的序列,以表明流并不像承诺的那样随机。

于 2013-09-18T19:28:56.687 回答
26

从 MSFT 的 STL得到了确认的答复:

与 VC 不同,GCC 并没有在 Windows 上实现 random_device 非确定性。Boost 有,所以你可以使用 Boost.Random。

于 2013-09-20T02:43:48.927 回答
4

您可能需要将参数传递给构造函数:

https://gcc.gnu.org/onlinedocs/gcc-4.9.1/libstdc++/api/a00899.html

于 2014-09-16T05:42:49.477 回答
4

这是一个GCC 错误,已在 GCC 9.2 中修复。

如果您遇到此问题,请更新您的编译器。(例如,您可以从 MSYS2 获得新的 GCC。)

于 2020-06-19T21:15:18.767 回答
2
  1. GCC 没有正确实现 rd.entropy() - 它总是返回 0(至少在 Mac OS X 上)。

  2. 不幸的是,似乎没有办法将额外的熵混合到 random_device 中,这很重要,因为它通常/经常(查看 Linux /dev/random 和 /dev/urandom,以及英特尔 RDRAND 实现)实现伪随机数生成器在引擎盖下。我希望能够通过注入我认为随机的东西与它的熵源产生的任何东西混合来提高它的输出。同样,由于该设备(或内核模块)在内部实现了一种加密算法来处理它获得的熵位以生成其输出,我希望能够通过注入我自己的数据与任何混合来“随机化”该过程设备选择的熵。例如,考虑 Java SecureRandom()。它不允许您设置种子(确实会将其转换为 PRNG),但它会很乐意将您提供的内容与它用来“随机化”其输出的任何内容混合在一起。

  3. 我个人更喜欢 RDRAND。具有紧凑 C 接口的小型汇编库。以下是参考资料:

    英特尔的 David Johnson 在 Stackoverflow 上解释 RDRAND

    Stackoverflow 指向适用于 Windows、Linux 和 Mac OS X 的 RDRAND 库源代码

    关于 RDRAND 库的英特尔博客和下载链接

于 2014-04-09T02:15:43.087 回答