算法导论Lecture 2:解递归

这个Lecture包括了CLRS中的Chapter3-Chapter4两章内容:渐近性标记和解递归。Erik Demaine主讲。Gee! 每次看到Erik的一头“秀发”跟Leiserson教授的光头就想笑笑,别误会,Erik's a man...

 

解递归

 

解递归常用的有三种方法:替换法(Substitution method),递归树法(Recursion tree),主方法(Master method)。

 

替换法

  1. Guess the form of the solution.
  2. Verify by induction.
  3. Solve for constants.

[Ex]. T(n) = 4T(n/2) + n

 

    --Guess: T(n) = O(n^3)

    --Assume: T(k) <= ck^3 for k < n

    --T(n) <= 4*c(n/2)^3 + n

              = cn^3/2 = cn^3 - (cn^3/2 - n)  // cn^3 is what we want, (cn^3/2 - n) is the residual, 余项

              <= cn^3 if cn^3/2 - n >=0, e.g c>=1

 

Another guess:

 

    --Guess: T(n) = O(n^2)

    --Assume: T(k) <= c1*k^2 - c2*k for k < n

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

              <= 4(c1*n^2/4 - c2*n/2) + n

              = c1*n^2 - 2c2*n + n

              = c1*n^2 - c2*n - (c2 - 1)*n   // c1*n^2 - c2*n is what we want, residual is (c2 - 1)*n

              < c1*n^2 - c2*n if (c2 - 1) * n >= 0, e.g c2 >= 1

              (c1由初始值T(1)决定,T(1) = Theta(1) = c, c>0, T(1) <= c1 - c2, c1 >= c + c2)

 

递归树法 Lecture 1中已经讲过。

 

主方法

 

Master method只能应用于某一类的递归式,形如: T(n) = aT(n/b) + f(n), a>= 1, b > 1, 且f(n)是渐近正(asymptotically positive)的。这个递归式描述的是某算法将大小为n的问题分成a个子问题,每个子问题大小为b。这a个子问题递归的解决,每一个需要时间T(n/b)。而问题的分割(Devide)与结果的合并(Combine)的花费由函数f(n)描述。

 

主方法由主定理来描述,共有三种情况,每一种情况都将f(n)与n^log_b(a)进行比较:

  1. 如果f(n) = O(n^(log_b(a) - e),e > 0,那么T(n) = Theta(n^log_b(a))。
  2. 如果f(n) = Theta(n^(log_b(a)),那么T(n) = Theta(n^log_b(a) lg(n))。
  3. 如果f(n) = Omega(n^(log_b(a) + e)),e > 0,并且af(n/b) <= cf(n),c < 1。那么T(n) = Theta(f(n))。

[Ex]. T(n) = 4T(n/2) + n, a = 4, b = 2, f(n) = n

        n = O(n^2),  //  Case 1

      => T(n) = Theta(n^2)

 

[Ex]. T(n) = 4T(n/2) + n^2, a = 4, b = 2, f(n) = n^2

         n^2 = Theta(n^2), // Case 2

      => T(n) = Theta(n^2 lg(n))

 

[Ex]. T(n) = 4T(n/2) + n^3, a = 4, b = 2, f(n) = n^3

        n^3 = Omega(n^(2+1)), e = 1 > 0,  // Case 3

      => T(n) = Theta(n^3)

 

 

Notes on Chapter 3 and Chapter 4.

 

这个笔记不想再别写一篇了,直接放在这里...

 

第三章中的渐近性标记有几个值得注意的地方,首先是这些标记容易引起争议的地方,比如渐近性标记是定义在自然数集上的,但是在渐近性标记的操作过程中很直接地就扩展到实数域上,或者只限定在自然数集的子集上。虽然备受争议,我们应该理解渐近性标记的准确含义,这样才能不误用这些标记。

 

另一点就是渐近性标记表示的实质上是一类函数的集合,虽然我们写成f(n)=Theta(g(n)),其实际意义却是f(n)属于Theta(g(n)),Theta(g(n))是一个函数集合。这里的等于号(=)可以理解为“是”而不是真正的“等于”,因为“等于”是对称的(a=b => b=a),而“属于”是不对称的!

 

在渐近性标记的定义中,对常数的要求是存在即可,证明中只要能找到满足条件的常数即可。

 

对这些渐近性标记可以有一个直观的类比(analogy):

 

f(n) = O(g(n))             => a <= b

f(n) = Omega(g(n))  => a >= b

f(n) = Theta(g(n))     = > a = b

f(n) = o(g(n))            => a < b

f(n) = omega(g(n))    => a > b

 

这一章的Chapter Notes中提到了Knuth与Graham,Patashnik合著的"Concrete Mathematics", 这本书包含了大量CS中用到的离散数学的内容,机工的英文版买了一本,字太小了,印刷差的一糊啊...

 

第四章,习题4.1-6

解递归式T(n) = 2T(sqrt(n)) + 1,可以用变量替换,令m = lg n,T(n) = 2T(sqrt(n)) + 1 化成T(2^m) = 2T(2^(m/2))+1,再令S(m) = T(2^m),式子可以写成S(m) = 2S(m/2) + 1,解得S(m) = Theta(lg(m)),也就是T(n) = T(2^m) = S(m) = Theta(lg(m)) = Theta(lg(lg(n)))。

你可能感兴趣的:(C++,c,算法,C#,F#)