Sunteți pe pagina 1din 18

Grafuri

Grafurile snt structuri de date cu aplicaii n multe domenii ale informaticii, algoritmii pentru reprezentarea i
prelucrarea grafurilor fiind considerai fundamentali n acest domeniu. n subcapitolul 1 snt prezentate principalele
noiuni ale domeniului, precum i modalitile uzuale de reprezentare a structurii de graf. n continuare snt descrise
tehnicile de parcurgere a grafurilor n lime i n adncime. Verificarea conexitii i calculul drumurilor n grafuri
snt tratate n subcapitolul 3.
1. Definiii i reprezentri ale grafurilor
Definiia 1.1. Se numete graf sau graf neorientat o structur G=(V,E), unde V este o mulime nevid iar E
este o submulime posibil vid a mulimii perechilor neordonate cu componente distincte din V.
Elementele mulimii V se numesc vrfuri, iar obiectele mulimii E se numesc muchii. Dac eE,
uv not. v) (u, e
, vrfurile u i v se numesc extremiti ale lui e, muchia e fiind determinat de vrfurile u i v. Dac
e=uvE se spune c vrfurile u, v snt incidente cu muchia e.
Definiia 1.2. Fie G=(V,E) graf. Vrfurile u, v snt adiacente n G dac uvE.
Definiia 1.3. Graful G=(V,E) este graf finit, dac V este o mulime finit.
n cadrul acestui capitol vor fi considerate n exclusivitate grafurile finite, chiar dac acest lucru nu va fi
precizat n mod explicit.
Definiia 1.4. Fie G
i
=(V
i
,E
i
), i=1,2 grafuri. G
2
este un subgraf al grafului G
1
dac
1 2
V V i
1 2
E E . G
2
este este un graf parial al lui G
1
dac V
2
=V
1
i G
2
este subgraf al lui G
1
.
Definiia 1.5. Un digraf este o structur D=(V,E), unde V este o mulime nevid de vrfuri, iar E este o
mulime posibil vid de perechi ordonate cu componente elemente distincte din V. Elementele mulimii E snt numite
arce sau muchii ordonate. Un graf direcionat este o structur D=(V,E), unde V este o mulime nevid de vrfuri, iar E
este o mulime posibil vid de perechi ordonate cu componente elemente din V, nu neaprat distincte. Evident, orice
digraf este un graf direcionat.
Terminologia utilizat relativ la digrafuri este similar celei corespunztoare grafurilor. n continuare vom
referi prin muchie i elementele mulimii E a unui graf direcionat, n situaia n care este tratat cazul unui graf
oarecare (neorientat sau direcionat).
Definiia 1.6. Se numete graf ponderat o structur (V,E,W), unde G=(V,E) este graf i W este o funcie
definit prin ( ) , 0 E : W . Funcia W este numit pondere i ea asociaz fiecrei muchii a grafului un cost/ctig al
parcurgerii ei.
Definiia 1.7. Fie G=(V,E) un graf, u,vV. Secvena de vrfuri :u
0
,u
1
,..,u
n
este un u-v drum dac u
0
=u, u
n
=v,
u
i
u
i+1
E pentru toi i, n i 0 .
Definiia 1.8. Fie G=(V,E) un graf. Elementul vV se numete vrf izolat dac, pentru orice eE, u nu este
incident cu e.
1.1 Moduri de reprezentare a grafurilor
Cea mai simpl reprezentare a unui graf este cea intuitiv, grafic; fiecare vrf este figurat printr-un punct,
respectiv muchiile snt reprezentate prin segmentele de dreapt, orientate (n cazul digrafurilor) sau nu i etichetate (n
cazul grafurilor ponderate) sau nu, avnd ca extremiti punctele corespunztoare vrfurilor care o determin
Exemple
1.1. Fie G=(V,E) graf, cu V={1,2,3,4,5,6}, E={(1,2),(1,3),(2,5),(3,5),(5,6)}. O posibil reprezentare grafic
este,

1
2
3
4
5
6
1.2. Fie D=(V,E) digraf, V={1,,5}, E={(1,2), (1,3), (1,5), (2,5), (3,5), (4,1), (5,4)}. Digraful poate fi
reprezentat grafic astfel,
1
2
3
5
4
1.3. Fie D=(V,E) graf direcionat, V={1,2,3,4,5}, E={(1,2), (1,3), (1,5) (2,5), (3,5), (4,4)}. Reprezentarea
grafic este,
1
2
3
4
5
1.4. Fie G=(V,E,W) graf ponderat, V={1,2,3,4}, E={(1,2), (1,3), (1,4), (2,3), (2,4)}, W((1,2))=5, W((1,3))=1,
W((1,4))=7, W((2,3))=4, W((2,4))=2. O posibil reprezentare grafic este:
1
3 2
4
5 1
2
7
4
n scopul reprezentrii grafurilor n memoria calculatorului snt utilizate n general urmtoarele structuri de
date.
1.2. Reprezentarea matriceal
Grafurile, digrafurile i grafurile direcionate pot fi reprezentate prin matricea de adiacen. Dac G=(V,E )
este graf, digraf sau graf direcionat cu
n V
, atunci matricea de adiacen AM
nxn
({0,1}) are componentele,
( )

'

altfel , 0
E v , v dac , 1
a
j i
ij
,
unde v
i
, v
j
reprezint cel de-al i-lea, respectiv cel de-al j-lea nod din V. n cazul unui graf neorientat, matricea
de adiacen este simetric.
Exemplu
1.5. Graful din exemplul 1.1, digraful din exemplul 1.2 i graful direcionat din exemplul 1.3 snt reprezentate
prin matricele de adiacen,

,
_

0 1 0 0 0 0
1 0 0 1 1 0
0 0 0 0 0 0
0 1 0 0 0 1
0 1 0 0 0 1
0 0 0 1 1 0
A
(1.1),

,
_

1 1 0 0 0
0 0 0 0 1
1 0 0 0 0
1 0 0 0 0
1 0 1 1 0
A
(1.2),

,
_

0 0 0 0 0
0 1 0 0 0
1 0 0 0 0
1 0 0 0 0
1 0 1 1 0
A
(1.3)
n cazul grafurilor ponderate, reprezentarea poate fi realizat prin matricea ponderilor. Dac G=(V,E,W) este
graf ponderat,
n V
, W M
nxn
((0, )) are componentele,
( ) ( )

'

altfel ,
E v , v dac , ) v , v ( W
w
j i j i
j , i

unde v
i
, v
j
reprezint cel de-al i-lea, respectiv cel de-al j-lea nod din V, 0 , dac ponderea are semnificaia
de ctig, respectiv n cazul n care se dorete reprezentarea costurilor ca ponderi ale grafului.
Exemplu
1.6. Presupunnd c ponderile reprezint costuri, matricea de reprezentare a grafului din exemplul 1.4.
este

,
_

2 7
4 1
2 4 5
7 1 5
W
.
1.3. Reprezentarea tabelar
Reinnd muchiile prin intermediul extremitilor i eventual valoarea ponderii ei, se obine reprezentarea
tabelar, mai economic din punctul de vedere al spaiului de memorie necesar. Dac graful conine vrfuri izolate
atunci este necesar pstrarea acestora ntr-un vector suplimentar VS. Mulimea muchiilor este reinut ntr-o matrice
A cu
E
linii i c coloane, unde c=2 dac graful nu este ponderat, altfel c=3. n primele dou coloane se scriu
perechile de vrfuri ce determin muchiile, n cazul grafurilor ponderate cea de-a treia coloan conine valoarea
ponderii muchiei respective.
Exemple
1.7. Graful din exemplul 1.1 poate fi reprezentat astfel, VS=(4),

,
_

6 5
5 3
5 2
3 1
2 1
A
1.8. Digraful din exemplul 1.2 este reprezentat prin

,
_

4 5
1 4
5 3
5 2
5 1
3 1
2 1
A .
1.9. Graful direcionat din 1.3. este reprezentat prin

,
_

4 4
5 3
5 2
5 1
3 1
2 1
A
.
1.10. Graful ponderat din exemplul 1.4. nu are vrfuri izolate, deci este reprezentat prin intermediul matricei

,
_

2 4 2
7 4 1
4 3 2
1 3 1
5 2 1
A
.
1.4. Reprezentarea prin intermediul listelor
Aceast reprezentare permite utilizarea economic a spaiului de memorare i, n anumite cazuri,
implementri mai eficiente pentru anumite clase de algoritmi. Vrfurile grafului snt memorate ntr-o list, fiecare nod
al listei N coninnd o referin spre lista vecinilor vrfului memorat ca informaie n N.
Dac graful nu este ponderat, el poate fi reprezentat prin structura list de liste, i anume: nodurile grafului se
trec ntr-o list L_nod, fiecare celul avnd structura,
informaie legtur vecini legtur nod urmtor
unde,
cmpul informaie conine identificatorul nodului;
legtur vecini reprezint referina spre nceputul listei vecinilor;
legtur nod urmtor conine adresa urmtoarei celule din lista L_nod.
Un graf ponderat poate fi reprezentat n mod similar, cu diferena c, fiecare celul din lista vecinilor conine
i ponderea muchiei respective (muchia care are ca extremiti vrful referit prin identificatorul de nod din lista
vecinilor i respectiv vrful indicat de informaia acelei celule din L_nod ce conine adresa primului element al listei
vecinilor).
2. Modaliti de parcurgere a grafurilor
Modalitatea de vizitare a tuturor vrfurilor grafului n care fiecare vrf al grafului este vizitat o singur dat se
numete parcurgere sau traversare. n acest paragraf snt prezentate metodele de parcurgere BF (n lime), DF (n
adncime) i metoda DF generalizat, notat DFG.
Primele dou metode de parcurgere snt aplicate grafurilor neorientate respectiv grafurilor direcionate i
presupun selectarea unui vrf iniial v
0
i identificarea acelor vrfuri ale grafului v cu proprietatea c exist cel puin un
drum de la vrful iniial ctre v. Grafurile cu proprietatea c oricare dou vrfuri snt conectate printr-un drum se
numesc grafuri conexe i snt prezentate n 3. Dac graful este conex, atunci prin aplicarea metodelor de parcurgere
vor fi identificate toate vrfurile grafului. Cele dou modaliti de parcurgere snt prezentate n continuare n cazul
grafurilor neorientate, extinderea la digrafuri i grafuri direcionate fiind imediat. Studiul proprietii metodei BF de
a calcula distanele minim ntre orice vrf al grafului conectat de vrful iniial i vrful iniial este prezentat n cazul
grafurilor oarecare.
Parcurgerea DFG presupune vizitarea tuturor vrfurilor unui graf sau graf direcionat prin aplicarea metodei
DF tuturor vrfurilor care, dup ultima traversare DF, nu au fost nc vizitate.
2.1. Metoda de parcurgere BF (Breadth First)
Traversarea BF presupune parcurgerea n lime a grafului, n sensul c, vrfurile grafului snt prelucrate n
ordinea cresctoare a distanelor la vrful iniial. Distana de la u la v, notat ( ) v , u , este numrul de muchii ale
unui cel mai scurt u-v drum.
La momentul iniial vrf curent este v
0
. Deoarece vrful curent la fiecare moment trebuie s fie unul dintre
vrfurile aflate la distan minim de v
0
se poate proceda n modul urmtor: iniial lui v
0
i se asociaz valoarea 0,
[ ] 0 v d
0

i fiecrui vrf
0
v v
i se asociaz valoarea , [ ] v d . Dac valoarea asociat vrfului curent este
m, atunci fiecruia dintre vecinii acestuia de valoare li se asociaz valoarea m+1. Se observ c, dac dup ce
toate vrfurile de valoare m au fost considerate i nici unui vrf nu i-a fost recalculat valoarea, atunci toate vrfurile
conectate cu v
0
au fost vizitate, deci calculul se ncheie.
Exemple
2.1. Fie graful,
1
2
5
6
7
3
4
i v
0
=1.Valorile calculate prin aplicarea metodei prezentate snt,
vrf
d
1 2 3 4 5 6 7
0 0

1 0 1 1 1

1
2 0 1 1 1 2 2 1
0 1 1 1 2 2 1
2.2. Fie graful,
1
2
3
4
5 7
6
8
9 10
11
i v
0
=1. Se observ c vrfurile 8, 9, 10 i 11 nu snt conectate cu vrful iniial.
Valorile rezultate prin aplicarea metodei snt:
vrf
d
1 2 3 4 5 6 7 8 9 10 11
0 0

1 0 1 1

1

1

2 0 1 1 2 1 2 1

0 1 1 2 1 2 1

Se observ c valorile lui d calculate n final reprezint numrul de muchii corespunztor unui cel mai scurt
drum care conecteaz vrful iniial cu vrful respectiv, pentru vrfurile neconectate cu v
0
valoarea d[v
0
] rezultat la
terminarea calculului este .
Fie G=(V,E) un graf,
n V
. O alternativ de implementare a metodei BF este construit prin utilizarea
urmtoarelor structuri de date,
A matricea de adiacen a grafului;
o structur de tip coad, C, n care snt introduse vrfurile ce urmeaz a fi vizitate i procesate (n sensul
cercetrii vecinilor lor);
un vector c cu n componente, unde,

'

, 0
, 1
i
c
Componentele vectorului c snt iniializate cu valoarea 0.
Parcurgerea BF poate fi descris astfel,
coada C este iniializat cu vrful v
0
;
ct timp
C
, este extras i vizitat un vrf i din coad, apoi snt introdui n coad vecinii lui i care nu au
fost deja introdui (acele vrfuri k cu proprietatea c c[k]=0 i a[i][k]=1). Vrfurile i ce au fost introduse n coad snt
marcate prin c[i]=1.
Exemplu
2.3. Pentru graful din exemplul 2.1., aplicarea metodei de traversare BF determin urmtoarea evoluie,

c
t
1 2 3 4 5 6 7
t=1 1 0 0 0 0 0 0
t=2 1 1 1 1 0 0 1
t=3 1 1 1 1 1 0 1
t=4 1 1 1 1 1 1 1
t=5 1 1 1 1 1 1 1
t=6 1 1 1 1 1 1 1
t=7 1 1 1 1 1 1 1
t=8 1 1 1 1 1 1 1
C
t
t=1 1
t=2 2 3 4 7
t=3 3 4 7 5
t=4 4 7 5 6
t=5 7 5 6
t=6 5 6
t=7 6
t=8
Observaie Deoarece graful din exemplul 2.1. este conex, traversarea BF realizeaz vizitarea tuturor vrfurilor
grafului. Aplicarea metodei BF grafului din exemplul 2.2. nu determin vizitarea vrfurilor 8,9, 10 i 11, deoarece
acestea snt vrfuri neconectate cu vrful iniial . Cu alte cuvinte, metoda BF aplicat unui graf determin vizitarea
tuturor vrfurilor care snt conectate cu vrful iniial selectat.
Sursa C pentru implementarea metodai BF este,
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
typedef struct nn
{ int inf;
struct nn *leg;
} nod,* pnod;
int insereaza_coada(pnod *head,pnod *tail,int info)
{
pnod nou;
if(nou=(pnod)malloc(sizeof(nod))){
nou->inf=info;
nou->leg=NULL;
if(*head==NULL) *head=nou;
else (*tail)->leg=nou;
*tail=nou;
dac i a fost adugat n coad
altfel
return 1;
}
else return 0;
}
int extrage_coada(pnod *head,pnod *tail, int *info)
{
if(*head){
pnod aux=*head;
*info=(*head)->inf;
(*head)=(*head)->leg;
free(aux);
if(*head==NULL)*head=*tail=NULL;
return 1;
}
else return 0;}
void breadth_first(int v0,int a[10][10],int n)
{
pnod head=NULL;
pnod tail=NULL;
int c[10];
for(int i=0;i<n;c[i++]=0);
int r=insereaza_coada(&head,&tail,v0);
c[v0]=1;
while(head){
r=extrage_coada(&head,&tail,&i);
printf("\n%i",i+1);
for(int k=0;k<n;k++)
if((a[i][k]==1)&&(c[k]==0)){
r=insereaza_coada(&head,&tail,k);
c[k]=1;
}
}
}
void main()
{
int n,v0,a[10][10];
clrscr();
printf("Numarul de varfuri:");
scanf("%i",&n);
printf("\nMatricea de adiacenta\n");
for(int i=0;i<n;i++)
for(int j=0;j<i;j++){
scanf("%i",&v0);
a[j][i]=a[i][j]=v0;
}
for(i=0;i<n;i++)a[i][i]=0;
printf("\nVarful initial ");
scanf("%i",&v0);
printf("\nParcurgerea BF a grafului este");
breadth_first(v0,a,n);
}
2.2. Metoda de parcurgere DF (Depth First)
Ideea metodei DF revine la parcurgerea n adncime a grafurilor. Considernd v
0
vrf iniial i M mulimea
vrfurilor vizitate de procedur, pentru vizitarea vecinilor este considerat unul din vrfurile din M cu proprietatea c
lungimea drumului calculat de metod pn la vrful iniial v
0
este maxim.
Implementarea acestei metode poate fi realizat n mai multe moduri, pentru meninerea mulimii vrfurilor
grafului disponibilizate pn la momentul curent fiind utilizat o structur de de date de tip stiv S. La momentul
iniial se introduce n stiv v
0
. La fiecare pas, se preia cu tergere ca vrf curent vrful stivei S i se introduc n stiv
vecinii nc nevizitai ai vrfului curent. Un vrf se marcheaz ca vizitat n momentul introducerii lui n S. Calculul
continu pn cnd este efectuat un acces de preluare din stiv i se constat c S este vid. Pentru gestiunea vrfurilor
vizitate, se utilizeaz un vector c cu n componente, unde n reprezint numrul vrfurilor grafului i, la fiecare
moment, componentele snt:

'

altfel , 0
vizitat fost a i dac , 1
c
i
Componentele vectorului c vor fi iniializate cu valoarea 0.
Exemple
2.4. Pentru graful,
1
2
5
6
7
3
4
i v
0
=1, prin aplicarea metodei descrise, rezult urmtoarea evoluie.
c
t
1 2 3 4 5 6 7
t=1 1 0 0 0 0 0 0
t=2 1 1 1 1 0 0 1
t=3 1 1 1 1 0 1 1
t=4 1 1 1 1 0 1 1
t=5 1 1 1 1 1 1 1
t=6 1 1 1 1 1 1 1
t=7 1 1 1 1 1 1 1
t=8 1 1 1 1 1 1 1
S
t
t=1 1
t=2 7 4 3 2
t=3 6 4 3 2
t=4 4 3 2
t=5 5 3 2
t=6 3 2
t=7 2
t=8
Ordinea n care snt vizitate vrfurilor corespunztor acestei variante de parcurgere DF este: 1, 2, 3, 4, 7, 6, 5.
2.5. Pentru graful din exemplul 2.2 vrfurile 8,9,10 care nu snt conectate cu vrful iniial nu vor fi vizitate nici
prin aplicarea metodei DF. Ordinea n care snt vizitate vrfurilor corespunztor acestei variante este: 1, 2, 3, 4, 6, 7, 5.
O variant de implementare a metodei DF rezult prin gestionarea stivei S n modul urmtor. Iniial vrful v
0
este unicul component al lui S. La fiecare etap se preia, fr tergere, ca vrf curent vrful stivei. Se introduce n stiv
unul dintre vecinii vrfului curent nc nevizitat. Vizitarea unui vrf revine la introducerea lui n S. Dac vrful curent
nu are vecini nc nevizitai, atunci el este eliminat din stiv i este efectuat un nou acces de preluare a noului vrf al
stivei ca vrf curent. Calculul se ncheie n momentul n care este efectuat un acces de preluare a vrfului stivei ca vrf
curent i se constat c S este vid. Evident, nici n cazul acestei variante nu vor fi vizitate vrfurile care nu snt
conectate cu vrful iniial ales.
Exemplu
2.6. Pentru graful,
1
2
5
6
7
3
4
i v
0
=1, prin aplicarea metodei descrise, rezult urmtoarea evoluie.
c
t
1 2 3 4 5 6 7
t=1 1 0 0 0 0 0 0
t=2 1 1 0 0 0 0 0
t=3 1 1 0 1 0 0 0
t=4 1 1 1 1 0 0 0
t=5 1 1 1 1 0 1 0
t=6 1 1 1 1 0 1 1
t=7 1 1 1 1 0 1 1
t=8 1 1 1 1 0 1 1
t=9 1 1 1 1 0 1 1
t=10 1 1 1 1 1 1 1
t=11 1 1 1 1 1 1 1
t=12 1 1 1 1 1 1 1
t=13 1 1 1 1 1 1 1
t=14 1 1 1 1 1 1 1
S
t
t=1 1
t=2 2 1
t=3 4 2 1
t=4 3 4 2 1
t=5 6 3 4 2 1
t=6 7 6 3 4 2 1
t=7 6 3 4 2 1
t=8 3 4 2 1
t=9 4 2 1
t=10 5 4 2 1
t=11 4 2 1
t=12 2 1
t=13 1
t=14
Ordinea n care snt vizitate vrfurile corespunztor acestei variante este: 1, 2, 4, 3, 6, 7, 5.
Urmtoarea surs C implementeaz varianta precedent de parcurgere DF.
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
typedef struct nn{
int inf;
struct nn *leg;
}nod,* pnod;
int insereaza_stiva(pnod *head,int info)
{
pnod nou;
if(nou=(pnod)malloc(sizeof(nod))){
nou->inf=info;
nou->leg=*head;
*head=nou;
return 1;
}
else return 0;
}
int extrage_stiva(pnod *head,int *info)
{
if(head){
pnod aux=*head;
*info=(*head)->inf;
(*head)=(*head)->leg;
free(aux);
return 1;
}
else return 0;}
void depth_first(int v0,int a[10][10],int n)
{
pnod head=NULL;
int c[10];
for(int i=0;i<n;c[i++]=0);
int r=insereaza_stiva(&head,v0);
c[v0]=1;
printf("\n%i",v0+1);
while(head){
r=extrage_stiva(&head,&i);
for(int k=0;k<n;k++)
if((a[i][k]==1)&&(c[k]==0)){
r=insereaza_stiva(&head,k);
c[k]=1;printf("\n%i",k+1);
}
}
}
void main()
{
int n,v0,a[10][10];
clrscr();
printf("Numarul de varfuri:");scanf("%i",&n);
printf("\nMatricea de adiacenta\n");
for(int i=0;i<n;i++)
for(int j=0;j<i;j++){
scanf("%i",&v0); a[j][i]=a[i][j]=v0;
}
for(i=0;i<n;i++)a[i][i]=0;
printf("\nVarful initial ");scanf("%i",&v0);
printf("\nParcurgerea DF a grafului este");
depth_first(v0,a,n);
}
3. Drumuri n grafuri. Conexitate
3.1 Drumuri; definiii
Una dintre cele mai importante proprieti ale grafurilor o constituie posibilitatea de accesare, prin
intermediul unei secvene de muchii (arce), dintr-un vrf dat a oricrui alt vrf al grafului, proprietate cunoscut sub
numele de conexitate sau conexiune. Aa dup cum a rezultat n 2., dac G=(V,E) este un graf conex, atunci pentru
orice vrf iniial v
0
considerat metodele BF i DF permit vizitarea tuturor vrfurilor din V.
Definiia 3.1. Fie G=(V,E) un graf, u,vV. Secvena de vrfuri : u
0
, u
1
,..,u
n
este un u-v drum dac u
0
=u, u
n
=v,
u
i
u
i+1
E pentru toi i, n i 0 . Lungimea drumului, notat l() este egal cu n. Convenional, se numete drum
trivial, un drum cu l()=0.
Definiia 3.2. Fie : u
0
, u
1
,..,u
n
un drum n graful G=(V,E). este un drum nchis dac u
0
=u
n
; n caz contrar,
se numete drum deschis. Drumul este elementar dac oricare dou vrfuri din snt distincte, cu excepia,
eventual, a extremitilor. Drumul este proces dac, pentru orice
1 n j i 0
u
i
u
i+1
u
j
u
j+1
.
Evident, orice drum elementar este un proces.
Exemplu
3.1. Pentru graful,

v
1

v
2

v
3

v
4

v
5

1
: v
1
, v
2
, v
3
, v
2
, v
5
, v
3
, v
4
este un v
1
- v
4
drum care nu este proces;

2
: v
1
, v
2
, v
5
, v
1
, v
3
, v
4
este un v
1
- v
4
proces care nu este drum elementar;

3
: v
1
, v
3
, v
4
este un v
1
- v
4
drum elementar.
Definiia 3.3. Fie : u
0
, u
1
,..,u
n
un drum n graful G=(V,E).

: v
0
, v
1
,..,v
m
este un subdrum al lui dac

este
un drum i pentru orice j,
m j 0
, exist i, n i 0 astfel nct u
i
=v
j
.
Observaie Orice drum cu lungime cel puin 1 conine cel puin un drum elementar cu aceleai extremiti.
ntr-adevr, dac : u
0
, u
1
,..,u
n
nu este elementar, atunci exist
n j i 0 <
i i 0 sau j n astfel nct u
i
=u
j
.
Atunci drumul

'

+
+
n j , 0 i dac , u ... u u ... u u
0 j dac , u ... u u
0 i dac , u ... u u
:
n 1 j i 1 0
i 1 0
n 1 j j
'

este de asemenea un u
0
-u
n
drum. Aplicnd n continuare eliminarea duplicatelor vrfurilor n modul descris, rezult n
final un u
0
-u
m
drum elementar.
Exemplu
3.2. n graful,

v
1

v
2

v
3

v
4
v
5

v
6
v
7

v
8

v
9

v
10

dac : v
1
, v
2
, v
4
, v
5
, v
3
, v
1
, v
2,
v
5
, v
6
, v
7
, v
8
, v
9,
v
5
, v
9
, v
8
, v
10
, atunci
1
: v
1
, v
2
, v
5
, v
9
, v
8
, v
10
,
2
: v
1
, v
2
, v
4
, v
5
, v
9
, v
8
,
v
10
snt v
1
-v
10
subdrumuri elementare.
3.2. Matricea existenei drumurilor; algoritmul Roy-Warshall
Lema 2.3.1. Fie G=(V,E) un graf,
n V
. Dac A este matricea de adiacen asociat grafului, atunci,
pentru orice p1,
) p (
ij
a
este numrul v
i
-v
j
drumurilor distincte de lungime p din graful G, unde ( )
) p (
ij
p
a A .
Demonstraie
Demonstrarea acestei afirmaii este realizat prin inducie dup p
Pentru p=1, deoarece pentru orice
n j , i 1
exist cel mult un v
i
-v
j
drum de lungime 1 i dac exist, fie
acesta : v
i
, v
j
. Rezult c numrul v
i
-v
j
drumurilor de lungime 1 este egal cu
( ) 1
ij
a
.
Presupunem c A
p-1
=
( )
( )
1 p
ij
a

are proprietatea c pentru toi
n j , i 1
,
( )
( )
1 p
ij
a

este egal cu numrul v
i
-
v
j
drumurilor de lungime p-1 n G.
Cum A
p
=A
p-1
A =
( )
( )
p
ij
a , rezult c,
n j , i 1
,

p
1 k
kj
) 1 p (
ik
) p (
ij
a a a . Orice v
i
-v
j
drum de lungime p n G
conine un v
i
-v
k
drum de lungime p-1 pentru un anume v
k
adiacent cu v
j
i reciproc, pentru orice v
k
adiacent cu v
j
oricrui v
i
-v
k
drum de lungime p-1 i corespunde un v
i
-v
j
drum de lungime p.
Din relaia care caracterizeaz elementele
( )
( )
p
ij
a , utiliznd ipoteza inductiv, rezult afirmaia enunat mai
sus.
Definiia 3.4. Fie M
n
({0,1)} mulimea matricelor de dimensiuni nxn, componentele fiind elemente din
mulimea {0,1}. Pe M
n
({0,1)}se definesc operaiile binare, notate i , astfel: pentru orice A=(a
ij
), B=(b
ij
) din
M
n
({0,1)}, A B=(c
ij
), A B=(d
ij
), unde
n j , i 1
, c
ij
=max{a
ij
, b
ij
}
d
ij
=max{min{a
ik
, b
kj
}, n k 1 }.
Dac A=(a
ij
) M
n
({0,1)}, se noteaz
( ) { } 1 k ; a A
) k (
ij
k

secvena de matrice definit prin:
( )
2 k , A A A , A A
) 1 k ( k 1


.
Dac A este matricea de adiacen a unui graf G=(V,E), atunci pentru fiecare k, 1 n k 1 ,

'

altfel , 0
k lungime de j la i la de drum exist dac , 1
a
) k (
ij
Matricea
) 1 n ( ) 2 ( ) 1 (
A A A M


se numete matricea existenei drumurilor n graful G.
Semnificaia componentelor matricei M este:

'



altfel , 1
G n drum v v exist nu dac , 0
m , n j , i 1
j i
ij
Exemplu
3.3. Pentru graful,

1
2
3
4

,
_

,
_

,
_

,
_

1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
,
1 1 1 1
1 1 1 1
1 1 0 1
1 1 1 1
,
1 1 1 1
1 1 1 1
1 1 1 0
1 1 0 1
,
0 1 0 1
1 0 0 1
0 0 0 1
1 1 1 0
3 2
M A A A
Observaie Calculul matricei existenei drumurilor permite verificarea dac un graf dat este conex. Graful
este conex dac i numai dac toate componentele matricei M snt egale cu 1.
Algoritmul Roy-Warshall calculeaz matricea existenei drumurilor ntr-un graf G cu n vrfuri.
void Roy_Warshall (unsigned char a[10][10],unsigned n,unsigned char m[10][10])
{int i,j,k;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
m[i][j]=a[i][j];
for (j=0;j<n;j++)
for (i=0;i<n;i++)
if(m[i][j])
for (k=0;k<n;k++)
if (m[i][k]<m[k][j]) m[i][k]=m[k][j];}
Datele de intrare snt: n, numrul de noduri i A, matricea de adiacen corespunztoare grafului. Matricea M
calculat de algoritm constituie ieirea i este matricea existenei drumurilor n graful G.
3.3. Drumuri de cost minim
Definiia 3.5. Fie G=(V,E,w) un graf ponderat. Costul drumului : u
1
,u
2
,..,u
n
, notat L(), este definit prin:
( ) ( )

1 n
1 i
1 i i
u , u w L .
Pentru orice u i v vrfuri conectate n G, u v, w-distana ntre u i v, notat D(u,v), este definit prin,
( ) ( ) { }
uv
D , L min v , u D , unde D
uv
desemneaz mulimea tuturor u-v drumurilor elementare din G.
Dac
uv
D
este astfel nct D(u,v)=L(), drumul se numete drum de cost minim.
Observaie Cu toate c este utilizat termenul de w-distan, n general D nu este o distan n sensul
matematic al cuvntului.n particular, dac funcia pondere asociaz valoarea 1 fiecrei muchii a grafului, atunci
pentru fiecare pereche de vrfuri distincte ale grafului, costul D(u,v) este lungimea unui cel mai scurt drum ntre cele
dou vrfuri. n acest caz D este o distan pe mulimea vrfurilor.
Algoritmul Dijkstra
Urmtorul algoritm a fost propus de ctre E. W. Dijkstra pentru determinarea w-distanelor D(u
0
,v) i a cte
unui u
0
-v drum de cost minim pentru fiecare vrf vu
0
ntr-un graf ponderat, unde u
0
este prestabilit.
Fie G=(V,E,w) un graf conex ponderat, u
0
V, SV, u
0
S. Se noteaz
S \ V S
i
( ) ( ) { } S x ; x , u D min S , u D
0 0
. Fie v S astfel nct D(u
0
,v)=D(u
0
, S ), : u
0
, u
1
,,u
p
v un u
0
-v drum de cost
minim. Evident, 0ip u
i
S i

: u
0
, u
1
,,u
p
un u
0
- u
p
drum de cost minim. De asemenea,
( ) ( ) { } E uv , S v , S u ); uv ( w u , u D min S , u D
0 0
+ .
Dac xS, y S astfel nct ( ) ( ) ) xy ( w x , u D S , u D
0 0
+ , rezult
( ) ( ) ) xy ( w x , u D y , u D
0 0
+ .
Pentru determinarea a cte unui cel mai ieftin u
0
-v drum, algoritmul consider o etichetare dinamic a
vrfurilor grafului.Eticheta vrfului v este (L(v),u), unde L(v) este lungimea unui cel mai ieftin u
0
-v drum determinat
pn la momentul respectiv i u este predecesorul lui v pe un astfel de drum.
Pentru (V,E,w) graf conex ponderat,
n V
i u
0
V, calculul implicat de algoritmul Dijkstra poate fi descris
astfel:
Pas 1: i=0; S
0
={u
0
}; L(u
0
)=0, L(v)= pentru toi vV, vu
0
. Dac n=1 atunci stop
Pas 2: Pentru toi v
i S
, dac L(v)>L(u
i
)+w(u
i
v), atunci L(v)=L(u
i
)+w(u
i
v) i eticheteaz v cu (L(v),u
i
).
Pas 3: Se determin d=min{L(v), v
i S
} i se alege u
i+1

i S
astfel nct L(u
i+1
)=d.
Pas 4: S
i+1
=S
i {u
i+1
}
Pas 5: i=i+1. Dac i=n-1, atunci stop. Altfel, reia Pas 2.
Observaie Dac (V,E,w) graf ponderat neconex, atunci, pentru u
0
V, algoritmul lui Dijkstra permite
determinarea w-distanelor D(u
0
,v) i a cte unui u
0
-v drum de cost minim pentru toate vrfurile v din componenta
conex creia i aparine u
0
.
Exemplu
3.4. Fie graful ponderat,
1
2
3
4
5
1 5
9
2
5
16
Considernd u
0
=1, etapele n aplicarea algoritmului Dijkstra snt:
P1: i=0; S
0
={1}; L(1)=0, L(i)= pentru toi 5 , 2 i .
P2:
0 S
={2,3,4,5}, u
0
=1
L(2)= >L(1)+5=5 L(2)=5, eticheteaz 2 cu 1
L(3)= >L(1)+1=1 L(3)=1, eticheteaz 3 cu 1
L(4)= >L(1)+9=9 L(4)=9, eticheteaz 4 cu 1
L(5)= , w(1,5)= , deci L(5) nu se modific
P3: selecteaz u
1
=3, L(3)=1, cea mai mic dintre w-distanele calculate la P2
P4: S
1
={1,3}
P5: i=i+1=1 4, reia P2
P2:
1 S
={2,4,5}, u
1
=3
Nu se modific nici o etichet i nici o w-distan (w(3,i)= , pentru toi i din
1 S
)
P3: selecteaz u
2
=2, L(2)=5, cea mai mic dintre w-distanele calculate la P2
P4: S
2
={1,3,2}
P5: i=i+1=2 4, reia P2
P2:
2 S
={4,5}, u
2
=2
L(4)= 9>L(2)+2=7 L(4)=7, eticheteaz 4 cu 2
L(5)= >L(2)+16=21, eticheteaz 5 cu 2
P3: selecteaz u
3
=4, L(4)=7, cea mai mic dintre w-distanele calculate la P2
P4: S
3
={1,3,2,4}
P5: i=i+1=3 4, reia P2
P2:
3 S
={5}, u
3
=4
L(5)= 21>L(4)+5=12, eticheteaz 5 cu 4
P3: selecteaz u
4
=5, L(5)=12, cea mai mic dintre w-distanele calculate la P2
P4: S
3
={1,3,2,4,5}
P5: i=i+1=4, stop.
Algoritmul calculeaz urmtoarele rezultate:
Vrful v pn la care este
calculat w-distana
1 2 3 4 5
D(1,v), eticheta lui v 0, 1 5, 1 1, 1 7, 2 12, 4
Drumurile de cost minim de la vrful 1 la fiecare dintre vrfurile grafului se stabilesc pe baza sistemului de
etichete astfel: drumul de la 1 la un vrf v este dat de: v
1
, eticheta lui v, v
2
eticheta lui v
1
amd, pn se ajunge la
eticheta 1. Astfel, v
0
-drumurile de cost minim snt:
pn la 2: 2,1;
pn la 3: 3,1;
pn la 4: 4,2,1;
pn la 5: 5,4,2,1.
Urmtoarea surs C implementeaz algoritmul Dijkstra.
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
typedef struct{
int predv;
float L;
} eticheta;
void creaza(int *s,int *sb,int nv,int u0)
{
s[0]=u0;
for(int j=0,i=0;i<nv;i++)
if(i-u0)sb[j++]=i;
}
void modifica(int *s,int *sb,int ui, int *ns, int *nb)
{
s[*ns]=ui;
(*ns)++;
for(int i=0;i<*nb;i++)
if(sb[i]==ui){
for(int j=i+1;j<*nb;j++)
sb[j-1]=sb[j];
(*nb)--;
return;
}
}
eticheta *Dijkstra(float w[][50],int nv,int u0)
{
eticheta *r=(eticheta *)malloc(nv*sizeof(eticheta));
for(int i=0;i<nv;i++)r[i].L=1000;
r[u0].L=0;
r[u0].predv=u0;
int s[50],sb[50],ns=1,nb=nv-1;
creaza(s,sb,nv,u0);
for(i=0;i<nv-1;i++){
float dmin=1000;
for(int j=0;j<nb;j++)
for(int k=0;k<ns;k++)
if(r[sb[j]].L>r[s[k]].L+w[sb[j]][s[k]]){
r[sb[j]].L=r[s[k]].L+w[sb[j]][s[k]];
r[sb[j]].predv=s[k];
}
int ui;
for(j=0;j<nb;j++)
if(r[sb[j]].L<dmin){
dmin=r[sb[j]].L;
ui=sb[j];
}
modifica(s,sb,ui,&ns,&nb);
}
return r;
}
void main()
{
int n,i,j;
clrscr();
printf("Numarul de varfuri");
scanf("%i",&n);
printf("Matricea ponderilor:\n");
float w[50][50];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%f",&w[i][j]);
int u0;
printf("\nVarful initial:");
scanf("%i",&u0);
u0--;
eticheta *rez=Dijkstra(w,n,u0);
for(i=0;i<n;i++){
printf("Distanta de la vf. %i la vf. %i este %7.2f\n",u0+1,i+1,rez[i].L);
printf("Un drum de cost minim este:");
printf("%i, ",i+1);
j=rez[i].predv;
while(j-u0){
printf("%i, ", j+1);
j=rez[j].predv;
}
printf("%i\n\n",u0+1);
}
free(rez);
getch();
}
n anumite aplicaii este necesar exclusiv determinarea w-distanelor D(v
0
,v), pentru toi vV. n acest caz
algoritmul Roy-Floyd permite o rezolvare a acestei probleme mai simplu de implementat dect algoritmul Dijkstra.
Algoritmul Roy-Floyd
Pentru (V,E,w) graf ponderat,
n V
i W matricea ponderilor, sistemul de w-distane D(v
0
,v), vV, poate fi
calculat pe baza urmtoarei funcii (similar algoritmului Roy-Warshall),
void Roy_Floyd (float w[10][10],unsigned n,float
d[10][10],float MAX)
{int i,j,k;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
d[i][j]=w[i][j];
for (j=0;j<n;j++)
for (i=0;i<n;i++)
if(d[i][j]<MAX)
for (k=0;k<n;k++)
if (d[i][k]>d[i][j]+d[j][k])
d[i][k]=d[i][j]+d[j][k];
}
Matricea D calculat de algoritm este matricea w-distanelor D(u,v) n graful ponderat conex (V,E,w); pentru
orice
n j , i 1

'

altfel ,
conectate sunt v , v ), v , v ( D
d
j i j i
ij
ntr-adevr, procedura realizeaz calculul dinamic al w-distanei ntre oricare dou vrfuri i i k, astfel: dac
exist un drum i-k drum ce trece prin j (
n j 1
), cu costul corespunztor (d
ij
+d
jk
)

inferior costului curent (d
ik
),
atunci noul drum de la i la k via j este de cost mai mic dect costul drumului vechi, deci w-distana ntre i i k trebuie
reactualizat la d
ij
+d
jk
.