二項分佈。計算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層):

化簡以後爲:

再次化簡

因此最後程序遞歸調用的總次數爲

 

運行隨機驗證幾個組合,能夠證實上述公式是正確的!

相關文章
相關標籤/搜索