使用相同的种子或相同的随机流初始化多个分布?

时间:2017-04-04 22:18:06

标签: java random simulation colt

我有一个Java模拟,我需要使用UniformExponentialPoissonGamma发行版 - 我需要初始化随机流和/或者每个具有相同种子的分布(这样我就可以完全重现一个轨迹给定一个固定的种子)。

我正在使用Parallel Colt(这是Colt的多线程版本)。

对于Uniform,我可以将DoubleUniform对象(从cern.jet.random.tdouble.DoubleUniform导入后)正确播种为:

int fixedSeed = 12345;
doubleUniformDist = new DoubleUniform (0.0, 1.0, fixedSeed);

但是,对于ExponentialPoissonGamma发行版(全部在cern.jet.random.tdouble中),我无法通过fixedSeed传递相同内容 - 因为他们希望传递DoubleRandomEngine个对象:

  

构造函数摘要

     

Exponential(double lambda, DoubleRandomEngine randomGenerator)   
  构造负指数分布。

     

Poisson(double mean, DoubleRandomEngine randomGenerator)   
  构造泊松分布。

     

Gamma(double alpha, double lambda, DoubleRandomEngine randomGenerator)   
  构造一个Gamma分布。

有没有办法像Exponential一样初始化这些(PoissonGammaUniform)?或者我应该在cern.jet.random.tdouble中实例化一个父/基类(如果是,如何?),从中扩展了所有这些类?

注意:

  1. 同样,我想要一个随机的流(所以我的所有 分布可以使用该流中的随机数) - 这是 对于重复性非常重要。
  2. 示例模拟可能需要数百万次(总计)对这些分布进行采样 - 因此性能/速度始终是一个问题。

3 个答案:

答案 0 :(得分:0)

它看起来像DoubleMersenneTwister,它扩展了DoubleRandomEngine,允许你在它的构造函数中设置一个种子。

答案 1 :(得分:0)

所有种类的随机变量生成始于统一(0,1)随机数。 ExponentialPoissonGamma的构造函数中的最后一个参数是为了提供一个统一(0,1)的源,它扩展了{{1抽象类。它看起来像Parallel Colt provides half a dozen such implementations。您需要选择其中一个,为要生成的每个分发创建一个单独但相同的种子实例,然后使用您创建的DoubleRandomEngine个实例之一构造每个分发对象。这样,底层的统一值流将是相同的,并且可以适当地转换为您想要的分布。

这是一个相当简约的实现:

DoubleRandomEngine

由于import cern.jet.random.tdouble.*; import cern.jet.random.tdouble.engine.*; public class RNG { public static void main(String[] args) { // create two instances of Mersenne Twister, seeded identically DoubleRandomEngine twister1 = new DoubleMersenneTwister(42); DoubleRandomEngine twister2 = new DoubleMersenneTwister(42); // print ten values from each, to show they produce identical U(0,1)'s' for(int i = 0; i < 10; ++i) { System.out.println(twister1.nextDouble() + ", " + twister2.nextDouble()); } System.out.println("\nNow for some exponentials...\n"); // instantiate two exponentials using our two twisters as the // underlying random engine Exponential exp1 = new Exponential(3, twister1); Exponential exp2 = new Exponential(3, twister2); // and print 10 of 'em to show they're synchronized. for(int i = 0; i < 10; ++i) { System.out.println(exp1.nextDouble() + ", " + exp2.nextDouble()); } } } 类转换了由&#34;引擎&#34;生成的所提供的制服流。在指数RV中,制服的种子相同,指数实际上是相同的种子。

答案 2 :(得分:0)

全部,谢谢 - 我修好了。看起来我之前得到的变化数字是由于我使用staticNextDouble()方法 - 这不适合我的目的,因为staticNextDouble()使用随机数生成器的内部/默认种子,绕过固定的外部我供应的种子。

staticNextDouble()替换nextDouble()次来电后,我现在可以精确地重现给定固定外部种子的轨迹。