矩阵中的最大路径成本

时间:2017-11-16 10:21:45

标签: algorithm matrix dynamic-programming

任何人都可以告诉算法在NxM矩阵中找到最大路径成本,从左上角开始,以右下角结束,左,右,向下移动在矩阵中允许并包含负成本。可以多次访问一个小区,在访问一个小区后,其成本将被替换为0

约束
1< = nxm< = 4×10 ^ 6
INPUT

4 5
1 2 3 -1 -2
-5 -8 -1 2 -150
1 2 3 -250 100
1 1 1 1 20

输出

37

图像中给出了说明 Explanation of Output

3 个答案:

答案 0 :(得分:3)

既然您还有负成本,那么请使用bellman-ford。你做的是你改变所有成本的标志(将负号转换为正值,将正值转换为正值)然后找到最短路径,这条路径将是最长的,因为你已经改变了符号。

如果符号永远不会消极,那么请使用dijkstra shrtest-path,但在此之前使所有值为负值,这将返回最长的路径及其成本。

矩阵是直接图。在你的图像中,你试图找到从索引(0,0)到(n-1,n-1)的路径(最大或最小)。

您需要将这些内容表示为图表。

  • 您需要一个链接列表,并且在每个节点中都有一个first_Node, second_Node,Cost to move from first node to second
  • 一系列链表。在每个数组索引中,您保存一个linkedlist。例如,有一个从0到5和0到1的路径(它是一个无向图),那么您的图形将如下所示。 enter image description here

如果你想要一个直接图,那么只需添加adj [0] = 5并且不添加adj [5] = 0,这意味着存在从0到5但不是从5到零的路径。 / p>

此处,链表仅代表连接的节点,而不是成本。你必须在那里添加额外的变量来保持每两个节点的成本,它将如下所示。

enter image description here

现在,而不是第一个链接列表将此链接列表放在您的数组中,您现在可以使用图表来运行最短路径算法或最长路径算法。

如果你想要一个智能算法,那么你可以使用启发式A *,我猜曼哈顿将是最好的。

如果您的边缘成本不是负数,那么请使用Dijkstra。

如果成本为负,则使用bellman-ford算法。

您始终可以通过将减号转换为加号和加号减号来找到最长路径,然后运行最短路径算法。创建的路径将是最长的。

我回答了这个问题,正如你在评论中所说,看看第二点。如果这是一项任务,那么这项任务的主要思想是确保Monotonocity

  • h代表启发式费用。
  • A代表累积成本。

其中说每个节点都为h(A) =< h(A) + A(A,B)。意味着如果你想从A移动到B,那么成本不应该降低(你可以用你的值做一些事情,这个属性会保留)但是增加,一旦你满足这个条件,那么每个节点A *选择,该节点将成为从源到目标的路径的一部分,因为这是具有最短/最长值的路径。

pathMax 你可以强调单调性。如果存在从AB的路径,则f(S ... AB)&lt; f(S ..B)然后设置f的成本(S ... AB)= Max(f(S ... AB),f(S ... A))其中S表示源。

答案 1 :(得分:2)

由于不允许向上移动,因此路径总是看起来像一组共享至少1个位置的水平间隔(对于向下移动)。答案可以表征为,例如

struct Answer {
   int layer[N][2]; // layer[i][0] and [i][1] represent interval start&end
                    // with 0 <= layer[i][0] <= layer[i][1] < M
                    // layer[0][0] = 0, layer[N][1] = M-1
                    // and non-empty intersection of layers i and i+1 
};

另一种编码方式是仅注意图层宽度和相互偏移;但你仍然需要确保最后一层包含退出单元格。

假设您有一个maxLayer例程,在每个图层中找到得分最高的区间(每层const O(M)),并且所有这些图层重叠,这将产生{{1最佳答案。但是,可能需要扩展间隔以确保发生重叠;并且在给定层中可能存在多个得分最高的区间。在这一点上,我会将问题建模为有向图:

  • 每个层每个分数有一个节点 - 最大化水平连续间隔。
  • 来自一层的节点根据扩展两个间隔的成本连接到下一层中的节点以实现至少1个重叠。如果它们已经重叠,则成本为0.边缘成本将始终为零或负值(否则,源或目标间隔可能通过增大而得分更高)。将(扩展的)源节点间隔值添加到连接成本中以获得&#34;边缘权重&#34;。

然后,您可以在此图表上运行Dijkstra(否定边权重,以便返回&#34;最长路径&#34;)以找到最佳路径。更好的是,由于所有路径只传递一次,每次只传递一次,因此您只需要跟踪到每个节点的最佳路径,并且只需要为正在处理的图层构建节点和边缘。

提前实施细节

  • 在O(M)中计算maxLayer,使用Kadane's Algorithm,修改后返回所有最大间隔而不是仅返回第一个。如果链接的算法丢弃一个间隔并重新开始,您可以保留该竞争者的副本以供以后使用。

  • 给定样本输入,最大间隔如下所示:

    O(N+M)
  • 给定这些间隔,它们将产生以下图表:

                         [0]
     1  2  3   -1   -2   [1 2 3]
    -5 -8 -1    2 -150 =>        [2]
     1  2  3 -250  100   [1 2 3]     [100]
     1  1  1    1   20   [1 1 1   1    20]
                                       [0]
    
  • 当两个边缘包含在单个节点(行1 1 1 1 20)上时,仅​​向前传送最高的输入值。

答案 2 :(得分:2)

对于一行中的每个元素,找到我们在行中水平移动时可以获得的最大成本,前提是我们遍历该元素。

EG。对于行

1 2 3 -1 -2

如果我们通过该元素水平移动,则获得的每个元素的最大成本将是

6 6 6 5 3

说明:

元素3的

:我们可以向后水平移动触摸1和2.我们不会向前水平移动,因为值-1和-2会降低成本值。

因此3 = 1 + 2 + 3 = 6

的最大成本

如果我们水平移动,对于您在描述中给出的输入,行中每个元素的最大成本矩阵将是

6     6    6    5      3  
-5   -7    1    2      -148  
6     6    6    -144   100  
24    24   24   24     24

由于我们可以从一行垂直移动到下一行,因此请更新每个元素的最大成本,如下所示:

cost[i][j] = cost[i][j] + cost[i-1][j]

所以最终的成本矩阵将是:

6    6    6     5      3 
1    -1   7     7      -145 
7    5    13    -137   -45  
31   29   37    -113   -21 

上述矩阵最后一行的最大值将为您提供所需的输出,即37