繁体   English   中英

二项式系数。 递归树。 如何避免多次计算相同的值

[英]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

计算下一行的算法的工作原理如下:

  • 将 1 保存在临时变量中。
  • 将 4 保存在临时变量中,并将 4 替换为 4 + 1(临时变量的先前值)。
  • 将6存入一个临时变量中,将6替换为6+4(临时变量之前的值)
  • 将 4 保存在一个临时变量中,并将 4 替换为 4 + 6(之前的值......我想你可以弄清楚这是怎么回事)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM