Shortest paths in graph - algorithm

I've got a problem with a 2-section question:
G=(V,E) is undirected unweighted graph. t,s are nodes in the graph. e=(a,b) is an edge in the graph.
1) Suggest an efficient algorithm that checks if e is a part of all shortest paths from s to t.
2) Suggest an efficient algorithm that checks if e is a part of one of the shortest paths from s to t.
I've seen in the forum suggestion to solving section 1, by using Dijkstra algorithm twice, once with the given edge and once without. Then you need to compare the results.
However, I didn't managed to figure more efficient way to solve section 2. I guess it is possible, but I don't know how.
Any suggestions?

Actually for an unweighted, undirected graph, you don't need to use Dijkstra, a simple BFS shall serve the purpose.
Following method checks whether e is a part of atleast one shortest path from s to t:
Compute the shortest path from s to e and the shortest path from e to t
If the sum of the lengths of these two paths is equal to the shortest path from s to t, then e is a part of atleast one shortest path from s to t.
s -----> e -------> t
If you want to know whether e is a part of exactly one shortest path from s to t, then in addition, the following link maybe be helpful. It concerns a directed graph, but our undirected graph can be thought of as a directed graph with edge from u to v and v to u.
How to find the number of different shortest paths between two vertices, in directed graph and with linear-time?

Problem 2 should be should be solvable using one (modified) pass of Dijkstra's algorithm.
As before, you keep the frontier of the search space in a priority queue, but you also add one more bit of information, which is a flag that denotes whether the path that lead to this part of the frontier went through the edge in question.
Initially, just the vertex s is in the queue, and the flag is false.
The flag is propagated (kept as true) if it was true when popped off the head of queue.
The flag is set to true for the first time, whenever the edge e is traversed (i.e. if you needed to traverse e to get to a v then when pushing v onto the queue, you set the flag to true).
e was used if when your target, t is popped from the stack, its flag is set to true.

Related

How do I keep track of the shortest paths in the Dijkstra algorithm when using a min-priority queue?

I'm trying to implement Dijkstra's algorithm with a priority queue.
From my understanding, "Dijkstra's algorithm" allows to to find the shortest 'paths', in that it will return a set of vertices that form the shortest path *.
From this answer here https://stackoverflow.com/a/20217659/1663462, as well as (Dijkstra's_algorithm#Algorithm) it seems I should be able implement it using just two datastructures: a graph and queue datastructure.
However, in my implementation using the two mentioned datastructures, when I finally reach the destination node, I don't have the vertices path stored? In other words I just have the shortest distance only (a single scalar value).
How is this meant to be kept track of? The only way I can think of is to use an additional datastructure - an array or hash map where the key would be the vertex and the value would be it's parent.
The actual question:
Is the additional datastructure necessary to achieve ("set of vertices that form the shortest path *")? If not, how do I determine the vertices?
You don't have to keep track of the whole path for each vertex as you've suggested. To produce the s-v paths themselves, the only thing you have to record for each vertex v is the edge that "discovered" it.
In other words, as a vertex v is being discovered by the algorithm, you record the edge (u,v) on which it achieved the value that minimized the distance from s.
Now, assuming you have the "discovering" edge for each vertex v in the graph, the path from s to v can be computed as follows: if (u,v) is the ("discovering") edge stored for v, then the shortest path from s to v is the path from s to u (which can be computed recursively), followed by the single edge (u,v).
So, to construct the shortest path from s to v, you start at vertex v, then you follow the edge stored for v in the reverse direction, and continue until you reach s.
Yes the additional data structure is necessary, I did not find a way to do without it.
One get the shortest 'distance' without it between two vertices, but it will not include the list of vertices between the source and destination vertex.
Although it is possible to store additional information on the nodes while running Dijkstra's algorithm, it is not strictly necessary.
Indeed, it is possible to trace back a shortest path after running Dijkstra's algorithm, even if no additional information was stored on the nodes. The only information needed on each node is its distance from the source.
I will use the following notations:
s is the source vertex;
t is the destination vertex;
w(u,v) is the length of edge (u,v) between two vertices u and v (given with the graph);
d(v) is the length of the shortest path from source s to a vertex v (computed by Dijkstra).
If Dijkstra's algorithm was run correctly, then the following proposition must be true for all vertices v except the source:
Vertex v has at least one neighbour u such that d(v) = d(u) + w(u,v).
For every vertex v, call pred(v) that neighbour.
Then a shortest path can be constructed in reverse, starting from destination t, by following the pred vertices.

