Académique Documents
Professionnel Documents
Culture Documents
3. Algoritmul Bellman-Ford
Algoritmul Bellman-Ford rezolv problema drumurilor minime de surs unic n cazul mai general, pentru un graf orientat n care costurile arcelor pot fi i negative. n cazul n care exist un ciclu de cost negativ accesibil din vrful surs, algoritmul returneaz ADEVRAT, iar n cellalt caz FALS. Ca i n algoritmul lui Dijkstra, algoritmul Bellman-Ford utilizeaz tehnica de relaxare, procednd la descreterea estimrii di a drumului minim de la sursa s la fiecare vrf iX pn cnd este obinut costul adevrat. Bellman-Ford(G,c,s) Iniializare-surs-unic(G,s) pentru i=1,n-1 execut pentru fiecare arc (i,j) din G execut relaxeaz(i,j,c) sfrit pentru sfrit pentru pentru fiecare muchie (i,j) din G execut dac dj>di+cij atunci returneaz FALS sfrit dac sfrit pentru returneaz ADEVRAT Algoritmul Bellman-Ford este de complexitate O(nm), unde m este numrul de arce.
Sunt permise arce de costuri negative, dar, pentru moment, presupunem c graful de intrare nu conine cicluri de cost negativ. Ieirea sub form de tabel a algoritmilor de gsire a drumurilor minime ntre toate perechile de vrfuri este o matrice d=(dij)i,j=1,2,,n, ale crei elemente reprezint costul drumului minim de la i la j. Pentru a rezolva problema gsirii drumurilor de cost minim ntre toate perechile de vrfuri, trebuie s calculm, pe lng costurile drumurilor minime, i matricea predecesorilor t=(t ij)i,j=1,2,,n, unde tij este 0 n cazul n care i=j sau nu exist drum de la i la j. n celelalte cazuri, elementul t ij este predecesorul lui j ntr-un drum minim de la i. Afiarea unui drum minim de la vrful i la vrful j se va realiza prin subprogramul: Tiprete-Drumurile-Minime-Dintre-Toate-Perechile(t,i,j) dac i=j atunci Tiprete i altfel dac tij=0 atunci Tiprete Nu exist drum de la i la j altfel Tiprete-Drumurile-Minime-Dintre-Toate-Perechile(t,i,tij) Tiprete j sfrit dac sfrit dac Algoritmul Floyd-Warshall folosete metoda programrii dinamice pentru determinarea drumului minim ntre toate perechile de vrfuri ale unui graf orientat. Algoritmul ia n considerare vrfurile intermediare ale unui drum minim, unde un vrf intermediar al unui drum elementar p=(p1, p2, , ph) este oricare vrf din p diferit de p1 i ph. Algoritmul are timpul de execuie O(n3) i se bazeaz pe urmtoarea observaie. Considerm mulimea {1, 2, , k} pentru un anumit k. Pentru oricare pereche de vrfuri i,jX, considerm toate drumurile de la i la j ale cror vrfuri fac parte din mulimea {1, 2, , k}. Fie p drumul de cost minim dintre aceste drumuri (drumul p este elementar deoarece presupunem c G nu conine cicluri de cost negativ). Algoritmul Floyd-Warshall exploateaz o relaie ntre drumul p i drumul minim de la i la j cu toate vrfurile intermediare n mulimea {1, 2, , k-1}. Relaia depinde de statutul lui k: acesta poate fi sau nu un vrf intermediar al lui p. Dac k nu este un vrf intermediar al drumului p, atunci toate vrfurile intermediare ale drumului p fac parte din mulimea {1, 2, , k-1}. Ca urmare, un drum minim de la vrful i la vrful j cu toate vrfurile intermediare n mulimea {1, 2, , k-1} este, de asemenea, un drum minim de la i la j cu taoate vrfurile intermediare n mulimea {1, 2, , k}. Dac k este un vrf intermediar al drumului p, atunci vom mpri p n p1=(i,, k) i p2=(k, , j).Rezult c p1 este drumul minim de la i la k cu toate vrfurile intermediare n mulimea {1, 2, , k}. De fapt, vrful k nu este un vrf intermediar al drumului p1, deci p1 este un drum minim de la i la k cu toate vrfurile intermediare n mulimea {1, 2, , k-1}. n mod similar se arat c p2 este un drum minim de la vrful kla vrful j cu toate vrfurile intermediare n mulimea {1, 2, , k-1}. Floyd-Warshall(c) d=c pentru k=1,n execut pentru i=1,n execut pentru j=1,n execut dij=min(dij, dik+dkj) tij=k
determin G1, unde V(G1)=v(G){s} si U(G1)=U(G) {(s,i) astfel incat iX(G)} dac Bellman-Ford(G1,c,s)=FALS atunci Tiprete Graful de intrare conine cel puin un ciclu de cost negativ altfel pentru fiecare vrf i din X(G1) execut h(i) primete valoarea dsi determinat de algoritmul Bellman-Ford sfrit pentru pentru fiecare arc (i,j) din U(G1) execut c1ij=cij+h(i)-h(j) sfrit pentru pentru fiecare vrf i din X(G) execut execut Dijkstra(G,c1,i) pentru a determina c1ij pentru orice j din X(G) pentru fiecare vrf j din U(G) execut dij=d1ij+h(j)-h(i) sfrit pentru sfrit pentru sfrit dac returneaz d Se poate observa destul de uor c timpul de execuie al algoritmului lui Johnson este O(n 2lgn +mn), dac n algoritmul lui Dijkstra implementm coada de prioritate cu ajutorul unui Heap Fibonacci. Implementarea simpl folosind un heap duce la un timp de execuie O(n m lgn). Bibliografie 1. T. Cormen, C. Leiserson, R. Rivest, Introducere n algoritmi 2. I. Tomescu, Probleme de combinatoric i teoria grafurilor