首页 > 代码库 > 分治算法Divide-and-Conquer概述

分治算法Divide-and-Conquer概述

设计过程分为三个阶段

         Divide: 整个问题划分为多个子问题  T(n)=D(n)

         Conquer:求解各子问题(递归调用正设计的算法)  T(n)=aT(n/b)

         Combine:合并子问题的解, 形成原始问题的解T(n)=C(n)

Note: 将规模为n的问题划分为a个子问题,每个问题的大小为n/b。(b可能不等于a!)

时间复杂度:T(n)=θ(1)     if n<c常数

                        T(n)=aT(n/b)+D(n)+C(n) 



经典问题1:归并排序

Divide阶段:在中间节点节段 时间为O(1)

Conquer阶段:两个子问题每个问题规模为n/2因此T(n)=2T(n/2)

Combine阶段:依次比对 O(n)

所以时间复杂度为 T(n)=2T(n/2)+O(n)   Master方法计算(第2种情况)T(n)=(nlogn)

 

经典问题2:大整数乘法

输入:n位二进制整数XY            输出:XY的乘积

分治思想:

X = A<<n/2+B  Y= C<<n/2 + D 即将大数划分为两个子部分

X*Y = (A<<n/2+B)*(C<<n/2+ D) = (A*C)<<n + (A*D+B*C)<<n/2 +C*D

将XY问题划分为计算AC,BD,AD,BC四个子问题,每个问题规模为n/2  (!!a不等于b)

T(n)=4T(n/2)+θ(n)  Master方法计算  Master方法计算(第一种情况)T(n)=(n^2)

优化:

(A-B)*(C-D) = AC+BD-(BC+AD) 所以XY的等式中(A*D+B*C)就可以用AC+BD+(B-A)(C-D)代替。

即,把原来计算AC,BD,AD,BC四个子问题,转换为AC、BD、CD三个子问题。

T(n)=3T(n/2)+θ(n)  计算的T(n)=O(n^(log2^3))≈O(n^(1.59))

 

经典问题3:矩阵乘法

输入:两个矩阵A、B           输出:A*B

分治:


一般思路就是划分了8个,规模为n/2的子问题。所以T(n)=8T(n/2)+θ(n)

可是减少子问题个数是优化的好的方向。之后就有善于思考的人提出用7个子问题实现:

M1 = A11 (B12 - B22)

M2 = (A11 + A12) B22

M3 = (A21 + A22) B11

M4 = A22 (B21 - B11)

M5 = (A11 + A22) (B11 + B22)

M6 = (A12 - A22) (B21 + B22)

M7= (A11 - A12) (B11 + B12)


C11 = M5 + M4 - M2 + M6

C12 = M1 + M2

C21 = M3 + M4

C22 = M5 + M1 – M3 – M7

 

之后就成功的降低时间复杂度。T(n)=7T(n/2)+θ(n)=O(n^(log2^7 ))≈O(n^(2.81))

上文说的经典分治算法,基本以减少子问题个数来降低时间复杂度,在划分和合并阶段没有特别的处理。

接下来的几章主要看比较有意思的三个问题。

分治算法Divide-and-Conquer概述