考虑两个 n 级矩阵 A, B, 矩阵 C = A * B. 则有 c i j = ∑ k = 1 n a i j ∗ b k j c_{ij} = \sum_{k=1} ^n a_{ij}*b_{kj} cij=∑k=1naij∗bkj.
对于两个矩阵相乘的问题,我们给出三个解决办法:迭代算法、简单分治算法、strassen分治算法。
解法一:迭代算法,即使用三层循环,这是最简单的算法,其代码如下:
void matrix_multiply( vector<vector<int>>& A, vector<vector<int>>& B, vector<vector<int>>& C){
// A, B, C 均为 n * n 矩阵,且 C[i][j] = 0;
for( int i = 0; i < A.size(); i++)
for(int j = 0; j < A.size(); j++)
for( int k = 0; k < A.size(); k++)
C[i][j] += A[i][k]* B[k][j];
}
测试用例:
算法分析:由于使用了三层循环,得到其时间复杂度为 O ( n 3 ) O(n^3) O(n3).
方法二:简单的分治算法
利用分块矩阵计算矩阵乘法。
对于 n 级矩阵A, 我们可以将其划分为 4 个 n/2 级矩阵,例如:
A n ∗ n = ( A 11 A 12 A 21 A 22 ) A_{n*n} = \begin{pmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \\ \end{pmatrix} An∗n=(A11A21A12A22)
同理,有
B n ∗ n = ( B 11 B 12 B 21 B 22 ) , C n ∗ n = ( C 11 C 12 C 21 C 22 ) B_{n*n} = \begin{pmatrix} B_{11} & B_{12} \\ B_{21} & B_{22} \\ \end{pmatrix} , C_{n*n} = \begin{pmatrix} C_{11} & C_{12} \\ C_{21} & C_{22} \\ \end{pmatrix} Bn∗n=(B11B21B12B22),Cn∗n=(C11C21C12C22)
则 C = AB 可以改写为:
( C 11 C 12 C 21 C 22 ) = ( A 11 A 12 A 21 A 22 ) ( B 11 B 12 B 21 B 22 ) \begin{pmatrix} C_{11} & C_{12} \\ C_{21} & C_{22} \\ \end{pmatrix} = \begin{pmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \\ \end{pmatrix} \begin{pmatrix} B_{11} & B_{12} \\ B_{21} & B_{22} \\ \end{pmatrix} (C