数学小牛马

V1

2022/03/28阅读:51主题:默认主题

[主定理证明]递归算法时间复杂度怎么算

分治算法

分治算法强调递归的求解一个问题,每个递归都有三个步骤:

  • 分解:将问题分解为子问题,子问题规模 原问题规模;
  • 解决:解决递归最底层无法分解的子问题;
  • 合并:将已解决的最小问题递归至上一层直至到根节点。

递归式

递归式是描述分治算法的一个等式或不等式,例如归并排序递归式为:

解释为: 时将原问题分治为两个原问题一半的子问题, 时使用常数时间解决问题。

实际运用是可能会忽略很多问题比如说归并排序数组长度为大于1的奇数子问题将会归结为:

但改变幅度不会超过常数因子,因此不作为考虑内容。

主定理方法

主方法为求解递归式时间复杂度提供了一种通用解法,主方法求解依赖于主定理。

定理描述:

为常数, 为函数, 是定义在非负整数上的递归式:

其中分解的子问题规模也可以解释为 的渐进界为:

  1. 若对某常数 ,有 ,则
  2. ,则
  3. 若对某常数 ,有 ,且对某常数 和足够大的 ,则

但要注意,主定理没有覆盖到全部可能,若 不符合情况2且找不到合理的常数 使得情况1或3成立时,这种情况将无法使用主定理求解,例如:

例1: ,这种情景使用递归树可以得出结果为

例2: 找不到合理的 使得 成立,但通过递归树方法可得到结果为

证明主定理

证明将参考算法导论中方法,分两步解决:

  1. 的幂次进行证明;
  2. 扩展至全部正整数。

两步证明考虑的原因可能是上述提及到的归并排序现象,不是每一次迭代都是完整的,但考虑太过于全面不仅会复杂化证明过程,而且只会相比原始结果有常数因子的出入,不会影响整体算法时间复杂度。

的幂次

因为每一个无法直接解决的问题都需要被分解为 个子问题,由于第一步证明所要求的 的值,问题生成的递归树将是完整的"满 叉树",高度则为 ,叶子节点为 ,上下替换元素即得

所以递归式的答案可以表示为非递归结构:

前一项计算叶子结点的复杂度,后一项则为从根节点层序计算每层的函数时间复杂度。换句话说表达的是叶子节点计算代价+分解与合并子问题的代价

现在需要考虑的问题是将任意一个非叶子节点看作根节点,这都将是一个完整的分治问题的递归树,所以在固定问题中每一层的计算代价不会无规律的变化,复杂度的分布只会有三种情况:

  • 从树根到叶子每一层来看复杂度越来越高;
  • 从根节点到叶子节点每层来看复杂度排布均匀;
  • 从树根到叶子每一层来看复杂度越来越低;

届时我们需要考虑总体递归式的算法时间复杂度将由这两项决定,因为叶子节点已经完全确定了复杂度的渐进紧确界,无非对应上述描述的就是三种情况:

  • 整体代价叶子节点决定
  • 整体代价均匀分布
  • 整体代价根节点决定

现在做 ,那么三种情况由确定的叶子节点紧确界作为比较对象:

  1. 若存在 ,那么:

    得到

  2. ,那么类似的:

    得到

  3. 根节点决定复杂度表示:常数 和足够大的 ,所以:

    得到

归结后得到上述主方法的三种情况的结果,因为

  • 情况1:

  • 情况2:

  • 情况3:

向上向下取整

上述证明仅仅针对了 的幂次考虑,为了扩展所以得到了递归式上界和下界为:

向上取整与向下取整分别证明的是递归式的时间复杂度上界与下界,由于是对称证明,所以描述向上过程,其中证明分为两步:

  • 证明问题规模会向上增加常数规模
  • 证明三种情景的向上取整结果
增加常数规模

每层的调用参数为:

利用 得到:

因为向上取整描述的是问题每一层分治向上取整,则递归树高度将向下取整为 ,最后一层的叶子节点数量为:

上述证明了最底层的根节点参数至多是常数个所以可以证明问题的规模没有发生非常数的增加。

重现三种情况

向上取整后递归式的计算式展开为:

其中

三类情况做阐述:

  • 情况3:

  • 情况2:

  • 情况1:类似情况2很容易推出 ,之后得:

如此得出向上取整的三种情况的解。

情况3的弱条件

情况3中的:对某常数 和足够大的