Documente Academic
Documente Profesional
Documente Cultură
PONDERATE
l. Dr. Ing. erban Radu
Departamentul de Calculatoare
Facultatea de Automatic i Calculatoare
Introducere
n afar de direcie, muchiile unui graf pot
avea o pondere
Dac vrfurile unui graf ponderat
reprezint orae, ponderile muchiilor pot
reprezenta distanele ntre orae, costurile
deplasrii cu avionul sau numrul curselor
de autobuze efectuate ntre orae
Definirea structurii de graf ponderat
typedef struct {
int n,
m;
// nr de noduri i nr de arce
int **c;
// matrice de
ponderi (costuri)
} GrafP;
Funcii cu grafuri ponderate
//
funcie de
adugare a
arcului
(v,w) la graful ponderat g
void addArc (GrafP
& g, int v,
int w,
int cost) {
g.c[v][w]
=
cost;
g.m++;
}
// funcie care ntoarce costul arcului (v,w)
int cost_arc (GrafP
g, int v, int w) {
return g.c[v][w];
}
Arborele minim de acoperire al
unui graf ponderat
Crearea arborelui minim de acoperire este mai
dificil ntr-un graf ponderat, dect ntr-unul
neponderat
Cnd se presupune c toate muchiile au
lungimi egale, este simplu pentru algoritm s
aleag una dintre muchii i s o adauge la
arborele de acoperire
Arborele minim de acoperire
Un graf conex are mai muli arbori de
acoperire, numrul acestor arbori fiind cu
att mai mare cu ct numrul de cicluri din
graful iniial este mai mare
Pentru un graf conex cu n
vrfuri, arborii
de acoperire au exact n-1
muchii
Pentru un graf dat, trebuie gsit
arborele
de acoperire de
cost total minim sau unul
dintre acetia, dac
sunt mai muli
Arborele minim de acoperire
Cnd muchiile au lungimi diferite, trebuie
s efectum anumite calcule, nainte de a
alege muchia potrivit
Presupunem c dorim s instalm o linie
de televiziune prin cablu, care s
conecteze ase orae
Cele ase orae vor fi conectate prin cinci
legturi
Arborele minim de acoperire
Costurile de conectare difer pentru
fiecare pereche de orae, deci trebuie ales
traseul care minimizeaz costul global
Presupunem c avem un graf ponderat cu
ase vrfuri, reprezentnd oraele:
Ajo,
Bordo, Colina, Danza, Erizo i Flor
Formularea problemei
Fiecare muchie are asociat o pondere,
care reprezint costul pentru instalarea
unei legturi prin cablu ntre dou orae
Se observ c unele dintre aceste legturi
sunt nepractice, din cauza costurilor prea
mari
Cum se poate alege un traseu care
minimizeaz costul de instalare al reelei
de cabluri ?
Soluia problemei
Se obine calculnd un arbore minim de
acoperire
Acesta va avea cinci legturi, va conecta
toate cele ase orae i va minimiza costul
total al instalrii acestor legturi
Observaii
n cazul grafurilor, algoritmii ncep
parcurgerea cu un anumit vrf i se
deplaseaz din aproape n aproape,
examinnd mai nti vrfurile mai
apropiate i apoi pe cele mai deprtate de
punctul de pornire
Observaii
Presupunem c nu cunoatem de la
nceput toate costurile de instalare a
cablului ntre oricare dou orae
Culegerea acestor informaii necesit timp
i se efectueaz pe parcurs
ncepem din Ajo
Din Ajo, exist dou orae la care putem
ajunge direct: Bordo i Danza
Se creeaz o list cu costurile legturilor,
introduse n ordinea cresctoare a costului
Ajo-Danza 4
Ajo-Bordo 6
Stabilirea legturii Ajo-Danza
Trebuie mai nti s adugm un vrf la
arbore i abia apoi s ncercm s
determinm ponderile muchiilor care
pleac din acel vrf
Stabilirea legturii Ajo-Bordo
Dup ce se stabilete legtura Ajo-Danza,
se inspecteaz toate oraele adiacente
oraului Danza: Bordo, Colina i Erizo
Ajo-Bordo 6
Danza-Bordo 7
Danza-Colina 8
Danza-Erizo 12
Observaii
Legtura Ajo-Danza nu mai apare n list
deoarece s-a instalat deja cablul
Rutele pe care s-a instalat deja cablul sunt
terse din list
Regul:
alegem ntotdeauna din list
muchia cea mai scurt (sau cea mai
ieftin)
Observaii
La orice moment din procesul de construcie
a reelei de cabluri, exist trei tipuri de orae:
1. Orae care sunt deja n arborele minim de
acoperire
2. Orae pentru care se cunoate costul de
conectare cu cel puin un ora care se afl
deja n arborele minim;
acestea se numesc
orae de frontier
3. Orae despre care nu cunoatem nc
nimic
Observaii
Ajo, Danza i Bordo fac parte din prima
categorie
Colina i Erizo din a doua categorie
Flor din ultima categorie
Pe msur ce algoritmul avanseaz,
oraele din categoria a treia trec n cea
de-a doua, iar cele de aici trec n prima
Stabilirea legturii Bordo-Erizo
Lista conine urmtoarele costuri:
Bordo-Erizo 7
Danza-Colina 8
Bordo-Colina 10
Danza-Erizo 12
Observaii
Legtura Danza-Bordo exista n vechea
list, dar nu mai exist acum, deoarece nu
are sens s lum n considerare legturi
ntre orae deja conectate, chiar printr-o
rut indirect
Din lista actual, legtura cea mai ieftin
este Bordo-Erizo, cu costul 7
Stabilirea legturii Erizo-Colina
Din Erizo, costul este 5 spre Colina i 7
spre Flor
Legtura Danza-Erizo trebuie tears din
list, deoarece Erizo este acum un ora
conectat
Coninutul actualizat al listei
Erizo-Colina 5
Erizo-Flor 7
Danza-Colina 8
Bordo-Colina 10
Cea mai ieftin dintre aceste legturi este
Erizo-Colina
Legtura Colina-Flor
Dup tergerea oraelor deja conectate,
lista conine doar legturile:
Colina-Flor 6
Erizo-Flor 7
Se stabilete ultima legtur, Colina-Flor,
cu costul 6
Rutele obinute reprezint cea mai ieftin
soluie de conectare a tuturor oraelor
Coada cu prioriti
O list n care putem selecta n mod repetat
elementul cu valoarea minim sugereaz
utilizarea unei cozi cu prioriti
Paii algoritmului
ncepem cu un vrf, pe care-l introducem n
arbore
Repetm urmtorii pai:
1. Determinm toate muchiile, de la cel mai
recent vrf ctre alte vrfuri, care nu aparin
arborelui; aceste muchii se insereaz n coada
cu prioriti
2. Alegem muchia cu ponderea minim, iar
aceasta se adaug (mpreun cu vrful de
destinaie) la arborele de acoperire
Observaii
Aceti pai se repet, pn cnd toate
vrfurile sunt n arbore
n pasul 1, prin cel mai recent
se nelege
nodul cel mai recent adugat n arbore
Muchiile necesare sunt gsite n matricea
de adiacen
Dup pasul 1, lista va conine toate
muchiile cu originea n vrfuri din arbore i
destinaia n vrfuri de pe frontier
Observaii
n procesul de meninere a listei de
legturi, o problem este de a terge
legturile care au destinaia n oraul
(vrful) cel mai recent conectat (adugat
n arborele de acoperire)
Fr aceast operaie, este posibil s
instalm legturi prin cablu care nu mai
sunt necesare
Observaii
Trebuie s ne asigurm c n coada cu
prioriti nu exist muchii a cror destinaie
s fie un nod aflat deja n arbore
Putem parcurge coada, cutnd i
eliminnd toate muchiile de acest fel, de
fiecare dat cnd adugm un vrf nou n
arbore
Observaii
Este mai simplu s memorm n coad, la
un moment dat, o singur muchie de la un
vrf din arbore ctre fiecare nod de
frontier dat
Coada trebuie sa conin o singur
muchie ctre fiecare vrf din categoria a
doua
Cutarea duplicatelor n coada
cu prioriti
De fiecare dat cnd adugm o muchie
n coad, ne asigurm c nu mai exist o
alt muchie cu aceeai destinaie
Dac mai exist astfel de muchii, o
pstrm numai pe cea cu ponderea
minim
Aceast operaie necesit cutarea
secvenial prin coada cu prioriti
Algoritmul lui Prim
Algoritmul folosete o coad
cu prioriti
de arce care leag
vrfuri din
arborele
minim de acoperire
cu alte vrfuri (coada
se modific
pe msur
ce algoritmul
evolueaz)
Algoritmul lui Prim
Algoritmul se bazeaz
pe observaia
urmtoare: fie S
o submulime a vrfurilor
grafului i R
submulimea de vrfuri care
nu sunt n S
Muchia de cost minim care unete
vrfurile din S
cu vrfurile din R
face parte
din
arborele minim de acoperire
Algoritmul lui Prim
Se poate folosi noiunea de tietur
n graf:
se taie toate arcele care leag
un nod k
de
restul nodurilor din graf i se determin
arcul de
cost minim dintre arcele tiate; acest arc va
face parte din
arborele minim de acoperire
i va
uni nodul k
cu
arborele minim de acoperire
al
grafului rmas dup
ndeprtarea nodului k
La fiecare pas se face o nou
tietur
n graful
rmas i se determin
un alt arc din arborele
minim de acoperire
Algoritmul lui Prim
Fiecare tietur
n graf mparte mulimea
nodurilor din graf n dou
submulimi:
S
(noduri incluse n
arborele minim de acoperire)
R
(restul nodurilor)
Iniial,
S
=
{1},
dac
se pornete cu nodul 1, iar
n final S va conine toate nodurile din graf
Exemplu
Se consider urmtorul graf neorientat,
cu
6 noduri,
cu
arcele
i costurile asociate:
(1,2)=6; (1,3)=1; (1,4)=5;
(2,3)=5; (2,5)=3;
(3,4)=5; (3,5)=6; (3,6)=4;
(4,6)=2;
(5,6)=6;
S Arce ntre S i R (arce tiate) Minim y
1 (1,2)=6;
(1,3)=1; (1,4)=5; (1,3)=1 3
1,3 (1,2)=6; (1,4)=5; (3,2)=5;
(3,4)=5; (3,5)=6; (3,6)=4
(3,6)=4 6
1,3,6 (1,2)=6; (1,4)=5; (3,2)=5;
(3,4)=5; (3,5)=6;
(6,4)=2; (6,5)=6
(6,4)=2 4
1,3,6,4 (1,2)=6; (3,2)=5; (3,5)=6;
(6,5)=6
(3,2)=5 2
1,3,6,4,2 (2,5)=3; (3,5)=6; (6,5)=6 (2,5)=3 5
Soluia problemei
O mulime de arce, adic
un tablou
de
perechi de noduri, sau dou
tablouri de
ntregi X i Y, cu semnificaia c
o pereche
x[i]-y[i] reprezint
un arc din
arborele
minim de acoperire
Este posibil i folosirea unui tablou
de
ntregi pentru arborele minim de acoperire
Implementarea algoritmului
Se folosesc dou
tablouri:
p[i]
= numrul nodului din S,
cel mai
apropiat de nodul i din R
c[i]
= costul arcului dintre i i p[i]
La fiecare pas se caut
n tabloul c,
pentru a gsi nodul k din R,
cel mai
apropiat de nodul i din S
Implementarea algoritmului
Pentru a nu mai folosi o mulime S, se
atribuie lui c[k] o valoare foarte mare,
astfel ca nodul k s
nu mai fie luat n
considerare n paii urmtori
Mulimea S este implicit mulimea
nodurilor i,
cu c[i] foarte mare
Celelalte noduri formeaz
mulimea R
Implementarea algoritmului
# define M 20 // nr maxim de noduri
# define M1 10000 // un nr f mare (cost arc absent)
# define M2 (M1+1)
// alt nr
f mare (cost arc folosit)
// algoritmul lui
Prim pentru arbore minim de acoperire
void prim (GrafP
g, int x[ ], int y[ ]){
int c[M], cmin;
int p[M], i,
j,
k;
int n
=
g.n;
// n = nr de vrfuri
for(i =
2;
i <=
n;
i++) {
p[i]=1;
c[i]=cost_arc (g,
1,
i);
// costuri iniiale
}
Implementarea algoritmului
for
(i
=
2;
i
<=
n;
i++) {
// caut
nodul k cel mai apropiat de un nod din
arbore
cmin = c[2]; k
=
2;
for
(j
=
2;
j
<=
n;
j++)
if (c[j] < cmin) {
cmin
=
c[j]; k
=
j;
}
x[i-1]
=
p[k]; y[i-1]
= k;// muchie de cost minim n x i y
c[k]
=
M2;
for
(j
=
2;
j
<=
n;
j++)
// ajustare costuri
if (cost_arc(g,
k,
j) < c[j] && c[j] < M2) {
c[j]
= cost_arc(g,
k,
j); p[j] =
k;
} }
}
Observaii
Sunt
necesare dou
constante mari: M1
arat
c
nu exist
un arc ntre dou
noduri, iar M2
arat
c
acel arc a fost
inclus n
arborele minim de acoperire
i c
va fi ignorat n continuare
Tabloul p
folosit n programul anterior
corespunde reprezentrii unui arbore
printr-un singur tablou, de predecesori
Evoluia tablourilor c
i p
pentru
exemplul dat este urmtoarea:
c[2] p[2] c[3] p[3] c[4] p[4] c[5] p[5] c[6] p[6] k
6 1 1 1 5 1 M1 1 M1 1 3
5 3 M2 1 5 1 6 3 4 3 6
5 3 M2 1 2 6 6 3 M2 3 4
5 3 M2 1 M2 6 6 3 M2 3 2
M2 3 M2 1 M2 6 3 2 M2 3 5
M2 3 M2 1 M2 6 M2 2 M2 3
Determinarea drumului de
lungime minim
O aplicaie frecvent a grafurilor orientate
i ponderate este determinarea drumului
cel mai scurt dintre dou vrfuri date
Dorim s determinm ruta cea mai ieftin
de la un ora
la
un
alt ora
Observaii
Muchiile grafului sunt orientate
Acestea reprezint calea ferat, pe care
se circul ntr-un singur sens
Dei n acest caz suntem interesai de
minimizarea unui cost, numele algoritmului
este problema drumului minim
Observaii
Prin drum minim
nu se nelege neaprat
drumul cel mai scurt, din punct de vedere
fizic
Poate fi vorba de drumul cel mai ieftin, cel
mai rapid sau cel mai bun, dintr-un alt
punct de vedere
Costuri minime
ntre oricare dou orae exist mai multe
drumuri posibile
Problema drumului minim presupune
determinarea, pentru un punct de pornire
dat i o destinaie precizat, a traseului cel
mai ieftin
Graf orientat i ponderat
Reeaua de cale ferat cuprinde numai linii
unidirecionale
Aceast situaie poate fi modelat printr-un
graf orientat i ponderat
Algoritmul lui Dijkstra
Soluia la problema drumului minim este
numit algoritmul lui Dijkstra, dup
numele lui Edsger Dijkstra, care l-a
descoperit n 1959
Algoritmul se bazeaz pe reprezentarea
grafului cu ajutorul matricei de adiacen
Algoritmul permite determinarea att a
drumului minim
dintre un vrf precizat i
altul, ct i a drumurilor minime, de la
vrful precizat la toate celelalte vrfuri
Prezentarea algoritmului
Dorim s determinm cel mai ieftin mod
de a cltori de la Ajo pn la orice alt
ora
Algoritmul trebuie s examineze numai o
singur informaie la un moment dat
Regul:
ntotdeauna se merge n oraul
pentru care costul total calculat din punctul
de pornire (Ajo) este minim
Trei tipuri de orae
1. Orae prin care am trecut deja;
acestea
sunt n arbore
2. Orae pentru care tim costurile de
cltorie;
acestea sunt pe frontier
3. Orae necunoscute
Observaii
Ajo i Bordo sunt de tipul 1
Oraele de tipul 1 formeaz un arbore,
care const din drumurile care ncep cu
acelai punct de pornire, fiecare
terminndu-se cu un alt vrf, diferit de
destinaie
Danza i Colina sunt orae de tipul 2 (de
frontier)
Observaii
Oraele se vor deplasa de la tipul 3
(necunoscute), n cel de-al doilea tip (de
frontier), iar de aici n arbore, pe msur
ce algoritmul avansez
Observaii
Cnd se cunosc costurile cltoriei din Ajo
pn n oricare alt ora, algoritmul se
termin
Pasul 5 indic rutele cele mai ieftine, din
Ajo pn n toate celelalte orae
Ideile algoritmului lui Dijkstra
1. De fiecare dat cnd ne aflm ntr-un ora
nou, actualizm lista de costuri
n list reinem numai drumul de cost minim
(cunoscut pn n momentul curent) dintre
punctul de pornire i un alt ora
precizat
2. Mergem ntotdeauna n oraul care are
calea cea mai ieftin fa de punctul de
pornire
Detalii de implementare
Se consider
ca nod surs
i nodul 1 i se
determin
lungimile drumurilor minime
d[2],
d[3],...,
d[n] pn
la nodurile 2,
3,..., n
Pentru memorarea nodurilor de pe un
drum minim se folosete un tablou
P, cu
p[i] =
nodul precedent lui i pe drumul
minim de la 1 la i (mulimea drumurilor
minime formeaz
un arbore, iar tabloul
P
reprezint
acest arbore de ci n graf)
Detalii de implementare
Se folosete un tablou
D,
unde
d[i] este distana
minim
de la 1 la i, dintre drumurile care trec
prin noduri deja selectate
O variabil
S
de tip mulime memoreaz
numerele nodurilor cu distan
minim
fa
de
nodul 1, gsite pn
la un moment dat
Iniial,
S={1} i d[i]=cost[1][i], adic
se consider
arcul direct de la 1 la i ca drum minim ntre 1 i i
Pe msur
ce algoritmul evolueaz, se
actualizeaz
D i S
Pseudocod algoritm Dijkstra
S =
{1}
// S =
mulime noduri pentru
care s-a
//determinat distana minim
fa
de nodul 1
repet
ct timp S conine mai puin de n noduri {
gsete muchia (x,y) cu x
S i y
S care
minimizeaz
d[x]
+
cost(x,y)
adaug
y la S
d[y] = d[x] + cost(x,y)
}
Detalii de implementare
La fiecare pas din algoritmul Dijkstra:
1) Se gsete dintre nodurile jS acel nod
"jmin" care are distana minim
fa
de nodurile
din S
2) Se adaug
nodul "jmin" la mulimea S
3) Se recalculeaz
distanele de la nodul 1 la
nodurile care nu fac parte din S, pentru c
distanele la nodurile din S rmn neschimbate
4) Se reine n p[j] numrul nodului precedent
cel mai apropiat de nodul j (de pe drumul minim
de la 1 la j)
Exemplu
Se consider
un graf orientat cu
urmtoarele costuri de arce:
(1,2)=5; (1,4)=2; (1,5)=6;
(2,3)=3;
(3,2)=4; (3,5)=4;
(4,2)=2; (4,3)=7; (4,5)=3;
(5,3)=3;
Exemplu
Drumurile posibile ntre 1 i 3 i costul lor:
1-2-3 = 8
1-4-3 = 9
1-4-2-3 = 7
1-4-5-3 = 8
1-5-3 = 9
Exemplu
Drumurile minime de la 1 la celelalte
noduri din
graf:
1-4-2 cu costul 4
1-4-2-3 cu costul 7
1-4 cu costul 2
1-4-5 cu costul 5
Observaii
ntr-un drum minim,
fiecare drum parial
este minim
n drumul 1-4-2-3, drumurile pariale 1-4-2
i 1-4 sunt i ele minime
Evoluia tablourilor
D i S pentru acest
graf,
n cazul algoritmului
lui
Dijkstra:
S d[2] d[3] d[4] d[5] Nod
1 5 M 2 6 4
1,4 4 9 2 5 2
1,4,2 4 7 2 5 5
1,4,2,5 4 7 2 5 3
Observaii
Tabloul P va arta astfel:
Funcie Dijkstra
void dijkstra (GrafP
g,int p[]) {
int d[M],
s[M];
// s
= noduri pentru
care se tie distana minim
int dmin;
int jmin,
i,
j;
for (i =
2;
i <=
g.n;
i++) {
p[i]=1; d[i]=cost_arc(g,
1,
i);
// distane iniiale de la 1 la alte noduri
}
s[1]
=
1;
Funcie Dijkstra
for (i =
2;
i <=
g.n;
i++) {
// repet
de n-1 ori
// caut
nodul j pentru
care d[j] este minim
dmin =
MARE;
for (
j
=
2;
j
<=
g.n;
j++)
// determin
minimul dintre distanele d[j]
if (s[j]
==
0 && dmin > d[j]) {
// dac
j
S i este mai aproape de S
dmin =
d[j]; jmin
=
j;
}
Funcie Dijkstra
s[jmin]
=
1;
// adaug
nodul jmin la S
for (
j
=
2;
j
<=
g.n;
j++)
// recalculare distane noduri fa
de 1
if ( d[j] >
d[jmin] + cost_arc(g,
jmin,
j) ) {
d[j] =
d[jmin] + cost_arc(g,
jmin,
j);
p[j] =
jmin;
// predecesorul lui j pe drumul minim
}
}
}
Observaii
Valoarea constantei MARE, folosit
pentru
a marca n matricea de costuri absena
unui arc, nu poate fi mai mare ca jumtate
din valoarea maxim
pentru tipul ntreg,
deoarece la nsumarea costurilor a dou
drumuri se poate depi cel mai mare
ntreg (se pot folosi pentru costuri i
numere reale foarte mari)