[英]Binomial Coefficients. Recursion tree. How to avoid calculating same values multiple times
我正在使用名為BinomialCoefficients 的程序。
我在C(5,3)
上做了一個盒子跟蹤,它返回10
這是正確的,但我注意到在C(5, 3)
完整遞歸樹中,值C(3, 2)
被評估了 2 次,並且C(2, 1)
被評估 3 次。
什么可以修改以避免多次計算相同的值?
這里只是顯示上下文的函數。
public static int C(int n, int k) {
if(k>n)
return 0;
else if(k==0 || k==n)
return 1;
else
return C(n-1, k-1)+C(n-1, k);
}
一種修改是使用乘法公式。 但是你必須考慮整數溢出......(編輯:看看@ajb在評論中說了什么)
我建議使用 Map 來緩存結果:
Map<String, Integer> cache = new HashMap<>();
public static int C(int n, int k) {
String cacheKey=key(n,k);
if (cache.containsKey(cacheKey){
return cache.get(cacheKey);
if(k>n)
return 0;
else if(k==0 || k==n)
return 1;
else {
int result = C(n-1, k-1)+C(n-1, k);
cache.put(cacheKey, result);
return result ;
}
public String key(int n, int k){
return n +"_"+k;
}
當然,使用字符串作為鍵並不是最有效的方法,但我猜它仍然比一遍又一遍地重新計算相同的值要快得多。
一種解決方案是每次從頂部重建帕斯卡三角形,使用循環而不是遞歸。 您可能會執行一些不需要的添加。 我不確定有多少。 計算出您要計算的遞歸函數不需要多少C(i,j)
將是一個有趣的練習。 我猜測平均而言,不超過一半的計算值是不必要的,因此它仍然應該比重復重新計算相同值的遞歸方法更快,並且它可能比使用哈希表更快,它攜帶它自己的開銷。
您應該能夠“就地”計算每一行,而無需為每一行分配一個新數組,以使其盡可能高效。 假設您正在計算C(12,3)
; 三角形的第 13 行將有 13 個元素,因此您可以分配一個長度為 13 的數組開始,並在計算第 N 行時使用數組的前N
元素。 假設你已經計算了第 5 行,所以數組將是
[1, 4, 6, 4, 1, x, x, ...] // don't care about the x's
計算下一行的算法的工作原理如下:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.