c++ - <random> 在 Linux 中生成相同的数字,但在 Windows 中不生成

标签 c++ linux windows gcc visual-studio-2013

下面的代码旨在生成区间 [1,100] 中的五个伪随机数的列表。我使用 time(0)default_random_engine 播种,它在 unix time 中返回系统时间.当我使用 Microsoft Visual Studio 2013 在 Windows 7 上编译和运行该程序时,它按预期工作(见下文)。但是,当我在 Arch Linux 中使用 g++ 编译器执行此操作时,它的行为很奇怪。

在 Linux 中,每次会生成 5 个数字。最后 4 个数字在每次执行时都会有所不同(通常情况如此),但第一个数字将保持不变。

在 Windows 和 Linux 上执行 5 次的示例输出:

      | Windows:       | Linux:        
---------------------------------------
Run 1 | 54,01,91,73,68 | 25,38,40,42,21
Run 2 | 46,24,16,93,82 | 25,78,66,80,81
Run 3 | 86,36,33,63,05 | 25,17,93,17,40
Run 4 | 75,79,66,23,84 | 25,70,95,01,54
Run 5 | 64,36,32,44,85 | 25,09,22,38,13

更神秘的是,第一个数字在 Linux 上会周期性地加一。得到上面的输出后,我等了大约30分钟,再次尝试发现第一个数字变了,现在一直生成为26。它周期性地继续递增1,现在是32。似乎对应随着 time(0) 的值变化。

为什么第一个数字在运行过程中很少改变,然后当它改变时,增加 1?

代码。它整齐地打印出 5 个数字和系统时间:

#include <iostream>
#include <random>
#include <time.h>

using namespace std;

int main()
{
    const int upper_bound = 100;
    const int lower_bound = 1;

    time_t system_time = time(0);    

    default_random_engine e(system_time);
    uniform_int_distribution<int> u(lower_bound, upper_bound);

    cout << '#' << '\t' << "system time" << endl
         << "-------------------" << endl;

    for (int counter = 1; counter <= 5; counter++)
    {
        int secret = u(e);
        cout << secret << '\t' << system_time << endl;
    }   

    system("pause");
    return 0;
}

最佳答案

这是怎么回事:

    libstdc++(GCC的标准库)中的
  • default_random_engineminstd_rand0,它是一个简单的线性同余引擎:

    typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
    
  • 这个引擎生成随机数的方式是 xi+1 = (16807xi + 0) mod 2147483647。

  • 因此,如果种子相差 1,那么大多数时候第一个生成的数字将相差 16807。

  • 这个生成器的范围是[1, 2147483646]。 libstdc++ 的 uniform_int_distribution 将其映射到 [1, 100] 范围内的整数的方式本质上是这样的:生成一个数字 n。如果数字不大于2147483600,则返回(n - 1)/21474836 + 1;否则,请使用新号码重试。

    应该很容易看出,在绝大多数情况下,两个仅相差 16807 的 n 在此过程下会在 [1, 100] 中产生相同的数字.事实上,人们预计生成的数字大约每 21474836/16807 = 1278 秒或 21.3 分钟增加 1,这与您的观察非常吻合。

MSVC的default_random_enginemt19937,没有这个问题。

关于c++ - <random> 在 Linux 中生成相同的数字,但在 Windows 中不生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32730906/

相关文章:

c++ - 在 centOS 6.x 中播放音频时出现/dev/dsp not found 错误

linux - 使用 ssh 连接时 git clone 失败

linux - 四级域名末尾带下划线的网站无法访问

c - linux下C如何区分字符串中的数据类型?

具有从 '%' 登录权限的 Mysql 用户无法从 'localhost' 登录

Windows 上的 Java : prevent '/' slash in file name from acting as a separator

c++ - 在 Windows 上快速编译 Qt C++

c++ - 使用 Qt 制作几乎原生的 Windows 应用程序?

c++ - 脱离的 std::optional<T> 对象的散列是什么?

C++ 参数类型转换