最简单的矩阵乘法可以通过三重循环来实现,其时间复杂度为Θ(n3),Strassen算法通过巧妙的增加加法来减少乘法实现了O(n2.81)的时间复杂度
Strassen算法的四个步骤:
- 将输入矩阵A、B与输出矩阵C分解为n/2×n/2的子矩阵,采用下标计算方法,此步骤花费Θ(1)时间。
- 创建10个n/2×n/2的矩阵,每个矩阵保存步骤1中创建的两个子矩阵的和或差,花费Θ(n2)。
- 用步骤1中创建的子矩阵和步骤2中创建的10个矩阵,递归的计算7个Pi矩阵积。
- 通过Pi矩阵的不同组合进行加减运算,计算出C的子矩阵,花费时间Θ(n2)。
为了方便计算矩阵积C=A⋅B,假定三个矩阵均为n×n矩阵,其中n为2的幂。做出这个假设是因为在每个分解步骤中,n×n矩阵都被划分为4个n/2×n/2的子矩阵,如果假定n是2的幂,则只要n≥2即可保证子矩阵规模n/2为整数。
假定将A、B和C均分解为4个n/2×n/2的子矩阵:
A=[A11A21A12A22],B=[B11B21B12B22],C=[C11C21C12C22]
根据矩阵乘法的定义,可以得到如下4个公式:
C11C12C21C22=A11⋅B11+A12⋅B21=A11⋅B12+A12⋅B22=A21⋅B11+A22⋅B21=A21⋅B12+A22⋅B22(1)
步骤2中,创建如下10个矩阵:
S1S2S3S4S5S6S7S8S9S10=B12−B22=A11−A12=A21+A22=B21−B21=A11+A22=B11+B22=A12−A22=B21+B22=A11−A21=B11+B12(2)
由于必须进行10次n/2×n/2矩阵的加减法,因此,该步骤花费Θ(n2)时间。
步骤3中,递归的计算7次n/2×n/2矩阵的乘法,如下所示:
P1P2P3P4P5P6P7=A11⋅S1=S2⋅B22=S3⋅B11=A22⋅S4=S5⋅S6=S7⋅S8=S9⋅S10
步骤4中,
C11C12C21C22=P5+P4−P2+P6=P1+P2=P3+P4=P5+P1−P3−P7
共进行了8次n/2×n/2矩阵的加减法,因此花费Θ(n2)时间。
代值计算后可以发现(2)式结果与(1)式是相同的。
描述Strassen算法运行时间T(n)的递归式:
T(n)={Θ(1)7T(n/2)+Θ(n2)n=1n>1
用主方法来求解这个递归式,可知解为T(n)=Θ(nlg7),由于lg7介于2.80和2.81之间,所以时间复杂度为O(n2.81)。
天知道Strassen是怎么想到这个方法的QAQ