矩陣乘法的Strassen演算法(上)
阿新 • • 發佈:2021-07-08
矩陣乘法演算法過程以及採用分治遞迴演算法後的對比
x B21
原始演算法
矩陣乘法相信大家都有所瞭解,即對於任意A=(aij)和B=(bij)都是n x n矩陣,可以定義矩陣乘法為cij= ∑k=1~naik x bkj。
1 SQUARE-MATRIX-MULTIPLY(A,B) 2 { 3 n = A.rows 4 let C be a new n x n matrix 5 for i =1 to n 6 for j =1 to n 7 c(ij) = 0 8 for k = 1 to n 9 c(ij) += a(ik) x b(kj)10 return C 11 }
以上程式碼為矩陣乘法的虛擬碼,第5行遍歷所有行,第6行遍歷所有列,第8行則將cij累加起來,所需要花費的時間顯而易見,為O(n3)。
一個簡單的分治演算法
假設每個矩陣都是n x n矩陣,且n為2的冪,這樣便可以使得每一個矩陣都可以劃分為四個子矩陣,由此來計算C = A x B。
由此可以得到,若A = [A11,A12,A21,A22],同理B和C也可以分成四個子矩陣,則可以得到以下四個公式:
C11= A11 x B11 + A12x B21
C12= A11 x B12 + A12 x B22
C21 = A21 x B11 + A22
C22 = A21 x B12 + A22 x B22
通過這樣的方式我們可以直接設計一個遞迴分治演算法:
1 SQUARE-MATRIX-MULTIPLY-RECURSIVE(A, B) 2 { 3 n = A.row 4 let C be a new n x n matrix 5 if n == 1 6 c11 = a11 x b11 7 else partition A, B, C 8 C11 = SQUARE-MATRIX-MULTIPLY-RECURSIVE(A11, B11) + SQUARE-MATRIX-MULTIPLY-RECURSIVE(A12, B21)9 C12 = SQUARE-MATRIX-MULTIPLY-RECURSIVE(A11, B12) + SQUARE-MATRIX-MULTIPLY-RECURSIVE(A12, B22) 10 C21 = SQUARE-MATRIX-MULTIPLY-RECURSIVE(A21, B11) + SQUARE-MATRIX-MULTIPLY-RECURSIVE(A22, B21) 11 C22 = SQUARE-MATRIX-MULTIPLY-RECURSIVE(A21, B12) + SQUARE-MATRIX-MULTIPLY-RECURSIVE(A22, B22) 12 return C 13 }
顯然,這裡的步驟7被省略了。那麼應該如何分解子矩陣呢?如果我們重新建立12個子矩陣進行計算,那麼我們將花費O(n2)的時間來建立這些子矩陣。實際上,我們使用下標來對子矩陣進行標記,所需要的時間就是常數項時間即O(1),對遞迴所消耗的時間就毫無影響。
現在我們來推測一下該遞迴分治演算法的執行時間,令T(n)表示兩個n x n矩陣乘積的時間。對於第3~7行,所消耗的時間均為常數項時間。對於8~11行,所消耗的時間則為T(n/2),同時,要計算4次矩陣加法,所消耗的時間為O(n2),因此我們可以得到時間遞迴公式:
T(n) = 8T(n/2) + O(n2)
該遞迴公式的解為O(n3),並不優於直接對矩陣進行乘法運算。
下一次我將詳細介紹Strassen演算法的過程❤