寻找总和最大的子矩阵[重复]
Posted
技术标签:
【中文标题】寻找总和最大的子矩阵[重复]【英文标题】:Finding a submatrix with largest sum [duplicate] 【发布时间】:2011-03-23 08:13:21 【问题描述】:可能重复:Finding a submatrix with the maximum possible sum in O(n^2)
我有一个 NxN 矩阵。我想在上面的矩阵中找出一个 MxM 子矩阵,它的元素之和最大。
什么是有效的算法。
【问题讨论】:
这不一定是重复的。重要的区别在于,在这个更简单的情况下,原始矩阵是正方形的,并且要找到的矩阵的大小是预先知道的(除非 M 在开始时是未知的,在这种情况下它们会非常相似)这意味着你只需要找到位置,而不是内部矩阵的形状,简化了问题。有了这些限制,这可以在二次时间内解决(见下面的答案),而标记为重复的问题不能在小于三次的时间内解决。 【参考方案1】:我有一个算法,在扩大 M 时以常数时间运行,在扩大 N 时以二次时间运行。
第一个子矩阵照常计数。保存总和。然后向右移动一个行字段 - 两个 MxM 矩阵重叠,因此您只需将两个不重叠的列相加即可。保存所有金额。现在您可以为该行选择最大的总和。
移到下一行。还记得保存的金额吗?第一行和第二行的 MxM 矩阵再次重叠,因此您只需将 MxM 矩阵的第一行和最后一行相加,然后在第二行计算第一个和。
现在转到第二行的第二个总和。和上面做同样的事情,但是你发现第一个 sum 的最后几行和第二行的第二个 sum 又重叠了。
我知道这有点令人困惑,如果你不明白,请告诉我,我会画一些图。该算法基于this answer中的论文。
编辑:我知道我答应了图片,但这应该足够了:
A AB AB AB AB B AC ABCD ABCD ABCD ABCD BD AC ABCD ABCD ABCD ABCD BD AC ABCD ABCD ABCD ABCD BD AC ABCD ABCD ABCD ABCD BD C CD CD CD CD D这是四个子模块,A、B、C、D,定位如下:
AB 光盘
首先计算 A 子矩阵的总和:sum(A)。这里没有优化。现在你要计算 B 的总和:sum(B)。您可以执行与 A 相同的操作,但请注意 A 和 B 重叠。因此,您将 sum(A) 分配给 sum(B),计算垂直向量的总和 A AC AC AC AC
并从 sum(B) 中减去 if,然后计算垂直向量的总和 B BD BD BD BD
并将其添加到 sum(B)。
你有 sum(B)。现在您可以继续并计算整个第一行子主题。
移动到第二行:matices C 和 D。你不必对整个 matice C 求和,因为在上一行中,你保存了 sum(A)。请注意它们再次重叠。你只需要添加A和C的区别:
//代码(1) subC = sum([A AB AB AB AB]) //作为减法 C addC = sum([C CD CD CD CD]) //as add C sum(C) = sum(A) - subC + addC
你有 sum(C)。现在你可以像这样得到 sum(D):
//代码(2) subD = sum([AB AB AB AB B]) //作为减法 D addD = sum([CD CD CD CD D]) //as add D sum(D) = sum(B) - subD + addD
但是比较 subD 与 subC 和 addD 与 addC。它们重叠!所以你可以这样做:
//代码(3) subD = subC - A + B //从 subC 中减去 A 上的值并将 B 添加到它 addD = addC - C + D //同上 sum(D) = sum(B) - subD + addD
您会看到,计算一个子矩阵的总和而不是 25 个附加项,而是 6 个。对于每个可能的 MxM 大小,我们对第一个子矩阵有 MxM 个附加项,对于第一行和第一列有 M*2+2 个附加项,并且其余6个。
【讨论】:
是的,正如你所说,我觉得这很混乱..(N - M + 1) * (N - M + 1)
不是线性的...
最坏的情况是M=1
和N—>∞
。在这种情况下,您将不得不比较 NxN 个元素,并且您可以想象的最佳算法只能读取每个元素一次。这意味着复杂度在 N 中不是线性的,而是二次的。您所描述的是通用算法的加速,它将从 N^2*M^2 (即对于每个 (N-M)^2 平方和内部矩阵的 (M^2) 元素)降低到 N^ 2(外矩阵中的每个元素只计入行列外的固定数量的内矩阵)。
修复了线性时间问题。电脑一开机,我就明白了。今天将发布图片。
@Ben Voigt:我已投票重新提出问题,请考虑上面的评论,您可能希望将投票更改为关闭。以上是关于寻找总和最大的子矩阵[重复]的主要内容,如果未能解决你的问题,请参考以下文章