Click here to Skip to main content
15,880,392 members
Articles / Programming Languages / C++

Shortest Path Algorithm

Rate me:
Please Sign up or sign in to vote.
3.06/5 (19 votes)
27 Feb 2019CPOL6 min read 39.1K   615   41   25
This explains the working of Bellman Ford algorithm.

Introduction

Shortest path algorithms are used in many real life applications, especially applications involving maps and artificial intelligence algorithms which are NP in nature. A graph is a collection of nodes \(V\) connected by edges \(E\) and can be expressed as \(G(V,E)\). Stands for vertices. These vertices and the connecting edges together can be imagined to form a three dimensional geometrical structure. In some cases, for each \((u,v)\) \(\epsilon E\) (here \(u,v,\) \(\epsilon V\) are vertices which are connected), there is a weight value assigned to it. This can also be called as "distance" or "cost" of connecting the two nodes. The shortest path algorithm traces the minimum distance (or cost) between two nodes \((u,v)\) which are either directly or indirectly connected. The weight values along each possible paths to the destination node from the source node are summed up, and the path with the minimum summation value is chosen as the shortest path.

We may represent a weighted graph \(G(V,E,w)\) as where the extra parameter represents the set of weight values across each edge. \(w:E \rightarrow \mathbb{R} - {0},w(e)\) Weight of the edge. Usually, shortest path algorithms are of time complexity \(\Omega (|V|)\) because every node needs to be visited at least once. In case of AI algorithms, the vertices are generated based on specific rules, and usually it’s a function of depth; because most nodes have more than one connection, we may also have non-polynomial relation between the depth and the number of nodes.

Algorithms like Dijkstra’s algorithm’s time complexity is \(O(|V|^{2})\) (note, \(|V|\) represent number of nodes and \(|E|\) represents number of edges). Note that the definition is actually a relation between the edge and a real number other than zero. This also shows that the weight values can be negative. So a modified version of the algorithm which also solves problems with negative weight edges is required. But doing this increases the time complexity; Dijkstra’s algorithm is a greedy algorithm, which selects the best possible path in the graph originating from a node, and later choosing the node with the least distance from the set of nodes yet to be visited, to further repeat the process with the newly selected node. Such an algorithm which solves graphs with negative weight values is Bellman Ford algorithm and its runtime complexity is \(O(|V|E|)\). Generally, \(|E| \geq 1\) unless there are disjoint nodes or graphs. Unless stated, the graphs discussed here are always assumed to not contain any disjoint sets or nodes.

Dijkstra’s Algorithm

This is a greedy algorithm which keeps selecting the node with the minimum weight from the list of nodes, to begin with.

Algorithm I

C++
Dijkstra (G=(V,E,w),s,d),
// V stands for the  vertices
// E stands for edges.         
// w is the weight value for each
// s is the source node. 
// d is the destination node.

     // Q can be a min-priority queue to improve the                
     // runtime complexity of the algorithm which changes 
     // to.

               For each // is the minimum value in the set 
                       Let 
                     Be a node that can immediately reached by the   
                           Node 
                Then for each 
                    The distance from the source to the node   
                    Is modified as, 
                     If then    
                          
                            Else 
                         No change in distance value.
                            //is the parent node of 
       
                    If v = d then 
                                End search returning  and 
 
                // this ensures that the node is not
                // visited again
               End For loop // For each 
 End function Dijkstra (G (V, E, w), s, d)

In the above algorithm, pre and dis(s,u) refer to "previous link" and "distance from s to u" respectively. We can see that for each node that is at minimum among the other unvisited nodes, are selected first. So the time complexity is \(O(|V|^{2})\), because in the worst case scenario every node is visited, and again, if every node is connected to every other node, then both pairs of nodes are visited each time the algorithm iterates. So this ends up visiting \(|V|\) nodes for each node in the graph. But we don’t always consider the worst case, as its occurrence is rare, but we rather rely on the average case or the amortised analysis of the algorithm.

The above described algorithm shows the shortest path between two nodes, given that even negative weight values can be included.

Bellman Ford Algorithm

When there are negative weights in the graph, each path needs to be visited for times on the worse case. This shows that the time complexity is \(O(|V|E|)\). The reason that every edge is compulsorily visited is, if the algorithm misses a negative edge, the shortest path itself changes; and moreover the greedy approach fails because, once the final destination node is reached before visiting each edge, we cannot conclude that to be the shortest path. Let’s say that the Dijkstra’s algorithm returns the shortest path to the destination to be \(a_{source}\rightarrow b\rightarrow c\rightarrow e_{destination}\) in a graph with negative weight values. Let’s further consider that that path is of length \(x_{1}\).

And another path \(a_{source}\rightarrow b\rightarrow l\rightarrow m\) to be of length \(x_{2} > x_{1}\). Then there can be a negative edge, if when visited reduces the length to a value less than \(x_{1}\). From the algorithm, we can say that the node at the shortest distance to the destination is returned as the answer. But for the case involving negative weight values, a path that’s considered to be "longer" at that instant might not be as long as expected. Because, if it has a connecting path, that travels through a negative edge, its distance might reduce beyond the currently chosen shortest path. Let’s consider there exists a path \(m\rightarrow f\rightarrow e_{source}\) with a negative distance \(w\). So the new path \(a_{source}\rightarrow b\rightarrow l\rightarrow m\rightarrow f\rightarrow e_{destination}\) will be of length \(x_{2}+w\) which could also be \(x_{2}+w < x_{1}\). So we cannot conclude the shortest path until we have visited each path in the graph. Even if we have visited each path in the graph, the shortest path might be something else unless the process is carried over for \(N \leq |V|E|\) times. But not lesser than \(|V|\) times.

Algorithm II

C++
BellmanFord(G(V, E, W),s,d), 
// V stands for the vertices.
// E stands for edges.
// w is the weight value for each.
// s is the source node. 
// d is the destination node.

    For i= 1 to  do 
                   // Q can be a min-priority queue to improve the
                   // runtime complexity of the algorithm which changes 
                   // to.
         
               For each // is the minimum value in the set 
                       Let 
                     Be a node that can immediately reached by the   
                           Node 
                Then for each 
                    The distance from the source to the node   
                    Is modified as, 
                     If then    
                          
                            Else 
                         No change in distance value.
                            //is the parent node of        
                    
                 // this ensures that the node is not
                 // visited again
               End For loop // For each 
        End For loop        // For i= 1 to  do
   Return Pre and Dis 
End function Dijkstra (G (V, E, w), s, d)

The above depicts the Bellman Ford algorithm. This algorithm, as we can see, always runs at the worst case of \(O(|V|E|)\). But we can modify it to run faster, by inserting an operation to check if there is any change after calling the ‘For each u∈Q_min’ loop, we can determine if we could terminate the process earlier. If there was no modification, then the function returns immediately.

Negative Cycles

There are many cases that are to be considered before the direct implementation of Bellman Ford algorithm. Because of involving negative edges, there are chances of having the shortest path of a graph’s loop undeterminable. For example, consider the case of having a graph with every edge having a negative weight value. Let’s consider that the Bellman Ford algorithm updates the distance of each node from the source node, by updating each edge for times. If every edge was negative, the shortest path that was obtained keeps becoming shorter each time we follow the same procedure (refer the Bellman Ford algorithm given in this article).

Definition

A negative edge cycle is defined as a cyclic path within that graph, which contains negative weight values and the net sum of each edge along the cyclic path sums up to a value less than zero. This causes the algorithm to never find the shortest path in the graph, and if such a scenario exists, then the solution becomes undefined.

This problem does not just arise when each edge in the graph has negative weight value, but also occurs when any arbitrary cyclic path in the graph has its edge values summing up to a value less than zero.

Reposting From

History

  • 3rd October, 2015: First written

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
India India
I like programming and the only languages I use as of now are C/C++. I am doing my second year computer science engineering and my favorite topics in computer science are: Data structures, algorithm analysis, Artificial Intelligence and I also like to develop learning algorithms. Apart from computer science, I also have a great interest in mathematics and physics. I like solving problems in these areas. I also like writing programs that solve problems in these areas.

I maintain a blog. I don't update it much. Here is it's URL: www.creativitymaximized.com

And my place in github: https://github.com/sreramk/

Comments and Discussions

 
QuestionFormatting PinPopular
Rick York27-Feb-19 5:44
mveRick York27-Feb-19 5:44 
AnswerRe: Formatting Pin
Philippe Verdy28-Feb-19 9:23
Philippe Verdy28-Feb-19 9:23 
GeneralRe: Formatting Pin
David Crow28-Feb-19 14:30
David Crow28-Feb-19 14:30 
GeneralRe: Formatting Pin
Super Lloyd28-Feb-19 15:57
Super Lloyd28-Feb-19 15:57 
GeneralRe: Formatting Pin
Philippe Verdy1-Mar-19 8:22
Philippe Verdy1-Mar-19 8:22 
GeneralRe: Formatting Pin
yafan1-Mar-19 3:18
yafan1-Mar-19 3:18 
GeneralRe: Formatting Pin
Philippe Verdy1-Mar-19 9:56
Philippe Verdy1-Mar-19 9:56 
False, this is known as the wellknown "Traveling Salesperson" (proven NP-class) problem.

Only some very strictly limited subclasses of "shortest path" (with severe restrictions) search are polynomial (P-class).

