Click here to Skip to main content
15,881,172 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.2K   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 
What's wrong with my punctuation, compared to the incorrect punctuation of your non-sense reply not poorly written with a natural language with almost no effort at all? Do you think you wrote any sentence that is not ambiguous even in English?

Sorry but the article above is competley unusable, it's not jsut a question of format, but essential parts are completely missing. So ambiguity is everywhere (and there's no way to look at the original to determine what was meant, given that it was on a site at the given URL that has disappeared completely).

If I was studying or llearing the Dijkstra algorithm, there's ample litterature about it everywhere (including in other CodeProject-hosted pages where there are also working sample code). Here nothing works. It's not just some typos you can correctly guess easily.

And the article itself is also incorrect in basic punctuation too. I diud not criticize the author that asked for help to fix it in 2015 (but nobody helped him at that time before the author abandoned his project or found a solution elsewhere).

And it's not me that revived the topic: it was revived by being "featured" by CodeProject itself in its home page or mailing list; even if it was visibly abandoned in its unusable state since long.
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 
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.