Vous êtes sur la page 1sur 10

Algorithmique I Anne 2007-2008

A. Benoit, B. Depardon JF. Pineau, C. Rezvoy

TD n 8 - Recherche de plus courts chemins


1 L'algorithme de Bellman-Ford
L'algorithme de Bellman-Ford rsout le problme des plus courts chemins avec origine unique dans le cas le plus gnral o les poids des arcs peuvent avoir des valeurs ngatives. tant donn un graphe orient pondr

G = (V, E ),

de fonction de poids

w,

et une origine

s,

l'algorithme

retourne une valeur boolenne indiquant s'il existe un circuit de poids ngatif accessible depuis

s.

S'il n'en existe pas, l'algorithme donne les plus courts chemins ainsi que leurs poids. Les notations sont les suivantes :

v sur le chemin (NIL s'il n'y en a pas), (u, v ) est le poids du plus court chemin de u vers v ( s'il n'existe pas), d[v ] est une variable qui est une borne suprieure du poids du plus court chemin de s vers v (cf. k question 4). On dnit le poids d'un chemin p = v0 , v1 , . . . , vk , est w (p) = i=1 w (vi1 , vi ).
contient le prdcesseur de
Algorithme 1 Bellman-Ford(G, w, s)

[v ]

1: pour tout sommet v V faire // Initialisation 2: d[v ] , [v ] NIL 3: d[s] 0 4: pour i de 1 |V | 1 faire 5: pour tout arc (u, v ) E faire // relchement de l'arc (u, v ) 6: si d[v ] > d[u] + w (u, v ) alors 7: d[v ] d[u] + w(u, v ), [v ] u 8: pour tout arc (u, v ) E faire // dtection des circuits ngatifs 9: si d[v ] > d[u] + w (u, v ) alors 10: retourner Faux 11: retourner Vrai
Question 1.1

On considre le graphe ci-dessous. Faire tourner l'algorithme en prenant

comme source le sommet

z.

Mme question en changeant le poids de l'arc

(y, v )

4.

5 u 6 z 7 2 x 9 8 -2 -3 7 -4 y v

Solution : Exemple lorsque l'algorithme tourne en considrant les arcs dans l'ordre suivant : (u, v ), (u, x), (u, y ), (v, u), (x, v ), (x, y ), (y, v ), (y, z ), (z, u), (z, x)

Avec w(y, v ) = 4 : l'algorithme renvoie faux cause d'un circuit de poids ngatif entre les sommets u et v .
1

u 0 z 7 2 x 9 6 8

5 -2 -3

v 0 7 -4 y z 7 2 6

6 u

5 -2 -3

v 0 7 -4 z 7 y 2 6

6 u

5 -2 -3

4 v

7 -4

x 7

x 7

y 2

2 u 0 z 7 2 x 7 9 6 8

5 -2 -3

4 v 0 7 -4 y 2 z 7 2 6

2 u

5 -2 -3

4 v

7 -4

x 7

y -2

Fig. 1: Bellman-Ford, renvoie vrai, les plus courts chemins sont en blancs

u 0 z 7 2 x 9 6 8

5 -2 -3

v 0 4 -4 y z 7 2 6

6 u

5 -2 -3

v 0 4 -4 z 7 y 2 6

6 u

5 -2 -3

4 v

4 -4

x 7

x 7

y 2

2 u 0 z 7 2 x 7 9 6 8

5 -2 -3

4 v 0 4 -4 y 2 z 7 2 6

2 u

5 -2 -3

2 v

4 -4

x 7

y -2

Fig. 2: Bellman-Ford, renvoie faux cause d'un circuit de poids ngatif

Question 1.2

Quelle est la complexit de cet algorithme ?

La phase d'initialisation s'excute en O(V ), la phase de relchement en O(V E ), et la phase de recherche de circuit ngatif en O(E ). Soit une complexit totale en O(V E ).
Solution : Question 1.3

Montrer qu'aprs le relchement de l'arc

(u, v ), d[v ] d[u] + w(u, v ).

Le relchement se fait ainsi : si d[v ] > d[u] + w (u, v ) alors d[v ] d[u] + w(u, v ), [v ] u
Solution :

Donc on a 2 cas :  soit d[v ] d[u] + w(u, v ), et dans ce cas rien n'est fait, la proprit est donc conserve  soit d[v ] > d[u] + w(u, v ), et dans ce cas on fait d[v ] d[u] + w(u, v ), donc d[v ] = d[u] + w(u, v ), la proprit est vraie.
d[v ] (s, v ) v
il

Question 1.4

Proprit du ma jorant : Montrer que

pour tout sommet

tout instant de l'algorithme. Montrer que lorsque n'est plus jamais modi.

d[v ]

a atteint sa borne infrieure

(s, v ),

Solution : Montrons l'invariant d[v ] (s, v ) pour tout v V en raisonnant par rcurrence sur le nombre d'tapes de relchement. En phase d'initialisation on a bien d[v ] (s, v ) puisque d[v ] = , v V {s}, et d[s] = 0 (s, s) (on a (s, s) = si s se trouve sur un circuit de longueur strictement ngative, et 0 sinon).

Considrons le relchement d'un arc (u, v ). L'hypothse de rcurrence implique que d[x] (s, x) pour tout x V avant le relchement. La seule valeur d pouvant changer est d[v ]. Si elle change, on a
d[v ]

d[u] + w(u, v ) (s, u) + w(u, v ) (d'aprs l'hypothse de rcurrence) (s, v ) (d'aprs l'ingalit triangulaire : (u, v ), (s, v ) (s, u) + w(u, v ))

et donc l'invariant est conserv. La valeur n'est plus modie par la suite une fois que d[v ] = (s, v ), car aprs avoir atteint sa borne infrieure d[v ] ne peut plus diminuer, et il ne peut pas non plus augmenter puisque les tapes de relchement n'augmentent pas les valeurs de d.
Question 1.5 Proprit de convergence : Considrons un plus court chemin

(s, . . . , u, v )

pour un sommet de

donn. Montrer que si

(u, v )

dans l'algorithme, alors on a

d[u] = (s, u) un moment prcdent toujours d[v ] = (s, v ) aprs l'appel.

le relchement

D'aprs la proprit du majorant, si d[u] = (s, u) un moment donn prcdant le relchement de l'arc (u, v ), alors d[v ] (s, v ) est vrie par la suite. En particulier, aprs le relchement de l'arc (u, v ), on a
Solution :

d[v ]

= =

d[u] + w(u, v ) (question 3) (s, u) + w(u, v ) (s, v )

La dernire galit provient de la sous-structure optimale d'un plus court chemin.


Question 1.6 Montrer que, si

s,

alors, la n de l'excution

G ne contient aucun circuit de poids ngatif accessible depuis de l'algorithme, d[v ] = (s, v ) pour tout sommet v accessible

depuis

s.

On dmontre ce lemme en faisant appel la proprit de relchement de : si p = v0 , v1 , . . . , vk est un plus court chemin dans G de s = v0 vk et si les arcs de p sont relchs dans l'ordre (v0 , v1 ), (v1 , v2 ), . . ., (vk1 , vk ), alors d[vk ] = (s, vk ). Cette proprit est vraie mme si d'autres tapes de relchement interviennent entre les relchements des arcs de p.
Solution :

chemin

Dmonstration : par rcurrence, montrons qu'aprs le relchement du ime arc de p, on a d[vi ] = (s, vi ). Pour i = 0, on n'a pas encore ralis de relchement, et on a donc d[v0 ] = d[s] = 0 = (s, s) (pas de circuit de poids ngatif ). Induction : on suppose que d[vi1 ] = (s, vi1 ). D'aprs la proprit de convergence on a d[vi ] = (s, vi ), et cette ingalit ne bouge plus ensuite. Montrons maintenant que, si G ne contient aucun circuit de poids ngatif accessible depuis s, alors, la n de l'excution de l'algorithme, d[v ] = (s, v ) pour tout sommet v accessible depuis s. Soit un sommet v accessible depuis s, et soit un plus court chemin de s v : p = v0 , v1 , . . . , vk , avec v0 = s et vk = v . Le chemin p a au plus |V | 1 arcs, et donc k |V | 1. Chacune des |V | 1 itrations de la boucle pour des lignes 4 7 relche tous les |E | arcs. Parmi les arcs relchs dans la ime itration, pour i = 1, 2, . . . , k , il y a (vi1 , vi ). D'aprs la proprit de relchement de chemin, on a donc d[v ] = d[vk ] = (s, vk ) = (s, v ).
Question 1.7

Montrer que pour chaque sommet

seulement si Bellman-Ford se termine avec

v, d[v ] < .

il existe un chemin de

vers

si et

Solution : Proprit aucun-chemin : S'il n'y a pas de chemin de s v , alors on a toujours d[v ] = (s, v ) = . Dmonstration : d'aprs la proprit de majorant, on a toujours = (s, v ) d[v ], d'o d[v ] = = (s, v ).

Nous pouvons prsent dmontrer la validit de l'algorithme.

