首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由mt19937生成的重复值

由mt19937生成的重复值
EN

Stack Overflow用户
提问于 2013-04-15 13:29:26
回答 3查看 879关注 0票数 0

我正在使用C++11的random库,我有一个小程序,在一个单位半径的圆上生成一个坐标对x,y。下面是简单的多线程程序

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <random>

using namespace std;



int main()
{
    const double PI = 3.1415;



    double angle, radius, X, Y;
    int i;
    vector<double> finalPositionX, finalPositionY;

    #pragma omp parallel
    {
        vector <double> positionX, positionY;

        mt19937 engine(0);
        uniform_real_distribution<> uniform(0, 1);
        normal_distribution<double> normal(0, 1);



        #pragma omp for private(angle, radius, X, Y)
        for(i=0; i<1000000; ++i)
        {
            angle  = uniform(engine)*2.0*PI;
            radius = sqrt(uniform(engine));
            X      = radius*cos(angle);
            Y      = radius*sin(angle);

            positionX.push_back(X);
            positionY.push_back(Y);
        }
        #pragma omp barrier

        #pragma omp critical
        finalPositionX.insert(finalPositionX.end(), positionX.begin(), positionX.end());
        finalPositionY.insert(finalPositionY.end(), positionY.begin(), positionY.end());
    }


    ofstream output_data("positions.txt", ios::out);
    output_data.precision(9);
    for(unsigned long long temp_var=0; temp_var<(unsigned long long)finalPositionX.size(); temp_var++)
    {
        output_data << finalPositionX[temp_var]
                    << "\t\t\t\t"
                    << finalPositionY[temp_var]
                    << "\n";
    }
    output_data.close();
    return 0;
}

问题:许多x坐标出现两次(与y坐标相同)。我不明白这一点,因为mt19937的周期比1.000.000长得多。有人知道这是怎么回事吗?

注意到:当我没有多线程应用程序时,我会得到相同的行为,所以这个问题与错误的多线程无关。

正如其中一个答案所指出的,编辑时,我不应该对两个线程使用相同的种子--但这是我在提出这个问题时所犯的错误,在我的实际程序中,我的线程看起来不一样。

EN

回答 3

Stack Overflow用户

发布于 2013-04-15 13:39:44

正如在这篇文章中所描述的(以及堆栈溢出管理器中的后文 ),真正的随机性并不能完美地分布。

良好的随机性:

糟糕的随机性:

我确实推荐阅读这篇文章,但概括地说: RNG必须是不可预测的,这意味着调用它100次并不能完美地填充10x10网格。

票数 1
EN

Stack Overflow用户

发布于 2013-04-15 13:46:33

使用代码的核心部分,我编写了这个不完美的测试,但从我所看到的情况来看,发行版是非常统一的:

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <random>
#include <map>
#include <iomanip>

using namespace std;

int main()
{
    int i;
    vector<double> finalPositionX, finalPositionY; 
    std::map<int, int> hist;


    vector <double> positionX, positionY;

    mt19937 engine(0);
    uniform_real_distribution<> uniform(0, 1);
    //normal_distribution<double> normal(0, 1);
    for(i=0; i<1000000; ++i)
    {
        double rnum = uniform(engine);            

       ++hist[std::round(1000*rnum)];

    }

    for (auto p : hist) {
        std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                  << p.first << ' ' << std::string(p.second/200, '*') << '\n';
    }

    return 0;
}

正如其他人已经说过的,看到一些价值观被重复并不是意料之外的事。对于normal发行版,我使用了对rnumhist的以下修改来测试它,它看起来也不错:

代码语言:javascript
复制
double rnum = normal(engine);                  
++hist[std::round(10*rnum)];
票数 1
EN

Stack Overflow用户

发布于 2013-04-15 13:38:17

首先,仅仅因为你得到两次相同的数字并不意味着它不是随机的。如果你掷了六次骰子,你会期望六种不同的结果吗?看生日悖论。话虽如此,你是对的,在这种情况下,你不应该看到太多的重复。

我不太熟悉“#语用omp并行”,但我猜您正在生成多个线程,所有这些线程都用相同的种子(0)启动mt19937。您应该对所有线程使用不同的种子,例如线程id。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16016432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档