要求:估计用以下代码计算binomial(100, 50, 0.25)的次数
private static double binomial(int N, int k, double p){ if(N == 0 && k == 0) return 1.0; if(N < 0 || k < 0) return 0.0; return (1.0 - p)*binomial(N-1, k, p) + p*binomial(N-1, k-1, p);}
解析:
约分即得到组合数递推公式

问题:
该方法一个递归就产生两个子递归,运算量非常大,如题数据会一直计算无法得到结果
改进方法:
思路:
已知二项概率公式和组合数公式
=C_N^kp^k(1-p)^{N-k}#)
!}#)
先计算组合数,但当N较大很大时,阶乘会超出int类型值域,所以需要每次乘一项后就约分为最简形式,可以使用求最大公约数的算法
例:

pubilc class Ex1_1_27{ //计算组合数 private static double Combine(int X, int Y, int Z){ if(x == 0 && Y == 0 && Z == -1){ return 1; } if(x == 0) x = 1; if(Y == 0) Y = 1; if(Z == 0) Z = 1; int a = Euclid(X, Y*Z); return Combine((x*1.0/a)/(Y*Z/a));//强转或x*1.0,否则返回int } //计算概率 private static double binomial(int N, int k, double p){ double p1 = 1; double p2 = 1; for(int i = 1; i <= k; i++){ p1 *= p; } for(int i = 1; i <= (N-k); i++){ p2 *= 1-p; } double C = Combine(N, k, N-k); return C * p1 * p2; } public static void main(String[] args){ System.out.println(binomial(100, 50, 0.25)); //概率:6.828252801404798E-91 }}