G ne contient aucun circuit de poids ngatif accessible depuis s, alors l'algorithme retourne VRAI, on a d[v ] = (s, v ) pour tous les sommets v V , et le sous-graphe G des sommets v dont (v ) = NIL et des arcs ( (v ), v ) est une arborescence des plus courts chemins de racine s. Montrer que si G contient un circuit de poids ngatif accessible partir de s, l'algorithme renvoie FAUX (on pourra raisonner par l'absurde).
Question 1.8 Montrer que si Solution : Supposons que G ne contienne aucun circuit de longueur strictement ngative accessible depuis s. Si v est accessible depuis s, alors d'aprs la question 1.6 on a d[v ] = (s, v ). Si v n'est pas accessible depuis s, alors la proprit se dduit de la proprit aucun-chemin, et d[v ] = = (s, v ). La proprit est donc vrie.

Proprit de sous-graphe prdcesseur : une fois que d[v ] = (s, v ) pour tout v V , le sous-graphe prdcesseur est une arborescence de plus courts chemins de racine s. Dmonstration : Il nous faut les trois proprits suivantes
4

 les nuds de G sont accessibles depuis s : par dnition (s, v ) est ni si et seulement si v est accessible depuis s, et donc les sommets accessibles depuis s sont exactement ceux dont l'attribut d a une valeur nie. Mais d[v ] a une valeur nie pour un sommet v V {s} si et seulement si [v ] = NIL. Donc les sommets de G sont accessibles depuis s.  G forme une arborescence de racine s : aprs l'initialisation, G ne contient que le sommet d'origine. Considrons maintenant un sous-graphe prdcesseur G obtenu aprs une squence d'tape de relchement. Montrons que G est sans circuit par l'absurde. On suppose que G contient un circuit c = v0 , v1 , . . . , vk , avec v0 = vk . On a donc [vi ] = vi1 pour i = 1, 2, . . . , k , et on peut supposer sans perte de gnralit que le circuit est du au relchement de l'arc (vk1 , vk ). Tous les sommets du circuit c sont accessibles depuis l'origine s, car ils ont tous un prdcesseur dirent de NIL, et on donc une longueur de plus court chemin nie. Juste avant l'appel relcher pour (vk1 , vk ), on a [vi ] = vi1 pour i = 1, 2, . . . , k 1, et la dernire mise jour de d[vi ] tait d[vi ] d[vi1 ] + w(vi , vi1 ), et si d[vi1 ] a t modi depuis, il a diminu. On a donc juste avant relcher : d[vi ] d[vi1 ] + w(vi , vi1 ). Puisque [vk ] est modi par l'appel, on a galement avant l'appel d[vk ] > d[vk1 ] + w(vk , vk1 ). Donc la longueur du plus court chemin le long du cycle c vaut :
k k

d[vi ] >
i=1 i=1

(d[vi1 ] + w(vi1 , vi ))

k k Mais, k i=1 d[vi ] = i=1 d[vi1 ]. On a donc 0 > i=1 w (vi1 , vi ). Donc, le circuit a un poids strictement ngatif, ce qui contredit l'hypothse selon laquelle G ne contient pas de circuit de longueur strictement ngative. Donc G est un graphe orient sans circuit. Il faut ensuite montrer par rcurrence que G forme une arborescence de racine s : montrer que pour chaque sommet v S , il existe un unique chemin de s v dans G .  G arborescence de plus courts chemins : v V , le chemin simple unique p de s v dans G est un plus court chemin entre s et v dans G. Soit p = v0 , v1 , . . . , vk , o v0 = s et vk = v . Pour i = 1, 2, . . . , k , on a la fois d[vi ] = (s, vi ) et d[vi ] d[vi1 ] + w(vi1 , vi ), d'o l'on conclut que w(vi1 , vi ) (s, vi ) (s, vi1 ). En sommant les poids le long du chemin p, on obtient k w(p) = i=1 w (vi1 , vi ) k i=1 ( (s, vi ) (s, vi1 )) = (s, vk ) (s, v0 ) = (s, vk ) Donc, w(p) (s, vk ). Comme (s, vk ) est une borne infrieure de la longueur d'un chemin quelconque de s vk , on conclut que w(p) = (s, vk ) et donc que p est un plus court chemin de s vers v = vk . Revenons la dmonstration de la validit de l'algorithme. Avec la proprit prcdente, et le fait que d[v ] = (s, v ), cela implique que G est une arborescence de plus courts chemins.

L'algorithme retourne vrai si G ne contient aucun circuit de poids ngatif ? la n de l'algorithme on a (u, v ) E
d[p]

= =

(s, v ) (s, u) + w(u, v ) d[u] + w(u, v )

et donc aucun des tests de la ligne 9 de l'algorithme ne permet de retourner faux.

Supposons maintenant qu'il existe un circuit de longueur strictement ngative c = v0 , v1 , . . . , vk , o v0 = vk , accessible depuis l'origine s. Alors,
k

w(vi1 , vi ) < 0
i=1

Supposons que l'algorithme retourne vrai. Alors d[vi ] d[vi1 ] + w(vi1 , vi ), pour i = 1, 2, . . . , k . On a donc, en sommant sur le circuit c
k i=1 d[vi ]

k i=1 (d[vi1 ] + k i=1 d[vi1 ] +

w(vi1 , vi )) k i=1 w (vi1 , vi )

Comme v0 = vk , chaque sommet de c apparat exactement une fois dans chacune des sommes. Donc
k k

d[vi ] =
i=1 i=1

d[vi1 ]

De plus, vu que d[vi ] est ni, on a


k

0
i=1

w(vi1 , vi )

k Ce qui contredit l'ingalit prcdente i=1 w (vi1 , vi ) < 0. Donc l'algorithme retourne vrai uniquement s'il n'y a pas de circuit de longueur strictement ngative, et faux sinon.

L'algorithme de Johnson
On s'intresse maintenant au problme consistant calculer les plus courts chemins pour

tout couple de sommets du graphe. L'algorithme de Johnson a une bonne complexit pour les graphes creux (peu d'artes en comparaison du nombre de sommets). Il utilise les algorithmes de Dijkstra et de Bellman-Ford, et renvoie soit la matrice des poids des plus courts chemins, soit l'assertion que le graphe possde un circuit de poids ngatif. La technique utilise consiste se ramener au cas avec uniquement des poids positifs, puis de faire tourner l'algorithme de Dijkstra en partant de chaque sommet. Si les poids ne sont pas tous positifs, on les rednit pour pouvoir se ramener au premier cas. Soit

