《算法导论》第4章 分治策略 个人笔记

第4章 分治策略

本章通过两个例子介绍分治策略,然后介绍三种方法求解递归式。

4.1 最大子数组问题

FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left_sum = - MAX
sum = 0
for i = mid downto low
    sum = sum + A[i]
    if sum > left_sum
        left_sum = sum
        max_left = i
right_sum = - MAX
sum = 0
for j = mid + 1 to high
    sum = sum + A[j]
    if sum > right_sum
        right_sum = sum
        max_right = j
return(max_left, max_right, left_sum + right_sum)
FIND-MAXIMUN-SUBARRAY(A, low, high)
if high == low
    return(low, high, A[low])
else
    mid = (low + high) / 2
    (left_low, left_high, left_sum) = FIND-MAXIMUN-SUBARRAY(A, low, mid)
    (rihgt_low, rihgt_high, rihgt_sum) = FIND-MAXIMUN-SUBARRAY(A, mid + 1, high)
    (cross_low, cross_high, cross_sum) = FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
    if left_sum >= right_sum and left_sum >= cross_sum
        return(left_low, left_high, left_sum)
    elseif right_sum >= left_sum and right_sum >= cross_sum
        return(right_low, right_high, right_sum)
    else
        return(cross_low, cross_high, cross_sum)

这里因为展现分治策略所以这样做,但复杂度略高, T(n)=Θ(nlgn)
这里给出一个我认为比较简单的方法,其本质是动态规划。

FIND-MAXIMUN-SUBARRAY(A, low, high)
now_sum = -MAX
max_sum = -MAX
left = low
right = low
for i = low to high
    if now_sum < 0
        now_sum = 0
        left = i
    now_sum +=A[i]
    if now_sum > max_sum
        max_sum = now_sum
        right = i
return(left, right, max_sum)

4.2 矩阵乘法的Strassen算法

普通方法: T(n)=Θ(n3)

SQUARE-MATRIX-MULTIPLY(A, B)
n = A.row
let C be a new nxn matrix
for i = 1 to n
    for j = 1 to n
        C[ij] = 0
        for k = 1 to n
            C[ij] += A[ik] * B[kj]

Strassen方法 T(n)=Θ(nlg7)
1. 将A、B和C分解成 n2×n2 的子矩阵
2. 创建10个 n2×n2 的矩阵 S1,S2,...,S10 ,每个矩阵保存步骤1中创建的两个子矩阵的和或差
3. 用步骤1中创建的子矩阵和步骤2中创建的10个矩阵,递归地计算7个矩阵积 P1,P2,...,P7
4. 通过 Pi 矩阵的不同组合进行加减运算,计算出结果矩阵C的子矩阵 C11,C12,C21,C22

步骤2中,创建如下10个矩阵:

S1=B12B22S2=A11+A12S3=A21+A22S4=B21B11S5=A11+A22S6=B11+B22S7=A12A22S8=B21+B22S9=A11A21S10=B11+B12

步骤3中,递归地计算7次矩阵乘法:

P1=A11S1P2=S2B22P3=S3B11P4=A22S4P5=S5S6P6=S7S8P7=S9S10

步骤4,得到C的子矩阵:
C11=P5+P4P2+P6C12=P1+P2C21=P3+P4C22=P5+P1P3P7

注:反正我记不住这些矩阵计算,也不想记,Strassen方法不怎么实用=。=
到目前为止,nxn矩阵相乘的渐进复杂度最优的算法是Coppersmith和Winograd提出的,运行时间为 O(n2.376) ,已经很好了,毕竟下界是 Ω(n2)

4.3 用代入法求解递归式

步骤:

  • 猜测解的形式
  • 用数学归纳法求出解中常数,并且证明解释正确的

4.4 用递归树求解递归式

在2.2节中就用到过递归树,可参考2.2那节内容。
递归树主要是计算每层的代价和递归树的层数。

4.5 用主方法求解递归式

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

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

那么 T(n) 有如下形式:
1. 若对某个常数 ε>0 f(n)=O(nlogaεb) ,则 T(n)=Θ(nlogab)
2. 若 f(n)=Θ(nlogab) ,则 T(n)=Θ(nlogablgn)
3. 若对某个常数 ε>0 f(n)=Ω(nloga+εb) ,且对某个常数 c<1 和所有足够大的n有 af(n/b)cf(n) ,则 T(n)=Θ(f(n))

注:这里的小于大于都是指多项式意义上的小于大于,如果函数 f(n) 落在间隙中,不能用主方法来求解递归式。

你可能感兴趣的:(算法导论)