L'algorithme de Bellman-Ford (Richard Bellman et Lester Ford) est un algorithme de programmation dynamique qui permet de trouver des plus courts chemins, depuis un sommet source donné, dans un graphe orienté pondéré. La recherche des plus courts chemins entre tous les nœuds d'un graphe est extrêmement utile dans de nombreux cas.
Contrairement à l'algorithme de Dijkstra, qui ne peut être utilisé que lorsque tous les arcs ont des poids positifs ou nuls, l'algorithme de Bellman-Ford autorise la présence de certains arcs de poids négatif et permet de détecter l'existence d'un circuit absorbant, c'est-à-dire de poids total négatif, accessible depuis le sommet source.
Fonctionnement de l'algorithme
Reprenons depuis le début. Comment réaliser l'algorithme ?
Une implémentation naïve pourrait avoir une complexité en temps exponentielle. Pourquoi l'algorithme si lent ? Ou bien à changer de concept ?
L'algorithme de Bellman-Ford effectue un parcours du graphe (contrairement à l'algorithme de Dijkstra).
Lire aussi: Tout sur la nouvelle Ford Ka
Prenons en compte que l'algorithme doit détecter l'existence d'un cycle améliorant (ou negative cycle en anglais). Un cycle améliorant est un cycle (qu'on peut emprunter) qui va sans cesse diminuer la distance parcourue. On emprunte le cycle améliorant, et ainsi de suite, ce qui entraine une boucle infinie.
Dans un graphe de \(N\) nœuds, le chemin le plus court ne passe jamais plus de deux fois par un même nœud. Cela signifie qu'une récursion ne pourra pas dépasser l'exploration de \(N\) nœuds, réalisant \(N\) étapes au maximum, tout en sélectionnant le plus court d'entre eux.
Pour éviter les cycles améliorants, on va réaliser \(N\) étapes au maximum (où \(N\) = nombre de nœuds). Cela nous donne une complexité en temps intéressante, tout en étant optimale.
Optimisation de l'algorithme
Voyons comment améliorer notre complexité en mémoire si possible.
Dans une implémentation naïve, on pourrait être tenté de remplir notre tableau chaque ligne dépend de la précédente pour être calculée. Le premier tour donc on n'a aucunes informations qu'on peut réutiliser. De même, le nœud 2 se retrouve dans cette situation. Cependant comme voisin le nœud 5 (notre nœud d'arrivée). Le nœud qui nous donne des informations est le nœud 3. On peut alors visiter les arcs du graphe pour effectuer la même opération. Le nœud 4 et on peut alors les exploiter à notre avantage. On peut donc se débarrasser de l'étape 0 et 1, ce qui entraine une économie de mémoire qu'on cherchait à réaliser.
Lire aussi: Votre Garage Ford Local
Chaque étape de notre tableau dépend de la précédente pour être calculée. On a besoin que de deux étapes à la fois, 1 et 2, et on peut donc se débarrasser de l'étape 0 et 1. Cela nous donne une complexité en mémoire de \(O(N)\) au lieu de trois.
L'algorithme itératif comporte une boucle sur les étapes, et l'autre sur les nœuds. On va donc réaliser un tour de boucle en plus. Cette amélioration simple et concis a un impact direct sur la complexité en temps de ce dernier.
Alternatives à Bellman-Ford
Pourquoi ne pas utiliser Dijkstra en \(O(M \log _2 M)\), si on cherche les plus courts chemins entre tous les nœuds du graphe ? Ou encore \(N\) fois l'algorithme de Dijkstra ? L'algorithme de Bellman-Ford est plus intéressant que l'algorithme naïf (avec complexité exponentielle) pour les graphes pondérés positivement et négativement.
Lire aussi: Antidémarrage Ford C-Max : Comment le désactiver
tags: #algorithme #de #ford #bellman #explication #simple