et l’algorithme détectera la présence éventuelle d’un cycle strictement négatif accessible depuis l’origine. Nous avons donc un graphe orienté valué G = (S, A, w) avec w : A ! R. Idée de l’algorithme. Comme pour Dijkstra, on met à jour progressivement une surestimation d[v] de la distance d’un PCC entre l’origine s et le sommet v. On appelle cette technique la méthode du ”relâchement” : étant donnés deux sommets u et v et les surapproximations d[u] et d[v] ainsi qu’un arc (u, v) 2 A, on peut mettre à jour d[v] si d[v] > d[u] + w(u, v) car l’arc (u, v) permet d’améliorer l’estimation d[v]. . . Procédure PCC-Bellman-Ford(G, s) //G = (S, A, w) : un graphe orienté, valué avec w : A ! R. //s 2 S : un sommet origine. begin pour chaque u 2 S faire ⇧[u] := ( nil 0 si u = s d[u] := 1 sinon pour i = 1 à |S| 1 faire pour chaque (u, v) 2 A faire si d[v] > d[u] + w(u, v) alors d[v] := d[u] + w(u, v) ⇧[v] := u pour chaque (u, v) 2 A faire si d[v] > d[u] + w(u, v) alors return (?, , ) return (>, d, ⇧) end Algorithme 7 : Algorithme de Bellman-Ford La complexité est directe : l’algorithme est en O(|S| · |A|). La première propriété est que d[v] est bien un majorant de (s, v) : Propriété 16 Soit G = (S, A, w) un graphe orienté valué. Soit s 2 S. A tout moment de l’algorithme on a d[v] (s, v). Preuve : C’est vrai au début de l’algorithme avec l’initialisation avec 1 pour tout v 6= s et à 0 pour s. Ensuite, la seule manière de changer d[v] est par ”relâchement” avec un arc (u, v) : on remplace l’ancienne valeur de d[v] par d[u] + w(u, v), or cette nouvelle valeur est aussi un majorant de (s, v) (car (s, v) (s, u) + w(u, v)). ⇤ 29