寻找总和最大的子矩阵[重复]

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) = sum(A) - sum(A AC AC AC AC) + sum(B BD BD BD BD)

你有 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=1N—>∞。在这种情况下,您将不得不比较 NxN 个元素,并且您可以想象的最佳算法只能读取每个元素一次。这意味着复杂度在 N 中不是线性的,而是二次的。您所描述的是通用算法的加速,它将从 N^2*M^2 (即对于每个 (N-M)^2 平方和内部矩阵的 (M^2) 元素)降低到 N^ 2(外矩阵中的每个元素只计入行列外的固定数量的内矩阵)。 修复了线性时间问题。电脑一开机,我就明白了。今天将发布图片。 @Ben Voigt:我已投票重新提出问题,请考虑上面的评论,您可能希望将投票更改为关闭。

以上是关于寻找总和最大的子矩阵[重复]的主要内容,如果未能解决你的问题,请参考以下文章

获得最大和的子矩阵?

动态规划---例题4.最大子矩阵和问题

[VijosP1764]Dual Matrices 题解

c_cpp 最大子阵列总和。在具有最大总和的数组(包含至少一个数字)中查找连续的子数组。

java 得到最大总和的子阵列

找到矩阵中总和最大的列并打印出来