使用泊松分布在范围内生成随机数

时间:2019-02-09 20:35:36

标签: java math poisson

我需要一个Poisson distribution

当前我有以下代码:

public static int getPoisson(double lambda) {
    double l = Math.exp(-lambda);
    double p = 1.0;
    int k = 0;

    do {
        k++;
        p *= Math.random();
    } while (p > l);

    return k - 1;
}

我想知道如何修改它,以便可以在定义的范围内生成x个值,例如,如果a = 5,b = 10和lambda = 6,则所有生成的值都将落在5至10。

注意:我可以重载该方法,从而接受范围参数,并在循环内调用getPossion方法;丢弃任何不适合此范围的东西。但是,我想检查一下是否有数学定义的方法可以实现这一目标和/或该方法是否合适。

编辑:丢弃“超出范围”值的方法:

public static int getPoisson(final double min, final double max, final double lambda) {
    int k = 0;
    do {
        k = getPoisson(lambda);
    } while (k < min || k > max);
    return k;
}

1 个答案:

答案 0 :(得分:0)

如果您只希望在给定范围内以固定(或很少改变)λ的概率获得很小范围内的一些整数,最简单的方法是为每个数字保留概率表并进行有偏抽样。

一些伪代码:

public class BoundedSampler {
  private final int min;
  private final double[] table;

  public BoundedSampler(int min, int max, double lambda) {
    this.min = min;
    this.table = new double[max - min + 1];

    double cumulative = 0;
    for(int x = min; x <= max; ++x) {
      double prob = probability(x, lambda);
      table[x - min] = cumulative + prob;
      cumulative += prob;
    }

    for(int i = 0; i < table.length; ++i) {
      table[i] /= cumulative;
    }
  }

  public int sample() {
    double r = Math.random();
    for(int i = 0; i < table.length; ++i) {
      if(table[i] <= r) {
        return i + min;
      }
    }
    return -1; // impossible: last table value == 1
  }
}

或使用alias method快速选择值。