分治算法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位二进制整数X和Y 输出:X和Y的乘积
分治思想:
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)
|
之后就成功的降低时间复杂度。T(n)=7T(n/2)+θ(n)=O(n^(log2^7 ))≈O(n^(2.81))
上文说的经典分治算法,基本以减少子问题个数来降低时间复杂度,在划分和合并阶段没有特别的处理。
接下来的几章主要看比较有意思的三个问题。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。