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

来源:互联网 发布:scala二维数组 编辑:程序博客网 时间:2024/06/02 01:28

第4章 分治策略

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

4.1 最大子数组问题

FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)left_sum = - MAXsum = 0for i = mid downto low    sum = sum + A[i]    if sum > left_sum        left_sum = sum        max_left = iright_sum = - MAXsum = 0for j = mid + 1 to high    sum = sum + A[j]    if sum > right_sum        right_sum = sum        max_right = jreturn(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 = -MAXmax_sum = -MAXleft = lowright = lowfor 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 = ireturn(left, right, max_sum)

4.2 矩阵乘法的Strassen算法

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

SQUARE-MATRIX-MULTIPLY(A, B)n = A.rowlet C be a new nxn matrixfor 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(主定理):令a1b>1是常数,f(n)是一个函数,T(n)是定义在非负整数上的递归式:

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

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

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

0 0
原创粉丝点击