You get a bonus - 1 coin for daily activity. Now you have 1 coin

Bellman - Ford Algorithm

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 .

C ++ program code:

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");
}

Pascal program code:

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.

created: 2014-11-30
updated: 2021-12-15
133003



Rating 9 of 10. count vote: 2
Are you satisfied?:



Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Algorithms

Terms: Algorithms