Java 生成泊松和二项式随机数的算法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1241555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Algorithm to generate Poisson and binomial random numbers?
提问by
i've been looking around, but i'm not sure how to do it.
我一直在环顾四周,但我不知道该怎么做。
i've found this pagewhich, in the last paragraph, says:
我找到了这个页面,在最后一段中,它说:
A simple generator for random numbers taken from a Poisson distribution is obtained using this simple recipe: if x1, x2, ... is a sequence of random numbers with uniform distribution between zero and one, k is the first integer for which the product x1· x2· ... · xk+1< e-λ
从泊松分布中提取的随机数的简单生成器使用以下简单方法获得:如果 x 1, x 2, ... 是在 0 和 1 之间均匀分布的随机数序列,则 k 是第一个整数乘积 x 1· x 2· ... · x k+1< e -λ
i've found another pagedescribing how to generate binomial numbers, but i think it is using an approximation of poisson generation, which doesn't help me.
我发现另一个页面描述了如何生成二项式数,但我认为它使用的是泊松生成的近似值,这对我没有帮助。
For example, consider binomial random numbers. A binomial random number is the number of heads in N tosses of a coin with probability p of a heads on any single toss. If you generate N uniform random numbers on the interval (0,1) and count the number less than p, then the count is a binomial random number with parameters N and p.
例如,考虑二项式随机数。二项式随机数是在 N 次抛硬币中正面出现的次数,在任何一次抛掷中出现正面的概率为 p。如果在区间 (0,1) 上生成 N 个均匀随机数,并对小于 p 的数进行计数,则该计数为参数为 N 和 p 的二项式随机数。
i know there are libraries to do it, but i can't use them, only the standard uniform generators provided by the language (java, in this case).
我知道有库可以做到这一点,但我不能使用它们,只能使用语言提供的标准统一生成器(在这种情况下为 java)。
采纳答案by Kip
Poisson distribution
泊松分布
Here's how Wikipedia says Knuth says to do it:
下面是维基百科说,克努特说,这样做:
init:
Let L ← e^(?λ), k ← 0 and p ← 1.
do:
k ← k + 1.
Generate uniform random number u in [0,1] and let p ← p × u.
while p > L.
return k ? 1.
In Java, that would be:
在 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;
}
Binomial distribution
二项分布
Going by chapter 10 of Non-Uniform Random Variate Generation(PDF)by Luc Devroye (which I found linked from the Wikipedia article) gives this:
通过 Luc Devroye的Non-Uniform Random Variate Generation(PDF)的第 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;
}
Please note
请注意
Neither of these algorithms is optimal. The first is O(λ), the second is O(n). Depending on how large these values typically are, and how frequently you need to call the generators, you might need a better algorithm. The paper I link to above has more complicated algorithms that run in constant time, but I'll leave those implementations as an exercise for the reader. :)
这两种算法都不是最优的。第一个是 O(λ),第二个是 O(n)。根据这些值通常有多大,以及您需要调用生成器的频率,您可能需要更好的算法。我链接到上面的论文有更复杂的算法,这些算法在恒定时间内运行,但我会将这些实现留给读者作为练习。:)
回答by Pablojim
For this and other numerical problems the bible is the numerical recipes book.
对于这个和其他数字问题,圣经是数字食谱书。
There's a free version for C here: http://www.nrbook.com/a/bookcpdf.php(plugin required)
这里有 C 的免费版本:http: //www.nrbook.com/a/bookcpdf.php(需要插件)
Or you can see it on google books: http://books.google.co.uk/books?id=4t-sybVuoqoC&lpg=PP1&ots=5IhMINLhHo&dq=numerical%20recipes%20in%20c&pg=PP1#v=onepage&q=&f=false
或者你可以在谷歌图书上看到它:http: //books.google.co.uk/books?id=4t-sybVuoqoC&lpg=PP1&ots=5IhMINLhHo&dq=numeric%20recipes%20in%20c&pg=PP1#v=onepage&q=&f=false
The C code should be very easy to transfer to Java.
C 代码应该很容易转移到 Java。
This book is worth it's weight in gold for lots of numerical problems. On the above site you can also buy the latest version of the book.
这本书对于许多数值问题来说是值得的。您还可以在上述网站上购买该书的最新版本。
回答by Miguel ángel Martínez
There are several implementations from CERN in the following library (Java code):
在以下库(Java 代码)中有几个来自 CERN 的实现:
http://acs.lbl.gov/~hoschek/colt/
http://acs.lbl.gov/~hoschek/colt/
Concerning binomial random numbers, it is based on the paper from 1988 "Binomial Random Variate Generation", that I recommend to you since they use an optimized algorithm.
关于二项式随机数,它基于 1988 年“二项式随机变量生成”的论文,我向您推荐该论文,因为它们使用了优化算法。
Regards
问候
回答by Ashutosh Gupta
Although the answer posted by Kip is perfectly valid for generating Poisson RVs with small rate of arrivals (lambda), the second algorithm posted in Wikipedia Generating Poisson Random variablesis better for larger rate of arrivals due to numerical stability.
尽管 Kip 发布的答案对于生成具有小到达率 (lambda) 的泊松 RV 是完全有效的,但由于数值稳定性,维基百科生成泊松随机变量中发布的第二种算法更适合较大的到达率。
I faced problems during implementation of one of the projects requiring generation of Poisson RV with very high lambda due to this. So I suggest the other way.
由于这个原因,我在实施需要生成具有非常高 lambda 的泊松 RV 的项目之一期间遇到了问题。所以我建议换一种方式。
回答by abolfazl bazghandi
you can add this to build.gradle
您可以将其添加到 build.gradle
implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'
and use class PoissonDistributionmore detail for class PoissonDistribution
并使用类PoissonDistribution为类 PoissonDistribution 提供更多详细信息