算法設計與分析課程複習筆記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:
參考:任課教師邱德紅教授的課件