矩阵乘法 - 除以& Conquer vs Strassen,Divide&征服更快?

时间:2012-02-12 22:23:28

标签: performance algorithm matrix matrix-multiplication divide-and-conquer

根据我的理解,Strassen的矩阵乘法方法应该是最快的...但是Divide&征服方法显然是我测试中最快的...我做错了什么?或者这是正确的吗?

指令是:“然后花费的总时间除以算法执行的次数,以获得解决给定实例所花费的时间”

所以我只是在每个方法中都有一个单独的“counter ++”并将时间划分为“录制/计数器++”

到目前为止,这是我的时代:(按顺序排列上/下:经典,除法和征服,strassen)(大小=矩阵大小)

尺寸2

经过的时间:8660纳秒

经过的时间:3849纳秒

经过的时间:5377纳秒

4号

经过的时间:24864纳秒

经过的时间:3080纳秒

经过的时间:5229纳秒

8号

经过的时间:125435纳秒

经过的时间:2920纳秒

经过的时间:5196纳秒

16号

经过的时间:867149纳秒

经过的时间:1559纳秒

经过的时间:2853纳秒

尺寸32

经过的时间:5191721纳秒

经过的时间:972纳秒

经过的时间:1722纳秒

64码

经过的时间:8155785纳秒

经过的时间:874纳秒

经过的时间:1696纳秒

示例输出 以下是我输出大小为4的矩阵的示例:

第一个随机生成矩阵: 10 57 33 70
6 12 38 70
20 41 65 98
83 0 31 73
第二个随机生成矩阵: 11 70 54 79
2 51 38 71
27 53 37 86
48 87 20 41
经典乘法矩阵: 4475 11446 5327 10545
4476 9136 3586 7464
6761 15462 7003 14099
5254 13804 7089 12216
经过的时间:21232纳秒

划分和征服乘法矩阵: 4475 11446 5327 10545
4476 9136 3586 7464
6761 15462 7003 14099
5254 13804 7089 12216
经过的时间:3042纳秒

Strassen乘法矩阵: 4475 11446 5327 10545
4476 9136 3586 7464
6761 15462 7003 14099
5254 13804 7089 12216
经过的时间:5303纳秒

5 个答案:

答案 0 :(得分:3)

斯特拉森的常数因素非常高,因此对于大多数输入来说,分而治之的速度会更快。尝试使用更大的矩阵(数千+元素)运行测试,看看Strassen的超越是否划分和征服

答案 1 :(得分:3)

只是一个想法:不要运行一次,运行100次。

实际上,首先运行100次而不记录时间,然后进行100次记录。如果你有时间,甚至数千次,就越好。

System.nanoTime()有时可能非常不准确,尤其是在现代计算机上同时运行数十个进程时。运行越多,不准确性对结果的影响就越小。最初的非定时尝试是“加速”Java VM,确保每个类都被加载,内存分配和垃圾收集以稳定的节奏稳定下来,等等。

可以提高测试准确性的另一个变化是从实际计算代码中删除所有类型的System.out调用(或实际上是任何输出),因为这只会给两个函数增加一个恒定的开销,从而扭曲结果

答案 2 :(得分:0)

您的“经典”实施有问题。它不应该那么慢。经典应该更快,直到你得到相当大的矩阵。当然,使用标准矩阵乘法,4x4应该更快,更快。

答案 3 :(得分:0)

Strassen的速度较慢,因为它对缓存不友好,仅在理论上是最快的。通常,“忽略缓存”算法(例如您的分治法)会更快。

答案 4 :(得分:0)

Strassen的算法时间复杂度为,但分而治之的算法时间复杂度为(您知道几乎为)。

当我们比较使用O(或theta)函数的某些算法时,我们的意思是当输入大小接近无穷大时,它们会更快(或更慢)。

如您所见,对于n的较小值,具有时间复杂度的算法可能比具有时间复杂度的算法要慢。这是因为常数(仅在输入大小较小时才显示其影响)。

chart

因此,如果输入大小较小,请使用已知的最快算法。但是,如果输入量很大,请使用渐近时间复杂度最小的算法。