本文介绍了<随机>在 Linux 中生成相同的数字,但在 Windows 中不生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码旨在生成区间 [1,100] 中包含五个伪随机数的列表.我用 time(0)default_random_engine 播种,它以 unix 时间.当我使用 Microsoft Visual Studio 2013 在 Windows 7 上编译和运行这个程序时,它按预期工作(见下文).然而,当我使用 g++ 编译器在 Arch Linux 中这样做时,它的行为很奇怪.

The code below is meant to generate a list of five pseudo-random numbers in the interval [1,100]. I seed the default_random_engine with time(0), which returns the system time in unix time. When I compile and run this program on Windows 7 using Microsoft Visual Studio 2013, it works as expected (see below). When I do so in Arch Linux with the g++ compiler, however, it behaves strangely.

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

In Linux, 5 numbers will be generated each time. The last 4 numbers will be different on each execution (as will often be the case), but the first number will stay the same.

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

Example output from 5 executions on Windows and Linux:

      | 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 上会定期递增 1.得到上面的输出后,等了大约30分钟,再次尝试,发现第一个数字变了,现在一直生成为26.它继续周期性地递增1,现在是32.似乎是对应的随着 time(0) 的变化值.

Adding to the mystery, that first number periodically increments by one on Linux. After obtaining the above outputs, I waited about 30 minutes and tried again to find that the 1st number had changed and now was always being generated as a 26. It has continued to increment by 1 periodically and is now at 32. It seems to correspond with the changing value of time(0).

为什么第一个数字在运行中很少发生变化,然后在变化时加 1?

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

The code. It neatly prints out the 5 numbers and the system time:

#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 << '#' << '	' << "system time" << endl
         << "-------------------" << endl;

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

    system("pause");
    return 0;
}

推荐答案

这是怎么回事:

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

  • default_random_engine in libstdc++ (GCC's standard library) is minstd_rand0, which is a simple linear congruential engine:

typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;

  • 这个引擎生成随机数的方式是 x = (16807x + 0) mod 2147483647.

  • The way this engine generates random numbers is x = (16807x + 0) mod 2147483647.

    因此,如果种子相差 1,那么大多数情况下第一个生成的数字将相差 16807.

    Therefore, if the seeds are different by 1, then most of the time the first generated number will differ by 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,这与您的观察非常吻合.

    The range of this generator is [1, 2147483646]. The way libstdc++'s uniform_int_distribution maps it to an integer in the range [1, 100] is essentially this: generate a number n. If the number is not greater than 2147483600, then return (n - 1) / 21474836 + 1; otherwise, try again with a new number.

    It should be easy to see that in the vast majority of cases, two ns that differ by only 16807 will yield the same number in [1, 100] under this procedure. In fact, one would expect the generated number to increase by one about every 21474836 / 16807 = 1278 seconds or 21.3 minutes, which agrees pretty well with your observations.

    MSVC的default_random_enginemt19937,没有这个问题.

    MSVC's default_random_engine is mt19937, which doesn't have this problem.

    这篇关于&lt;随机&gt;在 Linux 中生成相同的数字,但在 Windows 中不生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 08-23 16:18