首页 > 解决方案 > 使用泊松分布生成一个范围内的随机数

问题描述

我需要泊松分布

目前我有以下代码:

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;
}

标签: javamathpoisson

解决方案


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

一些伪代码:

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
  }
}

或者使用别名方法来快速取值。


推荐阅读