【问题标题】:Estimating number of recursive calls in binomial function (Sedgewick Algorithms, 4th Edition)估计二项式函数中的递归调用次数(Sedgewick 算法,第 4 版)
【发布时间】:2021-06-15 05:57:11
【问题描述】:

Robert Sedgewick 的“算法,第 4 版”的练习 1.1.27 的一部分是估计此函数进行的递归调用次数:

public static double binomial(int n, int k, double p) {
    if((n == 0) && (k == 0)) return 1;
    if((n < 0) || (k < 0)) return 0;
    return (1 - p) * binomial(n - 1, k, p) + p * binomial(n - 1, k - 1, p);
}

如下调用时:binomial(100, 50, 0.25).

不幸的是,我不知道在解决这类问题时我的思维过程应该是什么。我曾考虑用较小的值运行该方法以希望找到一种模式,但我不知道如何将其关联起来,因为有 3 个不同的变量,其中两个会影响递归基本情况。

如果有人能提供有关如何解决此问题的见解,我将不胜感激。

【问题讨论】:

  • 我建议您从调用函数时计算机所做的事情开始 - 评估它。尝试在参数中输入“100,50,0.25”,看看下一次递归调用会是什么。然后尝试执行下一次迭代。进行大约 10-20 次深度迭代,您就会开始了解需要多长时间。
  • 注意递归调用的次数不依赖于p。
  • k = 0解决它。然后求解k = 1。然后k = 2。继续前进,直到你看到一个模式。

标签: algorithm time-complexity


【解决方案1】:

只是一些小技巧,希望对你有所帮助:

  1. 递归的终点是p * binomial(N - 1, k - 1, p)
  2. 当计算遇到第一个端点时,它有 N 层用于循环包装。
  3. 结合 1 和 2,我们可以推断出 T(N) = N * T(N - 1)

所以 1.1.27 的估计是 N!,AKA 100!

【讨论】:

    【解决方案2】:

    如果你真的很难理解模式,你可以通过改变代码本身来计算,以便很容易地为你提供递归次数:

    double binomial(int n, int k, double p) {
        if ((n == 0) && (k == 0)) 
            return 0;
    
        if ((n < 0) || (k < 0)) 
            return 0;
    
        return binomial(n - 1, k, p) + binomial(n - 1, k - 1, p) + 2;
    }
    

    另一个提示,尝试找到递归的实际终点以及它对 k 和 n 的含义(注意 k 并不总是为 0,并尝试了解何时以及模式是什么)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2014-12-01
      相关资源
      最近更新 更多