Sunteți pe pagina 1din 8

TEMA 4

ALGORITMUL LUI BELLMAN-FORD

Algoritmul Bellman - Ford este un algoritm care calculează


cele mai scurte căi de la un vertex unic sursă la toate celelalte vârfuri
dintr-un digraf ponderat. Este mai lent decât algoritmul lui Dijkstra
pentru aceeași problemă, dar mai versatil, deoarece este capabil să
manipuleze grafice în care unele dintre greutățile de margine sunt
numere negative. Algoritmul a fost propus pentru prima dată de Alfonso
Shimbel (1955), dar în schimb este numit după Richard Bellman și
Lester Ford, Jr., care l-au publicat în 1958 și, respectiv, în 1956.
Edward F. Moore a publicat același algoritm și în 1957, iar din acest
motiv este numit uneori și algoritmul Bellman – Ford – Moore.
Greutățile negative ale marginilor se găsesc în diferite aplicații
ale graficelor, de unde și utilitatea acestui algoritm. Dacă un grafic
conține un "ciclu negativ" (adică un ciclu ale cărui muchii se însumează
la o valoare negativă) accesibilă de la sursă, atunci nu există o cale mai
ieftină: orice cale care are un punct pe ciclul negativ poate fi făcută mai
ieftină cu încă o plimbare în jurul ciclului negativ. Într-un astfel de caz,
algoritmul Bellman-Ford poate detecta și raporta ciclul negativ.

Prezentare generală

Algoritmul Bellman-Ford este un algoritm de căutare în graf,


care găsește cea mai scurtă cale între un vârf dat sursă și toate celelalte
vârfuri din graf. Acest algoritm poate fi utilizat atât pe grafurile
ponderate, cât și pe cele neponderate.
La fel ca și cel mai scurt algoritm de cale, Dijkstra, algoritmul
Bellman-Ford este garantat pentru a găsi cea mai scurtă cale într-un
graf. Deși este mai lent decât algoritmul lui Dijkstra, Bellman-Ford este
capabil să gestioneze grafurie care conțin greutăți negative ale muchiei,
deci este mai versatil.
Este demn de remarcat faptul că, dacă există un ciclu negativ în
graf, atunci nu există o cale mai scurtă. Ocolirea ciclului negativ de un
număr infinit de ori ar continua să scadă costul căii.

1 din 8 Profesor A.D.


Din această cauză, Bellman-Ford poate detecta și cicluri negative, ceea
ce este o caracteristică utilă.

Imaginați-vă un scenariu în care trebuie să ajungeți la un joc de


fotbal din casa dvs. Pe parcurs, pe fiecare drum, se poate întâmpla unul
din două lucruri. În primul rând, uneori, drumul pe care îl folosiți este
un drum cu taxă și trebuie să plătiți o anumită sumă de bani. În al
doilea rând, uneori cineva pe care îl cunoști locuiește pe acea stradă
(ca un membru al familiei sau un prieten). Acei oameni îți pot da bani
pentru a te ajuta să-ți reaprovizi portofelul. Trebuie să treci peste oraș
și vrei să ajungi în oraș cu cât mai mulți bani posibil, astfel încât să poți
cumpăra hot dog. Având în vedere că știți ce drumuri sunt drumuri cu
taxă și care drumuri au oameni care vă pot oferi bani, puteți folosi
Bellman-Ford pentru a vă ajuta să planificați traseul optim.

În loc de casa ta, un joc de fotbal și străzi care fie îți iau banii,
fie îți dau bani, Bellman-Ford se uită la un graf ponderat. Graful este o
colecție de margini care leagă vârfuri diferite în graf, la fel ca
drumurile. Marginile au un cost pentru ei. Fie este un cost pozitiv (cum
ar fi o taxă), fie un cost negativ (cum ar fi un prieten care îți va da
bani).
Deci, în graful de mai sus, o săgeată roșie înseamnă că trebuie să
plătiți bani pentru a utiliza acel drum, iar o săgeată verde înseamnă că
primiți bani plătiți pentru a utiliza acel drum. În graf, vârful sursă este
casa ta, iar vârful țintă este stadionul de fotbal.

