Algs4-1.1.27二項分布
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);
}
將已經計算過的值保存在數組中並給出一個更好的實現。
答:
1)遞歸調用次數公式為:
本題的調用次數為將N=100,k=50代入上式。
解題過程如下,解題過程並非如下列描述如此順利。
依據上面代碼得到遞歸式:T(N,k)=T(N -1,k)+T(N -1,k-1)
依此遞歸式可以看出是一棵二叉樹,求遞歸調用的次數等同於求這棵二叉樹的節點個數。
通過代碼可以看出樹的最大深度為N +1,對於一棵高度為N +1的滿二叉樹,其節點總個數為2 N +1+1-1=2 N +2-1,所以得遞歸調用的次數的上界為2 N+2-1。
由於k的取值範圍為0<=k<=N,不同的k值對這棵二叉樹的節點數也有影響,影響到底有多大?先按遞歸式畫出下圖滿二叉樹:
觀察上圖,將節點中第二個參數值為k、k-1、k-2、k-3…的個數統計,得出下面的表格數據:
層次 |
k |
k-1 |
k-2 |
k-3 |
k-4 |
0 |
1 |
||||
1 |
1 |
1 |
|||
2 |
1 |
2 |
1 |
||
3 |
1 |
3 |
3 |
1 |
|
4 |
1 |
4 |
6 |
4 |
1 |
觀察以上表格發現除第一列外,每個單元格中的值=其上一行同列單元格的值+其上一行同列的左邊列的值,而這一特性與帕斯卡三角形具有相同性質,各單元格的值也符合二項式公式C(N,k)。
上表中K-X=-1開始至K-N-1的列中的所有單元格值的和即為不存在的節點。所以總的節點個數為滿二叉樹的節點個數減去上述個數,得以下公式:
2)將已計算的值存數組的實現方式:
public class Test
{
public static void main(String[] args)
{
int N=Integer.parseInt(args[0]);
int k=Integer.parseInt(args[1]);
double p=Double.parseDouble(args[2]);
double[][] b=new double[N+1][k+1];
//
b[0][0]=1;
//
for(int i=1;i<N+1;i++)
b[i][0]=b[i-1][0]*(1-p);
//
for(int i=1;i<N+1;i++)
for(int j=1;j<i+1 && j<k+1;j++)
b[i][j]=b[i-1][j]*(1-p)+b[i-1][j-1]*p;
StdOut.println(b[N][k]);
}
}
參考資料:
《離散數學及其應用》原書第7版中文版ISBN:9787111453826
《組合數學》原書第二版中文版ISBN:9787111377870
Algs4-1.1.27二項分布