算法设计与分析课程复习笔记4——分治法

算法设计与分析课程复习笔记4——分治法

分治法

回顾:合并排序
分割、递归处理、合并

分治法

  • 将一个问题分割成几个规模小、性质相同的独立的子问题
  • 通常通过递归方法解决子问题
  • 合并每个子问题的解得到整个问题的解
  • 前提假设:原始问题的解能够通过子问题的求解获得

算法描述:

Solve(I)
n = size(I)
if (n <= smallsize)
	solution = directlySolve(I);
else
	divide I into I1, …, Ik.
	for each i in {1, …, k}
		Si = solve(Ii);
	solution = combine(S1, …, Sk);
return solution;

为什么要采用分治法?

  • 有时候它是最简单的方法
  • 通常更有效
  • 与其他方法的效率可能相同甚至更坏
  • 必须分析分治算法的代价
  • 不肯定是递归的

分治法的开销

  1. 分割开销
  2. 子问题解决开销
  3. 合并开销

形式:
T(n) = D(n) + Sum[ T(size( I i I_i ) ] + C(n)
更一般化:T(n) = a T(n/b) + f(n)

二分搜索

输入: 排序好的序列 a 0 a_0 , a 1 a_1 , …, a n 1 a_{n-1} 和数值X
思想:
将X与中值比较
左、右比较
规模逐渐减小

example:
3 7 11 12 15 19 24 33 41 55
     24
     ↓
19 24 33 41 55
   24
   ↓
  19 24
  24

二分搜索的时间复杂性
T ( n ) = { 1   i f T ( n 2 ) + 1   o t h e r w i s e T(n)=\left\{ \begin{aligned} 1 ifn=1\\ T(\lfloor\frac n2\rfloor)+1 otherwise \end{aligned} \right.

矩阵乘法

Z = X Y Z=XY
X , Y X,Y 均为n*n
时间开销:O(n3)
对于 X X (n*m) * Y Y (m*q)的情况,开销O(nmq)

矩阵乘法
I = A E + B G I=AE+BG
J = A F + B H J=AF+BH
K = C E + D G K=CE+DG
L = C F + D H L=CF+DH

扫描二维码关注公众号,回复: 10004607 查看本文章

考虑:分割成8个(n/2)*(n/2)相乘和另外4个矩阵加

T ( n ) = 8 T ( n / 2 ) + b n 2 T(n) = 8T(n/2) + bn^2
T ( n ) Θ ( n 3 ) T(n)仍然是Θ(n^3)

矩阵Strassen算法
如下定义 S 1 S_1 ~ S 7 S_7 :
S 1 = A ( F H ) S_1=A(F-H)
S 2 = ( A + B ) H S_2=(A+B)H
S 3 = ( C + D ) E S_3=(C+D)E
S 4 = D ( G E ) S_4=D(G-E)
S 5 = ( A + D ) ( E + H ) S_5=(A+D)(E+H)
S 6 = ( B D ) ( G + H ) S_6=(B-D)(G+H)
S 7 = ( A C ) ( E + F ) S_7=(A-C)(E+F)

I = S 5 + S 6 + S 4 S 2 I=S_5+S_6+S_4-S_2
J = S 1 + S 2 J=S_1+S_2
K = S 3 + S 4 K=S_3+S_4
L = S 1 S 7 S 3 + S 5 L=S_1-S_7-S_3+S_5

现在 Z = X Y Z=XY 只使用了7个递归相乘
T ( n ) = 7 T ( n / 2 ) + b n 2 T(n) = 7T(n/2) + bn^2
通过主方式求解: Θ ( n 2.808 ) Θ(n^{2.808})

实例比较:
当我们将两个100*100的矩阵相乘时,n3是1000000,而n2.808是413048

实际上有更优秀的算法,可达到 Θ ( n 2.376 ) Θ(n^{2.376}) ,n2.376仅为56494.(需另外查资料)

大整数相乘

大整数相乘
时间开销: Θ ( n 2 ) Θ(n^2)

分治法:
X =   a         b   X= a  |  b 
Y =   c         d   Y= c  |  d 

X = a 2 n / 2 + b X=a*2^{n/2}+b
Y = c 2 n / 2 + d Y=c*2^{n/2}+d
X Y = a c 2 n + ( a d + b c ) 2 n / 2 + b d XY=ac2^n+(ad+bc)2^{n/2}+bd

算法如下:

Mult(X,Y)
if|X|=|Y|=1 then do return XY
else return
Mult(a,c)2n+(Mult(a,d)+Mult(b,c))2n/2+Mult(b,d)

开销函数:
T ( n ) = { 1   i f 4 T ( n 2 ) + Θ ( n )   i f T(n)=\left\{ \begin{aligned} 1 ifn=1\\ 4T(\frac n2)+Θ(n) ifn>1 \end{aligned} \right.

主方式法求解: Θ ( n 2 ) Θ(n^2)

更好的方法(Karatsuba 1962)
利用高斯等式:
a d + b c = ( a + b ) ( c + d ) a c b d ad+bc=(a+b)(c+d)-ac-bd

算法如下:
Mult(X,Y)
if|X|=|Y|=1 then do return XY
else
A 1 A_1 =Mult(a,c);
A 2 A_2 =Mult(b,d);
A 3 A_3 =Mult((a+b),(c+d));
return A 1 2 n + ( A 3 A 1 A 2 ) 2 n / 2 + A 2 A_12^n+(A_3-A_1-A_2)2^{n/2}+A_2

开销函数:
T ( n ) = { 1   i f 3 T ( n 2 ) + Θ ( n )   i f T(n)=\left\{ \begin{aligned} 1 ifn=1\\ 3T(\frac n2)+Θ(n) ifn>1 \end{aligned} \right.

主方式求解: Θ ( n l o g 2 3 ) Θ(n^{log_23}) = Θ ( n 1.58 ) Θ(n^{1.58})

最近点对问题

蛮力法:计算出两两之间的距离然后比较的方法

分治法求解
假设:各点x坐标互异,各点y坐标互异
在一维空间上求解:排列,从左到右求最小距离

1️⃣分割
分割
2️⃣递归解决
递归解决
3️⃣整合
整合
L和R中是否各存在一点,它们之间的距离小于δ?
如果没有,结束。如果有,此类点对中距离最近的点即是整个问题的解。
4️⃣继续整合
继续整合
只需考虑上图中带条S内的点的距离。S中的点最多要与S中的7个点进行比较。

算法如下:
ClosestPair(P)
Preprocessing:预处理,递增排列
  Construct P x P_x and P y P_y as sorted-list by x- and y-coordinates
Divide:分割
 Construct L L , L x L_x , L y L_y and R R , R x R_x , R y R_y
Conquer:治理
 Let δ 1 δ_1 = ClosestPair( L L , L x L_x , L y L_y )
 Let δ 2 δ_2 = ClosestPair( R R , R x R_x , R y R_y )
Combination:整合
 Let δ = min( δ 1 δ_1 , δ 2 δ_2 )
 Construct S and S y S_y (按y坐标排序)
 For each point in S y S_y , check each of its next 7 points down the list(检查与后续7个点之间的距离)
 If the distance is less than δ, update the δ as this smaller distance(如果存在小于δ的距离,则为距离最短点对)

时间开销:
预处理: O ( n l g n ) O(n lg n)
分割: O ( n ) O(n)
治理: 2 T ( n / 2 ) 2T(n/2)
整合: O ( n ) O(n)

total: O ( n l g n ) O(n lg n)

参考:任课教师邱德红教授的课件

发布了25 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42605042/article/details/89607398