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/
本文对递归式求解中很重要的主方法进行介绍总结。
主方法
主方法为如下形式的递归式提供了一种”菜谱式”的求解方法:
其中 a≥1,b>1 是常数, f(n) 是渐进正数。
上式描述了这样的一个算法运行时间: 他将原问题的规模为 n 的问题划分为 a 个小的子问题,每个子问题的规模为原来的 1b . a 个子问题递归的进行求解,每个花费时间为 T(n/b) 。子问题合并的代价为 f(n)
主定理
这里我将书上的定义直接贴上来了。
主方法依赖主定理:
令
a≥1
和
b>1
是常数,
f(n)
是一个函数,
T(n)
是定义在非负整数上的递归式:
其中我们将忽略舍入问题 n/b 解释为 ⌊n/b⌋ 和 ⌈n/b⌉ , 那么 T(n) 有如下渐进界:
- 若对某个常数 ϵ>0 有 f(n)=O(nlogba−ϵ) , T(n)=Θ(nlogba)
- 若 f(n)=Θ(nlogba) , 则 T(n)=Θ(nbalgn)
- 若对某个常数 ϵ>0 有 f(n)=Ω(nlogba+ϵ) , 且对某个常数 c<1 和所有足够大的 n y有 af(n/b)≤cf(n) , 则 T(n)=Θ(f(n))
主定理的直观理解
主定理其实主要是比较两个函数 f(n) 和 nlogba , 其中较大的那个决定最终递归式的渐近解。
- 若 nlogba>f(n) , 则就是情况1, 解就直接是 T(n)=Θ(nlogba)
- 若 nlogba=f(n) , 则就是情况2, 解就需要在 f(n) 的基础上乘上个对数因子 lgn , T(n)=Θ(nlogbalgn)
- 若 nlogba<f(n) , 则就是情况3, 解为 T(n)=Θ(f(n))
主定理的细节理解
多项式意义上大于
主定理中,除了渐进大于(小于)以外,还有一个重要的概念就是多项式意义的大于(小于)(polynomially larger/smaller)
多项式大于意味着函数的比值会渐进的落在两个多项式之间。
f(n)
多项式意义上大于
g(n)
,当且仅当存在两个广义的多项式(分数指数也是可以的)
p(n),q(n)
使得如下不等式渐进成立:
例如对于两个函数
n2
和
nlgn
, 我们有
n2nlgn=nlgn
,
则函数 n2 多项式意义上大于 nlgn .
主定理中的细节
除了像上一部分那样有个大致的“大于”,“小于”的直观理解外,我们要理解定义中的具体细节,其实就是多项式大于/小于的应用。
- 第一种情况中,我们需要 f(n) 多项式意义上小于 nlogba , 即 f(n) 渐进小于 nlogba−ϵ 。 f(n) 必须渐近小于 nlogba , 同时要相差一个因子 nϵ , 其中 ϵ 是大于0的常数。
- 第二种情况中,除了多项式意义上的大于以外,而且还要满足“正则”条件 af(n/b)≤cf(n)
但是主方法中的三种情况并不能覆盖所有此形式的情况。情况1和情况2之间有一定的间隙,即 f(n) 渐近小于 nlogba d但不是多项式意义上的小于。同样的情况2和情况3也有类似的间隙。如果 f(n) 满足的条件正好落在间隙中,或者不满足情况3中的“正则”条件,就不能通过主方法来求解了。
例如求解如下递归式的时候:
我们按照主方法, a=2,b=2,f(n)=nlgn
我们可以看到
f(n)=nlgn
渐近大于
nlogba=n
, 但是我们需要的是多项式意义上的大于即
但是对于任意 ϵ>0 都无法满足 lgn 渐近大于 nϵ , 于是它并不是多项式意义上的大于,此递归式无法使用主方法来求解。
使用主方法的例子
对于矩阵乘法的Strassen方法递归式:
有
a=7,b=2,f(n)=Θ(n2)
, 因此
nlogba=nlog27
, 由于
2.8<lg7<2.81
, 对于
ϵ=0.8
, 就有
f(n)=Θ(n2)
多项式意义上大于
O(nlg7)
, 于是我们便可以得到最终的解为: