Throw an error if multiple shortest paths are found - algorithm

Given an undirected weighted graph, a start, and an end point. You need to find the shortest path to that end point, but throw an error if multiple shortest paths are found. How would we do the error part? Is there a way to check if multiple shortest paths to a destination node exist?
My idea is that when we pop out of the priority queue in dijkstra's algorithm, at that time if the node is the destination node, then we check if in this priority queue, another element exists for the same destination node.
During the relaxation, instead of only pushing to the queue if the distance is less than, we can push if the distance is less than or equal to. But I am not sure about it.
EDIT - Its a weighted undirected graph

One way to do this is by creating a shortest path DAG. Whenever you relax some edge from node A to node B with cost C (assuming the current shortest distance from source to each node is stored in array dist), if dist[A] + C is greater than dist[B] then do nothing, if dist[A] + C is equal to dist[B], then we can reach B in a shortest path using a different route than before, so we add A to the list of nodes that can reach B in its shortest path (let's call this array pars), so we add A to pars of B, and finally if dist[A] + C is less than dist[B], then we update dist[B] and clear the previous values from pars[B], and add A to pars[B].
The resulting graph is guaranteed to be a DAG if all edge weights are strictly greater than 0. Then you can count the number of paths to the destination node using some easy dynamic programming methods, process node in a topological order, then the number of paths of each node is the sum of number of paths of nodes that reach it (nodes in pars[node]).
Hopefully this was useful and clear.

Related

What algorithm should I use to get all possible paths in a directed weighted graph, with positive weights?

I have a directed weighted graph, with positive weights, which looks something like this :-
What I am trying to do is:-
Find all possible paths between two nodes.
Arrange the paths in ascending order, based on their path length (as given by the edge weights), say top 5 atleast.
Use an optimal way to do so, so that even in cases of larger number of nodes, the program won't take much time computing.
E.g.:- Say my initial node is d, and final node is c.
So the output should be something like
d to c = 11
d to e to c = 17
d to b to c = 25
d to b to a to c = 31
d to b to a to f to c = 38
How can I achieve this?
The best approach would be to take the Dijkstra’s shortest path algorithm, we can get a shortest path in O(E + VLogV) time.
Take this basic approach to help you find the shortest path possible:
Look at all nodes directly adjacent to the starting node. The values carried by the edges connecting the start and these adjacent nodes are the shortest distances to each respective node.
Record these distances on the node - overwriting infinity - and also cross off the nodes, meaning that their shortest path has been found.
Select one of the nodes which has had its shortest path calculated, we’ll call this our pivot. Look at the nodes adjacent to it (we’ll call these our destination nodes) and the distances separating them.
For every ending (destination node):
If the value in the pivot plus the edge value connecting it totals less than the destination node’s value, then update its value, as a new shorter path has been found.
If all routes to this destination node have been explored, it can be crossed off.
Repeat step 2 until all nodes have been crossed off. We now have a graph where the values held in any node will be the shortest distance to it from the start node.
Find all possible paths between two nodes
You could use bruteforce here, but it is possible, that you get a lot of paths, and it will really take years for bigger graphs (>100 nodes, depending on a lot of facotrs).
Arrange the paths in ascending order, based on their path length (as given by the edge weights), say top 5 atleast.
Simply sort them, and take the 5 first. (You could use a combination of a list of edges and an integer/double for the length of the path).
Use an optimal way to do so, so that even in cases of larger number of nodes, the program won't take much time computing.
Even finding all possible paths between two nodes is NP-Hard (Source, it's for undirected graphs, but is still valid). You will have to use heuristics.
What do you mean with a larger number of nodes? Do you mean 100 or 100 million? It depends on your context.

Finding number of paths between two nodes in a directed acyclic graph

My idea of solving this problem is to adjust DFS so that it stops when we hit the destination node, then set up a counter that adds up all of the neighbors of the starting node, then the neighbors of the starting node and its neighrbours recursively.
I'm just wondering if this will only count the paths from the source to the destination, and not any stray paths that don't lead to the destination node.
Thank you for the help.
You can use dynamic programming. You have a directed acyclic graph so you have a node (say s) with no arcs pointing into s. You also have a node (say t) that has no arcs pointing out of t. Because it is acyclic, you can use a topological sorting algorithm to find an ordering of the nodes such that every arc points away from s and towards t.
So start at s. The number of paths from s to s is 1, the empty path. Because the graph is acyclic, s must have a neighbour u such that the only arc pointing into u is su. Now you just repeat. In general, for a node w that has arcs from v1,...vk pointing into it. Then the number of paths from s to w is just the sum of the number of sv1 paths, ..., svk paths.
This is in the case of a single arc between each node. If there are multiple arcs you multiply so it would be (number of v1w arcs)(number of sv1paths) + ... + (number of vkw arcs)(number of svk paths)
And at each step you can use the fact that it is acyclic to find the node w such that you have already calculated all the sv1 to svk paths.
I would use BFS.
Let's call the source node s and the target node t.
When you BFS starting from s, all the paths with length 1 will be found and put into a queue. You can, then, take the first element of the queue (call it u) and find all the paths of size 2 (s -> u -> ...). Repeat the same thing for each distance, until you find all paths of all lengths from s to t.
A trick to speed it up would be: after you exhausted all the paths of a node w, store how many paths from w to t there are, and when another node (above w) reach w, you won't need to recompute all the paths.

Traversing exactly n edges, from source node to destination node, find longest path

Suppose we have a weighted graph, it is directed and cyclic. Every node has an edge directed toward every other node. There are no edges that connect a node to itself.
Now we have a source node, and a destination node. I have to start at the source node and traverse exactly n edges and end up at the destination node. Where n is some arbitrary positive integer (possibly greater than the number of nodes in the graph).
When we traverse an edge, we add it to our sum (edge weights are all positive). Now the path we take to reach our destination node can have cycles. How can we maximise our sum?
If you are not allowed cycles the problem is NP-complete - see https://en.wikipedia.org/wiki/Longest_path_problem
Assuming that you are allowed paths that can include cycles e.g. A,B,C,B,C
For i = 1..N compute, for each node, the length of the longest path of length i that terminates at that node. Save the length and the identity of the node just before the N.
Case i=0 is just a path of length 0 with previous node null for every node.
Work out case i+1 from case i by considering, for each node, every edge terminating in that node.
At the end chose the node for step N with the longest path terminating at it and use the records of previous nodes to trace back.
(The above was actually intended to compute the longest path between any two nodes because I misread the question, but you can modify it in the beginning to extend only paths which start at the source node, and in the end to consider only paths that end at the destination node).
Example added after question ab=1,ac=2,bd=10,cd=1 find the longest 2-step path from A to D.
i=0 start with A
i=1 longest path to B is length 1, last visited A. Longest to C is length 2, last visited A
i=2 longest to A is length 4 last visited C. Longest to D is 11 last visited B (max of 1+10 from B and 2+1 from C).
We wanted length 2 so we stop here and take the answer computed for D.

Finding a path in which the difference between min edge cost and max edge cost is minimum across all routes

We have to find the route from a source to a sink in a graph in which the difference between the maximum costing edge and the minimum costing edge is minimum.
I tried using a recursive solution but it would fail in condition of cycles and a modified dijkstra which also failed.
Is there an algorithm where i will not have to find all routes and then find the minimum?
Sort the edges by weight (in non-decreasing order), then for each edge do the next: Add the next edges (the ones with greater or equal weight in non-decreasing order) until the source and sink are connected, then update your answer with de difference between the last edge, like this:
ans = INFINITE
for each Edge e1 in E (sorted by weight in non-decreasing order)
clear the temporal graph
for each Edge e2 in E
if e2.weight >= e1.weight
add e2 to the temporal graph
if sink and source are connected in the temporal graph
ans = min(ans, e2.weight - e1.weight)
break
print ans
If you use the UNION-FIND structure to add edges and check connectivity between source and sink you should get an overall time of O(edges^2)
OK, so you have a graph, and you need to find a path from one node (source) to another (sink) such that max edge weight on the path minus min edge weight on the path is minimized. You don't say whether your graph is directed, can have negative edge weights, or has cycles, so lets assume a "yes" answer to all these questions.
When computing your path "score" (maximum difference between edge weights), we observe these are similar to path distances: you could have a path from A to B that scores higher (undesirable) or lower (desirable). If we treat path scores like path weights we observe that as we build a path by adding new edges, the path score (=weight) can only increase: given a path A->B->C where weight(A->B)=1 and weight(B->C)=5, yielding a path score of 4, if I add edge C->D to the path A->B->C, the path score can only increase or stay the same: the difference between minimum edge weight and maximum edge weight will not be lower than 4.
The conclusion from all of this is that we can explore the graph looking for best paths as if we are looking for optimal path in a graph with no negative edges. However, there could be (and likely to be, given the connectivity described) cycles. This means that Dijkstra's algorithm, properly implemented, will have optimal performance relative to this graph's topology given what we know today.
No solution without full graph exploration
One may be misled into thinking that we can make locally good decisions about which edge should belong to the optimal path without exploring the whole graph. The following subgraph illustrates the problem with this:
Say you've need a path from A to F, and you are at node B. Given everything you know, you'd choose a path to C, as it minimizes the path score. What you don't know (yet) is that the next edge in that path will cause the score of this path to increase substantially. If you knew that you would have chosen the edge B->D as a next element in an optimal path.

finding whether a path of a specific length exists in an acyclic graph

In an acyclic graph, I am trying to find out whether or not a path of length L exists between two given nodes. My questions is, what is the best and the simplest Algorithm to use in this case.
Note that the graph has a maximum of 50 nodes and 100 edges.
I have tried to find all the paths using DFS and then to check if that path exists between the two nodes but I got the answer "Time Limit Exceeded" from the online judge.
I also used the Uniform Cost Search Algorithm but I also a got a negative response.
I need a more efficient way for solving such problem. Thank you.
I don't know if it will be faster then a DFS approach - but it will give a feasible solution:
Represent the graph as a matrix A, and calculate A^L - a path of length L between i and j exists if and only if A[i][j] != 0
Also, regarding DFS solution: You do not need to find all paths in the DFS - you should limit yourself to paths of length <= L, and by this trim some searches, once the length have exceeded the needed length. You could also escape the search once a path of length L is reaching the target.
Another possible optimization could be bi-directional search.
Find all vertices which have path of length L/2 from the source to
them.
Next, find all vertices which have paths of length L/2 from them
to the target (DFS on the reverse graph)
Then, check if there is a vertex that is common to both sets, if
there is - you got a path of length L from the source to the target.
Since the graph is acyclic you can order vertices topologicaly.
Let's name starting vertex A and finish vertex B.
Now the core algorithm starts:
For each vertex count all possible distances from A to this vertex. At start there is
one path from A to A with length zero.
Then take vertices in topological order.
When you pick vertex x: Look at each predecessor and update possible distances here.
This should run in O(N^3) time.
You can use a modified Dijkstra algorithm where instead of saving for every vertex the minimum distance to the origin, you save all the possible distances less or equal to the one desired.
I believe that you can use the following algorithm to find the longest path in a tree. This assumes that your graph is connected, if it is not you would need to rerun this on each connected component:
Pick an arbitrary node, A.
Do a BFS (or DFS) from A to find the node in the tree farthest from A, call this node B.
Do a BFS (or DFS) from B to find the node in the tree farthest from B, call this node C.
The path from B to C is the longest path in the tree (possibly tied for longest).
Obviously if this path is longer than L then you can shorten it to find a path of length L.

Resources