2009-11-13 8 views
8

二項分布(n、p)から乱数を生成する必要があります。C#:二項分布から数値を生成する数値アルゴリズム

確率変数は、確率pで1をとるn個の均一変数の合計です。擬似コードでは、x=0; for(i=0; i<n; ++i) x+=(rand()<p?1:0);は、二項(n、p)を生成します。

これは、n = 10^6やp = 0.02のように小さくて実際に大きなnに対して生成する必要があります。それを生成する任意の高速数値アルゴリズムはありますか?

EDIT -

今これは私が(正確なポアソンと正規分布のための関数と一緒に)近似値として持っているものである -

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

ポアソン分布は、 'n * p <10'や' n *(1-p)<10'でうまくいくのでしょうか?どのようにあなたはその流通を選ぶでしょうか? – HelloGoodbye

+0

はい、大規模なnの場合。 nが無限大になると、二項(n、λ/ n)はポアソン(λ)に収束する。 – KalEl

答えて

4

お支払いをご希望の場合は、CenterspaceのNMathをご覧ください。

それ以外の場合、StatsプログラムRで使用されるCコードはhereであり、C#に移植するのは簡単です。

EDIT:Jack Xuのp178のPractical Numerical Methods with C#の方法を作成する際の詳細(inc。コード)があります。

別の編集:A free C# libraryあなたが望むことをします。

3

明白な方法はありませんこれを効率的に行う。小さなnについては、逆PDFを計算する公式を使用することもできます。より大きいnの場合は、計算しやすいapproximations to other distributionsのいずれかを使用するのが最も良いでしょう。

+0

私はPoissonとNormalの分布を使って書いた暫定的な近似ルーチンを実際に使っています。しかし、私はそれが生成する数値が真の二項から統計的にどれだけ離れているかは分かりません。コードを編集として追加しました。 – KalEl

4

また、ノーマルまたはポアソンからサンプルを採取してからMetropolis-Hastingsの手順を追加して、サンプルを受け入れるか拒否することもできます。あなたが受け入れた場合、あなたが拒否したら、あなたは完全に再サンプリングする必要があります。私の推測では、近似がとても近いので、ほとんどの場合、受け入れのステップが得られます。

Luc Devroye's bookには、二項サンプリングのアルゴリズムがあります。

PS良いアルゴリズムになったら、 Math.Net Numericsで共有してもよろしいですか?

関連する問題