《算法导论》学习笔记-分治策略求解递归式


分治策略

分解:将原问题划分成形式相同的子问题,规模可以不等,对半或2/3对1/3的划分。

解决:对于子问题的解决,很明显,采用的是递归求解的方式,如果子问题足够小了,就停止递归,直接求解。

合并:将子问题的解合并成原问题的解。

这里引出了一个如何求解子问题的问题,显然是采用递归调用栈的方式。因此,递归式与分治法是紧密相连的,使用递归式可以很自然地刻画分治法的运行时间。在这里本人需要说一下递归和分治的关系,**分治依托于递归,分治是一种思想,而递归是一种手段,递归式可以刻画分治算法的时间复杂度。**求解递归式的方法主要分为三种:代入法递归数法主方法

代入法

基本步骤

  1. 先猜测解的形式, 确定它的某个界的存在
  2. 再用归纳法去证明
    这种方法只适用于解的形式容易猜的情况. 需要靠经验

代入法的例子

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

  1. 猜测
    上述等式可以转换为 T(n)/n = 2T(n/2)/n + 1
    令 S(n) = T(n)/n
    则S(n) = S(n/2) + 1
    而这种形式与以下的等式很像(这是关键步骤)
    lgn = lg (n/2) + 1 (此处lg2 = 1)
    因此可以推测 T(n) / n = clgn (c是常数)
    因此猜出其解为 T(n) = O(nlgn)

  2. 数学归纳法证明这个解的合理性
    直接代入去运算

递归树法

在递归树中,每个结点表示一个单一子问题的代价,子问题对应某次递归函数调用。我们将树中每层中的代价求和,得到每层代价,然后将所有层的代价求和,得到所有层次的递归调用的总代价。但是分析这个总代价的规模却不是件很容易的事情,有时需要用到很多数学的知识。

举例分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据上面的思想我们可以得出总代价:
在这里插入图片描述
在这里插入图片描述

主方法

例如,归并排序递归式 T(n) = 2T(n/2) + cn ,Strassen算法递归式 T(n) = 7T(n/2) + Θ(n2) 等等。

但是有了这些递归式还不够,我们需要确切的知道T(n)到底是多少,它与n的关系如何。

因此,讲述一种求解上述形式的递归式的一般方法,称为主方法。该方法简单易行,通常不需要借助纸笔演算。

递归式(4-1)描述的是这样一种算法的运行时间:它将规模为n的问题分解为a个子问题,每个子问题规模为n/b,其中a和b都是正常数。a个子问题递归地进行求解,每个花费时间T(n/b)。函数f(n)包含了问题分解和子问题解合并的代价。例如,描述Strassen算法的递归式中,a=7,b=2,f(n) = Θ(n2) 。

定理4.1(主定理)

令 a≥1 和 b>1 是常数,f(n) 是一个函数,T(n) 是定义在非负整数上的递归式:T(n) = aT(n/b) + f(n)
那么T(n)有如下渐进界:

在这里插入图片描述
让我们尝试了解主定理的含义。对于三种情况,我们都将函数 f(n) 与函数 nlogba 进行比较。直觉上,递归式的解取决于两个函数中的较大者。如情况一是 nlogba 较大,情况3是 f(n) 较大。而情况2是两者一样大,这种情况需要乘上一个对数因子。

需要注意的是,两个函数比较大小时必须确保多项式意义上的小于,也就是说,两者必须相差一个因子 nε,其中 ε 是大于0的常数。另外情况3还需要满足一个额外的条件。

使用主方法

在这里插入图片描述
在这里插入图片描述

主定理的直观理解

在这里插入图片描述

证明主定理

思路是画出递归树,并归纳每层结点的代价以及叶子结点的代价,总代价即是各部分代价之和。详细过程可参考《算法导论》4.6节

发布了4 篇原创文章 · 获赞 6 · 访问量 631

猜你喜欢

转载自blog.csdn.net/Miller_em/article/details/105751952
今日推荐