算法设计与分析课程复习笔记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;
为什么要采用分治法?
- 有时候它是最简单的方法
- 通常更有效
- 与其他方法的效率可能相同甚至更坏
- 必须分析分治算法的代价
- 不肯定是递归的
分治法的开销
- 分割开销
- 子问题解决开销
- 合并开销
形式:
T(n) = D(n) + Sum[ T(size(
) ] + C(n)
更一般化:T(n) = a T(n/b) + f(n)
二分搜索
输入: 排序好的序列
,
, …,
和数值X
思想:
将X与中值比较
左、右比较
规模逐渐减小
example:
3 7 11 12 15 19 24 33 41 55
24
↓
19 24 33 41 55
24
↓
19 24
24
二分搜索的时间复杂性
矩阵乘法
均为n*n
时间开销:O(n3)
对于
(n*m)
(m*q)的情况,开销O(nmq)
考虑:分割成8个(n/2)*(n/2)相乘和另外4个矩阵加
则
矩阵Strassen算法
如下定义
~
:
现在
只使用了7个递归相乘
通过主方式求解:
实例比较:
当我们将两个100*100的矩阵相乘时,n3是1000000,而n2.808是413048
实际上有更优秀的算法,可达到 ,n2.376仅为56494.(需另外查资料)
大整数相乘
时间开销:
分治法:
算法如下:
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)
开销函数:
主方式法求解:
更好的方法(Karatsuba 1962)
利用高斯等式:
算法如下:
Mult(X,Y)
if|X|=|Y|=1 then do return XY
else
=Mult(a,c);
=Mult(b,d);
=Mult((a+b),(c+d));
return
开销函数:
主方式求解: =
最近点对问题
蛮力法:计算出两两之间的距离然后比较的方法
分治法求解
假设:各点x坐标互异,各点y坐标互异
在一维空间上求解:排列,从左到右求最小距离
1️⃣分割
2️⃣递归解决
3️⃣整合
L和R中是否各存在一点,它们之间的距离小于δ?
如果没有,结束。如果有,此类点对中距离最近的点即是整个问题的解。
4️⃣继续整合
只需考虑上图中带条S内的点的距离。S中的点最多要与S中的7个点进行比较。
算法如下:
ClosestPair(P)
Preprocessing:预处理,递增排列
Construct
and
as sorted-list by x- and y-coordinates
Divide:分割
Construct
,
,
and
,
,
Conquer:治理
Let
= ClosestPair(
,
,
)
Let
= ClosestPair(
,
,
)
Combination:整合
Let δ = min(
,
)
Construct S and
(按y坐标排序)
For each point in
, check each of its next 7 points down the list(检查与后续7个点之间的距离)
If the distance is less than δ, update the δ as this smaller distance(如果存在小于δ的距离,则为距离最短点对)
时间开销:
预处理:
分割:
治理:
整合:
total:
参考:任课教师邱德红教授的课件