w la fonction des poids avant rednition. La nouvelle fonction de poids w doit respecter u, v V ,
un plus court chemin de

deux proprits : 1. Pour chaque couple de sommets fonction de poids

est galement un plus court chemin pour la fonction le nouveau poids

v en w .

utilisant la

2. Pour chaque arte

(u, v ),

w (u, v )

n'est pas ngatif.

Dans la suite, on note comme dans l'exercice prcdent courts chemins (avec la fonction de poids

pour la fonction des poids des plus reprsente la fonction des poids des plus courts chemins en utilisant w), et w . u V, adjacent[u]
la liste des sommets adjacents

Voici l'algorithme de Dijkstra. Avec

u.

Algorithme 2 Dijkstra(G, w, s)

1: pour tout sommet v V faire // Initialisation 2: d[v ] , [v ] NIL 3: d[s] 0 4: E 5: F V [G] // ensemble des sommets de G 6: tantque F = faire 7: u v |d[v ] = min{d[x]|x F } // on choisit le sommet avec la plus petite 8: F F {u } 9: E E {u} 10: pour tout sommet v adjacent[u] faire // relchement de l'arc (u, v ) 11: si d[v ] > d[u] + w (u, v ) alors 12: d[v ] d[u] + w(u, v ), [v ] u

valeur de

Question 2.1

Proprit 1

Soit

h : V R une fonction quelconque faisant correspondre un rel chaque arte (u, v ) E , on dnit w (u, v ) = w(u, v ) + h(u) h(v ).
Soit

chaque sommet. Pour

seulement si

p = v0 , v1 , ..., vk un chemin allant de v0 vk . Montrer que w(p) = (v0 , vk ) si et (v0 , vk ). De plus, montrer que G possde un circuit de poids ngatif en w (p) = utilisant w si et seulement si G possde un circuit de poids ngatif en utilisant w .
Solution :

Commenons par montrer que w (p) = w(p) + h(v0 ) h(vk ). On a


w (p)

= = = =

k (vi1 , vi ) i=1 w k ( i=1 w (vi1 , vi ) + h(vi1 ) h(vi )) k i=1 w (vi1 , vi ) + h(v0 ) h(vk )

w(p) + h(v0 ) h(vk )

Donc, pour tout chemin p entre v0 et vk vrie w(p) + h(v0 ) h(vk ). Si un chemin est plus court qu'un autre pour la fonction w, alors il l'est galement pour w . Donc, w(p) = (v0 , vk ) si et seulement si w(p) = (v0 , vk ). Montrons que si G possde un circuit de poids ngatif en utilisant w alors il en est de mme pour la fonction de poids w . Soit c = v0 , v1 , ..., vk un circuit quelconque tel que v0 = vk . On a donc w (p) = w(p) + h(v0 ) h(vk ) = w(c).
Question 2.2 Proprit 2

w vriant galement la deuxime proprit (fonction non ngative). On cre un nouveau graphe G = (V , E ) avec V = V {s} (s / V ) et E = E {(s, v ) : v V }. La fonction de poids w est tendue de manire ce que w (s, v ) = 0 pour chaque v V .
On dsire maintenant dnir De plus, si G n'a pas de circuit de poids ngatif, on dnit

h(v ) = (s, v ) pour chaque v V

2.2.1 A partir des indications prcdentes, dnir une nouvelle fonction de poids et montrer

qu'elle vrie les deux proprits.


Solution : En tendant la fonction de pondration de la sorte, on a vu qu'aucun arc n'entre dans s, aucun plus court chemin de G , hormis ceux d'origine s, ne contient s. De plus G ne contient aucun circuit de longueur strictement ngative si et seulement si G n'en contient aucun.

