第4章 分治策略
本章通過兩個例子介紹分治策略,然後介紹三種方法求解遞歸式。
4.1 最大子數組問題
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left_sum = - MAX
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left_sum
left_sum = sum
max_left = i
right_sum = - MAX
sum = 0
for j = mid + 1 to high
sum = sum + A[j]
if sum > right_sum
right_sum = sum
max_right = j
return(max_left, max_right, left_sum + right_sum)
FIND-MAXIMUN-SUBARRAY(A, low, high)
if high == low
return(low, high, A[low])
else
mid = (low + high) / 2
(left_low, left_high, left_sum) = FIND-MAXIMUN-SUBARRAY(A, low, mid)
(rihgt_low, rihgt_high, rihgt_sum) = FIND-MAXIMUN-SUBARRAY(A, mid + 1, high)
(cross_low, cross_high, cross_sum) = FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
if left_sum >= right_sum and left_sum >= cross_sum
return(left_low, left_high, left_sum)
elseif right_sum >= left_sum and right_sum >= cross_sum
return(right_low, right_high, right_sum)
else
return(cross_low, cross_high, cross_sum)
這裏因爲展現分治策略所以這樣做,但複雜度略高,
這裏給出一個我認爲比較簡單的方法,其本質是動態規劃。
FIND-MAXIMUN-SUBARRAY(A, low, high)
now_sum = -MAX
max_sum = -MAX
left = low
right = low
for i = low to high
if now_sum < 0
now_sum = 0
left = i
now_sum +=A[i]
if now_sum > max_sum
max_sum = now_sum
right = i
return(left, right, max_sum)
4.2 矩陣乘法的Strassen算法
普通方法:
SQUARE-MATRIX-MULTIPLY(A, B)
n = A.row
let C be a new nxn matrix
for i = 1 to n
for j = 1 to n
C[ij] = 0
for k = 1 to n
C[ij] += A[ik] * B[kj]
Strassen方法:
1. 將A、B和C分解成
2. 創建10個
3. 用步驟1中創建的子矩陣和步驟2中創建的10個矩陣,遞歸地計算7個矩陣積
4. 通過
步驟2中,創建如下10個矩陣:
步驟3中,遞歸地計算7次矩陣乘法:
步驟4,得到C的子矩陣:
注:反正我記不住這些矩陣計算,也不想記,Strassen方法不怎麼實用=。=
到目前爲止,nxn矩陣相乘的漸進複雜度最優的算法是Coppersmith和Winograd提出的,運行時間爲O(n2.376) ,已經很好了,畢竟下界是Ω(n2) 。
4.3 用代入法求解遞歸式
步驟:
- 猜測解的形式
- 用數學歸納法求出解中常數,並且證明解釋正確的
4.4 用遞歸樹求解遞歸式
在2.2節中就用到過遞歸樹,可參考2.2那節內容。
遞歸樹主要是計算每層的代價和遞歸樹的層數。
4.5 用主方法求解遞歸式
定理4.1(主定理):令
那麼
1. 若對某個常數
2. 若
3. 若對某個常數
注:這裏的小於大於都是指多項式意義上的小於大於,如果函數
f(n) 落在間隙中,不能用主方法來求解遞歸式。