Algorithm 动态规划:寻找最大三角形

Algorithm 动态规划:寻找最大三角形,algorithm,dynamic-programming,pseudocode,Algorithm,Dynamic Programming,Pseudocode,我需要用动态规划在一个由0和1组成的矩阵中找到最大的三角形。如果这是我的矩阵: 1 0 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 0 1 然后有两个最大的三角形,其右角位于[2,2]和[4,4]。我只需要寻找正确的等腰三角形(角度为90◦, 45◦, 45◦) 我只需要看一个方向,因为所有其他方向都是对称的。所以基本上我需要一个函数,它接受矩阵并返回一个三角形,三角形是一个对象。我不需要完整的代码。伪代码对我来说也很好 首先,我想在这里使用平

我需要用动态规划在一个由0和1组成的矩阵中找到最大的三角形。如果这是我的矩阵:

 1 0 0 1 1
 0 1 1 1 1
 0 1 1 1 0
 1 1 1 1 1
 1 1 0 0 1
然后有两个最大的三角形,其右角位于[2,2]和[4,4]。我只需要寻找正确的等腰三角形(角度为90◦, 45◦, 45◦) 我只需要看一个方向,因为所有其他方向都是对称的。所以基本上我需要一个函数,它接受矩阵并返回一个三角形,三角形是一个对象。我不需要完整的代码。伪代码对我来说也很好


首先,我想在这里使用平方算法:,当你找到最大的平方,那么最大的三角形一定在那里。但是我可以很容易地找到反例,在这不起作用的地方。在那之后,我试着看上面的单元格,用动态规划来计算,但我不确定下一步该怎么做…所以我的计数在上面的矩阵中,将如下所示:

1 0 0 1 1
0 1 1 2 2
0 2 2 3 0
1 3 3 4 1
2 4 0 0 2
我想我们必须以某种方式使用它

更新

我想我现在非常接近了,当你遍历矩阵n*m,并使count[I][j]=1+min(count[I-1][j],count[I][j-1]),那么看看左边和上面的单元格。我们得到:

1 0 0 1 1
0 1 1 2 2
0 1 2 3 0
1 2 3 4 1
1 2 0 0 1
这对我来说很好,你可以看到[4,4]解的右角在哪里。有人能想出任何反例吗?我只需要返回一个解,所以返回这个解就可以了

更新2: 我找到了一个反例,让位置[4,4]为0,我们得到以下矩阵:

 1 0 0 1 1
 0 1 1 1 1
 0 1 1 1 0
 1 1 1 0 1
 1 1 0 0 1
遍历矩阵后,计数将如下所示:

1 0 0 1 1
0 1 1 2 2
0 1 2 3 0
1 2 3 0 1
1 2 0 0 1
现在它将返回带有右角[3,4](第三行第四列)的三角形,这是不正确的,它应该找到[2,2]。因此我认为可能只是从左上角(我们到目前为止所做的)和右下角开始,并从中取最大值。因此,右下角的计数将如下所示(查看下方和右侧的单元格):

现在我们确实找到了[2,2]的解,所以我认为使用这些方法可以得到解,有人能想出更好的解或反例吗

更新3: kraskevich让我意识到,我们必须使用这个算法四次。从左上角,右上角,左下角,右下角,然后取最大值,因为这样你就得到了所有的可能性。有谁有更好的方法来做到这一点吗?这个算法正确吗?(因此,相同的算法只有四倍,矩阵中只有另一个起点)


另外,对于那些不了解我在做什么的人(我可能会走得有点快),请再看一看:这种方法非常相似,并且很好地解释了所做的事情。

免责声明

我没有仅仅重申OP正在做什么,事实上,我们更新计数的方式是不同的

我同意我应该详细说明解决方案中所述算法有效的原因,因此我编辑了我的答案,以包括我所写方法的关键思想(观察部分)

在我发布我的解决方案时,我完全不知道OP的方法(参见),因此实际上我甚至没有尝试重申OP正在做什么。我只是希望对解决问题的方法给出一个正式的描述

起初,我一直试图避免发布正式的数学正确性证明(因为Stackoverflow主要用于编码),并且我相信从我编写解决方案的方式来看,应该很明显,正确性可以直接从归纳中得出。尽管如此,根据OP的要求,我已经在我的最新更新中包含了完整性证明

========================================================================

解决方案

你可以使用与你所引用的帖子类似的方法。为了简单起见,我们只考虑在讨论的左上角找到直角三角形。它应该是直截了当的,以概括我们对其他情况的方法。

我们定义了一个与输入矩阵大小相同的矩阵
D
,并将其所有条目初始化为
0
。我们希望使用
D[i][j]
来表示在
(i,j)
处转弯的最大三角形(左上角为直角)的大小

我们的方法基于以下观察结果:

对于在
(i,j)
处大小为
n
的三角形,有必要在
(i+1,j)
(i,j+1)
处都有大小为(至少)
n-1的三角形

我们可以利用这一事实,使用自下而上的方法计算
D
。我们将通过多次迭代计算
D
,其中在
n
第次迭代后,我们将找到大小为
n
的所有三角形。我们将根据以下规则更新
D

  • 在第一步中,如果输入矩阵在
    (i,j)
    处有
    1
    ,我们将
    D[i][j]=1

  • n
    -th过程中,对于
    D
    中值
    n-1
    的每个条目(假设该条目位于
    (i,j)
    ,我们检查
    D[i+1][j]
    D[i][j+1][/code>是否都等于
    n-1
    ,如果是,我们设置
    D[i][j]=n

  • 当遇到没有更新
    D
    项的过程时,我们终止算法

  • 备注:
    n
    -第次过程实际上找到了大小为
    n
    的三角形的所有位置,我们将使用此信息更新下一次过程,这是动态规划中的关键思想-我们找到了较小子问题的解,并将使用它帮助解决较大尺寸的问题

    最大三角形的大小(以及它的位置)可以在b中找到
    1 0 0 2 1
    0 4 3 2 1
    0 3 2 1 0
    2 2 1 1 1
    1 1 0 0 1
    
    function solve() {
        var row, col;
        var i = 0;
        var n;
        var here,above;
        for (row = 1 ; row < SIZE ; row++) {
            n = grid[0 + SIZE * row];
            for (col = 1 ; col < SIZE ; col++) {
                here = grid[col + SIZE * row];
                if (here > 0) {
                    if (n > 0) {
                        above = grid[col + SIZE * (row - 1)];
                        grid[col + SIZE * row] = 1 + Math.min(n, above);
                    }
                    n++;
                } else {
                    n = 0;
                }
            }
        }
    }