简体   繁体   English

为了找到最短路径,如何在有向加权图中将一个边精确设置为零?

[英]How to set exactly one edge to zero in directed weighted graph in order to find shortest path?

The following is the question I am working on: 以下是我正在研究的问题:

Consider a directed, weighted graph G where all edge weights are positive. 考虑一个有向加权图G ,其中所有边缘权重均为正。 The goal of this problem is to find the shortest path in G between two pre-specified vertices s and t , but with an added twist: you are allowed to change the weight of exactly one edge (of your choosing) to zero. 这个问题的目的是在两个预先指定的顶点st之间找到G的最短路径,但要增加一点扭曲:允许将(选择的)一条边的权重更改为零。

In other words, you must pick an edge in G to set to zero that minimizes the shortest path between s and t . 换句话说,您必须在G中选择一个边沿以将其设置为零,以最小化st之间最短路径。 Give an efficient algorithm to achieve this goal in O ( E lg V ) time and analyze your algorithm's running time. 给出一种有效的算法,以在O(E lg V)时间内实现此目标,并分析算法的运行时间。 Sub-optimal solutions will receive less credit. 次优解决方案将获得较少的信誉。

Hint: You may have to reverse the edges, run a familiar algorithm a number of times, plus do some extra work 提示:您可能需要反转边缘,多次运行熟悉的算法,并做一些额外的工作

So I have tried running Dijkstra's from s to all other nodes and then I have tried reversing the edges and running it again from s to all other nodes. 所以,我试图运行从s Dijkstra的所有其他节点,然后我试图逆转的边缘,从s再次运行到所有其他节点。 However, I found out that we have to run Dijskstra's from s to all other nodes and then reverse the edges and then run Dijkstra's from all other nodes to t . 但是,我发现我们必须将Dijskstra从s运行到所有其他节点 ,然后反转边,然后再将Dijkstra从所有其他节点运行t I am not exactly sure how this helps us to find the edge to set to zero. 我不确定这如何帮助我们找到要设置为零的边。 By my intuition I thought that we would simply set the maximum weight edge to zero. 根据我的直觉,我认为我们可以将最大重量边设置为零。 What is the point of reversing the edges? 反转边缘的意义何在?

We need to run Dijkstra's algorithm twice - once for the original graph with s as the source vertex, and once with the reversed graph and t as the source vertex. 我们需要运行Dijkstra的算法两次-一次是使用s作为源顶点的原始图,一次是使用反向图并且t作为源顶点的图。 We'll denote the distance we get between vertex s and i from the first run as D(i) and the distance we get between vertex t and i second run D_rev(i) . 我们将表示从第一次运行得到的顶点si之间的距离为D(i) ,从第二次运行得到的顶点ti之间的距离为D_rev(i)

Note that we can go follow the reversed edges backwards (ie, follow them in the original direction), thus D_rev(i) is actually the shortest distance from vertex i to t . 请注意,我们可以向后跟随反向边(即,沿原始方向跟随它们),因此D_rev(i)实际上是顶点it的最短距离。 Similarly, D(i) is the shortest distance from vertex s to i following Dijkstra's algorithm. 同样, D(i)是遵循Dijkstra算法的从顶点si的最短距离。

We can now loop through all the edges, and for each edge e which connects v1 and v2 , add up D(v1) and D_rev(v2) , which corresponds to the weight of the path s -> v1 -> v2 -> t with e being the zero edge, since we can go from s to v1 with a distance of D(v1) , set e to 0, go from v1 to v2 , and then go from v2 to t with a distance of D_rev(v2) . 现在我们可以遍历所有边缘,对于连接v1v2每个边缘e ,将D(v1)D_rev(v2) ,这对应于路径s -> v1 -> v2 -> t的权重s -> v1 -> v2 -> t D_rev(v2) s -> v1 -> v2 -> te为零边,因为我们可以从sv1且距离为D(v1) ,所以将e设置为0,从v1v2 ,然后从v2t的距离为D_rev(v2) The minimum over these is the answer. 这些最小的答案。

A rough proof sketch (and also a restatement) : if we set an edge e to 0, but don't use it in the path, we can be better off setting an edge that's in the path to 0. Thus, we need only consider paths that includes the zeroed edge. 粗略的证明草图(以及重述):如果将边e设置为0,但不在路径中使用它,则最好将路径中的边设置为0。因此,我们只需要考虑包括归零边缘的路径。 The shortest path through a zeroed edge e is to first take the shortest path from s to v1 , and then take the shortest path from v2 to t , which are exactly what were computed using the Dijkstra algorithm, ie, D and D_rev . 通过零边e的最短路径是首先采用从sv1的最短路径,然后采用从v2t的最短路径,这正是使用Dijkstra算法(即DD_rev计算D_rev

Hope this answer helps! 希望这个答案有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM