Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ <;随机>;在Linux中生成相同的数字,但在Windows中不生成_C++_Linux_Windows_Gcc_Visual Studio 2013 - Fatal编程技术网

C++ <;随机>;在Linux中生成相同的数字,但在Windows中不生成

C++ <;随机>;在Linux中生成相同的数字,但在Windows中不生成,c++,linux,windows,gcc,visual-studio-2013,C++,Linux,Windows,Gcc,Visual Studio 2013,下面的代码旨在生成间隔[1100]内五个伪随机数的列表。我使用时间(0)为默认\u随机\u引擎设定种子,该种子返回系统时间。当我使用Microsoft Visual Studio 2013在Windows 7上编译和运行此程序时,它可以正常工作(请参见下文)。然而,当我在ArchLinux中使用g++编译器执行此操作时,它的行为异常 在Linux中,每次将生成5个数字。最后4个数字在每次执行时都会不同(通常情况下也是如此),但第一个数字将保持不变 Windows和Linux上5次执行的输出示例:

下面的代码旨在生成间隔[1100]内五个伪随机数的列表。我使用
时间(0)
默认\u随机\u引擎
设定种子,该种子返回系统时间。当我使用Microsoft Visual Studio 2013在Windows 7上编译和运行此程序时,它可以正常工作(请参见下文)。然而,当我在ArchLinux中使用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上,第一个数字周期性地增加1。在获得上述输出后,我等待了大约30分钟,再次尝试发现第一个数字已经更改,现在总是生成为26。它继续周期性地增加1,现在是32。它似乎与
时间(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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
常数int上界=100;
常数int下限=1;
时间=系统时间=时间(0);
默认随机引擎e(系统时间);
均匀分布(下界、上界);

cout实现定义了
std::default\u random\u引擎
。请改用
std::mt19937
std::mt19937\u 64

此外,
std::time
ctime
函数不是很精确,请使用
标题中定义的类型:

#include <iostream>
#include <random>
#include <chrono>

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

    auto t = std::chrono::high_resolution_clock::now().time_since_epoch().count();

    std::mt19937 e;
    e.seed(static_cast<unsigned int>(t)); //Seed engine with timed value.
    std::uniform_int_distribution<int> u(lower_bound, upper_bound);

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

    for (int counter = 1; counter <= 5; counter++)
    {
        int secret = u(e);

        std::cout << secret << '\t' << t << std::endl;
    }   

    system("pause");
    return 0;
}
#包括
#包括
#包括
int main()
{
常数int上界=100;
常数int下限=1;
自动t=std::chrono::高分辨率时钟::now().time_-since_-epoch().count();
标准:mt19937 e;
e、 seed(static_cast(t));//具有定时值的seed引擎。
标准:均匀分布(下界,上界);

std::cout下面是发生的事情:

  • libstdc++(GCC的标准库)中的默认随机引擎是
    minstd\u rand0
    ,它是一个简单的线性同余引擎:

    typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
    
    typedef线性同余引擎minstd\u rand0;
    
  • 这个引擎生成随机数的方式是xi+1=(16807xi+0)mod 2147483647

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

  • 此生成器的范围是[12147483646]。libstdc++的
    统一int\u分布
    将其映射到范围[1100]中的整数的方式本质上是:生成一个数字
    n
    。如果该数字不大于2147483600,则返回
    (n-1)/21474836+1
    ;否则,请使用新数字重试。应该很容易看出,在绝大多数情况下,两个仅相差16807的
    n
    s将在[1100]中产生相同的数字在这个过程中。事实上,人们会期望生成的数字大约每21474836/16807=1278秒或21.3分钟增加一个,这与您的观察结果非常吻合


MSVC的默认随机引擎是mt19937,它没有这个问题。

在Linux中,随机函数不是概率意义上的随机函数,而是伪随机数生成器。 它是用一粒种子腌制的,基于这粒种子,产生的数字是伪随机且均匀分布的。 Linux方式的优点是,在使用群体信息设计某些实验时,可以测量已知输入信息调整的重复实验,可通过要求用户移动鼠标,将鼠标移动与一些按键混合,并添加自上次通电开始以来的微秒计数来创建

Windows随机数种子是从鼠标、键盘、网络和时间数字的集合中获得的。它是不可重复的。但是,如果如上所述,实验设计中涉及到一个种子,则可以将该salt值重置为已知种子


哦,是的,Linux有两个随机数生成器。一个默认值是32位模,另一个是64位模。您的选择取决于测试或实际使用所需的精度和计算时间。

什么是
sizeof(time\u t)
sizeof(默认值\u random\u引擎::result\u类型)
?请注意,
default\u random\u engine
在这两个平台上完全不同。顺便说一句,它仍然可以是随机的。每个程序员是否都经历过一个阶段,他们认为时间是一个很好的随机数生成器种子?@OldFart是的,它被称为学术界。在播种伪随机变量时是否需要使用更精确的时间e生成器?也许这很幼稚,但如果它引入了熵,那么感觉不准确几乎是可取的。(除非你的意思是它不够精确,从而导致潜在种子的数量大大减少。)我建议使用
std::random\u设备
而不是当前时间来设置随机生成器的种子。请检查任何关于random的参考示例。如果您不想让任何人猜到您的种子(从而复制您的序列)精度越低,随机性就越大。让我们走极端:将种子四舍五入到第二天(或一年?)->猜测很容易。使用飞秒精度->大量猜测来完成…@ChemicalEngineer
ctime
的粒度为1秒。
std::chrono
Implementative