Lecture
The history of the algorithm is connected immediately with three independent mathematicians: Lester Ford, Richard Bellman and Edward Moore. Ford and Bellman published the algorithm in 1956 and 1958, respectively, and Moore did it in 1957. And sometimes it is called the Bellman-Ford-Moore algorithm. The method is used in some distance vector routing protocols, for example, in RIP (Routing Information Protocol).
Like the Dijkstra algorithm, the Bellman-Ford algorithm calculates the shortest paths from one vertex to all others in a weighted graph. It is suitable for working with graphs that have negative weight edges. But the range of applicability of the algorithm affects not all such graphs, since each successive passage along the path made up of edges, the sum of the weights of which is negative (i.e., by a negative cycle), only improves the required value. An infinite number of improvements makes it impossible to determine one particular value that is optimal. In this regard, the Bellman-Ford algorithm is not applicable to graphs with negative cycles, but it allows one to determine the presence of such, as will be discussed later.
To solve the problem, that is, to find all the shortest paths from the vertex s to all the others, using the Bellman – Ford algorithm, this means using the dynamic programming method: break it into typical subtasks, find the solution last, thereby ending the main task. Here the solution to each of these subtasks is to determine the best path from one individual edge to any other. To store the results of the algorithm, we will create a one-dimensional d [] array. In each of its i-th element, the value of the shortest path from the vertex s to the vertex i (if any) will be stored. Initially, we assign the d [] elements to the array values equal to conditional infinity (for example, the number of obviously larger sums of all weights), and we write zero to the d [s] element. So we used known and necessary information, namely, it is known that the best path from the vertex s to itself is 0, and it must be assumed that other vertices from s are unavailable. As the algorithm runs, for some of them, this condition will turn out to be false, and the optimal cost of the paths to these vertices from s will be calculated.
Given the graph G = (V, E), n = | V |, and m = | E |. Denote the adjacent vertices of this graph by the symbols v and u (vÎV and uÎV), and the weight of the edge (v, u) by the symbol w. In other words, the weight of an edge going out of a vertex v and entering a vertex u will be equal to w. Then the key part of the Bellman-Ford algorithm will take the following form:
For i from 1 to n-1 perform
For j from 1 to m perform
If d [v] + w (v, u) d [u]
At each nth step, attempts are made to improve the values of the elements of the array d []: if the sum composed of the weight of the edge w (v, u) and the weight stored in the element d [v] is less than the weight d [u], then it is assigned to the last .
one
2 3 four five 6 7 eight 9 ten eleven 12 13 14 15 sixteen 17 18 nineteen 20 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include "stdafx.h"
#include #define inf 100000 using namespace std; struct Edges { int u, v, w; }; const int Vmax = 1000; const int Emax = Vmax * (Vmax-1) / 2; int i, j, n, e, start; Edges edge [Emax]; int d [Vmax]; // Bellman-Ford algorithm void bellman_ford (int n, int s) { int i, j; for (i = 0; i d [s] = 0; for (i = 0; i for (j = 0; j if (d [edge [j] .v] + edge [j] .w d [edge [j] .u] = d [edge [j] .v] + edge [j] .w; for (i = 0; i cout << endl << start << "->" << i + 1 << "=" << "Not"; else cout << endl << start << "->" << i + 1 << "=" << d [i]; } // main function void main () { setlocale (LC_ALL, "Rus"); int w; cout << "Number of vertices>"; cin >> n; e = 0; for (i = 0; i for (j = 0; j { cout << "Weight" << i + 1 << "->" << j + 1 << ">"; cin >> w; if (w! = 0) { edge [e] .v = i; edge [e] .u = j; edge [e] .w = w; e ++; } } cout << "Starting Vertex>"; cin >> start; cout << "List of shortest paths:"; bellman_ford (n, start-1); system ("pause >> void"); } |
one
2 3 four five 6 7 eight 9 ten eleven 12 13 14 15 sixteen 17 18 nineteen 20 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
program Ford_Bellman;
uses crt; const inf = 100,000; Vmax = 1000; Emax = Vmax * (Vmax-1) div 2; type Edges = record u, v, w: integer; end; Var i, j, e, n, w, start: integer; edge: array [1..Emax] of Edges; d: array [1..Vmax] of integer; {Bellman-Ford algorithm} procedure FB (n, s: integer); begin for i: = 1 to n do d [i]: = inf; d [s]: = 0; for i: = 1 to n-1 do for j: = 1 to e-1 do if d [edge [j] .v] + edge [j] .w d [edge [j] .u]: = d [edge [j] .v] + edge [j] .w; for i: = 1 to n if d [i] = inf then writeln (start, '->', i, '=', 'Not') else writeln (start, '->', i, '=', d [i]); end; {main program block} begin clrscr; write ('Number of vertices>'); read (n); e: = 1; for i: = 1 to n do for j: = 1 to n do begin write ('Weight', i, '->', j, '>'); read (w); if w <> 0 then begin edge [e] .v: = i; edge [e] .u: = j; edge [e] .w: = w; e: = e + 1; end; end; write ('Starting vertex>'); read (start); writeln ('List of shortest paths:'); FB (n, start); end. |
Here the graph is represented by a simplified list of edges, which is formed as the user enters the weights matrix. The main part of the Bellman-Ford algorithm (condition check) is performed m * (n-1) times, since the number of repetitions of the outer loop is n-1, and the inner one is m. Rejecting the nth iteration is advisable, since the algorithm does its job in an n-1 step, but starting the external loop n times will reveal the presence of a negative loop in the graph. This can be checked, for example, with the following modification:
one
2 3 four five 6 7 eight 9 ten eleven 12 |
bool x = true;
for (i = 0; i { if (i! = n-1) for (j = 0; j if (d [edge [j] .v] + edge [j] .w d [edge [j] .u] = d [edge [j] .v] + edge [j] .w; if (i == n-1) for (j = 0; j if (d [edge [j] .v] + edge [j] .w } if (! x) cout << endl << "The graph contains negative cycles" << endl; |
Here, the outer loop is executed n times (in C ++ it is customary to specify the initial value 0, therefore, for a given code n-1 times), and if improvement will be possible at the n-th stage, this indicates the presence of a negative cycle.
Comments
To leave a comment
Algorithms
Terms: Algorithms