Sunteți pe pagina 1din 13

Drumuri minime si maxime n grafuri orientate Algoritmul lui Roy-Floyd. Aplicatie.

Considerm un graf orientat G=(X,U) cu n noduri, n care fiecrui arc i este asociat un numr ntreg numit cost. Semnificaia acestui cost poate fi foarte variat, n funcie de domeniul pe care l descrie graful. De exemplu, dac graful reprezint harta unui ora n care arcele sunt strzile iar nodurile sunt interseciile dintre styi, atunci putem vorbi despre costul deplasrii unui automobil ntre dou intersecii, de-a lungul unei strzi. Acesta s-ar putea msura n cantitatea de benzin consumat, calculat prin prisma lungimii strzii n m sau in km.

Matricea costurilor
Pentru evidenierea costurilor tuturor arcelor unui graf cu n noduri se poate defini o matrice a, cu n linii *n coloane. Fiecare element a[i,j] poate fi: -c, dac exist un arc de cost c>0 ntre nodurile i i j; -0, dac i=j (graful nu are bucle); -0 dac nu exist arc ntre nodurile i i j. Problema determinrii drumului minim/ maxim ntre dou noduri face obiectul algoritmului urmtor.

Algoritmul Roy-Floyd
Se consider un graf orientat cu n noduri, pentru care se d matricea costurilor n forma de mai sus. Se cere ca, pentru fiecare pereche de noduri (i, j), s se tipreasc costul drumului minim de la i la j. Plecm de la urmtoarea idee: dac drumul minim ntre dou noduri oarecare i i j trece printr-un nod k, atunci drumurile de la i la k i de la k la j sunt la rndul lor minime. Pentru fiecare pereche de noduri (i, j ), cu i, j {1,2, ,n}, procedm astfel:

Dm lui k pe rnd valorile 1,2,,n, pentru ca nodul k despre care vorbeam mai sus poate fi, cel puin teoretic, orice nod al grafului. Dac suma dintre costul drumului de la i la j i costul drumului de la k la j este mai mic dect costul drumului de la i la j, adica a[i, k]+a[k, j]<a[i, j], atunci drumul iniial de la i la j este nlocuit cu drumul indirect ikj. Aceast nlocuire firete c se va opera ca atare n matricea costurilor: {a[i, j]:=a[i, k]+a[k, j]}. Drumurile minime ntre toate nodurile se regsesc la finele algoritmului tot n matricea costurilor, care a suferit n trasformri, pentru k=1,2,,n. In continuare este prezentata secventa de program care realizeaza aceste operatii. Complexitatea acesteia este reidicata deoarece am urmarit nu numai sa determinam noua matrice a costurilor ci sa si memoram noile drumuri de valoare minima (cost minim).
for i:=1 to n do for j:=1 to n do begin a[i,j]:=c[i,j]; b[i,j,1]:=c[i,j]; b[i,j,3]:=i; if c[i,j]>0 then begin b[i,j,2]:=2; b[i,j,4]:=j; end; end; repeat ok:=true; for i:=1 to n do for j:=1 to n do for k:=1 to n do if (a[i,k]<>0) and (a[k,j]<>0) and (j<>i) then if (a[k,j]+a[i,k]<b[i,j,1]) or (a[i,j]=0) then begin b[i,j,1]:=a[k,j]+a[i,k]; for i1:=3 to b[i,k,2]+2 do b[i,j,i1]:=b[i,k,i1]; for j1:=1 to b[k,j,2] do b[i,j,j1+b[i,k,2]+1]:=b[k,j,j1+2]; b[i,j,2]:=b[k,j,2]+b[i,k,2]-1;
2

ok:=false; end; for i1:=1 to n do for j1:=1 to n do a[i1,j1]:=b[i1,j1,1]; until ok;

Instructiuni de rulare a aplicatiei


Pentru a putea rula aplicatia trebuie sa urmati urmatorii pasi:
1. 2.

