(1) – Substitution Method

整个recurrence就是研究一个数学表达式:T(n) = aT(n/b)+f(n)   意思是先有一个问题T(n), 解决思路为把T(n)切分成a个小问题, 每个小问题的代价是T(n/b), 然后把a个T(n/b)的结果合并起来的代价是f(n);依次类推,直到T(k)的粒度小到其复杂度是一个常数。很像是递归吧~~递归只是一种实现方式,这里介绍的是一种思路和评估这种思路复杂度的方法。

经典的评估Recurrence的方法有3种,Substitutuon, Recursion Tree和Master Method.  看下面的命题:

T(n) = 4T(n/2) + n ,需要证明T(n)=O(n2 )

Substitution:

假设T(k) <= ck k<n; 所以 T(n) <= 4(n/2)2 +n = n2 +n 要证明n2 +n<=cn2 好像不容易。

我们换个假设,假设T(k)<=c1 k2 -c2 k ,这样的话T(n) <= c1 n2 -(2c2 -1)n = c1 n2 -c2 n-(c2 -1)n. 所以只要 c2 >= 1,就证明成功了。注意这里,似乎没有对c1 任何限制。其实不是的!对于所有的induction方法来说,我们都需要一个初始条件,T(n0 ) = H(1) <=c1 n0 2 -c2 n0 这里我使用H(1) 代表常数复杂度。为了满足初始条件,我们需要恰当的选择 c1 ,c2 和n0

其实这里的初始条件就对应了算法设计里面的Base Case。Base Case就是将问题切分到最后那个粒度最小的复杂度为常数的Case。就上面的那个例子来说,c1 和c2 ,对运行时起主导作用的是前者,你在实现时设计的Base Case能使c1 越小,程序运行越快。

(2) – Recursion Tree

T(n) = T(n/3) + T(2n/3) + n

Recursion Tree其实就是Iteration,只不过图型化以后我们看起来更容易理解了。

T(n) = T(n/3) + T(2n/3) + n
       = [T(n/9) + T(2n/9) + n/3] + [T(2n/9) + T(4n/9) + 2n/3]
       = ……
画成图就是:

总的cost就是把每一层的cost加起来。层数就是树的高度。上面的这个问题有点tricky的。从图上看分两种情况,一种以1/3的方式减少n,还有一种是以2/3的方式。前一种方式经过log3 n次就到达叶子节点,后一种方式经过log3/2 n次,因为log3/2 n > log3 n,树的高度为log3/2 n。每一层加起来的代价是cn, 其实越到下面,每一层的cost会小于cn的,因为那时候按照1/3的方式减少的那一枝已经不存在了。

T(n) <= cn x log3/2 n = O(nlgn)

Recursion tree很直观,我们可以用它来帮助我们猜测规律,然后再用Substitution方法Double Confirm。

不过无论是Substitution还是Recursion Tree都比较烦,不能马上得出结果。有人总结了规律,叫做Mater Method。使用Master Method, 我们很快就可以直接写出T(n)=aT(n/b)+f(n)的时间复杂度。

(3) – Master Method

前面分别介绍了 Resolving Recurrence(1) – Substitution Method 和 Resolving Recurrence(2) – Recursion Tree 来评估
T(n) = aT(n/b) + f(n) 的时间复杂度。

这一节介绍Master Method,既然叫Master,可见其重要程度。掌握了Master Method,我们可以很快写出Merge Sort, Heap Sort以及Quick Sort的时间复杂度。

Master Method:   (在 a>=1 并且 b>1 的情况下)

  • 如果f(n) is polynomially smaller than nlog b a , polynomially smaller就是grow slower, 数学表达式f(n)=O(nlog b a-e ), e>0。 T(n) = O(nlog b a )
  • 如果f(n) is polynomially same as nlog b a , T(n) = O(nlog b a lgn)
  • 如果f(n) is polynomially faster than  nlog b a , 并且 af(n/b) <= cf(n),  c<1 && n>=b , T(n) = H(f(n)) . H表示复杂度相当。

举个例子T(n)=4T(n/2)+n , 其中a=4, b=2, –> nlog b a =  n2 , 而f(n)=n, 属于第一种情况所以 T(n) = O(n2 )。 如果T(n)=2T(n/2)+n, 则属于第二种情况,T(n) = O(n lgn).

在算法导论中有详细的证明,太符号化的东西往往难以记忆,下面我们用recursion tree的方式,帮助理解和记忆。

可见, 第一层有一个节点,第二层有a的节点,第 i 层有ai 个节点,所以到叶子节点那层,叶子的个数就是 a的 树高 次幂。而树高=logb n , 我们可以很容易证明 alog b n = nlog b a 。所以一共有nlog b a 个叶子,每个叶子其实就是我们的initial condition,就是我们的base case,是整个算法的基石。

cost of all the leaves nodes = H(nlog b a )

现在对照recursion tree再来回顾一下Master Method 的 3 种情况:

1. 当所有叶子的代价比根节点高时, O(nlog b a ) > f(n), 从root到leaves,每层的cost在geometry increase,由叶子主导整个算法的时间复杂度,所以 T(n) = O(nlog b a )

2. 当所有叶子的代价和根节点相当时,表示从root 到 leaves的每一层的cost 是 几乎balance的,总代价应该是 每一层代价乘以树高, T(n) = nlog b a x logb n = H(f(n) x logb n = O(nlog b a lgn)。

3. 当所有叶子的代价比根节点低时,由根节点主导整个算法的时间复杂度。af(n/b) <= cf(n),  c<1 && n>=b 表示把任务T(n)切分成a个T(n/b)的过程中,必须保证a个T(n/b)的合并代价必须小于上层任务的合并代价,并且每次切分,其单个节点的合并代价都是在减少的。简单来说就是 从root 到leaves的过程中,代价是geometry decrease的。 结论是 T(n) = H(f(n))。

Resolving Recurrence相关推荐

  1. IDEA中进行SpringBoot开发时提示:Error resolving template xxx, template might not exist or might not be acce

    场景 IDEA中进行SpringBoot开发时提示: Error resolving template "xxx", template might not exist or mig ...

  2. C++实现线性递归矩阵 linear recurrence matrix算法(附完整源码)

    C++实现线性递归矩阵 linear recurrence matrix算法 C++实现线性递归矩阵 linear recurrence matrix算法完整源码(定义,实现,main函数测试) C+ ...

  3. DNS resolving 占用大量日志

    公司内部DNS配置好后,测试解析正常,只是几乎每秒都有无法解析的日志产生.但分析日志时发现,每天的日志都有2G左右.日志中几乎全是类似 network unreachable resolving 'w ...

  4. 解决 Idea 卡在 Resolving Maven dependencies ...

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. Idea卡在Resolving Maven dependencies的解决方案 在Reimpot A ...

  5. CF1182E Product Oriented Recurrence

    CF1182E Product Oriented Recurrence 有一个递推式 \(f_x=c^{2x-6}\cdot f_{x-1}\cdot f_{x-2}\cdot f_{x-3}\;\; ...

  6. 异常:Error resolving template “xxx“, template might not exist or might not be accessible...解决办法

    异常:Error resolving template "xxx", template might not exist or might not be accessible...解 ...

  7. 轻松解决idea一直卡在Resolving Maven dependencies的问题

    原文链接:https://blog.csdn.net/weixin_43018811/article/details/103782045 关注公众号 风色年代(itfantasycc) 500G Ja ...

  8. Eagerly caching bean '' to allow for resolving potential circular references

    tomcat启动时卡在: 一般这样的问题是两个原因: 1. 数据库连接不上: 2. mapper.xml 中有错误,比如单词拼写错误: 这个问题不是,采取的方法是 把项目的日志级别调整为debug模式 ...

  9. 【npm i 报错解决方法】npm ERR! code ERESOLVEnpm ERR!npm ERR! While resolving: by-web@1.2.2npm ERR!

    [npm i 报错解决方法]npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! np ...

最新文章

  1. mysql wait_timeout 8小时问题解决,tomcat数据源的配置
  2. Microsoft Visual Studio (VS)2010 常用快捷键大全 便捷开发
  3. lolfps高但画面不流畅_你吃鸡卡吗,超详细和平精英画面设置教程,解决卡顿,主播都在用...
  4. android 过滤cmcc,Android 无法通过cmcc wap2.0 test解决
  5. Python面试题(二)
  6. 阿里云PolarDB论文入选数据库顶会SIGMOD2021 最新一代架构领先世界
  7. 再一贴[亲爱的,我不小心怀孕了~!]
  8. 一些dos下简单命令
  9. java中的构造方法与代码块
  10. 飞鸽传书就不去袭击你们了
  11. 如何快速的打造python 版的vim ide
  12. SC15 供应商质量管理工程师(武汉)
  13. solr集群solrCloud的搭建
  14. 图论及其应用(吴望明中文版)
  15. 基于LSTM-Attention模型的光伏电站发电量预估(1)
  16. 深入浅出计算机组成原理(四)——穿越功耗墙,我们该从哪些方面提升“性能”?
  17. Prometheus(二)基础概念
  18. Web Spider 常见混淆EVAL、AA、JJ、JSFUCK
  19. 使用ArchR分析单细胞ATAC-seq数据(第四章)
  20. Android 淡出效果手写板

热门文章

  1. 百度搜索高级搜索指令和参数
  2. Netty技术笔记【韩顺平课程】
  3. 离散数学 --- 谓词逻辑 --- 谓词合式公式推理
  4. 鱼、美元和经济的故事
  5. 职高计算机word教学视频,浅谈中职《计算机应用基础》Word教学方法
  6. 了解公司各印章的作用并加强印章保护工作
  7. Ocaml 的入门整理 1
  8. win10自带输入法的标点符号切换
  9. 说说 exist 这个词
  10. 雾霾天我为何不逃离北京