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.
Related
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.
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.
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.
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.
The algorithm of A star search with a specified goal is pretty straightforward. However, what if there are multiple goals in a graph. For instance; you may want to find a shortest path that must include previously specified nodes. Constraint here is say your path must include A, B and C nodes( or more) not just find a path to node A or B or C. And of course the graph includes one or more A, B, C type nodes. So there is a question how can I adapt the A star search algorithm for multiple goals?
edit : we can visit nodes more than one.
You are describing conditions on path and not conditions on goal. A*, like all search algorithms - is finding a path to a goal [could be in a set, of goal, no problems with that].
Your problem [for the general case] is at least as hard as the Traveling Salesman Problem, and thus this problem is NP-Hard.
The reduction is simple: Given an instance of TSP - find the shortest path from a certain v to v such that the path is going through all vertices [constraint]. You can do it by simply marking each vertex with a different mark.
Note however, that A* algorithm has no problem to find shortest path to a vertex in a set of goal vertices. Remember that A* is based on Dijkstra's Algorithm, which is finding shortest path to all vertices from a single source.
You have a set z of all nodes, goal node G, and sets a though y of sub-goal nodes. Starting from S, the starting node, path to all nodes in a through y. Then, from those path to nodes in a through y, but if a route has already gone through a c node for example ignore all c nodes for that branch. Cull branches that move away from the eventual goal until you read the final goal state and have a path that runs through all known sub-goal states.
Hope that makes sense. I'll get a diagram up shortly, which might help.
Hmm.. Compute shortest paths from S->A, S->B, S->C, select the shortest (say to B), compute shortest path from B->C and B->A, select the shortest (say C), compute shortest path C to A. Then add the paths together.
[Edit]
Ok its not quite that simple. I think you could use A* to evalute shortest paths for all permutations between Start, A, B, C (which includes S->every node in the goal sets, each node in A to each in B etc.) and pick the shortest combination.