【问题标题】:Dijkstra's algorithm to find shortest path寻找最短路径的 Dijkstra 算法
【发布时间】:2019-10-06 22:35:16
【问题描述】:

一个特定的州在其 V 个城市的集合中有一组 E 道路,其中从城市 u 到相邻城市 v 的道路经过的时间由 cuv 给出。 (注意 cuv 不一定等于 cvu——实际上可能没有从 v 到 u 的路。)暴风雪过后,有些道路无法通行,但州长需要尽快从 s 市开车到 t 市有时间只清理一条无法通行的道路。给出一个 O(E log V ) 算法,该算法确定要耕种的道路(仅一条),以实现从城市 s 到城市 t 的最短可能时间路径。输入是所有道路的列表、每条道路的值 cuv、s、t 和一组不可通行的道路。如果道路清理没有帮助,算法应该这样说。

我认为解决这个问题的最接近的方法是使用 Dijkstra 算法找到最短路径,但是,由于我们不知道哪条道路不可通行,哪条道路可以通过,Dijkstra 算法似乎不适合这个问题。那么,有没有其他算法能够检查每条边的状态并找到最短路径?对不起我的逻辑,我不太了解这个问题,任何回复或提示都会有所帮助,谢谢。

谁能解释我的问题与Shortest path between two vertices when exactly one edge weight can be reduced by 50%?的相似之处

【问题讨论】:

  • 我不认为我的问题与这个相似,你能解释一下它们有何相似之处吗?在我的问题中,无法通行的道路(u,v)是由于雪,有从 u 到 v 不再有任何优势。如果我们犁路,成本再次变为 Cuv。我们不知道这是否会影响 s --> t 或影响多少。因此,如果它不缩短我们的时间消耗,它可能不需要犁路。但是在您发布的问题中,解决方案似乎必须包括优惠券才能获得 50% 的折扣。
  • 原理是一样的——一个动作可以做一次。在链接的问题中,它是一张优惠券,在您的问题中,它是雪犁。两种情况下的解决方案都是相同的:复制您的图表,其中第一个副本是使用犁之前的状态,第二个副本是犁之后的状态。您寻找从犁前的 s 到犁后的 t 的最短路径(如果需要,也可以寻找犁前的 t)。两个副本之间的边正是无法通行的街道(您只能遍历其中任何一个;您最终会进入图表的第二个副本并且无法返回)。
  • “你寻找一条从犁前的 s 到犁后的 t 的最短路径(如果你愿意,也可以是犁前的 t)。两个副本之间的边缘正是无法通行的街道”你能解释一下吗?这个说法,我还在苦苦挣扎,Dijkstra的算法是如何通过复制我的图找到最短路径的。我们必须在这两个图上运行算法吗?一个在犁前,一个在犁后,我们怎么知道要犁哪条路才能得到最短的路径。(如果你能举一个更好的例子)
  • 我想你可以使用 Dijkstra 的算法,如果你记住禅宗哲学家巴绍曾经写过的话:“一条路……无法通行……不是一条路。还有一个甜甜圈…… .没有洞……是丹麦人”。他是个有趣的人……

标签: algorithm


【解决方案1】:

我们将给定的图称为G(V, E),其中E可以拆分为D + F,其中 D 表示可以通行的道路,F 表示不可通行的道路。

按照 cmets 中的建议,复制图表,这样您就有了 G(V,D)G'(V',D')。对于任何给定的顶点 u ∈ V,都有一个“复制”顶点 u' ∈ V'。所以还有一个s'和一个t'。我们此时不包括 FF'

然后定义一组边(u,v'),对于每条边(u,v) ∈ F .因此, 中的这些边是从 VV'可通行 连接——仅在那个方向上。

我们称这个新图为 G°(V°, E°),其中 V° = V + V', E° = D + D' + F° 如上一段所定义。

现在解决中从s{t, t'}的问题。由于从 V'V 没有边,以 t' 结尾的解决方案路径将只使用一条边 (u, v') 来自 。请注意,如果通过比 t' 更短的路径到达 t,这意味着没有使用来自 的边(不需要无法通行的道路被犁)。

中寻找s{t, t'}之间最短路径的问题现在是一个标准问题,可以用 Dijkstra 算法求解。还需要一件事:对于每个访问过的 w' ∈ V',来自 的边 (u,v') ——被越过到达那里 - 需要记录。这些信息应该只是传递给算法访问的下一个顶点,以便当 t' 最终找到时,可以立即给出答案,即边 (u,v' ).

本算法中访问的边数最多为|E°| = |D + D' + F°| ≤ 2|E| = O(|E|)。该算法只访问每条边一次,因此时间复杂度为O(|E|)

【讨论】:

  • 感谢您的回复,但是很抱歉我是学习算法的新手,时间复杂度 O(E) 和 O(ElogV) 一样吗?由于我的作业需要设计一个算法 O(ElogV),如果这个重复的方法不是,我可能不得不考虑另一种方法来解决它。
  • O(E) 优于 O(ElogV)。您当然可以添加一些虚拟操作来使其 O(ElogV),但为什么要让算法 worse
【解决方案2】:

您可以尝试如下解决这个问题:

您可以维护一个数组 dist[n][2],其中 n 是顶点数。

dist[i][0] 表示到达 i 所需的最短时间,而无需清除任何积雪的道路

dist[i][1] 表示通过清除一条从源头到 i 的有雪的道路到达 i 所需的最短时间。

现在可以用来解决这个问题的数据结构是队列。该算法在下面提到。

1. Insert your source vertex into the queue and mark it as zero.          //marking 0 helps us to know that no roads has been cleared yet.
2. Do while queue is not empty
    2.1 Pop element from queue. Let it be x.
    2.2 For all the vertices i connected to x
        dist_without_clearing = dist[x][0] + cxi
        dist_with_clearing = dist[x][1] + cxi
        dist_with_clearing = min(dist_with_clearing,dist[x][0] + cxi)    // here only the roads that are covered with snow needs to be considered.
        if(dist_without_clearing < dist[i][0]) 
            insert(i,0) in queue
            dist[i][0] := dist_without_clearing
        endif
        if(dist_with_clearing < dist[i][1])
            insert(i,1) in queue.
            dist[i][1] := dist_with_clearing
        endif
3. Return min(dist[destination][0], dist[destination][1]) as your answer.

【讨论】:

  • 这个算法的运行时间是O(E log V)吗?
  • 这里使用的算法是SPFA(最短路径更快算法)。它的最坏情况复杂性与贝尔曼福特的相同。平均复杂度为 O(E),其中 E 是图中的边数。
猜你喜欢
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多