《算法导论》学习笔记之Chapter4.2矩阵乘法Strassen

来源:互联网 发布:虾米音乐 2.0mac 编辑:程序博客网 时间:2024/05/01 05:01

4.2 矩阵乘法,代码如下:

//求两个方阵的乘积public static int[][] squareMatrixMultiply(int[][] a, int[][] b){int n = a.length;int[][] c = new int[n][n];for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){c[i][j] = 0;for (int k = 0; k < n; k++){c[i][j] = c[i][j] + a[i][k] * b[k][j];}}}return c;}

上述直接计算矩阵乘积的算法时间复杂度有θ(n.^3)。如果采用分治策略,递归算法进行矩阵乘积计算,时间复消耗T(n) = 8T(n/1) + θ(n.^2);

下面介绍一个速度更快的算法,Strassen算法:其实该算法步骤很简单,很好实现,但是实现起来较为繁琐(此处是指用java语言实现),这里就只记下其原理,实现步骤:

(1)将矩阵(方阵,且n是2的幂)A,B,C均分解为四个子矩阵;

(2)创建10个n/2 * n/2的方阵S1,。。。S10,而Sn如下:

                                      S1 = B12-B22;S2=A11+A12;.......S10=B11+B12

(3)用步骤1和步骤2中的矩阵,递归的计算7个矩阵乘积P1,...P7:

                                              P1=A11*S1;P2=S2*B22 ....P7=S9*S10;

(4)对步骤3创建的Pi矩阵进行加减运算,即可求出C的4个子矩阵:

                                     C11=P5+P4-P2+P6;......C22=P5+P1-P3-P7;


从上述步骤可知,个人觉得该算法没有什么特殊意义,就是发现了其中的冗余计算步骤(但是我没仔细推敲),在单纯的分治算法递归的基础上进行一些改进,使基本的8次矩阵乘法,变成了现在的7次矩阵乘法,说明8次矩阵乘法运算中又一次是多余的,就把这次多余的矩阵乘法,通过矩阵加减运算进行替代,提升了算法速度。Strassen使得时间复杂度变为T(n) = 7T(n/2) + θ(n.^2),即n的2次方。

在n较小时,Strassen算法可能不如直接算法快,但当n很大时,Strassen算法会快于直接算法。

在实际应用中,稠密矩阵的快速乘法程序在矩阵规模超过一个交叉点时使用Strassen算法,一旦子问题规模降低到交叉点之下,就切换到一个简单的方法。交叉点的大小依赖于具体系统。



原创粉丝点击