非常特殊矩阵的最大子矩形

时间:2012-01-21 22:06:59

标签: algorithm r

在处理图像处理任务时,我遇到了以下问题:单位正方形中有n个坐标为$ x_i $和$ y_i $的点,每个点都分配有正或负权重$ w_i $。找到一个矩形,使得位于矩形内的那些点的所有权重之和为正和最大。

通过定义合适的网格,可以将问题重新描述为在n×n矩阵A中找到子矩阵,其中元素之和是最大的。这也被称为“最大子矩形问题”,并且之前已经在SO上进行了讨论。虽然蛮力方法的运行时间为O(n ^ 5),但有一种棘手的解决方案,其运行时间为O(n ^ 3)。它利用一个解决方案来解决相应的一维问题,称为"maximal subarray problem",运行时间为O(n)。

我在R中实现了两种算法,可以在几秒钟内解决100个点。但是有了数千个点,它可能会太慢,甚至可能将环路外包给一些Fortran或C代码。

现在看矩阵A.当假设(没有失去一般性)所有点都有不同的x坐标或y坐标时,A有一个特殊的形式:在A的每一行和一列中都有一个非零元素。对于具有此特殊属性的矩阵,我假设应该有一个算法在O(n ^ 2)时间内执行任务,甚至更好。

以下是添加了最佳矩形的示例:

set.seed(723)
N <- 50; w <- rnorm(N)
x <- runif(N); y <- runif(N)
clr <- ifelse (w >= 0, "blue", "red")
plot(x, y, pch = 20, col = clr, xlim = c(0, 1), ylim = c(0, 1))
rect(0.075, 0.45, 0.31, 0.95, border="gray")

你看到可能有红色,即。负,指向最佳矩形。它还表明,解决x坐标和y坐标的一维情况是不够的。

我会将标准解决方案转换为Fortran,但我肯定希望手头有更高效的算法。

3 个答案:

答案 0 :(得分:1)

These guys(从维基页面找到)声称对于二维情况有一个更简单的子立方解决方案。它可能是你已经知道的那个。

答案 1 :(得分:0)

请参阅“稀疏矩阵中的最大和子矩形”的已接受答案。对于具有m个非零元素的nxn矩阵,解决方案需要O(nm log n)时间。所以,对于你来说,由于你有n个非零元素,这将给出O(n ^ 2 log n)时间。可能你将能够处理n大于或等于50倍的情况,而不是标准的O(n ^ 3)解决方案。

答案 2 :(得分:-1)

我能做的最好的是O(n ^ 2 log n)。

如果我们看一下kadane的2D算法对你的类型输入中的Kadane的1D算法进行的n + 1选择2次调用,除了O(n)个连续对之外的所有对都在1D阵列上,这些阵列仅在一个元素中不同。我将介绍卡丹的1D的分而治之的变种;通过缓存每个递归调用的结果,只需要重新计算涉及已更改的数组元素的O(log n),从而将内部循环的(分摊的)运行时间从Theta(n)减少到Theta(log n)。

def maxsubarray(arr, a, b):
    # this function returns a 4-tuple
    # element 0 is the max over intervals of the form [i, j)
    # element 1 is the max over intervals of the form [i, b)
    # element 2 is the max over intervals of the form [a, j)
    # element 3 is the max over intervals of the form [a, b), i.e., sum(arr[a:b])
    n = b - a
    if n == 0:
        return (0, 0, 0, 0)
    elif n == 1:
        x = arr[a]
        y = max(x, 0)
        return (y, y, y, x)
    else:
        m = a + n // 2
        l = maxsubarray(arr, a, m)
        r = maxsubarray(arr, m, b)
        return (max(l[0], r[0], l[1] + r[2]),
                max(r[1], l[1] + r[3]),
                max(l[2], l[3] + r[2]),
                l[3] + r[3])