2 din 8 Profesor A.D.


În drum spre acolo, doriți să maximizați numărul și valoarea
absolută a marginilor ponderate negativ pe care le luați. Dimpotrivă,
doriți să minimizați numărul și valoarea marginilor ponderate pozitive
pe care le luați. Bellman-Ford face exact acest lucru.

Complexitatea algoritmului

Algoritmul Bellman-Ford face ∣E∣ relaxări pentru fiecare iterație


și există ∣V∣ - 1 iterații. Prin urmare, cel mai rău scenariu este că
Bellman-Ford rulează în timp O (∣V∣⋅∣E∣).
Cu toate acestea, în unele scenarii, numărul de iterații poate fi
mult mai mic. Pentru anumite grafuri, este necesară o singură iterație
și, prin urmare, în cel mai bun caz, este necesar doar O ( ∣E ∣) timp. Un
exemplu de graf care ar avea nevoie doar de o rundă de relaxare este
un graf în care fiecare vârf se conectează doar la următorul într-un mod
liniar, cum ar fi graf de mai jos:

Se dă un graf orientat conex cu N noduri şi M muchii cu costuri.


Definim un lanţ ca fiind un şir de noduri cu proprietatea că între
oricare două consecutive există o muchie. Costul unui lanţ este dat de
suma costurilor muchiilor care unesc nodurile ce îl formează. Definim
un ciclu ca fiind un lanţ cu proprietatea că primul element al său este
egal cu ultimul.

3 din 8 Profesor A.D.


Fie că avem graful din imaginea de mai jos. În mod normal
suntem tentați să folosim Algoritmul lui Dijkstra, dar din păcate el
funcționează doar pe grafuri orientate cu costuri pozitive. De aceea va
trebui să folosim algoritmul Bellman-Ford.
Funcționează la fel ca și Dijkstra, dar are mici diferențe. Dacă se
găsește însă un circuit negativ, atunci nu există soluție (pentru că
drumul ar fi minimizat la maxim) .

Algoritmul minimizează drumul de la nodul de start la oricare


vârf x până la obținerea costului minim. Costurile se rețin într-un vector
d , iar pentru fiecare arc (j,k) se verifică dacă minimizează distanța de
la nodul de start la nodul x (d[x] > d[j] + cost[j][x] ), iar această
operație se repetă de n ori. Pentru a obține 100 de puncte,
îmbunătăţirea costului nodurilor vecine se face introducându-le într-o
coadă în cazul scăderii costului, dacă nu apar deja.

Remarcă:
 Algoritmul Bellman Ford poate fi folosit si pentru grafuri ce
conțin muchii de cost negativ, dar nu poate fi folosit pentru
grafuri ce conțin cicluri de cost negativ (când căutarea unui
drum minim nu are sens). Cu ajutorul sau putem afla daca un
graf conține cicluri.
 Algoritmul folosește același mecanism de relaxare ca si Dijkstra,
dar, spre deosebire de acesta, nu optimizează o soluție folosind
un criteriu de optim local, ci parcurge fiecare muchie de un
număr de ori egal cu numărul de noduri si încearcă sa o relaxeze
de fiecare data, pentru a îmbunătăți distanta până la nodul
destinație al muchiei curente.

4 din 8 Profesor A.D.


 Motivul pentru care se face acest lucru este ca drumul minim
dintre sursa si orice nod destinație poate sa treacă prin maximum
|V| noduri (adică toate nodurile grafului); prin urmare, relaxarea
tuturor muchiilor de |V| ori este suficienta pentru a propaga până
la toate nodurile informația despre distanta minima de la sursa.
 Daca, la sfârșitul acestor |E|*|V| relaxări, mai poate fi
îmbunătățită o distanță, atunci graful are un ciclu de cost negativ
si problema nu are soluție.

Algoritmul Bellman-Ford

Algoritmul Bellman Ford funcționează supraestimând lungimea căii de


