二项分布。计算binomial(100,50,0.25)将会产生的递归调用次数(算法第四版1.1.27)

算法第四版35页问题1.1.27,估计用一下代码计算binomial(100,50,0.25)将会产生的递归调用次数:算法

public 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)      
}

虽然书上只让估计调用次数,可是以为想知道到底调用了几回。函数

 

我用图画出递归调用的状况spa

 

能够看出递归中有不少重复调用好比,第4层递归 分别调用了binomial(n-3,k-1,p)和binomial(n-3,k-2,p)三次。这就是这个算法效率低的缘由。能够看出重复调用的次数是一个杨辉三角3d

根据杨辉三角的性质,code

第m层递归函数被调用的状况为:blog

第m层第x(x<=m)项为:递归

可是有些调用实际上不会发生,结合函数的返回条件:get

if(n == 0 && k == 0) return 1.0;
if(n<0 || k<0) return 0.0;

 

设咱们传入的初始参数为n=N,k=K 则,能够得出已下结论:it

  1. 当m=N+1且x=K+1时,知足程序退出的第一个条件;
  2. 当m>N+1或x>K+1时,知足程序退出的第二个条件(根据杨辉三角的性质,第m行有m项,全部此时有K+1<x<=m)

让咱们看看知足以上结论的详细项:class

  1.下列递归调用的x>K+1,知足结论2:

    •   m=K+2行的第K+2项:
    •   m=K+3行的第K+2项到K+3项:
    •   ……
    •   m=N+1行的第K+2项到最后一项:

  2.m=N+1行的第K+1项递归调用的第一个参数n和第二个参数k均为0,知足结论1。

  3.当m=N+2时,显然m>N+1,知足结论2;

 

若是调用参数知足函数退出条件,那么由调用的递归实际上就不会发生,数量为的系数✖️2。

N+2以后的递归都不会发生,因此作计算时只考虑到N+2层。N+2层的无效调用数量,为N+1层知足结论1或2的调用的数量*2,一次类推,直到K+3层的无效调用数量,为K+2层知足结论1或2的调用数量*2;K+2层到1层上,全部调用都有效;由于K+1层到1层,没有调用知足结论1或2.

根据杨辉三角的性质:从第1层到第N+2层全部的系数和为 

 

其中不会实际发生的调用次数为从(K+2层到N+1层):

化简以后为:

再次化简

因此最后程序递归调用的总次数为

 

运行随机验证几个组合,能够证实上述公式是正确的!

相关文章
相关标签/搜索