递归式求解-主方法

http://pytlab.org/2017/09/10/%E9%80%92%E5%BD%92%E5%BC%8F%E6%B1%82%E8%A7%A3-%E4%B8%BB%E6%96%B9%E6%B3%95/

本文对递归式求解中很重要的主方法进行介绍总结。

主方法

主方法为如下形式的递归式提供了一种”菜谱式”的求解方法:

T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)

其中
a1,b>1 a≥1,b>1是常数,
f(n) f(n)是渐进正数。

上式描述了这样的一个算法运行时间: 他将原问题的规模为 n n的问题划分为 a a个小的子问题,每个子问题的规模为原来的 1b 1b a a个子问题递归的进行求解,每个花费时间为 T(n/b) T(n/b)。子问题合并的代价为 f(n) f(n)


主定理

这里我将书上的定义直接贴上来了。

主方法依赖主定理:

a1 a≥1 b>1 b>1是常数, f(n) f(n)是一个函数, T(n) T(n)是定义在非负整数上的递归式:

T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)

其中我们将忽略舍入问题
n/b n/b解释为
n/b ⌊n/b⌋
n/b ⌈n/b⌉, 那么
T(n) T(n)有如下渐进界:

  1. 若对某个常数 ϵ>0 ϵ>0 f(n)=O(nlogbaϵ) f(n)=O(nlogb⁡a−ϵ) T(n)=Θ(nlogba) T(n)=Θ(nlogb⁡a)
  2. f(n)=Θ(nlogba) f(n)=Θ(nlogb⁡a), 则 T(n)=Θ(nbalgn) T(n)=Θ(nbalgn)
  3. 若对某个常数 ϵ>0 ϵ>0 f(n)=Ω(nlogba+ϵ) f(n)=Ω(nlogba+ϵ), 且对某个常数 c<1 c<1和所有足够大的 n ny有 af(n/b)cf(n) af(n/b)≤cf(n), 则 T(n)=Θ(f(n)) T(n)=Θ(f(n))

主定理的直观理解

主定理其实主要是比较两个函数 f(n) f(n) nlogba nlogb⁡a, 其中较大的那个决定最终递归式的渐近解。

  1. nlogba>f(n) nlogb⁡a>f(n), 则就是情况1, 解就直接是 T(n)=Θ(nlogba) T(n)=Θ(nlogb⁡a)
  2. nlogba=f(n) nlogb⁡a=f(n), 则就是情况2, 解就需要在 f(n) f(n)的基础上乘上个对数因子 lgn lgn T(n)=Θ(nlogbalgn) T(n)=Θ(nlogb⁡algn)
  3. nlogba<f(n) nlogb⁡a<f(n), 则就是情况3, 解为 T(n)=Θ(f(n)) T(n)=Θ(f(n))

主定理的细节理解

多项式意义上大于

主定理中,除了渐进大于(小于)以外,还有一个重要的概念就是多项式意义的大于(小于)(polynomially larger/smaller)

多项式大于意味着函数的比值会渐进的落在两个多项式之间。 f(n) f(n)多项式意义上大于 g(n) g(n),当且仅当存在两个广义的多项式(分数指数也是可以的) p(n),q(n) p(n),q(n)使得如下不等式渐进成立:

p(n)f(n)g(n)<q(n) p(n)≤f(n)g(n)<q(n)

例如对于两个函数 n2 n2 nlgn nlgn, 我们有 n2nlgn=nlgn n2nlgn=nlgn,

n13nlgnn n13≤nlgn≤n

则函数
n2 n2多项式意义上大于
nlgn nlgn.

主定理中的细节

除了像上一部分那样有个大致的“大于”,“小于”的直观理解外,我们要理解定义中的具体细节,其实就是多项式大于/小于的应用。

  1. 第一种情况中,我们需要 f(n) f(n)多项式意义上小于 nlogba nlogb⁡a, 即 f(n) f(n)渐进小于 nlogbaϵ nlogb⁡a−ϵ。  f(n) f(n)必须渐近小于 nlogba nlogb⁡a, 同时要相差一个因子 nϵ , 其中 ϵ ϵ是大于0的常数。
  2. 第二种情况中,除了多项式意义上的大于以外,而且还要满足“正则”条件 af(n/b)cf(n) af(n/b)≤cf(n)

但是主方法中的三种情况并不能覆蓋所有此形式的情况。情况1和情况2之间有一定的间隙,即 f(n) f(n)渐近小于 nlogba nlogb⁡ad但不是多项式意义上的小于。同样的情况2和情况3也有类似的间隙。如果 f(n) f(n)满足的条件正好落在间隙中,或者不满足情况3中的“正则”条件,就不能通过主方法来求解了。

例如求解如下递归式的时候:

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

我们按照主方法, a=2,b=2,f(n)=nlgn a=2,b=2,f(n)=nlgn

nlogba=nlog22=n nlogb⁡a=nlog2⁡2=n

我们可以看到 f(n)=nlgn f(n)=nlgn 渐近大于  nlogba=n nlogb⁡a=n, 但是我们需要的是多项式意义上的大于即

nlgn>nnϵ,ϵ>0 nlgn>n⋅nϵ,ϵ>0

但是对于任意
ϵ>0 ϵ>0都无法满足
lgn lgn渐近大于
nϵ , 于是它并不是多项式意义上的大于,此递归式无法使用主方法来求解。

使用主方法的例子

对于矩阵乘法的Strassen方法递归式:

T(n)=7T(n/2)+Θ(n2) T(n)=7T(n/2)+Θ(n2)

a=7,b=2,f(n)=Θ(n2) a=7,b=2,f(n)=Θ(n2), 因此 nlogba=nlog27 nlogb⁡a=nlog2⁡7, 由于 2.8<lg7<2.81 2.8<lg7<2.81, 对于 ϵ=0.8 ϵ=0.8, 就有 f(n)=Θ(n2) f(n)=Θ(n2)多项式意义上大于 O(nlg7) O(nlg7), 于是我们便可以得到最终的解为:

T(n)=Θ(nlg7)

点赞