矩阵相乘的Strassen算法
2016-05-05 22:46
344 查看
LZ是菜鸟一枚,非计算机专业学生,正在学习算法导论这本书,希望养成学习完一个问题之后进行归纳整理的习惯,所以开始了博客之路,内容都是最基础的笔记,如果发现错误希望你能慷慨的帮我指出来,这样我才能改正并进步哦。
话不多说 下面是第二次记录么么哒
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+aik⋅bkj
return C
上述代码中总共有三重循环,每一层循环都执行n步,因此时间复杂度为Θ(n3),下面考虑使用分治思想来降低这个时间复杂度。
[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算法。
P1=A11(B12−B22)
P2=(A11+A12)B22
P3=(A21+A22)B11
P4=A22(B21−B11)
P5=(A11+A22)(B11+B22)
P6=(A12−A22)(B21+B22)
P7=(A11−A21)(B11+B12)
相乘后的矩阵结果表示为:
C11=P5+P4−P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1−P3−P7
最后给出相关的伪代码表示
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,B12−B22)
P2=MATRIX-STRASSEN(A11+A12,B22)
P3=MATRIX-STRASSEN(A21+A22,B11)
P4=MATRIX-STRASSEN(A22,B21−B11)
P5=MATRIX-STRASSEN(A11+A22,B11+B22)
P6=MATRIX-STRASSEN(A12−A22,B21+B22)
P7=MATRIX-STRASSEN(A11−A21,B11+B12)
C11=P5+P4−P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1−P3−P7
return C
显然这个算法的时间复杂度的递归式如下:
使用主方法计算可得时间复杂度为Θ(nlg7),相比前面的算法有一定的改进。
话不多说 下面是第二次记录么么哒
问题描述
实现两个n维方阵A=(aij)n×n和B=(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+aik⋅bkj
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(B12−B22)
P2=(A11+A12)B22
P3=(A21+A22)B11
P4=A22(B21−B11)
P5=(A11+A22)(B11+B22)
P6=(A12−A22)(B21+B22)
P7=(A11−A21)(B11+B12)
相乘后的矩阵结果表示为:
C11=P5+P4−P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1−P3−P7
最后给出相关的伪代码表示
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,B12−B22)
P2=MATRIX-STRASSEN(A11+A12,B22)
P3=MATRIX-STRASSEN(A21+A22,B11)
P4=MATRIX-STRASSEN(A22,B21−B11)
P5=MATRIX-STRASSEN(A11+A22,B11+B22)
P6=MATRIX-STRASSEN(A12−A22,B21+B22)
P7=MATRIX-STRASSEN(A11−A21,B11+B12)
C11=P5+P4−P2+P6
C12=P1+P2
C21=P3+P4
C22=P5+P1−P3−P7
return C
显然这个算法的时间复杂度的递归式如下:
使用主方法计算可得时间复杂度为Θ(nlg7),相比前面的算法有一定的改进。
相关文章推荐
- java算法导论之FloydWarshall算法实现代码
- MIT Introduction to Algorithms 学习笔记(一)
- MIT Introduction to Algorithms 学习笔记(二)
- MIT Introduction to Algorithms 学习笔记(三)
- MIT Introduction to Algorithms 学习笔记(四)
- MIT Introduction to Algorithms 学习笔记(五)
- MIT Introduction to Algorithms 学习笔记(六)
- MIT Introduction to Algorithms 学习笔记(七)
- MIT Introduction to Algorithms 学习笔记(八)
- MIT Introduction to Algorithms 学习笔记(九)
- MIT Introduction to Algorithms 学习笔记(十)
- 堆排序/优先级队列
- 插入排序
- Red-Black Tree 的Java实现
- 逆序对
- 算法导论之堆
- LCS 最长公共子序列
- 使用Java完成《算法导论》习题2.2-2
- 使用Java完成《算法导论》习题2.3-2
- 使用Java完成《算法导论》习题2.3-4