【问题标题】:Graph theory question, Java. Which algorithm to achieve the following图论问题,Java。下面哪个算法实现
【发布时间】:2009-11-26 21:02:06
【问题描述】:

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

可视化问题。边是道路,边权重是在道路上行驶的车辆的最大重量限制。我们希望将最大的卡车从 A 开到 B。因此,在给定路径上行驶的卡车的最大允许重量是该路径中所有边缘的最小重量。我想要从 A 到 B 的所有路径的最大最大允许权重。

我可以使用某种 Dijkstra 算法来解决这个问题吗?我不确定如何以我可以实现的算法的形式表达这个问题。任何帮助深表感谢。

更新: 我测试了一些对我不起作用的东西。一个节点必须为每个传入边缘拥有一辆最大卡车。

【问题讨论】:

  • "...从 A 到 B。它将返回一个 int,这是该路线上的最小边。但与从 A 到 B 的其他路线相比,最大的边。"什么 ?你说“从 A 到 B 最小,但从 A 到 B 最大”
  • 可以有更多从 A 到 B 的路线。关键是我们想驾驶最大的卡车从 A 到 B。选择的边是所选路线中最小的边,但最大的比较到从 A 到 B 的其他路线中的最小边。

标签: java algorithm graph-theory


【解决方案1】:

Dijkstra 的算法应该可以工作,但在这种情况下你的“距离”有点奇怪。您的“距离”是您可以到达节点的最大卡车尺寸。让我们称其为节点 v 的 M[v]。您需要按从最大 M[v] 到最小 M[v] 的顺序处理节点(与正常 Dijkstra 相反),并计算从 v 到 w 的每条边 e:

M[w] = max(M[w], min(e.weight, M[v]))

【讨论】:

  • 很好,现在每个节点的成本都是 init 到 integer.max。当我这样做时,默认成本应该是多少?
  • 所有节点都应该默认为0,除了源节点从无穷大开始。
  • 完美,我现在回到 Eclipse。非常感谢!
  • 想到一件事,一个节点有多个传入边。每条边都会“带来”自己的最大边。所以这意味着如果 B 有不止一种方法,这将不起作用?
  • 是的,其中一个传入的边缘将获胜。在上面的公式中最后增加 M[w] 的那个(假设没有关系)。生成的路径可以反向重建。从 w=destination 开始,对于每个 w,检查所有边 e:v->w 并取 v 使得 min(e.weight, M[v]) == M[w]
【解决方案2】:

这听起来(几乎)与maximum flow problem 完全一样,可以使用Ford-Fulkerson algorithm 有效地解决。

正如基思在评论中指出的那样,由于卡车不能分成多个部分,因此必须稍微改变算法的最大值,以仅找到具有最大最小路径段的 一个 路径。

【讨论】:

  • 最大流量不太合适,这会让您将卡车切成碎片并以不同的方式发送。
  • @Keith:是的,不像最大流量那样完全。虽然我喜欢切碎的卡车的想法。 ;-)
【解决方案3】:

我想你正在寻找这个

Shortest path

编辑:其实你不是,最大流量链接是正确的

【讨论】:

    【解决方案4】:

    所以如果我理解正确的话,你是在问“可以从 A 开到 B 的最大卡车是什么”

    要应用 Dijkstra 算法,您需要一种方法来模拟“成本”。如果要使用标准实现,可以将权重的倒数分配给成本。因此,成本最高的边缘是最大权重最低的边缘。当然,由于您可能想要使用漂亮的整数,您可以简单地修改比较而不是实际使用倒数。

    【讨论】:

      【解决方案5】:

      您正在寻求优化 [http://en.wikipedia.org/wiki/Flow_network]。容量是道路的最大重量限制;流量就是卡车的重量。

      【讨论】:

        【解决方案6】:

        您可以采用一种最小生成树方法。一次连接节点一条边,首先连接最高流量的边,直到 A 和 B 连接。您添加到图中的最后一条边是从 A 到 B 必须穿过的最低流量边。可能不是最有效的解决方案(O(N2) 最坏情况) ,但至少它是直截了当的。

        【讨论】:

          【解决方案7】:

          这既不是最短路径问题,也不是最大流量问题。实际上没有问题。他说 - 想要所有路径 A 到 B 的最大权重。所以去通过 BFS 从 A 生成所有路径。对于以 B 结尾的所有路径,求路径边缘的最小权重。

          【讨论】:

          • 在执行 BFS 时,您将如何实际存储路径片段?
          • 那说明一个图不小,多条路径可以很大?我猜你对从 A 到 B 的最大允许重量的单一路径感兴趣?这样做:通过任何算法找到 A-B 路径,例如迪杰斯特拉。然后删除权重最小的边。再次找到 A-B 路径。继续这样做,直到没有 A-B 路径。在移除边缘之前存在的最后一条路径将是最大权重的路径。
          【解决方案8】:

          使用Dijkstra's algorithm,最大卡车重量的倒数作为边缘成本,单个边缘重量的最大值作为总路径成本。

          edge_cost 等于 1/(允许的最大卡车重量) 给定路线的total_cost 是路线中所有边的单个edge_cost 的最大值。

          【讨论】:

            【解决方案9】:

            上面的各种答案只是简单地提出了具有修改权重函数的 Dijkstra 算法。例如,w(e) = -c(e),或'w(e) = 1/c(e)',其中w(e) 是算法使用的边的权重,c(e) 是边的容量原始问题的表述。

            这些不起作用。

            人们可以很容易地创建反例,从而产生不正确的结果。例如,考虑图表:

            a---3-->b---3--->c---3-->d
             \                       ^
              \                      |
               \----------3----------|
            

            假设a(算法公式中节点a的距离)的值为零。从ad 的两条路径在这个问题中是等价的。然而,如果我们只是否定边缘容量,距离(d)使用长路径是(-3)+(-3)+(-3) = -9,而使用短路径它将是-3。如果我们反转边缘容量,使用长路径的距离(d)将为(1/3)+(1/3)+(1/3)=1,而使用短路径的距离(d)仅为(1/3)

            起作用的是修改算法的松弛步骤,即不使用加法 (+) 和小于 (<) 的函数,而是分别使用函数 @987654335 @ 和大于 (>),并使用最大堆而不是最小堆。如果我们否定边缘权重并使用小于,我们可以避免最后两个修改,但我们无法避免替换+,因为我们需要一些运算符@,其中a @ a = a 用于所有a 值,而+ 仅适用于 a=0

            所以,我看到的唯一正确答案是 Keith Randall 给出的第一个答案。

            一个很好的练习是正式证明修改后的算法是正确的。需要证明的是: - 如果u 是在任何循环迭代中具有最大值d(u) 的节点,则没有涉及未标记节点的路径可以创建到u 的路径产生大于d(u) 的距离。

            直观上很容易看出,因为所有其他未标记节点的距离都小于(或等于)'u'的距离(因为我们选择u作为距离最大的那个),并且生成的路径是由min 的连续调用产生的,因此它只能变小,不能变大。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-04-21
              • 2022-08-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-25
              相关资源
              最近更新 更多