Find Two vertices with lowest path weight

I am trying to solve this question but got stuck.
Need some help,Thanks.
Given an undirected Connected graph G with non-negative values at edges.
Let A be a subgroup of V(G), where V(G) is the group of vertices in G.
-Find a pair of vertices (a,b) that belongs to A, such that the weight of the shortest path between them in G is minimal, in O((E+V)*log(v)))
I got the idea of using Dijkstra's algorithm in each node which will give me O(V*((E+V)logv))),which is too much.
So thought about connecting the vertices in A somehow,did'nt find any useful way.
Also tried changing the way Dijkstra's algorithm work,But it get's to hard to prove with no improvment in time complexity.
Note that if the optimal pair is (a, b), then from every node u in the optimal path, a and b are the closest two nodes in A.
I believe we should extend Dijkstra's algorithm in the following manners:
Start with all nodes in A, instead of a single source_node.
For each node, don't just remember the shortest_distance and the previous_node, but also the closest_source_node to remember which node in A gave the shortest distance.
Also, for each node, remember the second_shortest_distance, the second_closest_source_node, and previous_for_second_closest_source_node (shorter name suggestions are welcome). Make sure that second_closest_source_node is never the closest_source_node. Also, think carefully about how you update these variables, the optimal path for a node can become part of the second best path for it's neighbour.
Visit the entire graph, don't just stop at the first node whose closest_source and second_closest_source are found.
Once the entire graph is covered, search for the node whose shortest_distance + second_shortest_distance is smallest.

most lightweight circle in directed graph that goes through specific vertex

I have directed Graph G(V,E) with weight function w. so that weight of each (u,v) is a positive value. I need to find the most lightweight circle in the graph that vertex k' is part of it.
I've also given an algorithm i can use which can find the most lightweight path for a graph with positives weights ( i can use it only once).
I thought about creating a sub graph G' where all vertices and edges that are strongly connected components. find the graph which k' is part of it. then find for the most lightweight adjacent edge from k' to some v of vertices. from that v i can run the algorithm given and find the lightweight path then add the weight of the vertex missing ( (k',v) ).
is that seems correct ? I'm in the beginning of this course and I feel i'm not there yet.
It is a single-source shortest-path problem, where you exclude k->k self-loop as a solution, and find a longer path from k to k. The trick is always expand the shortest path thread.
Given this definition, you can start Googling...
I can't imagine why you called your source vertex k'. Anyway...
Add a new vetrex w that has the same outgoing edges as k'.
Then use Dijkstra's algorithm to find the shortest path from w to k'.
Substitute k' for w in the path, and you have the smallest cycle including k'.
Very interesting problem. I am assuming that there are no negative values in the graph, or otherwise the following solutions requires first normalizing the vertices such that the negative values become at least 0. First method (trivial) is to detect all cycles starting from the target vertex (k). Then compute the weight of all those cycles and take the minimum. The second method is to run Dijkstra algorithm (again watch out negative weights) from the target node (k). Then iterate over all incoming edges of (k), and select the source node that has the minimum Dijkstra value. Now the lightest cycle includes the single path (formed by Dijkstra traversal) from (k) to the chosen node + the bridge to come back to (k). I hope that helps :)

