矩阵相乘的Strassen算法

LZ是菜鸟一枚,非计算机专业学生,正在学习算法导论这本书,希望养成学习完一个问题之后进行归纳整理的习惯,所以开始了博客之路,内容都是最基础的笔记,如果发现错误希望你能慷慨的帮我指出来,这样我才能改正并进步哦。
话不多说 下面是第二次记录么么哒

问题描述

实现两个n维方阵A=(aij)n×nB=(bij)n×n的乘法运算,C=AB,C中的元素cij表示为:

cij=k=1naikbkj


使用的算法

分治策略。
如果直接进行计算,C中共有n2个元素,每个元素根据上面的公式要计算n个值的和。伪代码如下:
SQUARE-MATRIX-MULTIPLE(A,B)
n=A.rows 计算方阵的行数和列数
let C be a new n×n matrix
for i=1 to n
for j=1 to n
cij=0
for k=1 to n
cij=cij+aikbkj
return C
上述代码中总共有三重循环,每一层循环都执行n步,因此时间复杂度为Θ(n3),下面考虑使用分治思想来降低这个时间复杂度。

简单地分治

首先我们先考虑一个比较简单直观的分治算法,简单起见将三个矩阵的维数n设为2的幂,并且简单的将每个矩阵分别划分为四个子矩阵的形式,如下:

[A11A21A12A22],[B11B21B12B22],[C11C21C12C22]

由此可以将公式C=AB写成下面一组等价的方程:

C11=A11B11+A12B21

C12=A11B12+A12B22

C21=A21B11+A22B21

C22=A21B12+A22B22

分析上述四个方程,其中包含8个n2×n2的矩阵的乘法运算,和4个n2×n2矩阵的加法运算,加法运算的时间复杂度是Θ(n2)。从而写出时间复杂度的递归式如下:
这里写图片描述
使用主方法求解上述递归式,可以得到该简单分治策略的时间复杂度是Θ(n3),相比直接计算的方法并没有明显的改善。仔细分析上述递归式我们不难看到,分治后的算法之所以没有取得更短的时间复杂度最主要的原因还是递归式中进行了8次递归运算,如果我们能考虑将这里的8次递归减少到7次递归那么相应的时间复杂度就会接着降低到Θ(nlg7)
基于这种思想,出现了Strassen算法。

Strassen算法

该算法的核心思想是令递归树稍微不那么茂盛,也即是上面说的将8次递归减少到7次递归。这7次乘法运算分别是:
P1=A11(B12B22)
P2=(A11+A12)B22
P3=(A21+A22)B11
P4=A22(B21B11)
P5=(A11+A22)(B11+B22)
P6=(A12A22)(B21+B22)
P7=(A11A21)(B11+B12)

相乘后的矩阵结果表示为:
C11=P5+P4P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1P3P7

最后给出相关的伪代码表示

MATRIX-STRASSEN(A,B)
n=A.row
Let C be a new matrix
if n==1
c11=a11b11
else partition A,B and C as

[A11A21A12A22],[B11B21B12B22],[C11C21C12C22]

P1=MATRIX-STRASSEN(A11,B12B22)
P2=MATRIX-STRASSEN(A11+A12,B22)
P3=MATRIX-STRASSEN(A21+A22,B11)
P4=MATRIX-STRASSEN(A22,B21B11)
P5=MATRIX-STRASSEN(A11+A22,B11+B22)
P6=MATRIX-STRASSEN(A12A22,B21+B22)
P7=MATRIX-STRASSEN(A11A21,B11+B12)
C11=P5+P4P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1P3P7

return C

显然这个算法的时间复杂度的递归式如下:
这里写图片描述
使用主方法计算可得时间复杂度为Θ(nlg7),相比前面的算法有一定的改进。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页