la vârful de pornire la toate celelalte vârfuri. Apoi relaxează iterativ
acele estimări găsind noi căi care sunt mai scurte decât căile
supraevaluate anterior. Procedând în mod repetat pentru toate
vârfurile, putem garanta că rezultatul este optimizat.

Pasul 1: Începem cu următorul graf


ponderat:

Pasul 2: Alegem un vârf de start și


atribuim valoarea infinit tuturor
celorlalte vârfuri:

Pasul 3: Vizităm fiecare margine și


relaxăm distanța drumului dacă este
inexactă:

5 din 8 Profesor A.D.


Pasul 4: Noi trebuie să facem acest
lucru de V ori, deoarece în cel mai
rău caz, este posibil ca lungimea
traseului unui vârf să fie reajustată
de V ori:

Pasul 5: Observăm modul în care


vârful din colțul din dreapta sus a
avut lungimea traseului ajustată:

Pasul 6: După ce toate vârfurile au


lungimea traseului, verificăm dacă
este prezent un ciclu negativ:

➢ Trebuie să menținem distanța de cale a fiecărui vârf. Putem stoca


asta într-o matrice de dimensiunea v, unde v este numărul de
vârfuri.
➢ De asemenea, dorim să putem obține cea mai scurtă cale, nu
numai să cunoaștem lungimea celei mai scurte căi. Pentru
aceasta, mapăm fiecare vârf la vârful care și-a actualizat ultima
dată lungimea căii.
➢ Odată ce algoritmul s-a terminat, putem retrograda de la vârful
destinației la vârful sursă pentru a găsi calea.

6 din 8 Profesor A.D.


Algoritmul Bellman-Ford în pseudocod

function bellmanFord(G, S)
for each vertex V in G
distance[V] <- infinite
previous[V] <- NULL
distance[S] <- 0

for each vertex V in G


for each edge (U,V) in G
tempDistance <- distance[U] + edge_weight(U, V)
if tempDistance < distance[V]
distance[V] <- tempDistance
previous[V] <- U

for each edge (U,V) in G


If distance[U] + edge_weight(U, V) < distance[V}
Error: Negative Cycle Exists

return distance[], previous[]

Aplicații ale algoritmului Bellman-Ford

Pentru Internet în mod specific, există multe protocoale care


utilizează Bellman-Ford:
• Un exemplu este protocolul Informații de rutare. Acesta este unul
dintre cele mai vechi protocoale de internet și previne buclele
prin limitarea numărului de hamei pe care le poate face un
pachet în drum spre destinație.
• Un al doilea exemplu este protocolul de rutare a gateway-ului
interior. Acest protocol proprietar este utilizat pentru a ajuta
mașinile să facă schimb de date de rutare într-un sistem.

O variantă distribuită a algoritmului Bellman-Ford este utilizată


în protocoalele de rutare de distanță-vector, de exemplu Protocolul de
informare a rutei (RIP). Algoritmul este distribuit deoarece implică un
număr de noduri (routere) în cadrul unui sistem autonom (AS), o
colecție de rețele IP deținute de obicei de un ISP. Se compune din
următorii pași:

7 din 8 Profesor A.D.


1. Fiecare nod calculează distanțele dintre el însuși și toate
celelalte noduri din AS și stochează aceste informații sub formă
de tabel.
2. Fiecare nod trimite tabelul său către toate nodurile învecinate.
3. Atunci când un nod primește tabele de distanță de la vecinii săi,
calculează cele mai scurte rute către toate celelalte noduri și își
actualizează propriul tabel pentru a reflecta orice modificări.

Principalele dezavantaje ale algoritmului Bellman-Ford în această


setare sunt următoarele:
 Modificările în topologia rețelei nu sunt reflectate rapid,
deoarece actualizările sunt răspândite nod cu nod.
 Numără până la infinit dacă eșecurile de legătură sau nod fac un
nod inaccesibil de la un set de alte noduri, aceste noduri pot
petrece pentru totdeauna creșterea treptată a estimărilor
distanței până la acesta și, între timp, pot exista bucle de rutare.

8 din 8 Profesor A.D.

S-ar putea să vă placă și