我需要一个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;
}
答案 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快速选择值。