【问题标题】:Using Dijkstra's algorithm to find a path that can carry the most weight使用 Dijkstra 算法找到可以承载最大权重的路径
【发布时间】:2011-09-09 01:52:53
【问题描述】:

我有一个图,有 X 节点和 Y 边。加权边缘。重点是从一个节点开始,在最后一个位置的另一个节点停止。现在问题来了:

可视化问题。边是道路,边权重是在道路上行驶的车辆的最大重量限制。我们想驾驶最大的卡车从 A 到 F。我想要从 A 到 F 的所有路径的最大允许重量。

我可以使用某种 Dijkstra 算法来解决这个问题吗?我不确定如何以我可以实现的算法的形式表达这个问题。任何帮助深表感谢。我很困惑,因为 Dijkstra 的算法只查看最短路径。

【问题讨论】:

  • 这听起来更像是一个 Flow 问题:en.wikipedia.org/wiki/Flow_network
  • 这是无向图上的简单最小最大搜索算法。从开始节点到结束节点的所有可用路径中查找最大路径权重,其中对于路径路径中的所有边,每个边的权重不小于给定的轨道高度
  • @Artur Mustafin - 您的编辑完全改变了问题。请不要将问题编辑成您想要的意思,即使您不理解,原始含义也很清楚。
  • 好的,我不明白“我想要从 A 到 F 的所有路径的最大允许权重”这句话,请描述一下“所有路径的权重”是什么意思,以及如果您明白我的意思,请在所有方面都更加耐心。
  • @Artur Mustafin - 这意味着您想要最大化k,这样就存在从AF 的路径,它的所有边权重为>= k。跨度>

标签: javascript algorithm dijkstra


【解决方案1】:

如果我理解正确,你想找到一些节点之间的路径,最大瓶颈边缘。也就是说,你想要最小边缘尽可能大的路径。如果这是您想要解决的问题,那么可以使用 Dijkstra 算法的一个非常直接的修改来解决问题。

该算法背后的想法是对 Dijkstra 算法进行扭曲运行。通常,在运行 Dijkstra 算法时,您会跟踪到每个节点的最短路径的长度。在修改后的 Dijkstra 算法中,您改为为每个节点存储到达该节点的任何路径上的最小权重边的最大可能值。换句话说,通常在 Dijkstra 算法中,您通过找到使数量最大化的边来确定要扩展的边

d(s, u) + l(u, v)

其中 s 是起始节点,u 是您目前探索过的某个节点,(u, v) 是一条边。在修改后的 Dijkstra 中,您会发现边缘最小化

min(瓶颈(s, u), l(u, v))

也就是说,您考虑从源节点到您目前看到的任何节点的路径上的瓶颈边缘,并考虑如果您离开该节点并去其他地方会形成什么瓶颈路径。这是到达目标节点的最佳瓶颈路径,您可以重复此过程。

这个 Dijkstra 算法的变体也使用良好的优先级队列在 O(m + n log n) 时间内运行。如需更多信息,请考虑查看对算法进行简要讨论的these lecture slides

有趣的是,这是一个众所周知的问题,在许多算法中都用作子程序。例如,用于解决最大流量问题的早期多项式时间算法之一使用该算法作为子程序。具体方法请查看these lecture notes

希望这会有所帮助!如果我误解了您的问题,请告诉我,以便我删除/更新此答案。

【讨论】:

  • +1,当我说有一个O(X + Y) 算法时,这就是我的想法——尽管这实际上是错误的。您可以将其设为O(X + Y + V),其中V 是使用类似于计数排序思想的权重:保持MaxEdgeWeight 列表-L[i] = list of nodes x for which d[x] = i,其中d[x] = maximum minimum edge from source to x。当d[x] 减少时,我们将它插入到一个“较小的”列表中,但不要从原始列表中删除它。相反,当从列表 i 扩展节点 x 时,我们首先检查是否为 d[x] = i,如果不是,则忽略它。
【解决方案2】:

没有 Dijkstra,没有流量问题。这要容易得多:只需使用您最喜欢的图形搜索(BFS 或 DFS)。

无需计算和跟踪与到达图中某个节点相关的成本,只需计算允许使用此路径的最大卡车的“大小”(路径中所有边的权重的最小值)。当多个搜索路径在一个节点中相遇时,丢弃具有较低“卡车重量限制”的路径。

【讨论】:

  • 我同意,对图形使用合取矩阵 (M),对节点重新排序,使列的起始节点 (A) 索引为 0,最后一个节点 (F) 索引= L(M)-1。
【解决方案3】:

这是一种简单有效的方法:

MAX 为图中的最大边权重。二分搜索0 <= k <= MAX,这样您就可以只使用权重为>= k 的边从AF。您可以使用breadth first search 看看这是否可能(如果它的重量太小,请不要占优势)。

这给出了O((X + Y) log V) 算法,其中V 是您的权重范围。

【讨论】:

  • 这是错误的。在完全处理图形之前,您不能排除任何图形节点,因为它可以是解决方案的一部分,因此排除的节点可以位于具有最大权重的路径中。
  • @Artur Mustafin - 您编辑的问题只是错误的,对于 OP 发布的内容是正确的。
  • 如果卡车太重而无法在某条道路上通过,那么将其包含在搜索中是没有意义的,所以我相信 IVlad 是对的。
  • 是的。当然,在其中一种情况下是可能的。
  • 我试图解决问题UVa 10099 - The Tourist Guide。我首先使用了能够解决O(X^3) 中的问题的 Floyd-Warshall 算法。然后我用O((X + Y) log V) 更好的时间复杂度解决了这个问题,其中V 是图中的权重范围。
【解决方案4】:

类似 Dijkstra 的算法需要的是最优子结构,以及一种快速计算目标值的方法,用于具有已知目标值的路径的单边扩展。这里,最优子结构意味着如果你有一条从顶点 x 到不同顶点 y 的最优路径,那么从 x 到倒数第二个顶点的子路径是最优的。

(IVlad,我只能通过随机化得到 O(X + Y)。)

【讨论】:

  • (注意:这个框架涵盖了归因于不是 Dijkstra 的人的算法。)
  • 不能把这条评论放在它所属的地方:即使流和路径是密切相关的组合对象,我认为我的任何同事或我都不会将此描述为“流问题”。
猜你喜欢
  • 1970-01-01
  • 2021-03-07
  • 2011-02-18
  • 2018-05-23
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多