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)
其中
a≥1,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)
主定理
这里我将书上的定义直接贴上来了。
主方法依赖主定理:
令
a≥1
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)有如下渐进界:
- 若对某个常数
ϵ>0
ϵ>0有
f(n)=O(nlogba−ϵ)
f(n)=O(nlogba−ϵ),
T(n)=Θ(nlogba)
T(n)=Θ(nlogba)
- 若
f(n)=Θ(nlogba)
f(n)=Θ(nlogba), 则
T(n)=Θ(nbalgn)
T(n)=Θ(nbalgn)
- 若对某个常数
ϵ>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
nlogba, 其中较大的那个决定最终递归式的渐近解。
- 若
nlogba>f(n)
nlogba>f(n), 则就是情况1, 解就直接是
T(n)=Θ(nlogba)
T(n)=Θ(nlogba)
- 若
nlogba=f(n)
nlogba=f(n), 则就是情况2, 解就需要在
f(n)
f(n)的基础上乘上个对数因子
lgn
lgn,
T(n)=Θ(nlogbalgn)
T(n)=Θ(nlogbalgn)
- 若
nlogba<f(n)
nlogba<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,
n13≤nlgn≤n
n13≤nlgn≤n
则函数
n2
n2多项式意义上大于
nlgn
nlgn.
主定理中的细节
除了像上一部分那样有个大致的“大于”,“小于”的直观理解外,我们要理解定义中的具体细节,其实就是多项式大于/小于的应用。
- 第一种情况中,我们需要
f(n)
f(n)多项式意义上小于
nlogba
nlogba, 即
f(n)
f(n)渐进小于
nlogba−ϵ
nlogba−ϵ。
f(n)
f(n)必须渐近小于
nlogba
nlogba, 同时要相差一个因子
nϵ
nϵ, 其中
ϵ
ϵ是大于0的常数。
- 第二种情况中,除了多项式意义上的大于以外,而且还要满足“正则”条件
af(n/b)≤cf(n)
af(n/b)≤cf(n)
但是主方法中的三种情况并不能覆盖所有此形式的情况。情况1和情况2之间有一定的间隙,即
f(n)
f(n)渐近小于
nlogba
nlogbad但不是多项式意义上的小于。同样的情况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
nlogba=nlog22=n
我们可以看到
f(n)=nlgn
f(n)=nlgn 渐近大于
nlogba=n
nlogba=n, 但是我们需要的是多项式意义上的大于即
nlgn>n⋅nϵ,ϵ>0
nlgn>n⋅nϵ,ϵ>0
但是对于任意
ϵ>0
ϵ>0都无法满足
lgn
lgn渐近大于
nϵ
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
nlogba=nlog27, 由于
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)