可能重复:
Finding a submatrix with the maximum possible sum in O(n^2)
我有一个NxN矩阵。我想找出上述矩阵的MxM子矩阵,其元素总和最大。
什么是有效的算法。
答案 0 :(得分:2)
我有一个算法,当放大N时会在恒定时间内运行,而在放大N时会增加二次时间。
第一个子矩阵像往常一样计算。节省金额。然后向右移动一行字段 - 两个MxM矩阵重叠,因此您只需将两个非重叠列相加即可。保存所有金额。现在您可以选择该行的最大金额。
转到下一行。还记得保存的金额吗?第一行和第二行的MxM矩阵再次重叠,因此您可以对MxM矩阵的第一行和最后一行求和,并计算第二行的第一行。
现在转到第二行的第二个总和。做同样的事情,但你发现第一行的最后一行和第二行的第二行重叠。
我知道这有点令人困惑,如果你不明白,请告诉我,我会画出一些照片。该算法基于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 CD
首先计算A子矩阵的总和:sum(A)。这里没有优化。现在你要计算B的总和:总和(B)。您可以像在A中一样,但请注意A和B重叠。因此,您将sum(A)指定给sum(B),计算垂直向量A AC AC AC AC
的总和,并从sum(B)中减去if,然后计算垂直向量的总和B BD BD BD BD
并将其加到总和中(B)。
sum(B) = sum(A) - sum(A AC AC AC AC) + sum(B BD BD BD BD)
你有总和(B)。现在,您可以继续并计算整个第一行子项。
移动到第二行:matices C和D.您不必对整个matice C求和,因为在前一行中,您保存了sum(A)。注意它们再次重叠。您只需要添加A和C之间的差异:
//code (1) subC = sum([A AB AB AB AB]) //as substract C addC = sum([C CD CD CD CD]) //as add C sum(C) = sum(A) - subC + addC
你有总和(C)。现在你可以得到这样的总和(D):
//code (2) subD = sum([AB AB AB AB B]) //as substract D addD = sum([CD CD CD CD D]) //as add D sum(D) = sum(B) - subD + addD
但是将subD与subC和addD与addC进行比较。他们重叠!所以你可以这样做:
//code (3) subD = subC - A + B //from subC substract value on A and add B to it addD = addC - C + D //same as above sum(D) = sum(B) - subD + addD
你可以看到,而不是25个用于计算一个子矩阵之和的加法,我们做6.对于MxM的每个可能大小,我们对第一个子矩阵有MxM加法,对第一个行和第一个列有M * 2 + 2个加法其余的6个愿望。