I have this question form the Sedgewick's course on algorithms: "Critical edge. Given an edge-weighted digraph, design an E*log(V) algorithm to find an edge whose removal causes the maximal increase (possibly infinite) in the length of the shortest path from s to t. Assume all of the edge weights are strictly positive. (Hint: compute the shortest path distances d(v) form s to v and consider the reduced costs c′(v,w)=c(v,w)+d(v)−d(w) ≥ 0.)"
I've read on the internet that three (3) guys in 1989 came up with an algorithm of complexity O(E + V*log(V)) what required advanced data structures, and I think it was on a graph (not digraph). If it got three advanced computer scientist to develop this algorithms, is not it too much of a problem for an introductory course? But maybe it is much easier for just O(E*log(V)).
Can you help me to solve it? I don't understand the hint given in the question.
Here is a sketch of an algorithm to find the critical edge on a shortest path, based on Sedgewick's hint.
First, the reduced cost c′(v,w)=c(v,w)+d(v)−d(w) corresponds to the increase in the length of the shortest path from s to w, when going through v just before w. (If v is in the shortest path from s to w then this increase is 0.) (Indeed d(v) is the length of the shortest path from s to v and c(v, w) the cost to go from v to w.)
Suppose the shortest path from s to t is (s, ..., v, t) and that we remove the last edge (v, t). Then the increase in the length of the shortest path from s to t equals the minimum of the c'(u, t) for all in-edges (u, t), with u != v.
Suppose u is such that c'(u, t) is the minimum (still u != v). Then follow the shortest path from s to u backward, until you reach a vertex, say w, belonging to the shortest path from s to t (without any removed edge). The shortest path from s to t is something like (s, ..., w, ..., v, t).
Observe that if you remove any edge between w and t, you will get a maximum increase of c'(u, t) int the shortest path. Indeed, in case one of the edges between w and t is missing, it suffices to go from w to t through the vertex u. On the other hand, note that removing the last edge (v, t) will cause exactly this increase.
Now, just iterate with w what was done with t. Find a vertex x such that c'(x, w) is mininum and x is not on the shortest path. Follow the shortest path from s to x backward until you reach a vertex belonging to the shortest path from s to w.
Once you reach s then you're able to determine which vertex to remove to cause the maximum increase in the lenght of the shortest path.
This is a confusing question, I agree. Here are some my thoughts about it.
The "reduced cost" term and definition is used when reducing the A* search algorithm to Dijkstra's algorithm by replacing the original cost with the reduced cost:
c′(v,w) = c(v,w) - h(v) + h(w) = c(v,w) - (h(v) - h(w)) > 0
The h(v) - h(w) part is a drop of a heuristic function, which should not be more than the edge cost in case of consistent (monotonic) heuristic, thus the reduced cost is still greater than 0 (see slides 14 and 15 here)
It looks like Sedgewick suggests using the original distance function (d(v)) as a consistent heuristic when searching for the new/replacement shortest path in G' which is the same as the original G, but with one removed edge along the original shortest path from s to t. Personally, I don't see how it might help solving the most vital edge problem in O(ElogV) though.
There is also a similar problem: find all downward and upward critical edges in a graph. By definition, decreasing a cost of downward critical edge decreases the overall SP cost. Increasing a cost of upward critical edge increases the overall SP cost. All critical edges can be found in O(ElogV), see ch.8 here. But this does not answer the question what edge is the most critical (causes the max SP increase when removed).
As you noted, the most vital edge problem was solved by Malik, Mittal and Gupta (1989) in
O(E + V*log(V)) time. I have not found the original MMG paper, but this presentation explains it quite well. As far as I can see, it can be solved with a priority queue, no specific data structures required.
Sorry for not actually answering the original question (solution for most vital edge in a digraph using reduced costs), but still hoping that the links and thoughts above might be useful for someone. I would be happy to see the solution meant by Sedgewick.
Related
I was trying to come up with a solution for finding the single-source shortest path algorithm for an undirected weighted graph using BFS.
I came up with a solution to convert every edge weight say x into x edges between the vertices each new edge with weight 1 and then run the BFS. I would get a new BFS tree and since it is a tree there exists only 1 path from the root node to every other vertex.
The problem I am having with is trying to come up with the analysis of the following algorithm. Every edge needs to be visited once and then be split into the corresponding number of edges according to its weight. Then we need to find the BFS of the new graph.
The cost for visiting every edge is O(m) where m is the number of edges as every edge is visited once to split it. Suppose the new graph has km edges (say m').
The time complexity of BFS is O (n + m') = O(n + km) = O(n + m) i.e the Time complexity remains unchanged.
Is the given proof correct?
I'm aware that I could use Dijkstra's algorithm here, but I'm specifically interested in analyzing this BFS-based algorithm.
The analysis you have included here is close but not correct. If you assume that every edge's cost is at most k, then your new graph will have O(kn) nodes (there are extra nodes added per edge) and O(km) edges, so the runtime would be O(kn + km). However, you can't assume that k is a constant here. After all, if I increase the weight on the edges, I will indeed increase the amount of time that your code takes to run. So overall, you could give a runtime of O(kn + km).
Note that k here is a separate parameter to the runtime, the same way that m and n are. And that makes sense - larger weights give you larger runtimes.
(As a note, this is not considered a polynomial-time algorithm. Rather, it's a pseudopolynomial-time algorithm because the number of bits required to write out the weight k is O(log k).)
In my research I confront a variant of the vertex cover problem as follows:
Given a graph G, a vertex v and a number k, to decide whether G has a vertex cover of size k
that contain v.
I have search all over literature and could not find a similar problem. I am interested in the complexity of this problem ( I have proved that it complete for $P^NP[long]$ ).
The question is have you ever seen such variant of vertex cover problem? How do you call this problem ?
Given a graph G and a integer K, to decide whether G has a vertex cover of size K is the decision problem of minimal vertex cover problem. And it is NP-complete.
If fact, the problem you described is no difference with that one. That is because if you have contained vertex v, you can remove v and all edges having v as an end-point. What you should do next is to decide whether you can cover the left sub-graph with k-1 vertices.
Is it possible to modify A* to return the shortest path with the least number of turns?
One complication: Nodes can no longer be distinguished solely by their location, because their parent node is relevant in determining future turns, so they have to have a direction associated with them as well.
But the main problem I'm having, is how to work number of turns into the partial path cost (g). If I multiply g by the number of turns taken (t), weird things are happening like: A longer path with N turns near the end is favored over a shorter path with N turns near the beginning.
Another less optimal solution I'm considering is: After calculating the shortest path, I could run a second A* iteration (with a different path cost formula), this time bounded within the x/y range of the shortest path, and return the path with the least turns. Any other ideas?
The current "state" of the search is actually represented by two things: The node you're in, and the direction you're facing. What you want is to separate each of those states into different nodes.
So, for each node in the initial graph, split it into E separate nodes, where E is the number of incoming edges. Each of these new nodes represents the old node, but facing in different directions. The outgoing edges of these new nodes will all be the same as the old outgoing edges, but with a different weight. If the old weight was w, then...
If the edge doesn't represent a turn, make the new weight w as well
If the edge does represent a turn, make the new weight w + ε, where ε is some number significantly smaller than the smallest weight.
Then just do a normal A* search. Since none of the weights have decreased, your heuristic will still be admissible, so you can still use the same heuristic.
If you really want to minimize the number of turns (as opposed to finding a nice tradeoff between turns and path length), why not transform your problem space by adding an edge for every pair of nodes connected by an unobstructed straight line; these are the pairs you can travel between without a turn. There are O(n) such edges per node, so the new graph is O(n3) in terms of edges. That makes A* solutions as much as O(n3) in terms of time.
Manhattan distance might be a good heuristic for A*.
Is it possible to modify A* to return the shortest path with the least number of turns?
It is most likely not possible. The reason being that it is an example of the weight-constrained shortest path problem. It is therefore NP-Complete and cannot be solved efficiently.
You can find papers that discuss solving this problem e.g. http://web.stanford.edu/~shushman/math15_report.pdf
Given a graph with edges having positive weights, a pair of nodes, and a path between the nodes, what's the best algorithm that will tell me how to modify the edge weights of the graph to the minimum extent possible such that the specified path becomes the shortest path between the nodes (as computed by A*)? (Of course, had I specified the shortest path as input, the output would be "make no changes").
Note: Minimum extent refers to the total changes made to edge weights. For example, the other extreme (the most disruptive change) would be to change the weights of all edges not along the specified path to infinity and those along the path to zero.
You could use the Floyd-Warshall algorithm to compute the distances for all the paths, and then modify the desired path so that it becomes the shortest path. For example, imagine the following graph of 3 nodes.
Let the path be a -> b -> c. The Floyd-Warshall algorithm will compute the following matrix.
The numbers with green circles are the distances of a -> b (2) and b -> c (4). The red circled number is the shortest distance for a path between a and c (3). Since 2 + 4 = 6 ≠ 3, you know that the path must be adjusted by 3 to be the minimum path.
The reason I suggest this approach as opposed to just calculating the distance of the shortest path and adjusting the desired path accordingly is that this method allows you to see the distances between any two nodes so that you can adjust the weights of the edges as you desire.
This reminds me vaguely of a back-propagation strategy as is often found in neural network training. I'll sketch two strategies, the first of which is going to be flawed:
Compute the cost of your candidate path P, which we will call c(P).
Compute the cost of the shortest path S, which we will call c(S).
Reduce every edge weight w(p) ∈ P by (c(P) - c(S) - epsilon) / |P|, where epsilon is some vanishingly small constant by which you would like your path to be less than c(S), and |P| is the number of edges in P.
Of course, the problem with this is that you might well reduce the cost of path S (or some other path) by more than you reduce the cost of P! This suggests to me that this is going to require an iterative approach, whereby you start forwards and reduce the cost of a given weight relative to the shortest path cost which you recompute at each step. This is hugely more expensive, but thankfully shortest path algorithms tend to have nice dynamic programming solutions!
So the modified algorithm looks something like this (assume i = 0 to start):
Compute the cost of the first i steps of your candidate path P, which we will call c(p_0...p_i).
Compute the cost of the shortest path S, which we will call c(S), and the cost of its first i components, which we will denote by c(s_0...s_i).
Reduce edge weight w(p_n) by c(p_0...p_i) - c(s_0...s_i) - epsilon, where epsilon is some vanishingly small constant by which you would like your path to be less than c(S).
Repeat from step 1, increasing i by 1.
Where P = S to begin with, if epsilon is 0, you should leave the original path untouched. Otherwise you should reduce by no more than epsilon * |P| beyond the ideal update.
Optimizing this algorithm will require that you figure out how to compute c(s_0...s_i+1) from c(s_0...s_i) in an efficient manner, but that is left as an exercise to the reader ;-)
I am given a directed graph with a weight function and a vertex s.
My goal is to find for any other vertex v, the shortest path from s to v that goes through exactly one negative edge. The time complexity of the algorithm should be O(|E| + |V|*log|V|), so guess I need to use Dijkstra's algorithm somehow.
I am guessing that I need to translate my given graph somehow to a new graph with non-negative weights that a shortest path from s to v in this graph will be equivalent to the required shortest path in the given graph.. or maybe I need to modify Dijkstra's algorithm somehow??
I tried to think about it a little, don't have any ideas right now... :(