C#:从二项分布生成数字的数值算法

Kal*_*lEl 8 c# numerical

我需要从二项式(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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jur*_*gen 5

另一种选择是从正常或泊松中采样,然后添加Metropolis-Hastings步骤来接受或拒绝您的样本.如果您接受完成,如果拒绝,则必须再次完全重新取样.我的猜测是因为近似值非常接近,所以你几乎总会得到一个接受步骤,偶尔你会拒绝.

此外吕克·德夫罗伊的书有二项分布抽样一些伟大的算法.

PS如果你最终得到一个好的算法; 你介意在Math.Net Numerics上分享吗?


Ric*_*ton 4

如果你愿意付费,那么可以看看Centerspace 的NMath 。

否则,统计程序 R 使用的 C 代码位于此处,并且应该可以直接移植到 C#。

编辑: Jack Xu 的《C# 实用数值方法》第 178 页上有关于为此创建方法的详细信息(包括代码) 。

另一个编辑:一个免费的 C# 库,可以满足您的需求。