Insatlati o versiune a programului Turbo (Borland) Pascal.

Copiati fisierele baban.pas, baban.exe, input.txt, input.bak si baban.bak in folderul in care ati instalat programul Turbo (Borland) Pascal. Deschideti programul (de obicei exista un executabil BP.exe in folderul in care a fost instalat)
3. 4. 5.

Apasati F3 pentru a deschide ferestra cu aplicatiile existente. Selectati fisierul baban.pas si apasati Open.

6.
7.

Se incarca aplicatia selectata.

Apasati Ctrl+F9 pentru a introduce un set de date. O sa apara urmatoarea interfata:

Dupa ce ati introdus numarul de noduri apasati Enter. O sa apara urmatoarea fereastra:
8.

9.

Scrieti cifra corespunzatoare modului de introducere a matricei. Scrieti 2 pentru a citi matricea dintr-un fisier text input.txt. Fisierul a fost copiat o data cu copierea executabilului si se gaseste in folderol in care este instalat programul. Acesta poate fi modificat, dar trebuiesc respectate regulile de introducere a unei matrici patratice: o singura linie a matricii pe un rand, cu elementele despartite printr-un singur spatiu; numarul de linii este egal cu numarul de coloane si egal cu valoarea lui n care a fost introdusa mai sus; un exemplu de astfel de fisier este prezenntat mai jos.

Scrieti 1 pentru a introduce matricea costurilor de la tastatura. Se va deschide urmatoarea fereastra:

Introduceti matricea costurilor. Pozitiile de forma c[i,i] vor lua automat valoarea zero. Scrieti 0 pentru ca matricea costurilor sa fie generata automat, in mod aleatoriu. Arcele grafului vor lua valori de la 0 la noua.

Acestea au fost modalitatile de introducere a matricei costurilor. In continuare vom prezenta instructiunile ce se executa pentru procesarea acestei matrice. Pentru inceput se va afisa matricea costurilor:

10.

Trebuie precizat ca elementele matricei sunt cele de culoare alba si verde (cele de pe diagonal principala). Cifrele de culoare rosie sunt afisate pentru a ajuta la citirea pozitiei unui elemet. De exemplu: c[4,6]=6.

Apoi se vor afisa, pentru a putea face o comparative, atat matricea initiala a costurilor cat si noua matrice a costurilor, determinata prin aplicarea algoritmului. Semnificatia culorilor este aceiasi prezentata mai sus, cu precizarea ca elementele din noua matrice a costurilor de culoare rosie sunt acele elemente care au fost modificate prin aplicarea algoritmului.
11.

Precizari necesare:
Programul a fost conceput si cu o parte grafica interactiva care permite vizualizarea grafului cat si a drumurilor de cost minim intre oricare doua noduri ale grafului. In continuare este prezentata secventa (procedura) de program care realizeaza afisarea grafica.

procedure graf(c:matrice;p,r:byte); var alpha,um:real; x1,x2,x3,x4,y1,y2,y3,y4:longint; un,xi,yi,i1,j1,r1:integer; s,st,ts:string; begin initgraph(xi,yi,s); alpha:=2*pi/n; if p>0 then begin st:=''; for i1:=1 to b[p,r,2] do if i1<b[p,r,2] then begin str(b[p,r,i1+2],ts); st:=st+' '+ts+' '+chr(26); end; str(b[p,r,i1+2],ts);
8

