このペーパーの主な内容は、次のように、Javaプログラミングの二項分布の再帰的かつ非回復的な実装です。
問題の原因:
アルゴリズムのセクション1.1の第4版の演習27、セクション1.1:return(1.0 -p) *二項(n -1、k、p) + p *二項(n -1、k -1、p);
再帰呼び出しの数を計算します。再帰フォーミュラはここからどのようにして来ましたか?
二項分布:
定義:n独立したyes/非実験の成功時間kの離散確率分布、各実験での成功の確率はp(n、p、k)として示されます。
確率式:p(ξ= k)= c(n、k) * p^k *(1-p)^(nk)
ここで、c(n、k)=(nk)!/(k! *(nk)!)は、ξ〜b(n、p)、期待:eξ= np、分散:dξ= npq、q = 1-p。
確率統計には再帰式があります。
これは、質問の再帰形式の原因です。
再帰式は、c(n、k)= c(n-1、k)+c(n-1、k-1)からのものです。実際のシナリオは、n個の個人からkを選択することです。組み合わせはいくつありますか? n人を1からnまで整理します。 KTH ONEが選択されていない場合は、残りのN-1人からkを選択する必要があります。 KTH ONEが選択されている場合、残りのN-1人からK-1を選択する必要があります。
本の二項分布の再帰的実装:
public static double binomial(int n、int k、double p){count ++; //再帰コールの数を記録する場合(n == 0 && k == 0){return 1.0; } if(n <0 || k <0){return 0.0; } return(1.0 -p) *二項(n -1、k、p) + p *二項(n -1、k -1、p); }実験結果:
NKPコール数10 5 0.25 246720 10 0.25 243553830 15 0.25 2440764535
結果から、この再帰的な方法を呼び出す必要がある回数は幾何学的災害であり、たとえ50を50であっても考慮されていなくても、私たちは見ることができます。
二項分布の改善再帰実装:
private static long count = 0; private static double [] [] m; private static double binomial(int n、int k、double p){count ++; if(n == 0 && k == 0){return 1.0; } if(n <0 || k <0){return 0.0; } if(m [n] [k] == -1){//計算結果を保存して計算した場合は直接使用します。m[n] [n] [k] =(1.0 -p) *二項(n -1、k、p) + p *二項(n -1、k -1、p); } return m [n] [k]; } public static double binomial(int n、int k、double p){m = new double [n + 1] [k + 1]; for(int i = 0; i <= n; i ++){for(int j = 0; j <= k; j ++){m [i] [j] = -1; }} return binomial(n、k、p); }実験結果:
NKPコール数10 5 0.25 10120 10 0.25 45230 15 0.25 120350 25 0.25 3204100 50 0.25 5205
実験結果から、呼び出しの数が大幅に減少し、アルゴリズムを使用できることがわかります。
二項分布の非回転率の実装:
実際、再帰を使用する代わりに、複合数と要因を直接計算するのが高速です。
//組み合わせの数を計算しますパブリック静的二重組み合わせ(ダブルN、ダブルK){double min = k; double max = nk;ダブルT = 0; double nn = 1; double kk = 1; if(min> max){t = min; min = max; max = t; } while(n> max){//分母の大部分の因子を計算する必要はありませんnn = nn*n; n - ; } while(min> 0){//小さい部分の要因を計算しますkk = kk*min; min--; } nn/kkを返します。 } //二項分布値を計算するパブリック静的二重二項(int n、int k、double p){double a = 1; double b = 1;ダブルC =コンビネーション(n、k); while((nk)> 0){//(1-p)a = a*(1-p)の(nk)電力を計算します。 n - ; } while(k> 0){// p b = b*pのk電力を計算します。 k--; } c*a*bを返します。 }実験結果:
NKP二項分布値10、5、0.25 0.0583920043945312520、10、0.25 0.00992227527967770650、25、0.25 8.44919466990397E-55
前のアルゴリズムと比較すると、計算結果は正しく、走行速度は非常に高速です。
要約します
上記は、Javaプログラミングの二項分布の再帰的および非再帰的実装コードの例に関するこの記事の全体的な内容です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!