Ipotizzando che i pesi siano di qualsiasi segno e che non esista alcun ciclo di lunghezza negativa, l'algoritmo di Bellman-Ford ha come scopo:
Definendo
L'algoritmo termina in
interface Edge {
src: number;
dest: number;
weight: number;
}
function bellmanFord(graph: Edge[], V: number, E: number, src: number): void {
// Passaggio 1: Inizializza le distanze da fonte a tutti gli altri vertici come INFINITO
let distance: number[] = Array(V).fill(Infinity);
// Distanza da fonte a se stessa è sempre 0
distance[src] = 0;
// Rilassa gli archi |V| - 1 volte
for (let i = 1; i < V; i++) {
for (let j = 0; j < E; j++) {
const u = graph[j].src;
const v = graph[j].dest;
const weight = graph[j].weight;
if (distance[u]!== Infinity && distance[u] + weight < distance[v]) {
distance[v] = distance[u] + weight;
}
}
}
// Controlla la presenza di cicli negativi
for (let j = 0; j < E; j++) {
const u = graph[j].src;
const v = graph[j].dest;
const weight = graph[j].weight;
if (distance[u]!== Infinity && distance[u] + weight < distance[v]) {
console.log("Il grafo contiene un ciclo di peso negativo");
return;
}
}
// Stampa l'array delle distanze costruito
console.log(distance);
}
// Utilizzo dell'esempio
const graph: Edge[] = [
{ src: 0, dest: 1, weight: -1 },
{ src: 0, dest: 2, weight: 4 },
{ src: 1, dest: 2, weight: 3 },
{ src: 1, dest: 3, weight: 2 },
{ src: 1, dest: 4, weight: 2 },
{ src: 3, dest: 2, weight: 5 },
{ src: 3, dest: 1, weight: 1 },
{ src: 4, dest: 3, weight: -3 }
];
bellmanFord(graph, 5, 8, 0);
L'informazione sulla connettività scambiata dai nodi è costituita dal Distance Vector (DV):
Il ricalcolo avviene con la formula:
Processo di ricezione DV da un vicino:
Vantaggi:
Se si rompe un arco che è fondamentale per collegare due nodi (bridge) si può creare un loop infinito tra due nodi perché le tabelle di routing si aggiornano con distanza infinita tra quei due nodi (non convergono).
Per rimediare al problema esistono 4 modi: