使用 Mersenne Twister (C++)

问题描述

我有一个 Monte Carlo 代码,需要使用 MPI 并行运行许多模拟。我想确定每次模拟中生成的数字属于不同的序列。

这是我写的一个非常简单的“测试”,但我不确定它是否真的测试了我所描述的内容

#include <mpi.h>
#include <time.h>
#include <random>

int rank;
//std::random_device rd; std::mt19937 mt(rd()) I used this before
std::mt19937 mt(clock()+rank);

int main(int argc,char* argv[])
{

  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  std::uniform_int_distribution<int> RandInt(0,100);  
  int xx = RandInt(mt);
  std::cout << rank << ":\t" << xx << "\t" << mt() << std::endl;

  MPI_Finalize();
  return 0;
}

执行这个程序三次给了我:

1:  57  3629598283
3:  70  877812043
0:  55  871110422
2:  60  603182895

3:  5   3326625701
2:  72  2574563463
1:  59  1557541786
0:  53  2000448965

0:  16  574716192
1:  53  3847148496
2:  54  3235101660
3:  23  2433046543

我编写这个程序的方式是否意味着每个线程都会实例化每个自己的随机生成器?这是否安全并保证不同的数字序列?而且,如果有的话,使用注释行 std::random_device rd; std::mt19937 mt(rd()) 有什么区别?

编辑

有关该计划的更多详细信息。

每次运行中的随机数都是在 main.cpp 和另一个文件 mclib.cpp生成的。随机生成器位于头文件 mclib.hpp 中。

ma​​in.cpp

#define MAIN
#include "mclib.hpp"
#include <mpi.h> //etc 

int main(){
 MPI_Init(&argc,&argv);
 MPI_Comm_rank(MPI_COMM_WORLD,&rank);

//choose random point
 std::uniform_int_distribution<int> RandInt(0,100);  
 int xx = RandInt(mt);

//calculate energy differences and check metropolis criterion
// double dE = ... 
bool accept = metropolis(dE);


 MPI_Finalize();
 return 0;
}

mclib.cpp

bool metropolis(double dE){
 std::uniform_int_distribution<double> RandDouble(0,1);
double epsilon = RandDouble(mt);
//compare epsilon with boltzmann factor or accept if dE<0
... 
} 

mclib.hpp

#ifdef MAIN
int rank;
std::mt19937 mt(clock()+rank);
#else
extern int rank;
extern std::mt19937 mt;
#endif

我需要为每次模拟播种两次吗?一次进入main.cpp,另一次进入mclib.cpp

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)