But even if it is polynomial with these restrictions, it is still unusable for notable applications such as navigation: the degree of the polynom and the base N factor is too high (gerographic databases contain billions nodes and millions paths, it would not find any path in a reasonnable time. All algorithms are in fact replaced by heuristic that don't necesarily provide the absolute shortest path (which would be stupid because evaluation of weights is based on estimations on average conditions, and realtime conditions make them variable: we need adaptative heuristics that can adapt to these unpredictable but unavoidable variations): the required restrictions have to be canceled and there's no other choice than using heuristics, especially when the path determination is for a unique temporary usage and will run on small local devices or with strictly limited resources on a remote server that must serve many concurrent users.

These heuristics will use various metrics for different conditions, and need to find alternatives (not just the immediate "best" solution which will be unusable in practice for any travel above about 1 kilometer: users actually don't need these navigation helpers for short distances where there's no real choice and variability for the path even if the cost/time for this single path (or a couple of paths, one of them being the most frequent and evident, except in exceptional conditions where the other one will be used unconditionally) will be varying much more than what is set in averaged metrics in the database.

The article jsut above just speaks about some of these conditions. And in practice it's unusable in a graph with more than about 200 nodes, if you need a reply in a few seconds, or with more than 1000 nodes if you need a reply in a few minutes. If you're designing an object to manufacture, you can use it with graphs having about 2000 nodes and let it run for a few hours. If your project must complete in a limtied number of days, these hours doing nothing else will be costly because the design must be tested and will need to be tweaked repeatedly after tests.

So you use heuristics that give a "good enough" solution by accepting a deviation by some reasonnable percentage from the optimum. When you have a deadline (happens all the time in real working conditions) these P-algorithms will be phased out: instead you'll make a design with smaller (arbitrary) building blocks that will be optimized and assembled later, you'll test and optimiez only the few building blocks that cost you the most after testing but is needed for over 80% of cases, you'll have no time (and no budget) to optimize further the remaining 20% cases), and you won't break the initial optimization of the important blocks by making small local optimizations for its interconnections with the other blocks.

Interative production models favor heuristic that will constantly give you good enough results, you'll stop the optimization before the completion of the full algorithm because running it longer will offer only very small benefits compered to the huge cost of the delay.

Heuristic solutions also have a huge advantage: they are more resistant to unexpected changes of conditions, or to failures, as they are more easily interoperable by allowing replacements with compatible components within a predefined range of acceptable characteristics, and it is easier to reproduce at lower cost. And they also work because it's not possible to define a complete set of precise "weights" over a very large graph and these weights are evaluated progressively over a long time and not reevaluated very often (geographic databases are best refreshed completely over several decennials, even if there are yearly updates, and there are always large set of paths that were never really evaluated but only estimated by loose formulas based on small sets of sample conditions deliveraing only partial metrics with a significant error margin: it makes no sense to optimize more to get high precision which are orders of magnitude smaller than the error margin).

The polynomial algorithm does not even work with statistically estimated metrics where the weight for each link traversal is not a single precise value, but is only an estimated range of possible values with 80% of probability and a few % or errors for the range width.
GeneralRe: Formatting Pin
#realJSOP1-Mar-19 8:01
mve#realJSOP1-Mar-19 8:01 
GeneralRe: Formatting Pin
Philippe Verdy1-Mar-19 8:27
Philippe Verdy1-Mar-19 8:27 
GeneralRe: Formatting Pin
#realJSOP1-Mar-19 8:34
mve#realJSOP1-Mar-19 8:34 
GeneralRe: Formatting Pin
Philippe Verdy1-Mar-19 8:40
Philippe Verdy1-Mar-19 8:40 
GeneralRe: Formatting Pin
#realJSOP1-Mar-19 8:49
mve#realJSOP1-Mar-19 8:49 
GeneralRe: Formatting Pin
Philippe Verdy1-Mar-19 9:56
Philippe Verdy1-Mar-19 9:56 
GeneralMy vote of 4 Pin
KarstenK5-Nov-15 2:41
mveKarstenK5-Nov-15 2:41 
GeneralRe: My vote of 4 Pin
Sreram K5-Nov-15 8:02
Sreram K5-Nov-15 8:02 
QuestionWhat about two way weighting? Pin
Member 1159380830-Oct-15 6:51
Member 1159380830-Oct-15 6:51 
AnswerRe: What about two way weighting? Pin
Sreram K5-Nov-15 7:55
Sreram K5-Nov-15 7:55 
GeneralRe: What about two way weighting? Pin
Member 115938086-Nov-15 5:06
Member 115938086-Nov-15 5:06 
QuestionSource code is missing Pin
Sten Hjelmqvist9-Oct-15 0:16
Sten Hjelmqvist9-Oct-15 0:16 
AnswerRe: Source code is missing Pin
Sreram K9-Oct-15 2:04
Sreram K9-Oct-15 2:04 
Questionlike these articles on combinatorics Pin
Midnight4898-Oct-15 6:31
Midnight4898-Oct-15 6:31 
AnswerRe: like these articles on combinatorics Pin
Sreram K11-Oct-15 5:21
Sreram K11-Oct-15 5:21 
QuestionI need help editing! Pin
Sreram K7-Oct-15 3:27
Sreram K7-Oct-15 3:27 
AnswerRe: I need help editing! Pin
Sreram K8-Oct-15 5:24
Sreram K8-Oct-15 5:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.