【问题标题】:How to solve: T(n) = T(n/2) + T(n/4) + T(n/8) + (n)如何求解:T(n) = T(n/2) + T(n/4) + T(n/8) + (n)
【发布时间】:2011-08-03 10:48:54
【问题描述】:

我知道如何为只调用自己一次的算法做递归关系,但我不确定如何做一次多次调用自己的事情。

例如:

T(n) = T(n/2) + T(n/4) + T(n/8) + (n)

【问题讨论】:

  • 应该去cstheory 一个 - 你如何推荐迁移问题?
  • “做重复关系”是什么意思?
  • @Claudiu - 你会标记它,但我怀疑这是一个研究级的 comp sci 问题
  • @Robin 类似this
  • 这不是CS理论问题,而是实际复杂性分析中的简单问题

标签: algorithm recursion recurrence


【解决方案1】:

就像编码斐波那契数列(困难方式)一样,您只需键入以下内容:

long fib(long n){
 if(n <= 1) return n; 
 else return fib(n-1) + fib(n-2);
}     

或者,更好的是,使用全局变量来记忆它以使其更快。再次使用斐波那契数列:

static ArrayList<Long>fib_global = new ArrayList(1000); 
  //delcare a global variable that can be appended to
long fib(long n){
   if(n >= fib_global.length)fib_global.add(fib(n-1) + fib(n-2));
   return fib_global.get(n);
}

代码一次只会执行其中一个调用,并且很可能按照您输入它们的从左到右的顺序执行,这样您就不必担心执行次数你需要打电话。

【讨论】:

    【解决方案2】:

    使用递归树。请参阅 CLRS“算法简介”中递归树的最后一个示例。

    T(n) = T(n/2) + T(n/4) + T(n/8) + n。根将是 n(cost) & 分为 3 个递归。所以递归树如下所示:

    T(n) = n = n T(n/2)T(n/4)T(n/8) (n/2) (n/4) (n/8) T(n/4)T(n/8)T(n/16)T(n/8)T(n/16)T(n/32)T(n/16)T(n/32)T( n/64)

                                                 n---------------------------------> n      
    
                                 (n/2)         (n/4)           (n/8)--------------> (7/8)n
    
                             n/4 n/8 n/16  n/8 n/16 n/32  n/16 n/32 n/64)--------> (49/64)n
                                                ...         
    

    最长路径:最左边的分支 = n -> n/2 -> n/4 -> ... -> 1

    最短分支:最右边的分支 = n -> n/8 -> n->64 -> ... -> 1

    叶子数(l):3^log_8(n) n^0.5

    查看树 - 直到 log_8(n) 级树已满,然后随着我们往下走,越来越多的内部节点不存在。通过这个理论,我们可以给出界限,

    T(n) = Big-Oh (求和 j=0 到 log_2(n)-1 (7/8)^j n) = ... => T(n) = O(n)。 T(n) = Big-Omega(求和 j=0 到 log_8(n)-1 (7/8)^j n) = ... => T(n) = Big-Omega(n)。

    因此,T(n) = Theta(n)。

    这里的要点是: T(n/2) 路径的长度最长...

    这不能是一棵完整的三叉树...高度 = n 的以 2 为底的对数 & # 叶子必须小于 n ...

    希望,这样你就可以解决问题了。

    【讨论】:

      【解决方案3】:

      有两种方法可以解决这个问题。一个是展开递归并找到可能需要创造性并且可能非常困难的相似之处。另一种方法是使用Akra-Bazzi method

      在这种情况下,g(x) = na1 = a2 = a3 = 1b1 = 1/2b2 = 1/4b3 = 1/8。解方程

      这是1/2^p + 1/4^p + 1/8^p = 1,你得到p = 0.87915。解积分你会得到,这意味着复杂度是:O(n)

      【讨论】:

        【解决方案4】:

        正如 CLRS 所说,T(n) 可以通过数学归纳法替换为cn。这种归纳假设适用于n 以下的数字。如上所述,我们需要证明的是参数值为n。因此,如下: 假设:T(n) &lt;= cn 代表下面的数字 n; 总结:

        T(n) = T(n/2) + T(n/4) + T(n/8) + n
            <= c/2*n + c/4*n + c/8*n + n
             = (7/8*c + 1) * n
            <= cn (when c >= 8)
        

        就是这样。

        【讨论】:

          【解决方案5】:

          查看图片以获得更好的解释-

          树的高度:我们采用 log(n)(base 2),因为与 n/4 和 n/8 相比,n/2 使树更长。我们的 GP 系列将持续到 k=logn(base)。

          【讨论】:

          • 为什么 n/2^k = 1 ?
          • 因为在某个时间点,一个特定的 k 值会导致这个表达式为 1。假设这样得到 k 的值,k 的值会让我们知道什么是树高度。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-03
          • 2021-02-27
          • 2011-02-14
          • 1970-01-01
          • 1970-01-01
          • 2013-01-10
          相关资源
          最近更新 更多