Algorithm 特定类型图中的最长路径

Algorithm 特定类型图中的最长路径,algorithm,graph-theory,graph-algorithm,pseudocode,Algorithm,Graph Theory,Graph Algorithm,Pseudocode,我知道对于一般图来说,这个问题是NP难的。然而,我考虑的是一种特殊的图,它由一个圈和圈的每个顶点上的一条附加边组成。例如,对于长度为7的循环,我们有以下图表: 对所有边进行加权(权重为实数,可以为正或负)。我想在这个图上找到最大的简单路径,其中路径的大小是路径上边的权重之和 该算法在循环的大小上应该是线性的。但是任何想法都是值得赞赏的。最长的路径几乎肯定是在两个外部顶点之间。几乎可以肯定,覆盖循环中的所有顶点也是必要的 因此,您希望使用DFS来映射O(N)中的循环。然后计算当前循环安排的长度。

我知道对于一般图来说,这个问题是NP难的。然而,我考虑的是一种特殊的图,它由一个圈和圈的每个顶点上的一条附加边组成。例如,对于长度为7的循环,我们有以下图表:

对所有边进行加权(权重为实数,可以为正或负)。我想在这个图上找到最大的简单路径,其中路径的大小是路径上边的权重之和


该算法在循环的大小上应该是线性的。但是任何想法都是值得赞赏的。

最长的路径几乎肯定是在两个外部顶点之间。几乎可以肯定,覆盖循环中的所有顶点也是必要的

因此,您希望使用DFS来映射O(N)中的循环。然后计算当前循环安排的长度。将循环中的第一个点到其外部以及最后一个点到其外部的距离添加到该长度。这就给出了实际的路径长度,它与循环长度分开存储

增加第一个点和最后一个点的索引(可以在O(1)中完成),删除现在从第一个点指向最后一个点的边的长度。然后再次添加外部长度。重复此操作,直到覆盖了所有顶点。由于存储和更新路径长度而不是每次实际重新计算路径长度(这需要(O(N^2)),因此可以在O(N)中完成

这允许在O(N)中遍历循环。但是,这不是一个精确的算法。这需要检查您不应该对某些i,j使用第一个+i和/或最后一个-j。要完全检查这一点,基本上需要O(N^2)


不过,您可能会在大约O(N log N)的时间内完成此操作通过巧妙地确定这些边缘情况在哪里是可能的。我怀疑精确的线性算法是可能的。

在循环中选择一个链接。最长的路径要么通过该链接,要么不通过该链接,因此让我们计算出这两种情况下的最佳答案,并选择其中最好的一种

如果最长路径未通过循环链接,请删除该链接以生成一棵树。在每个节点上,从叶上计算出该节点下的最长路径,以及从该节点到任何后代的最长路径。在每个节点上,您可以通过查看其子节点上的答案来计算答案。根节点上的答案给出l最长的路

如果最长路径确实经过您拾取的链接,则它必须由一个从链接一端顺时针走的部分和一个从链接另一端逆时针走的部分组成。这两个部分的长度加起来不超过1加上组成循环的链接数。对于i=1,计算出成本从链路每侧开始的顺时针和逆时针路径的长度,并保持运行最大值。对于某些k,通过链路的最长路径的长度为最多k个链路的顺时针最长路径和最多N-k个链路的逆时针最长路径之和(可能存在一些类似的-ve链接成本),因此您可以找到通过所选链接的最长路径,成本也为O(n)

计算两种情况下的成本O(n)并选择最佳值,可得出总成本O(n)

这可以简化为线性时间并在线性时间内求解

  • 断开循环连接(在任何节点)
  • 将剩余图形的第二个副本添加到循环断开连接的点上(我们可以跳过最后一个节点)
  • 将修改后的Kadane算法应用于生成的节点列表
  • 如果找到的路径没有边,则在图中搜索权重最大的边。如果此边具有非负权重,则报告此单条边路径。如果不允许空路径,则仍报告此单条边路径,如果允许空路径,则报告空路径
  • ->

    必要的Kadane算法修改:

  • 跟踪当前路径(子阵列)中的节点数。当子阵列有
    N
    个或多个“循环”节点时,从尾部修剪节点。要有效修剪这些节点,我们需要一个队列,该队列可以报告其元素的最小值。只要路径的头部向前,就将元素推送到该队列(如果非负,则添加叶边权重),修剪路径尾部时弹出元素,并在当前路径重置为空路径时重置队列。此队列包含前缀长度(不一定简单)路径,其中最小值给出了适当的位置来推进路径的尾部。这样的队列可以实现为只包含非递减值的deque,也可以实现为回答中提到的一对堆栈
  • 将路径长度重置为
    max(0,叶边权重)
    当前路径长度低于零的位置(而不是像最初的Kadane算法那样将其重置为零)
  • 将当前(非空)路径与迄今为止的最佳路径进行比较时,添加非负叶边权重(对应于头部节点)

  • 当然,这是一个从图中剪除死角的例子,然后找到权重最低的边,并将其两端用作最长(权重最高)的起点和终点链。@paddy:如果权重不能为负,那就行了…@paddy:我不太明白。你能说得更具体一点吗?@becko:这会改变问题;结果上的偏移量将与路径中的边数成正比。@becko嗯,检查对的简单算法将是
    O(N^3)
    。您需要对循环进行预处理,以获得
    O(1)
    中两点之间的距离。您是否考虑了负权重?如果在所选节点和最长路径之间,有一条边具有巨大的负权重,该怎么办?它将找到最长的路径