我需要从二项式(n,p)分布中生成随机数。
二项式(n,p)随机变量是n个均匀变量的总和,其中概率为1。在伪代码中,x=0; for(i=0; i<n; ++i) x+=(rand()<p?1:0);
将生成二项式(n,p)。
我需要为小的和非常大的n生成这个,例如n = 10 ^ 6和p = 0.02。是否有任何快速数值算法来生成它?
编辑 -
现在这就是我的近似值(以及精确泊松和正态分布的函数) -
public long Binomial(long n, double p) {
// As of now it is an approximation
if (n < 1000) {
long result = 0;
for (int i=0; i<n; ++i)
if (random.NextDouble() < p) result++;
return result;
}
if (n * p < 10) return Poisson(n * p);
else if (n * (1 - p) < 10) return n - Poisson(n * p);
else {
long v = (long)(0.5 + nextNormal(n * p, Math.Sqrt(n * p * (1 - p))));
if (v < 0) v = 0;
else if (v > n) v = n;
return v;
}
}
答案 0 :(得分:5)
另一种选择是从正常或泊松采样,然后添加Metropolis-Hastings步骤来接受或拒绝您的样本。如果您接受完成,如果拒绝,则必须再次完全重新取样。我的猜测是因为近似值非常接近,所以你几乎总会得到一个接受步骤,偶尔你会拒绝。
同样Luc Devroye's book有一些很好的二项式采样算法。
PS如果你最终得到一个好的算法;你介意在Math.Net Numerics分享吗?
答案 1 :(得分:4)
如果您愿意付费,请查看Centerspace的NMath。
否则,统计程序R使用的C代码为here,并且应该直接移植到C#。
编辑:杰克徐在Practical Numerical Methods with C#的p178上为此创建方法有详细信息(包括代码)。
另一个编辑:A free C# library做你想做的事。
答案 2 :(得分:3)
没有明显的方法可以有效地做到这一点。对于小n,您可能只是使用公式来计算逆PDF。对于较大的n,您可能最好使用更容易计算的approximations to other distributions之一。