解递归式(分析递归式的算法复杂度)

算法设计中经常会用到递归,利用递归式的方法可以清晰地显示算法的整个过程,而对于分析算法的复杂度,解递归式就有了用处,这里的方法来自于《算法导论》。

(一)代换法(substitution  method):

实质上就是数学归纳法,先对一个小的值做假设,然后推测更大的值得正确性。由于是数学归纳法,那么我们就需要对值进行猜测。现在,我们看下面这个例子:


我们先假设一个结论T(n) = O(lg(n - b)),并且假设对T(n / 2上取整)成立(这就是数学归纳法了),那么把T(n / 2上取整)用假设的结论进行代换,我们有T(n) <= lg((n - b)) / 2上取整)

<= lg((n - b) / 2 + 1) + 1 = lg(n - b + 2),对于任意的b >= 2,即满足要求T(n) <= lg(n) = O(lgn)。证毕。

这是一个很简单的例子,但是其中有些事情还是要交代的。

一个是结论的猜测不是一个容易的事情。另一个是在上面的例子中我没有直接下结论说T(n) = O(lg(n)),而是减去了一个常数b,这是为什么呢?答案是:we can prove something stronger for a given value by assuming something stronger for smaller values.还有一点值得说明,请看下面这个例子:


这里出现了sqrt(n),我们采用变量代换的方法:令n = 2 ^ m,则上式变为T(2 ^ m) = 2T(2 ^ (m / 2) ),再设S(m) = T(2 ^ m),则得到S(m) = 2S(m / 2) + 1。我们先假设S(m) = m - b <= O(m),且对S(m / 2)成立,那么S(m) = 2 * (m - b) / 2 + 1 = m - b + 1,对于任意的b >= 1都有S(m) = O(m),然后回代有T(n) = T( 2 ^ m) = S(m) = O(m) = O(lgn)。

这里我们采用了变量代换的方法。如果假设时,感觉变量不明朗,那么这是一种很有效的方法。

(二)递归树方法(recursion tree):

递归树最适合猜出合适的结果,然后用代换法验证

利用递归树方法求算法复杂度我想最好的例子就是归并排序了,这里我不想拿归并排序做例子,而只是用书中一些更简单形象的例子来说明:

根据上式我们建立递归式T(n) = 3T(n / 4) + cn^2,这里我们抛去上下界函数的影响(sloppiness that we can tolerate),并且把Theta(n ^ 2)用cn^2代替。下面建立递归树模型:






在递归树中,每一个结点都代表一个子代价,每层的代价是该层所有子代价的总和,总问题的代价就是所有层的代价总和。

所以,我们利用递归树求解代价,需要知道什么呢,一个是每一层的代价,一个是层数,就是这两个。

这些,都需要我们用觉察的态度来发现,而事实证明,这不是一件难事,很多情况下是有规律可循的。

我们且看上面这个例子,递归树的构造很简单,当递归调用到边界是,就达到了常量T(1),达到常量T(1)所用到的递归次数就是整个递归树的深度,我们从图中可以得到第i层的结点的代价为n / ( 4 ^ i ),当n / (4 ^ i) = 1即i = log4(n)时,递归到达了边界,所以,整个递归树的深度就是i = log4(n)。我们要求的总的代价是所有的总和,结果为O(n ^ 2)。计算过程我就不再累述了。但是,递归树并不是都是这样的满的树,也就是不是每一层的结点都是相同的结构,所以我们在构造递归树的时候要仔细看好这一点,才能保证在计算时不会出错。

当叶子不全在一个高度上时,我们可以先忽略这个误差,认为全是在最底层,然后用代换法验证是否成立。

(三)主方法(master method):

The master theorem concerns recurrence relations of the form:

T(n) = a \; T\!\left(\frac{n}{b}\right) + f(n)  \;\;\;\; \mbox{where} \;\; a \geq 1 \mbox{, } b > 1

In the application to the analysis of a recursive algorithm, the constants and function take on the following significance:

  • n is the size of the problem.
  • a is the number of subproblems in the recursion.
  • n/b is the size of each subproblem. (Here it is assumed that all subproblems are essentially the same size.)
  • f (n) is the cost of the work done outside the recursive calls, which includes the cost of dividing the problem and the cost of merging the solutions to the subproblems.

It is possible to determine an asymptotic tight bound in these three cases:

