您的位置:首页 > 职场人生

黑马程序员____矩阵相乘常规法和Strassen方法算法分析

2012-09-17 12:43 531 查看
----------------------android培训java培训、期待与您交流!
----------------------

矩阵相乘是计算机编程领域的常见问题。按照常规方法解决问题的算法复杂度为,在矩阵规模超过一定规模后,复杂度增长使得计算时间过长,无法令人满意。显然,矩阵相乘的下界在,但这个想法过于理想。目前得到的最优方案为,由于最优方案的实现过于复杂,没有在计算机上完美实现。Strassen方法通过分治递归的思想,将算法的复杂度降到了左右,并且实现较为简单。本实验的目的就是在程序实现矩阵相乘常规法和Strassen方法的基础上,比较两者在不同数据规模下的速度。

一、
算法分析

1.
矩阵相乘常规法



伪码实现如下:

MATRIX-MULTIPLY(A, B)

n ← rows[A]

let C be an n × n matrix

for i ← 1 to n

do for j ← 1 to n

do cij ← 0

for k ← 1 to n

do cij ← cij + aik× bkj

return C

通过伪代码循环嵌套的分析,可以直观地看出算法复杂度为。

2.
矩阵相乘Strassen法

将一个 n × n的矩阵乘法分割为 2 × 2个(n/2) × (n/2)大小的子矩阵相乘。



P1=a
⋅(f−h)
P2= (a+
b)⋅h
P3= (c+
d)⋅e
P4=d
⋅(g−e)
P5= (a+
d)⋅(e+h)
P6= (b−d)⋅(g+h)
P7= (a−c)⋅(e+f
)
r =P5+
P4−P2+P6
s =P1+
P2
t =P3+
P4
u =P5+
P1−P3−P7
这样在子矩阵的加乘法中,一共涉及到7次乘法,由于在大规模矩阵的情况下,矩阵相乘的复杂度远大于加减矩阵的复杂度,所以Strassen算法比常规法有所改进(Strassen方法的正确性在此略过)。




b81c
法复杂度得到一定的改进。

二、程序实现

关键步骤说明
程序在实现的过程中。有时会碰到分割出的矩阵的n不为偶数的情形,此时应对矩阵加一条零边,使分割顺利进行,而不影响计算结果。

分割出的矩阵使用动态二维矩阵存储,节约存储空间。在矩阵使用完以后及时回收,以免堆内存溢出。

三、测试程序

范例测试(正确性测试)
The Source matrix is displayed below:
1 7 4 0 9

4 8 8 2 4

5 5 1 7 1

1 5 2 7 6

1 4 2 3 2

The Target matrix is displayed below:

2 1 6 8 5

7 6 1 8 9

2 7 9 5 4

3 1 2 3 3

4 1 1 3 8

常规法所得结论:

The Result matrix is displayed below:

95 80 58 111 156

102 114 112 154 162

72 50 59 109 103

86 58 49 97 127

51 44 36 65 74

Strassen法所得结论:

The Result matrix is displayed below:

95 80 58 111 156

102 114 112 154 162

72 50 59 109 103

86 58 49 97 127

51 44 36 65 74

根据手动计算结果,均正确。

压力测试(不同数据规模下运行速度):(单位为秒)



图表1



表格1

数据取600位上界,即超过10分钟跳出。可以看到使用Strassen算法时,耗时不但没有减少,反而剧烈增多,在n=700时计算时间就无法忍受。仔细研究后发现,采用Strassen算法作递归运算,需要创建大量的动态二维数组,其中分配堆内存空间将占用大量计算时间,从而掩盖了Strassen算法的优势。于是对Strassen算法做出改进,设定一个界限。当n<界限时,使用普通法计算矩阵,而不继续分治递归。

改进后算法优势明显,就算时间大幅下降。之后,针对不同大小的界限进行试验。在初步试验中发现,当数据规模小于1000时,下界S法的差别不大,规模大于1000以后,n取值越大,消耗时间下降。最优的界限值在32~128之间。

因为计算机每次运算时的系统环境不同(CPU占用、内存占用等),所以计算出的时间会有一定浮动。虽然这样,试验结果已经能得出结论Strassen算法比常规法优势明显。使用下界法改进后,在分治效率和动态分配内存间取舍,针对不同的数据规模稍加试验可以得到一个最优的界限。

四、 实验小结

本次实验成功实现了矩阵相乘的常规法和Strassen算法,发现了Strassen算法在使用动态内存分配时的缺陷,并进行改进。实验中还发现Strassen算法消耗内存明显,在使用空间换取时间时要进行适当取舍。

---------------------- android培训java培训、期待与您交流!
----------------------

详细请查看:http://edu.csdn.net/heima
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息