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



我有一个Java模拟,我需要使用UniformExponentialPoissonGamma分布 - 我需要使用相同的种子初始化随机流和/或这些分布中的每一个(这样我就可以准确地重现给定固定种子的轨迹)。

我正在使用并行柯尔特(这是柯尔特的多线程版本)。

对于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)
构造一个伽马分布。

有没有办法初始化这些(ExponentialPoissonGamma),就像我对Uniform所做的那样?或者我应该实例化一个父/基类(如果是这样,如何?)cern.jet.random.tdouble所有这些类都已从中扩展?

笔记:

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

看起来DoubleMersenneTwister扩展了 DoubleRandomEngine,允许您在其构造函数中设置种子。

各种随机变量生成都以 Uniform(0,1) 随机数开头。ExponentialPoissonGamma的构造函数中的最后一个参数是让你提供一个扩展DoubleRandomEngine抽象类的 Uniform(0,1) 的源。 看起来Parallel Colt提供了六个这样的实现。 您需要选择其中之一,为要生成的每个分配创建一个单独但种子相同的实例,然后使用您创建的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());
}
}
}

由于Exponential级将"发动机"产生的制服流转换为指数RV,并且制服的种子相同,因此指数实际上是相同的种子。

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

在用nextDouble()替换staticNextDouble()调用后,我现在可以准确地重现给定固定外部种子的轨迹。

相关内容

  • 没有找到相关文章

最新更新