我正在使用C++11的random库,我有一个小程序,在一个单位半径的圆上生成一个坐标对x,y。下面是简单的多线程程序
#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长得多。有人知道这是怎么回事吗?
注意到:当我没有多线程应用程序时,我会得到相同的行为,所以这个问题与错误的多线程无关。
正如其中一个答案所指出的,编辑时,我不应该对两个线程使用相同的种子--但这是我在提出这个问题时所犯的错误,在我的实际程序中,我的线程看起来不一样。
发布于 2013-04-15 13:39:44
正如在这篇文章中所描述的(以及堆栈溢出管理器中的后文 ),真正的随机性并不能完美地分布。
良好的随机性:

糟糕的随机性:

我确实推荐阅读这篇文章,但概括地说: RNG必须是不可预测的,这意味着调用它100次并不能完美地填充10x10网格。
发布于 2013-04-15 13:46:33
使用代码的核心部分,我编写了这个不完美的测试,但从我所看到的情况来看,发行版是非常统一的:
#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发行版,我使用了对rnum和hist的以下修改来测试它,它看起来也不错:
double rnum = normal(engine);
++hist[std::round(10*rnum)];发布于 2013-04-15 13:38:17
首先,仅仅因为你得到两次相同的数字并不意味着它不是随机的。如果你掷了六次骰子,你会期望六种不同的结果吗?看生日悖论。话虽如此,你是对的,在这种情况下,你不应该看到太多的重复。
我不太熟悉“#语用omp并行”,但我猜您正在生成多个线程,所有这些线程都用相同的种子(0)启动mt19937。您应该对所有线程使用不同的种子,例如线程id。
https://stackoverflow.com/questions/16016432
复制相似问题