I was wondering if there is an algorithm which would find shortest paths in graph.
Let's say that I have a graph where there are couples of path from one vertex to another. Two or more of these paths have the same cost. How can I mark, find etc all shortest paths between these vertices ? As far as I know Dijkstra or Bellman-Ford algorithms will find shortest path but they "choose" only one.
Dijkstra's algorithm gives you the cost to all the possible intermediate nodes, and the cost of the shortest path to the sink. You can get all the paths from source to sink by doing a depth first search from the sink to the source (going backwards), where you traverse an edge (backwards) only if the cost of that edge is equal to the difference between cost of the shortest path from the source to the two nodes. Of course you get the paths in reverse order, but reversing them is easy.
.
Take a look at Floyd-Warshall.
In computer science, the
Floyd–Warshall algorithm (sometimes
known as the WFI
Algorithm or
Roy–Floyd algorithm) is a graph
analysis algorithm for finding
shortest paths in a weighted graph
(with positive or negative edge
weights). A single execution of the
algorithm will find the lengths
(summed weights) of the shortest paths
between all pairs of vertices though
it does not return details of the
paths themselves. The algorithm is an
example of dynamic programming.
Related
Will Dijkstra's shortest path algorithm return correct results on a directed tree with negative weight edges?
On a general graph with negative weights, the algorithm will fail, but since it’s a directed tree it feels like the algorithm will succeed.
From other answers, you know that there is no good reason to run Dijkstra's algorithm if you know that the graph is a tree.
If you do run it, though, it will work even if the tree has negative edge weights.
The reason that Dijkstra's algorithm doesn't work for graphs with negative weights, is that negative weights allow a 2nd, shorter, path to be found to a vertex after its distance has already been decided. In a tree there are no 2nd paths.
In a tree there is only one path between any two given nodes, so searching for the "shortest" path in a tree makes little sense: when you find a path it is the shortest, and this search does not need to take weights into account, so there is no need to use Dijkstra's algorithm. A simple depth-first search will do.
If the graph is not a tree, but a directed acyclic graph (DAG) with negative edges, then Dijkstra's algorithm cannot be used to find a shortest path. Take this counter example:
If we have to look for the shortest path from A to C, Dijkstra's algorithm will proceed to visit B and C, and as it hits the target, it will stop looking further, never considering the edge from B to C.
Other attempts to apply Dijkstra
Another (now deleted) answer proposed to make all edge weights positive by adding an absolute value to all weights, but this does not yield correct results: what is the shortest path in the original graph, is not guaranteed to be still the shortest path in the derived graph.
Counter example:
Where in the original graph the shortest path from A to C runs via B, in the adjusted graph, the shortest path is A-C.
I was told that BFS can give you the shortest path from the source vertex to the destination vertex, which makes sense since you traverse the adjacent nodes. However, I do not see how that is guaranteed to happen always. Nowhere in the BFS pseudocode logic do I see to pick the correct adjacent node to guarantee to have the shortest path. BFS could pick any random adjacent node and end up with the longer path from the source vertex to the destination vertex. Then how does BFS give the shortest path from the source vertex to the destination vertex?
In the case of unweighted graphs, it is guaranteed that eventually, we will get the shortest path using BFS.
But in the case of a weighted graph, we can still run a variant of BFS, i.e., using a priority queue for neighbors nodes (based on weights of edges). This variant is called Dijkstra’s algorithm.
You are correct. Using BFS alone does not guarantee to find the shortest path.
It will only fetch you the shortest path when all the edges have an equal edge weight in the case of a weighted graph. For unweighted graphs, you can assume equal edge weights.
Other algorithms (for example, Dijkstra’s algorithm) adapt BFS to find the shortest paths.
Thanks to your question, which pushed me to come up with an interesting case, where BFS can actually fetch you the shortest path in case of weighted graphs:
When we have a linear weighted undirected graph (with no cycles), i.e., a graph with 2 adjacent nodes for middle nodes and 1 adjacent node for nodes are the extreme ends (like a double linked list), BFS could actually fetch us the shortest path.
PS: BFS does not pick up any adjacent node randomly. The adjacent node's selection depends on the adjacent nodes' order in the particular node's adjacency list. So, it's dependent on your code implementation and not on some random factor.
Given a directed graph with edges having -ve or +ve weights, what is the algorithms to find the smallest weight edges of all paths from vertex s to vertes d?
From Wikipedia
You are describing the Single Source shortest path problem. Which can be solved using Dijkstra's if the edges are only positive or Bellman-Ford if the edges are allowed to be negative as well.
The most important algorithms for solving this problem are:
Dijkstra's algorithm solves the single-source shortest path problem.
Bellman–Ford algorithm solves the single-source problem if edge weights may be negative.
A* search algorithm solves for single pair shortest path using heuristics to try to speed up the search.
Floyd–Warshall algorithm solves all pairs shortest paths.
Johnson's algorithm solves all pairs shortest paths, and may be faster than Floyd–Warshall on sparse graphs.
Viterbi algorithm solves the shortest stochastic path problem with an additional probabilistic weight on each node.
I would find all reachable from s, e.g. by depth first search. Then find all nodes that can reach d (equivalently, all nodes reachable from d in the graph with directions reversed). Now you want the smallest weight edges that start in the first set and end in the second set.
Given: undirected weighted connected graph. s,t are vertices.
Question: Find an algorithm as efficient as possible that returns a path from s to t. In that path, the edge that has the highest weight, will has the least weight as possible. So if we have 5 paths from s,t and for every path we have the heaviest edge, so the minimum edge of these 5.
What I've tried:
Use some algorithm to find the shortest path between s and t.
Delete all the edges that are not part of the shortest paths we've found
Use BFS with some modification, We run BFS depending on the number of paths from s to t. Every time we find a maximum edge and store it in an array, then we find the minimum of the array.
I'm struggling to find an algorithm that can be ran in (1), Bellman ford won't work - because it has to be directed graph. Dijkstra won't work because we don't know if it has negative circles or negative edges. And Prim is for finding MST which I'm not aware of how it can help us in finding the shortest path. Any ideas?
And other from that, If you have an algorithm in mind that can solve this question, would be much appreciated.
You can solve this with Kruskal's algorithm. Add edges as usual and stop as soon as s and t are in the same cluster.
The idea is that at each stage of the algorithm we have effectively added all edges below a certain weight threshold. Therefore, if s and t are in the same cluster then there is a route between them consisting entirely of edges with weight less than the threshold.
You can solve it by converting into a MST problem, basically the path from s to t in the MST would be the path which has the least possible maximum weight
find the most negative edge in the graph
add that (weight+1) to every edge.
Now all edge are positive so you can apply Dijkstra's algorithm
you can get the shortest_path between source and destination
Now count the number of edges between source and destination (say x)
Real shortest path will be: shortest_path - x * (weight+1)
What is the most efficient shortest path algorithm performed on a graph that is not directed and only has positive edges out of these five algorithms?
BFS
DAG
Dijkstra
Floyd-Warshall
Bellman-Ford
So I know Dijkstra's can't be used on negative edges and has a running time of O(E * logV) where E is the number of edges and V is the number of vertices, so this would be my best guess. Is this correct?
If you need to find the shortest path in an unweighted graph, BFS would be the best option, however if there are weights on the edges, and you only need to find the optimal route between a single source and one or many other nodes, Dijkstra would be the best option. If you need to find the shortest path between any two pairs of nodes(i.e. have multiple sources), the best option is Floyd-Warshall.