矩阵乘法 - 分而治之 vs Strassen,分而治之更快?

Posted

技术标签:

【中文标题】矩阵乘法 - 分而治之 vs Strassen,分而治之更快?【英文标题】:Matrix Multiplication - Divide & Conquer vs Strassen, Divide & Conquer is faster? 【发布时间】:2012-03-04 10:16:06 【问题描述】:

据我了解,Strassen 的矩阵相乘方法应该是最快的……但分治法显然是我测试中最快的……我做错了什么吗?或者这样说对吗?

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

所以我只是在每个方法中都有一个单独的“counter++”并划分时间“recorded / counter++”

到目前为止,这是我的时代:(按上/下顺序:经典、分而治之、施特拉森)(大小 = 矩阵大小)

尺寸 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 纳秒

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

【问题讨论】:

你确定你的分治算法能给出正确的结果吗? Strassen 本质上是分而治之;他们以这种方式进行多次加法和乘法一定有一些原因。 是的,我实际上将所有计算的矩阵打印到控制台,并确保它们都是相同的 我同意pad,确保你在比较结果。不是用手。计算并打印均方误差。 我保证我做到了。我将复制并粘贴我的输出示例(编辑 OP) "计算并打印均方误差。"我不知道该怎么做,或者这意味着什么 【参考方案1】:

Strassen 中的常数因子非常高,因此对于大多数输入,分治会更快。尝试使用更大的矩阵(数千个元素)运行您的测试,看看 Strassen 是否超过了分治法

【讨论】:

我的电脑无法处理高于 256 的任何内容。在 512 处它会停止(教授说它应该最终停止)。只是模式似乎不会改变?... 256 仍然是一个相对较小的矩阵。很多这些算法都适用于非常大的输入。 我必须就我的发现写一份报告.. 没有其他人在回答这个问题,所以我依靠你的回答 Oleksi!谢谢【参考方案2】:

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

实际上,先运行100次不记录时间,然后运行100次记录它。如果有时间,甚至可以上千次,越多越好。

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

Strassen 较慢是因为它对缓存不友好,它只是“理论上”最快的。 “cache-oblivious”算法,例如你的分而治之的算法,通常更快。

【讨论】:

【参考方案5】:

Strassen 的算法时间复杂度是 ,但分治算法的时间复杂度是 (你知道, 几乎是 )。

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

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

因此,如果您的输入很小,请使用您知道的最快的算法。但如果您的输入量非常大,请使用具有最小渐近时间复杂度的算法。

【讨论】:

以上是关于矩阵乘法 - 分而治之 vs Strassen,分而治之更快?的主要内容,如果未能解决你的问题,请参考以下文章

文心一言 VS 讯飞星火 VS chatgpt (22)-- 算法导论4.2 2题

实施 Strassen 矩阵乘法算法的问题

矩阵乘法的Strassen算法及时间复杂度

矩阵乘法 strassen

Algorithms - Strassen's algorithm for matrix multiplication 矩阵乘法 Strassen 算法

Algorithms - Strassen's algorithm for matrix multiplication 矩阵乘法 Strassen 算法