st:=st+' '+ts+' '+'de lungime '; str(b[p,r,1],ts); st:=st+ts; setcolor(lightred); settextstyle(defaultfont,horizdir,2); outtextxy(6,6,st); settextstyle(defaultfont,horizdir,1); end; for i1:=1 to n do begin x1:=trunc(10*n*(2*cos(i1*alpha)+3)); y1:=trunc(10*n*(2*sin(i1*alpha)+3)); setcolor(blue); circle(x1,y1,10); setcolor(lightgreen); str(i1,s); if i1<10 then outtextxy(x1-3,y1-3,s) else outtextxy(x1-6,y1-3,s); for j1:=1 to n do if c[i1,j1]>0 then begin x2:=trunc(10*n*(2*cos(j1*alpha)+3)); y2:=trunc(10*n*(2*sin(j1*alpha)+3)); if x1=x2 then um:=pi/2 else um:=arctan((y1-y2)/(x2-x1)); x3:=trunc(x1+2*abs(i1-j1)/(i1-j1)*sin(um)+10*(x2-x1)/sqrt(sqr(x2-x1)+sqr(y2-y1))); y3:=trunc(y1+2*abs(i1-j1)/(i1-j1)*cos(um)+10*(y2-y1)/sqrt(sqr(x2-x1)+sqr(y2-y1))); x4:=trunc(x2+2*abs(i1-j1)/(i1-j1)*sin(um)+10*(x1-x2)/sqrt(sqr(x2-x1)+sqr(y2-y1))); y4:=trunc(y2+2*abs(i1-j1)/(i1-j1)*cos(um)+10*(y1-y2)/sqrt(sqr(x2-x1)+sqr(y2-y1))); if x1=x2 then if y2<y4 then un:=270 else un:=90 else

if x3>x4 then un:=360+round(180*arctan((y2-y1)/(x1-x2))/pi) else un:=180+round(180*arctan((y2-y1)/(x1-x2))/pi); if p=0 then begin setcolor(yellow); setfillstyle(solidfill,yellow); end else begin setcolor(darkgray); setfillstyle(solidfill,darkgray); for r1:=1 to b[p,r,2]-1 do if (b[p,r,r1+2]=i1) and (b[p,r,r1+3]=j1) then begin setcolor(yellow); setfillstyle(solidfill,yellow); end; end; if c[i1,j1]>0 then begin if (un<375) and (un>345) then if un<360 then begin pieslice(x4,y4,un-15,360,10); pieslice(x4,y4,0,360-un,10); end else begin pieslice(x4,y4,un-15,360,10); pieslice(x4,y4,0,un-340,10); end else pieslice(x4,y4,un-15,un+15,10); line(x3,y3,x4,y4); str(c[i1,j1],ts); if p=0 then setcolor(lightred); if c[i1,j1]<10 then

10

outtextxy(trunc((x3+x4+12*abs(i1-j1)/(i1-j1)*sin(um)-3)/2),trunc((y3+y4+12*abs(i1-j1)/ (i1-j1)*cos(um)-3)/2),ts) else outtextxy(trunc((x3+x4+20*abs(i1-j1)/(i1-j1)*sin(um)-6)/2),trunc((y3+y4+20*abs(i1-j1)/ (i1-j1)*cos(um)-6)/2),ts); end; end; end; readln; closegraph; end;

Partea grafica este disponibila doar pentru grafurile care au mai putin de 9 noduri; pentru grafuri de dimensiuni mai mari se vor afisa doar drumurile sub forma:

Primele doua cifre (sau numere de pe un rand), de culoare rosie reprezinta nodurile intre care se calculeaza drumul de cost minim. Urmatoarea cifra (sau numar), de culoare verde reprezinta costul drumului minim gasit intre cele doua noduri. Daca aceasta nu este o cifra, ci este caracterul - atunci inseamna ca nu a fost gasit drum intre aceste doua noduri. Sirul de numere ramas reprezinta chiar drumul de cost minim gasit.

11

Daca se introduce un 0 si se apasa Enter atunci se va reveni in programul principal, putandu-se introduce o noua matrice a costurilor in unul din modurile prezentate mai sus. Daca se introduce un 1 si se apasa Enter atunci se poate vizualiza in modul graphic un anumit drum. Programul va va cere sa introduceti un nod de plecare si unul de sosire, afisand apoi drumul de cost minim dintre acestea (arcele ce formeaza drumul vor fi afisate in galben, celelalte fiind de culoare gri).

12

13

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