【问题标题】:Numerical algorithm to generate numbers from Binomial distribution从二项分布生成数字的数值算法
【发布时间】:2009-11-13 11:43:53
【问题描述】:

我需要从 Binomial(n, p) 分布中生成随机数。

Binomial(n, p) 随机变量是 n 个均匀变量的总和,这些变量以概率 p 取 1。在伪代码中,x=0; for(i=0; I<n; ++I) x+=(rand()<p?1:0); 会生成一个 Binomial(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;
        }
    }

【问题讨论】:

  • 泊松分布是否适用于n * p &lt; 10n * (1 - p) &lt; 10?您是如何选择该发行版的?
  • 是的,对于大 n。 Binomial(n,lambda/n) 收敛到 Poisson(lambda),因为 n 趋于无穷大。

标签: c# random


【解决方案1】:

另一种选择是像您一样从 Normal 或 Poisson 采样,然后添加 Metropolis-Hastings 步骤来接受或拒绝您的样本。如果你接受你就完成了,如果你拒绝,你必须再次完全重新采样。我的猜测是,因为近似值非常接近,你几乎总是会得到一个接受步骤,偶尔你可能会拒绝。

Luc Devroye's book 也有一些很棒的二项式采样算法。

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

【讨论】:

    【解决方案2】:

    如果您愿意付费,请查看 Centerspace 的NMath

    否则,Stats 程序 R 使用的 C 代码是 here,应该可以直接移植到 C#。

    编辑:Jack Xu 在Practical Numerical Methods with C# 的 p178 上有关于为此创建方法的详细信息(包括代码)。

    另一个编辑:A free C# library 可以满足您的需求。

    【讨论】:

      【解决方案3】:

      没有明显的方法可以有效地做到这一点。对于小的 n,您不妨只使用计算逆 PDF 的公式。对于较大的 n,您可能最好使用更容易计算的 approximations to other distributions 之一。

      【讨论】:

      • 我实际上正在使用我编写的一些使用泊松和正态分布的临时近似例程。但是,我不确定它生成的数字在统计上与真正的二项式相差多远。我已将我的代码添加为编辑。
      猜你喜欢
      • 2013-02-07
      • 2012-04-21
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 2018-10-19
      • 1970-01-01
      相关资源
      最近更新 更多