为什么vc ++编译器会导致这种统计模式?

时间:2018-05-10 23:05:56

标签: c++ visual-c++ random statistics

我正在运行以下程序:

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <chrono>
using namespace std;

const int N = 200;          // Number of tests.
const int M = 2000000;      // Number of pseudo-random values generated per test.
const int VALS = 2;         // Number of possible values (values from 0 to VALS-1).
const int ESP = M / VALS;   // Expected number of appearances of each value per test.

int main() {
    for (int i = 0; i < N; ++i) {
        unsigned seed = chrono::system_clock::now().time_since_epoch().count();
        srand(seed);
        vector<int> hist(VALS, 0);
        for (int j = 0; j < M; ++j) ++hist[rand() % VALS];
        int Y = 0;
        for (int j = 0; j < VALS; ++j) Y += abs(hist[j] - ESP);
        cout << Y << endl;
    }
}

该程序执行N次测试。在每个测试中,我们生成介于0和VALS-1之间的M个数字,同时我们在直方图中计算它们的外观。最后,我们在Y中累积误差,这些误差对应于直方图的每个值与期望值之间的差异。由于数字是随机生成的,因此每个测试中每个数字理想情况下都会出现M / VALS次数。

在运行我的程序后,我分析了结果数据(即Y的200个值),我意识到发生了一些我无法解释的事情。我看到,如果用vc ++编译程序并给出一些N和VALS(在这种情况下N = 200和VALS = 2),我们会得到不同M值的不同数据模式。对于某些测试,结果数据遵循正常分配,对于一些测试,它没有。此外,这种类型的结果似乎是交替的M(每个测试中产生的伪随机数的数量)增加:

  • M = 10K,数据不正常:

enter image description here enter image description here

  • M = 100K,数据正常:

enter image description here enter image description here

  • 等等:

enter image description here enter image description here

enter image description here enter image description here

enter image description here enter image description here

正如您所看到的,根据M的值,结果数据遵循正态分布或以其他方式遵循非正态分布(双峰,狗食或统一类型),其中Y的更极端值具有更大的存在。

如果我们用其他C ++编译器(gcc和clang)编译程序,那么结果的多样性就不会发生。在这种情况下,看起来我们总是获得Y值的半正态分布:

enter image description here enter image description here

您对此有何看法?解释是什么?

我通过这个在线编译器进行了测试:http://rextester.com/l/cpp_online_compiler_visual

0 个答案:

没有答案
相关问题