java - 使用泊松分布生成一个范围内的随机数
问题描述
我需要泊松分布。
目前我有以下代码:
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;
}
解决方案
如果您只想在具有固定(或很少更改)的 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
}
}
或者使用别名方法来快速取值。
推荐阅读
- python - 使用熊猫从不同列中的值较大的行中打印列中的最小值
- html - mailto 链接无法使用 Bootstrap
- sql - 使用 BETWEEN 填充记录
- assembly - SASM 立即关闭(NASM Windows 10)
- sql - Linux上的Postgres文字回车错误
- android - 关闭图库而不关闭应用程序 [Android]
- angular - 除非我使用 changeDetection onpush 调用 detectChanges(),否则 HTML 模板不会更新
- netsuite - Netsuite Restlet 脚本用户注释链接
- c# - Windows 窗体富文本框。如何在“rtf”中查找粗体、下划线和其他文本格式并为 3rd 方供应商插入其他标签
- r - 错误:软件包是由具有不同内部结构的 R 版本安装的;它需要重新安装