Java 生成泊松和二项式随机数的算法?
我一直在四处寻找,但不知道怎么做 我发现,在最后一段中,它说: 从泊松分布中提取的随机数的简单生成器使用以下简单方法获得:如果x1,x2。。。是在0和1之间均匀分布的随机数序列,k是乘积为x1·x2·的第一个整数xk+1Java 生成泊松和二项式随机数的算法?,java,math,probability,random,poisson,Java,Math,Probability,Random,Poisson,我一直在四处寻找,但不知道怎么做 我发现,在最后一段中,它说: 从泊松分布中提取的随机数的简单生成器使用以下简单方法获得:如果x1,x2。。。是在0和1之间均匀分布的随机数序列,k是乘积为x1·x2·的第一个整数xk+1
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;
}
二项分布 按照Luc Devroye的第10章(我从中找到链接)给出:
public static int getBinomial(int n, double p) {
int x = 0;
for(int i = 0; i < n; i++) {
if(Math.random() < p)
x++;
}
return x;
}
public static int getBinomial(int n,双p){
int x=0;
对于(int i=0;i
请注意
这两种算法都不是最优的。第一个是O(λ),第二个是O(n)。根据这些值通常有多大,以及调用生成器的频率,可能需要更好的算法。我在上面链接的那篇文章有更复杂的算法,它们在固定时间内运行,但我将把这些实现留给读者作为练习。:) 对于这个和其他数值问题,《圣经》是数值食谱书 这里有一个C的免费版本:(需要插件) 或者你可以在谷歌图书上看到: C代码应该很容易传输到Java
对于许多数值问题,这本书是值得的。在上述网站上,您还可以购买该书的最新版本。以下库中有来自CERN的几个实现(Java代码): 关于二项式随机数,我向您推荐的是基于1988年“二项式随机变量生成”的论文,因为它们使用了优化算法
关于尽管Kip发布的答案对于生成具有小到达率(lambda)的泊松RVs是完全有效的,但维基百科发布的第二种算法对于更大的到达率更好,因为数值稳定性
由于这一点,我在执行一个项目时遇到了问题,该项目要求生成具有非常高λ的泊松RV。所以我建议另一种方法。您可以将此添加到build.gradle
implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'
并使用类泊松分布
数字配方(第三版)一书对产生泊松和二项式偏差有完整的解释。其他一些可用的库也给出了:数字配方书不是免费的。您需要有密码才能解锁PDF文件。@Kip在您的第一个示例中,L代表Lambda,P代表什么?@AkshatAgarwal实际上L代表e^(−拉姆达)。p只是一个介于0和1之间的数字。在每次迭代中,它会被随机量减少(当它被0到1之间的随机数乘以时),直到p小于L为止。λ越大,L越小(接近0),这意味着在p小于L之前,我们将平均经历更多的循环迭代。lambda有限制吗?当我通过1000或2000分时,我的平均成绩是745分。如果我通过较低的数字,结果似乎是正确的。
implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'