【问题标题】:Finding the shortest path in a colored graph在彩色图中找到最短路径
【发布时间】:2014-04-14 01:38:22
【问题描述】:

我要解决的问题是:

给定一个图,其中每条边都用红色或蓝色着色:

a) 给出一个算法,该算法产生两个顶点 (s,t) 之间的路径,该路径经过最少数量的红边。

b) 给出一个算法,该算法生成两个顶点 (s,t) 之间经过最少蓝色边的路径,在从 s 到 t 且经过最少红色边的所有路径中边缘。

到目前为止: a) 我可以使用修改后的 BFS 算法。查看一个顶点v时,将所有通过蓝色边连接到v的顶点先放入队列中,然后将其余的添加到队列的末尾。因此,算法第一次遇到 t 将是有问题的路径。

如何证明这个算法的正确性?看起来很贪心。如何将其扩展为答案 b)?

感谢您的宝贵时间。

【问题讨论】:

  • 当 s 外的“蓝色”路径在该节点和 t 之间有两条红色路径时会发生什么,如果 s 外的第一个“红色”路径只有节点的“蓝色”路径可以到达吨? (您的策略的反例)
  • 你考虑过加权图表吗?在 A 的情况下,您可以将权重 0 分配给蓝色边缘,将权重 1 分配给红色边缘,然后找到成本最低的路径。然后对于 B,只需反转权重。
  • @Joel:您对 b) 的建议不起作用,因为我们仍然主要希望尽量减少红色边缘。蓝边仅用作决胜局
  • @ErstwhileIII:OPs 算法仍然会找到正确的路径。您可以在纸上验证这一点
  • @NiklasB。啊,你说得对,我看错了 B 的问题。

标签: algorithm graph-algorithm breadth-first-search


【解决方案1】:

您需要牢记关于算法的两个重要细节:

  1. 可以在您的场景中多次将节点添加到队列中。不过,您只能探索一次。您可以通过为每个节点维护一个布尔标志来执行此操作,该标志告诉您是否已经探索过一个节点。
  2. 您只能在将t 移出队列后立即停止算法,而不能在将其放入队列后立即停止。

如果你这样做(并且你的问题并不表明你不这样做),那么你的算法确实是正确的。

如何证明这个算法的正确性?

如果将边权重 1 分配给红色边,将边权重 0 分配给蓝色边,则问题会减少到在转换后的图中找到最短路径。让我们将 Dijkstra 应用到这个问题上。我将证明您的算法实际上实现了 Dijkstra,这证明了它的正确性。

我们可以证明我们在优先级队列中只有两个不同距离的节点:如果m是优先级队列中节点的最小距离,那么我们不能有距离为m + 2的节点在队列中,因为这意味着我们必须已经探索了距离为m + 1 的节点,这是不可能的,因为我们按距离递增的顺序探索节点。

您修改后的 BFS 实际上使用双端队列作为 2 值优先级队列实现了 Dijkstra 算法:如果 Q 是您的队列,那么有一个索引 i,这样 Q[1..i] 只包含距离为 mQ[i+1..] 的节点仅包含距离为 m + 1 的节点。

如何将其扩展为答案 b)?

您可以通过维护一个 4 值优先级队列来扩展这个概念,例如实现为两个双端队列。一个队列将保存距离为m 红色边缘的节点,另一个将保存距离为m + 1 红色边缘的节点。两者都按增加的蓝色边缘数量排序(每一个中也只有两个不同的距离值)。

【讨论】:

    【解决方案2】:

    [[如果您将与蓝色边缘相邻的节点放在队列前面而不是评论中讨论的队列末尾,则提到的算法是正确的。]]

    对于问题 (B),只需丢弃不在原始最短路径中的边(使用最小红色边)。很容易找到边缘 u-v 是否在最短路径中。如果 distance[source][u]+cost[u][v]+distance[v][destination]=distance[source][destination],则 u-v 在最短路径中。丢弃多余的边缘后,剩下的任务就很容易了。

    【讨论】:

    • OPs 算法其实是正确的。它找到右边的最短路径。
    • @Niklas B:他将从源代码转到“a”和“c”。他将处理“a”并转到“b”,而不是从“c”到“d”。而不是他将 b 到目的地并终止算法。 source-a-b-destination 显然不是最优的。
    • 没有。他永远不会去b,因为它被添加到队列的末尾(在c 之后),而d 在探索c 之后被添加到队列的前面
    • 所以也许我需要按照“当前最短路径”的方式存储一些东西,并在每次达到 t 时更新它以使算法正确?感谢您的回答。
    • 可以在bfs的队列前面加一个节点吗?我不这么认为,你不是遍历级别bu级别。我认为他的意思是他将首先处理蓝色边缘,而不是红色边缘。
    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2016-06-25
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    相关资源
    最近更新 更多