Case 1

Generic form

If f(n) = O\left( n^{c} \right) where c < \log_b a (using Big O notation)

then:

T(n) = \Theta\left( n^{\log_b a} \right)
Example
T(n) = 8 T\left(\frac{n}{2}\right) + 1000n^2

As one can see from the formula above:

a = 8, \, b = 2, \, f(n) = 1000n^2, so
f(n) = O\left(n^c\right), where  c = 2

Next, we see if we satisfy the case 1 condition:

\log_b a = \log_2 8 = 3>c.

It follows from the first case of the master theorem that

T(n) = \Theta\left( n^{\log_b a} \right) = \Theta\left( n^{3} \right)

(indeed, the exact solution of the recurrence relation is T(n) = 1001 n^3 - 1000 n^2, assuming T(1) = 1).

Case 2

Generic form

If it is true, for some constant k ≥ 0, that:

f(n) = \Theta\left( n^{c} \log^{k} n \right) where  c = \log_b a

then:

T(n) = \Theta\left( n^{c} \log^{k+1} n \right)
Example

T(n) = 2 T\left(\frac{n}{2}\right) + 10n

As we can see in the formula above the variables get the following values:

a = 2, \, b = 2, \, c = 1, \, f(n) = 10n
f(n) = \Theta\left(n^{c} \log^{k} n\right) where  c = 1, k = 0

Next, we see if we satisfy the case 2 condition:

\log_b a = \log_2 2 = 1, and therefore, yes,  c = \log_b a

So it follows from the second case of the master theorem:

T(n) = \Theta\left( n^{\log_b a} \log^{k+1} n\right) = \Theta\left( n^{1} \log^{1} n\right) = \Theta\left(n \log n\right)

Thus the given recurrence relation T(n) was in Θ(n log n).

(This result is confirmed by the exact solution of the recurrence relation, which is T(n) = n + 10 n\log_2 n, assuming T(1) = 1.)

Case 3

Generic form

If it is true that:

f(n) = \Omega\left( n^{c} \right) where  c > \log_b a

and if it is also true that:

a f\left( \frac{n}{b} \right) \le k f(n) for some constant  k < 1 and sufficiently large  n (often called the  regularity condition)

then:

T\left(n \right) = \Theta\left(f(n) \right)
Example[edit]
T(n) = 2 T\left(\frac{n}{2}\right) + n^2

As we can see in the formula above the variables get the following values:

a = 2, \, b = 2, \, f(n) = n^2
f(n) = \Omega\left(n^c\right), where  c = 2

Next, we see if we satisfy the case 3 condition:

\log_b a = \log_2 2 = 1, and therefore, yes,  c > \log_b a

The regularity condition also holds:

 2 \left(\frac{n^2}{4}\right) \le k n^2 , choosing   k = 1/2

So it follows from the third case of the master theorem:

T \left(n \right) = \Theta\left(f(n)\right) = \Theta \left(n^2 \right).

Thus the given recurrence relation T(n) was in Θ(n2), that complies with the f (n) of the original formula.

(This result is confirmed by the exact solution of the recurrence relation, which is T(n) = 2 n^2 - n, assuming T(1) = 1.)

Inadmissible equations

The following equations cannot be solved using the master theorem:

  • T(n) = 2^nT\left (\frac{n}{2}\right )+n^n
    a is not a constant; the number of subproblems should be fixed
  • T(n) = 2T\left (\frac{n}{2}\right )+\frac{n}{\log n}
    non-polynomial difference between f(n) and  n^{\log_b a} (see below)
  • T(n) = 0.5T\left (\frac{n}{2}\right )+n
    a<1 cannot have less than one sub problem
  • T(n) = 64T\left (\frac{n}{8}\right )-n^2\log n
    f(n) which is the combination time is not positive
  • T(n) = T\left (\frac{n}{2}\right )+n(2-\cos n)
    case 3 but regularity violation.

In the second inadmissible example above, the difference between f(n) and n^{\log_b a} can be expressed with the ratio \frac{f(n)}{n^{\log_b a}} = \frac{\frac{n}{\log n}}{n^{log_2 2}} = \frac{n}{n \log n} = \frac{1}{\log n}. It is clear that \frac{1}{\log n} < n^\epsilon for any constant \epsilon > 0. Therefore, the difference is not polynomial and the Master Theorem does not apply.



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值