Dijkstra's Single Source Shourtest Path with an extra edge with weight of 'w'

In an recent interview I was asked to implement single source shortest path algorithm(for undirected and positive weighted graph) with slight modification i.e. we're given an extra edge with weight 'w'. And we have to find if we can find a more shorter path, than the one calculated by SSSP algo, by connecting that extra edge, with weight 'w', between two nodes which are not already connected.
Here's an image. As according to SSSP the shortest path between A(source) & D(destination)is A-B-C-D i.e. total of 8.
But given the extra edge. It can be connected between A and D, which are not already connected, to minimize the shortest path yielded through SSSP algo.
Image of graph with extra edge contributing the shortest path
I tried thinking about the solution. But nothing struck so far. I've implemented the Dijkstra algorithm to find the shortest path. But this little modification has baffled me. So can you help a little bit.
There are two options:
We don't need an extra edge. This case is handled by a standard Dijkstra algorithm.
A shortest path with an extra edge looks like this: shortest_path(start, V) + (V, U) + shortest_path(U, target). That is, we go from the start to some vertex V by the shortest path in the original graph, then we go to U (again, an arbitrary vertex) by adding this extra edge (V and U mustn't be connected) and then we go from U to the target node by the shortest path in the original graph.
We can use the structure of the path to get an O(n ^ 2) solution: we can compute shortest paths from the start node to all the others (one run of the Dijkstra's algorithm) and all shortest paths from the target node to all other nodes (one more run). Now we can just iterate over all possible pairs (V, U) and pick the best one.
Bonus: we can solve it in O(m log n) for a sparse graph. The idea is as follows: instead of checking all (U, V) pairs, we can find such U that it has the minimal distance to the target among all vertices that are not connected to V in degree(V) * log V (or even linear) time (this problem is known as finding the smallest element not in the set).
i am not sure I ubderstand your question. You Have a weighted graph ,and can add a edge with w, add to where make shortest path.
I think we can use spfa + dp to solve the problem. Set all other edge to w and create boolean matrix m, m[i,j] =1 mean no edge between i,j, dp[u,0] mean shortest distance when we reach u without using an extra edge, dp[u,1]mean using an extra edge. I don’t write the dp transfer equation. So we can iterate in spfa, and we can also backtrack the best way of dp and get where to set an extra edge.
We do not use Dijkstra algorithm in above solution.
spfa is also a Single Source Shourtest Path algoritm, it can deal negative weighted edge, but not negative cycle.
It’s just my think,i have not try it.but I think it’s a idea to solve it.
If any wrong, tell me please.

Preprocess shortest paths under contention

It is easy to prove that if P is a shortest path between u and v, then every subpath is also a shortest path.
Given a connected Graph, I want to preprocess a the shortest path between every pair of nodes in a Matrix, such that:
Path[u,v] = Path[v,u]
If x,y in Path[u,v] then Path[x,y] is a subpath of Path[u,v].
I can not figure out an algorithm or a prove and actually I do not know if this is posible.
Any idea is welcome.Thank you.
You can only get (1) if you are working with undirected graphs OR if it is guaranteed that the weight of the arc (a, b) is equal to the weight of the arc (b, a) for all arcs in your graph.
The problem you describe sounds like the all-pairs shortest path problem: for each pair of nodes in a connected graph, find the shortest paths between nodes in the pair. The Floyd-Warshall algorithm can be used to find the lengths of paths and it is straightforward to reconstruct the shortest paths from there.
This algorithm further requires that there are no negative cycles (otherwise a shorter path could always be obtained by running through that cycle again) but that requirement seems reasonable.
To guarantee property (2), you need to make sure when reconstructing paths you are reconstructing "canonical" paths whenever more than one shortest path may be possible. To do this, impose an ordering on the vertices and always test candidate nodes in ascending order, always preferring the lowest-ordered node which maintains the shortest-path property.
Wikipedia has a fairly good write-up.

Resources