I tried to write pseudo-code based on this solution.
But I couldn't understand this part "Once we have run Bellman-Ford, we can look back at the results from Floyd-Warshall to determine whice partial paths corresponded to the path found in G'". Can anyone help me to understand this using pseudo-code?
Let's look at a very simple example, with one gas station.
Find the shortest path in G' is start - s - target
To find the corresponding path in G, look at each hop in the G' path and find the shortest feasible path in G between the nodes in G1 hop'
start - s becomes start - v1 - s
s - target becomes s - v2 - target
Adding the partial paths together we get the answer
start - v1 - s - v2 - target
So the pseudo code is
Construct G'
Find P' the shortest path in G'
LOOP over hops in P'
Find Pg shortest path between hop source and hop destination in G
Add Pg to Ps ( eliminating common vertex )
Output Ps
Related
I'm trying to figure out the most optimal way to get the shortest paths from all the source nodes to any one of the target nodes that leads to the minimum weight in a weighted graph. All nodes are either a source node or a target node. So figure we have a graph consisting of A, B, C as source nodes and D, E, F as target nodes. A, B, C has to find the shortest path to any one of the target nodes that happens to have the shortest path.
The naive solution is to use the Dijkstra's algorithm or something similar to first find the shortest path from A to D and then from A to E etc. and then comparing the final weight of each of those shortest paths to see which is actually the shortest. I want to know if there is a more efficient solution to this.
Add a new node that leads to all the sources (make these new edges 0-weight), and run Dijkstra's from the new node.
Let's consider this graph:
Let's say
I want first path with source as A, destination as H and
I want second path with source as A, destination as D.
I am not able to apply suurballe algorithm as it works for paths with same source and same destination only.
Expected O/p is first path => A-E-F-G-H, second path => A-B-C-D. These two are vertex disjoint paths.
How to calculate 2 vertex disjoint paths in this situation?
An approach that works quite well for many problems is to think about how to transform it into one you can solve.
In this case: You already know the Suurballe algorithm that can solve the problem of vertex disjoint paths if the target vertex of both is the same.
So to solve your problem, you can just add a vertex X to your graph and connect D and H to it. Then execute Suurballe's algorithm with start A and target X and remove X from the end of the returned paths. As the only way to reach X is via D and H, those must be the last ones in the path before X.
The problem is finding a shortest path between two vertices in a directed graph
converting edges which enter vertices (u in U) to two edges and converting edges which enter non u vertices into 3 edges, effectively making the path through u vertices shorter than non u vertices. if there exists a shortest path of equal length which goes through all u in U.
the idea is to then run the BFS algorithm once and check whether the shortest path contains all edges in u and is of equal length to the shortest path between s and t (taking all the multiplied edges into account).
EDIT: sorry, forgot to ask the question, is this algorithm correct?
The idea of your algorithm can work. Namely that you run BFS to find the shortest path, then run BFS again on an altered graph that makes it better to go through U. BUT the way that you described altering it may shift what the best path is.
Here is the issue. Suppose that P1 is a best path with more steps that goes through all of U, while P2 is a good path that goes through one expensive hop from U to U, before alteration P1 may be better than P2 but after you change the weights, P2 is better than P1. And so you find P2 the second time, it doesn't go through all of U, and you wrongly conclude that P1 doesn't exist.
To fix it, you have to set a fixed reward for entering/leaving U. Same change in all edge weights. Now the more nodes of U that a path goes through, the better it is, but you have not changed the relative value of two paths that go through the same number of nodes of U. And now your reasoning works with no gotchas.
OP here, I've managed to prove the algorithm since posting the question.
proof:
if there exist shortest paths P1,P2,P3...Pn then after augmenting the graph by multiplying edges which enter non U vertices by 3 and edges which enter U vertices by 2 (I later realized the augmentation can be 2 and 1) the lengths of the shortest paths would be:
3 * |Pi| - |{u | u in Pi}|
the number of edges in the path times 3 minus the number of vertices in the path which are in U.
clearly now the shortest path is that which minimizes 3 * |Pi| - |{u | u in Pi}|
but 3*|Pi| is a constant for all shortest paths so we actually want to maximize |{u | u in Pi}|
which means that we'll want to pass through as many vertices in u as possible so if by using BFS and recovering the shortest path we find that it doesn't contain all vertices in U we can certainly say that such a path doesn't exist, if we do find that there's a path which goes through all vertices in U we must check it's length (after restoring it to be a path in the original graph) we can simply check if it's length is the length of a shortest path between s and t if yes then it's a path which goes through all vertices in U and is a shortest path, if not then clearly it isn't.
I'm having trouble trying to figure out a shortest-path algorithm such that given a undirected unweighted graph with an start point a and end point b, every path must contain/run into the vertex v.
Is it possible to get it in O(n) if the length is greater than n / 2?
I found this question but it didn't spark anything in my head. It did get me thinking about BFS but how would I know when I went through vertex v?
Can anyone point me into some direction?
Thanks!
Just break down the problem into two subproblems: find a path from a to v and then another path from v to b.
If there's a requirement that the overall path cannot reuse an edge or vertex, then you'll need to do something more elaborate. It's not immediately clear to me exactly what that is. One possibility is to remove the edges/vertices used in the path from a to v (except for v itself) while searching for a path from v to b. But that won't guarantee a shortest overall path, so you'd have to do some backtracking. But I suspect that there's a better approach.
graph algorithm question for you.
I have a graph, used to represent a road network. So there are cycles in it (a roundabout would be a trivial one). Also some edges are bi-directional, some are uni-directional (one way streets). Edges are weighted by their length.
Let's say I have two nodes and have already have computed the shortest path between them. What I'd like to do is find all the other paths that connect the two nodes that are shorter than some distance X. Call these paths the "alternates".
An example in ascii art is below, where I have labelled the edges with letters and the nodes with numbers.
F
5----6
E / \ G
3--------4
/ D \
B / \ C
1--------------2
A
Let's say I have the path covering edge A that goes from 1->2 and I want to find alternates. One alternate to that path would be BDC, provided that its length is less than X. BEFGC is another one.
Another example path would be BD that connects nodes 1->4. An alternate to that one would be AC.
More requirements:
alternates should not include any part of the main path. So if the main path is A, any alternate that contains A is not a valid alternate. In the BD example above that connects 1->4, BEFG is not a valid alternate because it includes B which is in the main path.
alternates should not have internal cycles. For example this alternate path would not be allowed for connecting 1->2: BDGFEDC because it traverses edge D twice.
Thanks!
If you run Dijkstra's algorithm to find the shortest path, you have a table which gives you, for each node, the shortest distance to that node from the source. I would delete from the graph the points on the shortest path, run Dijkstra's algorithm, and then do a depth first search from the target, terminating the search every time the path you are currently investigating becomes a cycle, or the sum of the distance on the path so far and the shortest distance from the current node to the source is more than X.
Every time you actually reach the source node you can print out the path so far.