Supposons que G et G ne contiennent aucun circuit de longueur strictement ngative. On dnit h(v ) = (s, v ) pour tout v V . D'aprs l'ingalit triangulaire on a h(v ) h(u)+ w(u, v ) pour tout arc (u, v ) E . Donc, si l'on dnit les nouveaux poids w comme tant : w (u, v ) = w(u, v ) + h(u) h(v ), on a bien w (u, v ) 0, et la seconde proprit est vrie.
2.2.2

Gnrer

partir du graphe

ci-dessous, et calculer les nouveaux poids.

2 3 1 2 -4 5 6 4 7 1 -5 4 8 3

Solution :

Voir gure 3.
0 -1 0 0 3 2 -4 5 0 -4 6 4 0 0 7 1 -5 2 4 8 3 -5 0 0 4 1 0 1 2 0 5 -4 2 4 0 10 0 0 4 5 -1 2 0 13 3 -5

0 0

(a) Fonction de pondration initiale w

(b) Fonction de pondration modie w

Fig. 3: Graphe

Question 2.3

Algorithme de Johnson

crire l'algorithme de Johnson en s'inspirant des questions prcdentes. Faire tourner l'algorithme sur le graphe ci-dessus. Justier la correction de l'algorithme et calculer sa complexit. On rappelle que l'algorithme de Dijkstra implment par un tas de Fibonacci a une complexit en

O(V logV + E ).
Solution :

Algorithme 3 Johnson(G, w, s)

1:

G , o V [G ] = V [G] {s}, E [G ] = E [G] {(s, v ) : v V [G]}, v V [G] 2: si Bellman F ord(G , w, s) =Faux alors
Calculer

et

w(s, v ) = 0

3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:

print sinon

le graphe contient un circuit de longueur strictement ngative

v S [G ] faire h(v ) (s, v ) // (s, v ) calcul avec Bellman-Ford pour tout arc (u, v ) E [G ] faire w (u, v ) w(u, v ) + h(u) h(v ) pour tout sommet u V [G] faire (u, v ), v V [G] Excuter Dijkstra(G, w, u) // an de calculer pour tout sommet v V [G] faire (u, v ) + h(v ) h(u) du,v retourner D
pour tout sommet

La ligne 1 construit G . La ligne 2 excute l'algorithme de Bellman-Ford sur G en utilisant la fonction de pondration w et le sommet d'origine s. Si G , et donc G, contient un circuit de longueur strictement ngative, alors on signale le problme. Le reste de l'algorithme suppose donc que le graphe ne contient aucun circuit de longueur strictement ngative, et calcule les (u, v ) en utilisant Dijkstra un fois pour chaque sommet de longueurs des plus courts chemins V . La ligne 12 stocke dans du,v (lment de la matrice D de taille |V | |V |) la valeur (u, v ).
2/1
0 -1 0 0 0 0 0 1 2 -4 5 0 -4 6 4 0 0 7 1 -5 3 2 4 8 3 -5 0 0 4 1 0 1 2 0 5 -4 2 4 0 10 0 0 4 5 -1 2 0 13 3 -5

2 0/0 1 2 0 5 0/-4 2 4 2/2 10 0 0 4 0 13 3 2/-3

0/0 2 2/3 1 2 0 5 2/-1 2 4 0/1 10 0 0 4 0 13 3 0/-4

0/4 2 2/7 1 2 0 5 2/3 2 4 0/5 10 0 0


0 5 2/-2

0/-1 2

0 13 3 0/0

2/2 1

4 2 10 0

0 13 0 2 4 0/0 3 0/-5

2/5 2 4/8 1 2 0 5 0/0 2 4 2/6 10 0 0 4 0 13 3 2/1

Si la le de priorit min de Dijkstra est gre avec un tas de Fibonacci, le temps d'excution de l'algorithme est alors de O(V 2 log V + V E ). L'implmentation, plus simple, base sur un tas min binaire donne un temps d'excution en O(V E log V ).

10