Sunteți pe pagina 1din 16

Informatic clasa a XI-a Teorie

1
Cap.6 Metoda Greedy


6.1 Mecanism general

Este o metod general de elaborare a algoritmilor. n esen ea se aplic problemelor n care se d o
mulime A coninnd n date de intrare cerndu-se s se determine o submulime B a sa care s ndeplineasc
anumite condiii pentru a fi acceptat. Cum n general exist mai multe astfel de mulimi, se d i un criteriu
conform cruia, dintre submulimile acceptabile (numite soluii posibile), se alege una singur (numit soluie
optim) ca rezultat final.
Soluiile posibile au urmtoarea proprietate: dac submulimea BcA este o soluie posibil i C cB,
atunci i C este o soluie posibil. Vom presupune c mulimea vid este ntotdeauna o soluie posibil.
Metoda Greedy trateaz acest tip de probleme n dou moduri care urmeaz aceeai metod dar difer
doar prin ordinea de efectuare a unor operaii:

a) Se pleac de la soluia vid. Se alege pe rnd, ntr-un anumit fel, un element din A neales la paii
precedeni. Dac adugarea lui la soluia parial anterior construit conduce la o soluie posibil,
construim noua soluie prin adugarea elementului ales. Secvena de algoritm care descrie aceast
variant este:

algoritm Greedy1(A,n,B)
B
pentru i1.n executa
Alege(A,i,x)
Posibil(B,x,v)
daca v=1 atunci Adauga(B,x)
sf_daca
sf_pentru
sf_algoritm

Funcia Alege furnizeaz n mod dinamic elementul x=a
j
e{a
i
,.......a
n
}i efectueaz interschimbarea
elementelor a
i
i a
j
. Funcia Posibil furnizeaz v=1 dac B{x} este o soluie posibil i v=0 n caz
contrar. Funcia Adauga nlocuiete pe B cu B {x}.

b) Lucrurile decurg ca mai sus cu excepia faptului c se stabilete de la nceput (i nu n mod dinamic)
ordinea n care trebuie considerate elementele mulimii A. Algoritmul corespunztor este:


algoritm Greedy2(A,n,B)
B
Prel)A)
pentru i1.n executa
Posibil(B,a
i
,v)
daca v=1 atunci Adauga(B,a
i
)
sf_daca
sf_pentru
sf_algoritm

Funcia Prel efectueaz o prelucrare a elementelor mulimii A conform unui anumit criteriu.

Metoda Greedy nu caut s determine toate soluiile posibile i s aleag pe cea optim conform
criteriului de optimizare dat, ci const n a alege pe rnd cte un element urmnd s-l introduc eventual n
soluia optim; de aici provine numele Greedy (lacom).
Un exemplu tipic l constituie problemele de optimizare. Astfel, dac trebuie determinat maximul unei
funcii de cost depinznd de parametrii a
1
,.....,a
n
ideea general a metodei este de a alege la fiecare pas
acel element care s fac s creasc ct mai mult valoarea acestei funcii.
Exemplu: Se d o mulime X={x
1
,x
2
,.....,x
n
} cu elemente reale. S se determine submulimea cu suma
elementelor maxim.
Se observ uor c dac o submulime Y conine un element y
0
0, atunci suma submulimii Y-{y
0
}
dect suma elementelor din submulimea Y. Deci soluia optim va avea toate elemetele pozitive. Funcia
Alege furnizeaz x=a
i
, funcia Posibil returneaz v=1 dac a
i
>0 i v=0 n caz contrar. Algoritmul este:

Informatic clasa a XI-a Teorie

2
algoritm SUBM(X,Y,n,k)
float X[n],Y[n]
k0
pentru i1,n executa
daca x
i
>0 atunci kk+1; y
k
x
i

sf_daca
sf_pentru


Observaie: Metoda Greedy nu furnizeaz soluia optim pentru orice problem. n acest caz trebuie s
cunoatem mcar n ce msur suntem apropiai de soluia optim.


6.2 Exemple demonstrative


1. Problema continu a rucsacului

Enun: O persoan are un rucsac cu care poate transporta o greutate maxim G. Persoana are la dispoziie n
obiecte i cunoate pentru fiecare obiect greutatea i ctigul care se obine n urma transportrii lui la
destinaie. Obiectele pot fi tiate n buci. S se precizeze ce obiecte i n ce proporie trebuie transportate
astfel nct ctigul total obinut s fie maxim.

Rezolvare: Algoritmul bazat pe metoda Greedy este urmtorul:
se calculeaz pentru fiecare obiect n parte eficiena de transport (ctigul obinut prin transportul
unei uniti de greutate din obiectul respectiv).
obiectele se sorteaz n ordinea descresctoare a eficienei de transport i se preiau n calcul n
aceast ordine
ctigul iniial va fi 0, iar greutatea rmas de ncrcat va fi greutatea G a rucsacului
att timp ct nu a fost completat greutatea maxim a rucsacului i nu au fost luate n considerare
toate obiectele se procedeaz astfel: dintre obiectele nencrcate se selecteaz acele cu cea mai
mare eficien de transport i avem dou posibiliti:
a) acesta ncape n totalitate n rucsac, deci se scade din greutatea de ncrcat greutatea
obiectului, la ctig se accumuleazctigul obinut prin transportarea acelui obiect i se
tiprete 1, n sensul c ntregul obiect a fost ncrcat
b) obiectul nu ncape n totalitate n rucsac, caz n care se calculeaz ce parte din el se poate
transporta, se accumuleaz ctigul obinut, se tiprete procentul care s-a ncrcat din obiect,
greutatea rmas de ncrcat devine 0 i algoritmul se ncheie
Exemplu: greutatea rucsacului este G=3 i avem la dispoziie 3 obiecte:

Ctig 2 4 6
Greutate 2 1 3
Eficien(ctig/greutate) 1 4 2

Se sorteaz obiectele descresctor dup eficien i se obine ordinea 2 2 1.
Obiectul 2 se ncarc n ntregime: G3-1=2, castig0+4=4
Din obiectul 3 se ncarc 2/3: G2-(2/3)*3=0 (i algoritmul se va ncheia), castig4+(2/3)*6=8
Ctigul total este 8.

Observm c metoda Greedy se remarc n alegerea obiectului care va fi transportat (n ordinea
descresctoare a eficienei de transport), alegere asupra creia nu se revine.


2. Arborele parial de cost minim

Definiie: Se numete arbore un graf neorientat, conex i fr cicluri.

n figura alturat este desenat un arbore. Se observ c oricum am elimina o muchie, graful i pierde
proprietatea de conexitate, i oriunde am aduga o muchie, apare un ciclu. Acest lucru este valabil n orice
arbore.
Informatic clasa a XI-a Teorie

3

Teorem: Fie un graf neorientat G=(X,U).
Urmtoarele afirmaii sunt echivalente:
1) G este un arbore
2) G este un graf conex, minimal cu aceast
proprietate (eliminnd o muchie oarecare se
obine un graf neconex)
3) G este un graf fr cicluri, maximal cu
aceast proprietate (dac se adaug o muchie se
obine un graf care are mcar un ciclu)

Definiie: Fie graful G=(X,U) cu n>2 noduri, m
muchii i p componente conexe. Numrul v(G)=m-n+p se numete numrul ciclomatic al grafului G.

Observaii:
- se poate arta c v(G) furnizeaz numrul de cicluri elementare din graf
- numrul v(G) reprezint numrul de muchii ce trebuie nlturate din graf astfel nct acesta s nu
conin cicluri

Definiie: Fie G un graf neorientat. Un graf parial H al lui G, cu proprietatea c H este arbore, se numete
arbore parial al lui G.

Corolar: Un graf neorientat G conine un arbore parial dac i numai dac G este conex.

Propoziii:
1) Un arbore cu n>2 vrfuri conine cel puin dou vrfuri terminale.
2) Orice arbore cu n vrfuri are n-1 muchii.
3) Un graf G cu n vrfuri i m muchii este arbore dac este aciclic i m=n-1.
4) Un graf G cu n vrfuri i m muchii este arbore dac este conex i m=n-1.
5) Un graf cu n vrfuri i cel puin n muchii conine cel puin un ciclu.
6) Numerele d1>d2>d3>.......>dn>1 sunt gradele nodurilor unui arbore cu n>2 noduri dac i numai
dac d1+d2+....+dn=2(n-1).

Definiie: Un graf neorientat care nu conine cicluri se numete pdure.

n practic se ntlnesc foarte des probleme de tipul urmtor: se dorete conectarea unor consumatori
la o surs de energie electric astfel nct costul branrii s fie minim. Transpunnd problema n termenii
teoriei grafurilor, se cere de fapt determinarea unui arbore parial de cost minim, adic un arbore care are
proprietatea c suma costurilor muchiilor sale s fie minim.

Definiie: Suma costurilor muchiilor unui graf se numete costul grafului. Dac se definete funcia c:UR
+

care asociaz fiecrei muchii un numr real numit cost, costul grafului este

e
=
U u
u c G c ) ( ) (
Funcia c se numete funcia cost.
Fie G=(X,U) un graf conex, reprezentat prin matricea costurilor. Se tie c prin eliminarea uneia sau a
mai multor muchii se obine un graf parial. Dac graful parial al unui graf G conex este arbore, acesta se
numete arbore parial al lui G. Dac dintr-un graf conex G=(X,U) se elimin muchii astfel nct s se
obin un arbore parial al crui cost s fie minim, acesta se numete arbore parial de cost
minim(APM).

Proprietate: Pentru graful G conex, cu funcia de cost c, exist un graf parial H conex i de cost minim, care
este i arbore.
Pentru determinarea APM sunt cunoscui mai muli algoritmi, cei mai utilizai fiind algoritmul lui Kruskal
(1956) i algoritmul lui Prim, ambii bazai pe o strategie Greedy.




Algoritmul lui Kruskal
Informatic clasa a XI-a Teorie

4

Se pleac iniial de la n arbori disjunci, fiecare fiind format dintr-un nod al grafului : H
1
, H
2
,.,H
n
. La
fiecare pas vom ncerca s unificm doi dintre arborii existeni, alegerea celor doi arbori ce vor fi unificai
fcndu-se astfel: dintre toate muchiile nealese nc, se selecteaz muchia de cost minim care are o
extremitate ntr-un arbore i cealalt extremitate n alt arbore. Prin adugarea acestei muchii la arborele care se
construiete, se vor unifica cei doi arbori disjunci ntr-unul singur. Dup n-1 pai se obine APM care conine n-
1 muchii.
Algoritmul pseudocod corespunzator este:

algoritm Kruskal(G,U)
AC
pentru fiecare varf ve X(G) executa
Formeaza_Multime(v)
sfarsit pentru
sorteaza muchiile din u in ordinea crescatoare a costului c
pentru fiecare muchie (u,v)eU(G),in ordinea crescatoare a costului
executa
daca Gaseste_Multime(u)=Gaseste_Multime(v) atunci
AA {(u,v)}
Uneste(u,v)
sfarsit daca
sfarsit pentru
returneaza A

Algoritmul folosete o structur de date pentru mulimi disjuncte pentru reprezentarea mai multor mulimi de
elemente disjuncte. Fiecare mulime conine vrfurile unui arbore din pdurea curent. Funcia
Gaseste_Multime(u) returneaz un element reprezentativ din mulimea care l conine pe u. Astfel, putem
determina dac dou vrfuri u i v aparin aceluiai arbore testnd dac Gaseste_Multime(u) este egal cu
Gaseste_Multime(v). Combinarea arborilor este realizat de funcia Uneste(u,v).

Pentru a implementa algoritmul lui Kruskal vom reprezenta graful prin vectorul muchiilor, fiecare muchie
avnd ataat i costul. Pentru a specifica la fiecare pas din ce arbore face parte un nod i, vom folosi vectorul L.
Iniial, pornim cu n arbori disjunci, deci L[i]=i , pentru ie{1,2,.n}. Pentru a eficientiza alegerea
muchiilor, vectorul muchiilor u se va ordona cresctor dup costul muchiilor. Pentru a alege cele n-1 muchii ale
APM se parcurg elementele vectorului u astfel:
Fie v=[u[i].x,u[i].y] muchia ce urmeaz a fi analizat (plecm cu i=1). Dac n vectorul L
extremitile muchiilor au valori egale, adic L[u[i].x]=L[u[i].y], atunci cele dou extremiti aparin
aceluiai subarbore, deci alegerea acestei muchii ar duce la formarea unui ciclu. n caz contrar, nseamn c
extremitile muchiei fac parte din subarbori diferii, fie aceatia H
x
i H
y
, care pot fi unificai, operaie care
presupune c pentru toate vrfurile celor doi arbori trebuie s apar n vectorul L aceeai valoare (provenit din
primul sau din al doilea arbore). Acest pas se repet pn am reuit s alegem cele n-1 muchii ale APM.

Exemplu: Fie graful din figura urmtoare:

















Pasii algoritmului sunt:
Informatic clasa a XI-a Teorie

5

Configuratia initiala:

Dup ordonarea cresctoare a muchiilor
dup costul c ataat, avem:
u=([5,4],[3,4],[3,5],[1,2],
[2,5],[2,3],[6,5],[2,6],[2,7],
[1,7],[7,6])
c=(1,1,2,2,2,3,3,3,3,4,5)
L=(1,2,3,4,5,6,7) , fiecare nod
fcnd parte dintr-un arbore.










Pasul 1:

Se alege muchia de cost minim [5,4] i L
devine: (1,2,3,5,5,6,7) deoarece am
unificat arborii H
4
i H
5
i am obinut
subarborele H
5
=(4,5). Ceilali subarbori
rmn nemodificai.











Pasul 2:
Se alege muchia [3,4] de
cost minim, unificm H
3
i H
5
i obinem
L=(1,2,3,3,3,6,7) i H
3
=(3,4,5).















Pasul 3:
Informatic clasa a XI-a Teorie

6
Se verific muchia [3,5] care nu poate fi
aleas deoarece L[3]=L[5] (vrfurile 3 i 5 aparin
deja aceluiai subarbore H
3
) i alegerea ei ar provoca
apariia unui ciclu.
Se alege muchia [1,2], se unific H
1
i H
2
i
obinem: L=(1,1,3,3,3,6,7) i H
1
=(1,2).











Pasul 4:
Se alege muchia [2,5], se unific H
1
i H
3
i
obinem: L=(1,1,1,1,1,6,7) i
H
1
=(1,2,3,4,5).













Pasul 5:

Muchia [2,3] nu poate fi aleas pentru c ar crea un
ciclu.
Se alege muchia [6,5] i se obine subarborele
H
1
=(1,2,3,4,5,6).















Pasul 6:
Informatic clasa a XI-a Teorie

7
Se alege muchia [2,7] si L devine
(2,2,2,2,2,2,2), ceea ce corespunde unui
arbore parial de cost minim H=([1,2], [2,5],
[3,4], [5,4], [6,5], [2,7]), costul total
fiind 12.












Nu are importan care subarbore se alege pentru a transfera vrfurile celuilalt subarbore.

Observaie: Dac exist mai multe muchii cu acelai cost, pentru un graf conex G pot exista mai multe
posibiliti de alegere a unei muchii de cost minim, deci pot exista mai muli APM. Aceti arbori se vor deosebi
prin muchiile ce vor fi luate n consideraie, i nu prin costul asociat, deoarece aceast cost va fi acelai pentru
toi arborii, i anume ei vor avea cost minim.

Implementarea algoritmului lui Kruskal este:

#include<stdio.h>
#define N 30
#define M 60
typedef struct {
int x,y;
float cost;
}MUCHIE;
void citire_muchii(MUCHIE u[M],int &n,int &m)
{
int k;
FILE *f=fopen(graf.in,r);
fscanf(f"%d %d",&n,&m);
for(k=1;k<=m;k++)
fscanf(f,"%d %d %f",&u[k].x,&u[k].y,&u[k].cost);
fclose(f);
}
void sortare(MUCHIE u[M],int m)
{
MUCHIE aux; int i,j;
for(i=1;i<=m-1;i++)
for(j=i+1;j<=m;j++)
if(u[i].cost>u[j].cost)
{
aux=u[i]; u[i]=u[j]; u[j]=aux;
}
}
void creare_apm(MUCHIE u[M],int n,int m)
{
int L[N],k,i,v,w,j;
float ct=0; //cost total apm
for(i=1;i<=n;i++) L[i]=i; //n subarbori disjuncti
i=1; k=0;
printf("\n\nAPM: ");
while(k<n-1)
{
if(L[u[i].x]!=L[u[i].y])
//extremitatile muchiei sunt in subarbori diferiti
Informatic clasa a XI-a Teorie

8
{
k++;
ct+=u[i].cost; //adaugam costul muchiei i
printf("[%d,%d] ",u[i].x,u[i].y);
v=L[u[i].y]; w=L[u[i].x];
for(j=1;j<=n;j++)
if(L[j]==v) L[j]=w; //reunim cei doi arbori
}
i++; //trecem la urmatoarea muchie
}
printf("\n\ncostul total este %.2f\n",ct);
}
void main()
{
MUCHIE u[M]; int n,m;
citire_muchii(u,n,m); sortare(u,m); creare_apm(u,n,m);
}



Algoritmul lui Prim


Graful conex este dat prin matricea costurilor, forma 1. La fiecare pas k>0 obinem un arbore H
1
cu k+1
vrfuri i n-(k+1) arbori cu cte un singur vrf. La fiecare pas se alege muchia de cost minim care are o
extremitate n arborele H
1
deja creat i cealalt extremitate liber. Lucrm cu vectorul T n care vom avea,
pentru fiecare vrf neales nc, vrful din H
1
de care acesta se leag printr-o muchie de cost minim (legtur de
tip tat). n componenta corespunztoare din vectorul Q vom avea costul muchiei adugate. Cum la nceput
avem n H
1
doar vrful 1, n toate componentele lui T avem 1, cu excepia lui T[1], iar n Q, valorile
corespunztoare din linia 1 a matricei costurilor c. La pasul k, dup alegerea unui nou vrf w care se adaug la
H
1
, se vor actualiza componentele din T i Q pentru vrfurile nealese nc deoarece adugarea vrfului w poate
modifica aceste valori. Algoritmul are ordinul de complexitate u(n
2
).
Algoritmul pseudocod corespunztor este:

algoritm Prim(G,c,rad)
QX(G)
pentru fiecare ueQ executa
D[u]
sfarsit pentru
D[rad]0
T[rad]0
cat timp Q=0 executa
uExtrage_Minim(Q)
pentru fiecare vecinilor lui u executa
daca veQ i c(u,v)<D[v] atunci
T[v]u
D[v]c(u,v)
sfarsit daca
sfarsit pentru
sfarsit cat timp

Se iniializeaz vectorul Q astfel nct acesta s conin toate vrfurile grafului i se iniializeaz cmpul D al
fiecrui vrf cu , excepie fcnd rdcina rad, al crei cmp D este iniializat cu 0. Tatl rdcinii se
iniializeaz cu 0, deoarece rad nu are nici un printe. Pe parcursul algoritmului, mulimea X-Q conine vrfurile
arborelui curent. Se identific un vrf ueQ incident unei muchii de cost minim care traverseaz tietura (X-
Q,X) (cu excepia primei iteraii n care u=rad deoarece are cheia D[rad]=0). Eliminarea lui u din mulimea Q
l adaug pe acesta mulimii U-Q a vrfurilor din arbore. n liniile urmtoare se actualizeaz cmpurile D i T ale
fiecrui vrf v adiacent lui u, dar care nu se afl n arbore. Actualizarea respect condiiile D[v]=c(v,T[v])
i (v,T[v]) s fie o muchie de cost minim care l unete pe v cu un vrf din arbore.

Informatic clasa a XI-a Teorie

9
Fie graful din figura
urmtoare:













Configuraia iniial:




Pasul 1:


Pasul 2:




Pasul 3:
Informatic clasa a XI-a Teorie

10




Pasul 4:



Pasul 5:









Pasul 6:
Informatic clasa a XI-a Teorie

11




Implementarea algoritmului lui Prim este:

#include<stdio.h>
#define N 30
#define M 60
#define INF 1<<14
void citire_graf(int c[N][N],int &n)
{
int m,i,j,x,y,z;
FILE *f=fopen(graf.in,r);
fscanf(f,"%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) c[i][j]=INF;
for(i=1;i<=n;i++) c[i][i]=0;
for(i=1;i<=m;i++)
{
fscanf(f,"%d %d %d",&x,&y,&z);
c[x][y]=c[y][x]=z;
}
fclose(f);
}
void creare_apm(int c[N][N],int n)
{
int V[N],T[N],Q[N],i,j,min,w,ct=0; //costul total al arborelui
for(i=1;i<=n;i++) V[i]=i; //varfurile neincluse in arbore
V[1]=0;
for(j=2;j<=n;j++)
{
T[j]=1; Q[j]=c[1][j];
}
printf("\n\nAPM: ");
while(1)
{
min=INF; //determinam muchia de cost minim
for(i=2;i<=n;i++)
if(V[i] && Q[i]<min)
{
min=Q[i]; w=i;
}
if(min==INF) break;
V[w]=0; //varful w a fost inclus in arbore
printf("[%d,%d] ",T[w],w); //muchia adaugata
ct+=c[T[w]][w]; //actualizam costul arborelui
for(j=2;j<=n;j++)
if(V[j] && Q[j]>c[w][j])
{
Informatic clasa a XI-a Teorie

12
T[j]=w; Q[j]=c[w][j];
}
}
printf("\ncostul total este %d\n",ct);
}
void main()
{
int c[N][N],n;
citire_graf(c,n); creare_apm(c,n);
}


3. Drumuri minime n grafuri orientate. Algoritmul lui Dijkstra


Fie G=(X,U) i l:UR
+
. Se pune problema determinrii unor drumuri de lungime minim n acest graf.
Rezolvarea ei are multiple aplicaii practice. Considernd drept noduri diferite puncte dintr-un ora, dac
ponderea l(u), unde u=(x
i
,x
j
), reprezint durata de trecere de la x
i
la x
j
, problema revine la determinarea
drumurilor de durat minim; dac l(u) reprezint costul transportului de la x
i
la x
j
, problema revine la
determinarea drumurilor avnd costul de transport minim etc.
Pentru tratarea problemelor de minim vom asocia grafului G matricea costurilor n forma a), adic
C=(c
ij
)
nxn
definit astfel:
l(x
i
,x
j
) dac (x
i
,x
j
)eU

c
ij
= 0 dac i=j

+ dac (x
i
,x
j
)eU


Problem: Fiind dat un graf orientat G=(X,U), o funcie l:UR
+
i un nod x
0
, s se determine pentru
toate vrfurile x
i
pentru care exist drum de la x
0
la x
i
, lungimea celui mai scurt drum i unul dintre drumurile
minime de la x
0
la x
i
.
Algoritmul utilizreaz metoda Greedy genernd
drumurile minime n ordinea cresctoare a lungimilor.

Exemplu: Pentru graful din figura alturat,
considernd nodul de plecare 1, se vor obine n ordine:
D
1
=(1,2) de lungime 1
D
2
=(1,2,5) de lungime 2
D
3
=(1,2,5,3) de lungime 4
D
4
=(1,2,5,3,4) de lungime 5
De la 1 la 6 nu exist drum.




Se pornete din x
0
. Evident cel mai scurt drum
de la x
0
la unul din celelalte vrfuri ale grafului este dat de arcul (x
0
,x
j
) de lungime minim. Urmtorul drum n
ordinea lungimilor va fi dat fie de un alt arc cu extremitatea iniial x
0
, fie de un drum (x
0
,x
j
,x
p
). Alegem n
continuare drumuri n ordinea cresctoare a lungimilor, pn cnd am determinat drumuri minime de la x
0
ctre
toate vrfurile pentru care exist drum pornind din x
0
. Pentru aceasta se consider S mulimea vrfurilor x
j
eX
pentru care am gsit drum minim de la x
0
la x
j
. Iniial S={x
0
}. La fiecare pas, adgm n S acel nod x
k
eX-S cu
proprietatea c drumul minim de la x
0
la x
k
are cel mai mic cost dintre toate drumurile de la x
0
la x
p
, cu x
p
eX-S.
Pentru exemplul considerat S va avea pe rnd urmtorul coninut:
S={1}
S={1,2}
S={1,2,5}
S={1,2,5,3}
S={1,2,5,3,4}

2 7 3


1 1 2 1


1 3 5
4



1 3


6

Informatic clasa a XI-a Teorie

13
Se observ c drumul de la x
0
la x
k
(nodul ce urmeaz s-l adugm n S la un moment dat) trece numai prin
vrfuri din S (cu excepia lui x
k
). Pentru a alege nodul x
k
eX-S ce urmeaz a fi adgat n S vom folosi un vector
D=(d
1
,d
2
,...,d
n
) astfel nct:

lungimea drumului minim de la x
0
la x
i
, dac x
i
eS
d
i
=
lungimea drumului minim de la x
0
la x
i
ce folosete numai vrfuri din
S, dac x
i
eS

Iniial d
i
=C(x
0
,i), ()i=1..n, adic este linia x
0
din matricea costurilor. La un moment dat, adgm n S
nodul x
k
cu proprietatea c d
k
=min{d
j
| x
j
eX-S}. Dup adgarea lui x
k
n S trebuie actualizate valorile lui d
pentru elementele care nu sunt n S, deoarece este posibil ca drumul minim de la x
0
la unul dintre aceste noduri
(folosind noduri din S) s foloseasc nodul x
k
pe care tocmai l-am adgat. Drumul minim de la x
0
la x
j
ce
folosete noduri din S (inclusiv x
k
) va fi de forma (x
0
,,x
k
,x
j
). Deci pentru x
j
eX-S, d
j
se modific dup
adugarea lui x
k
la S numai dac d
k
+C(k,j)<d
j
, caz n care d
j
d
k
+C(k,j). n final, vectorul d va conine
costurile (lungimile) drumurilor minime de la x
0
la celelalte noduri; dac pentru un nod x
j
nu exist drum de la
x
0
la x
j
, atunci d
j
=.
Pentru a reine i drumurile minime (nu numai lungimile lor) vom considera un vector numit T (tat) care
reine indicele precedentului fiecrui nod n drumul minim de la x
0
la acel nod.
Iniial:
0 dac i=x
0
sau C(x
0
,i)=
T
i
=
x
0
dac C(x
0
,i)= i i=x
0

La fiecare actualizare de forma d
j
d
k
+C(k,j) vom avea i o actualizare a vectorului T de forma T
j
k.
Algoritmul se ncheie cnd S conine toate nodurile x
j
pentru care exist drum de la x
0
la x
j
, deci fie cnd S=X
(dac exist drumuri de la x
0
la toate celelalte noduri), fie cnd mulimea X-S cuprinde numai noduri pentru
care nu exist drumuri pornind din x
0
la ele (caz n care min{d
j
| x
j
eX-S}=). Pentru reprezentarea
mulimii S se poate folosi vectorul caracteristic S cu n componente definit astfel:

0 dac x
i
eS
S
i
=
1 dac x
i
eS

Exemplu: Considerm graful anterior i punctul x
0
=1. Cei trei vectori au valorile iniiale:
D=(0, 1, , , 3, )
T=(0, 1, 0, 0, 1, 0)
S=(1, 0, 0, 0, 0, 0)

1) determinm min(D[i] | S[i]=0) => min=1,k=2 => S[2]1
Actualizm distanele la nodurile neselectate nc.
S[3]=0; D[3]= > D[2]+C[2,3]=1+7=8 => D[3]8, T[3]2
S[4]=0; D[4]= D[2]+C[2,4]=1+ , nu se poate actualiza
S[5]=0; D[5]=3 > D[2]+C[2,5]=1+1=2 => D[5]2, T[5]2
S[6]= ; D[6]= D[2]+C[2,6]=1+ , nu se poate actualiza
Dup primul pas configuraia celor trei vectori este:
D=(0, 1, 8, , 2, )
T=(0, 1, 2, 0, 2, 0)
S=(1, 1, 0, 0, 0, 0)

2) determinm min(D[i] | S[i]=0) => min=2, k=5 => S[5]1
Actualizm distanele la nodurile neselectate nc.
S[3]=0; D[3]=8 > D[5]+C[5,3]=2+2=4 => D[3]4, T[3]5
S[4]=0; D[4]= D[5]+C[5,4]=2+, nu se poate actualiza
S[6]=0; D[6]= D[5]+C[5,6]=2+, nu se poate actualiza
Dup al doilea pas configuraia celor trei vectori este:
D=(0, 1, 4, , 2, )
T=(0, 1, 5, 0, 2, 0)
S=(1, 1, 0, 0, 1, 0)

3) determinm min(D[i] | S[i]=0) => min=4, k=3 => S[3]1
Informatic clasa a XI-a Teorie

14
Actualizm distanele la nodurile neselectate nc.
S[4]=0; D[4]= > D[3]+C[3,4]=4+1=5 => D[4]5, T[4]3
S[6]=0; D[6]= D[3]+C[3,6]=4+, nu se poate actualiza
Dup al treilea pas configuraia celor trei vectori este:
D=(0, 1, 4, 5, 2, )
T=(0, 1, 5, 3, 2, 0)
S=(1, 1, 1, 0, 1, 0)

4) determinm min(D[i] | S[i]=0) => min=5, k=4 => S[4]1
Actualizm distanele la nodurile neselectate nc.
S[6]=0; D[6]= D[4]+C[4,6]=5+, nu se poate actualiza
Dup al patrulea pas configuraia celor trei vectori este:
D=(0, 1, 4, 5, 2, )
T=(0, 1, 5, 3, 2, 0)
S=(1, 1, 1, 1, 1, 0)

5) determinm min(D[i] | S[i]=0) => min= i algoritmul se ncheie pentru c nu exist nici-un
drum de la nodul 1 la nodul 6

Programul care implementeaz algoritmul lui Dijkstra este urmtorul:

#include<stdio.h>
#define N 20
#define INF 1<<14
void citire(int c[N][N],int &n,int &xp)
{
int i,j,x,y,z; FILE *f=fopen(graf.txt,r);
fscanf(f,"%d %d",&n,&xp); //numarul de noduri si nodul de plecare
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
c[i][j]=INF;
for(i=1;i<=n;i++) c[i][i]=0;
while(!feof(f))
{
fscanf("%d %d %d",&x,&y,&z); //arcul si costul sau
c[x][y]=z;
}
fclose(f);
}
void minim(int S[N],int D[N],int n,int &q)
{
int i; long m;
m=2*INF;
for(i=1;i<=n;i++)
if(!S[i]&&D[i]<m)
{
m=D[i]; q=i;
}
}
void determinare_drumuri(int c[N][N],int D[N],int T[N],int n)
{
int S[N],i,x,j,k,ok;
//initializari
for(i=1;i<=n;i++)
{
D[i]=c[xp][i]; S[i]=0;
if(c[xp][i]<INF) T[i]=xp;
else T[i]=0;
}
S[xp]=1; T[xp]=0; ok=1; x=0;
do{
minim(S,T,n,k); //determina nodul k aflat la distanta minima
x++;
if(D[k]==INF||x==n)
Informatic clasa a XI-a Teorie

15
ok=0; //nu mai pot fi construite drumuri minime
else
{
//actualizam vectorii S,T si D
S[k]=1;
for(j=1;j<=n;j++)
if(!S[j]&&D[j]>D[k]+c[k][j])
{
D[j]=D[k]+c[k][j];
T[j]=k;
}
}
}while(ok);
}
void drum(int D[N],int T[N],int i)
{
if(i)
{
drum(D,T,T[i]);
printf("%d ",i);
}
}
void afisare_drumuri(int D[N],int T[N],int n)
{
int i;
for(i=1;i<=n;i++)
if(i!=xp)
if(D[i]==INF)
printf("\nNu exista drum de la %d la %d\n",xp,i);
else
{
printf("\nDrumul minim de la %d la %d: ",xp,i);
drum(D,T,i); printf("\n");
printf("\tLungimea drumului este %d\n",D[i]);
}
}
void main()
{
int c[N][N],D[N],T[N],n,xp;
citire(c,n,xp); determinare_drumuri(c,D,T,n);
afisare_drumuri(D,T,n);
}

Datorit selectrii minimelor, complexitatea algoritmului este O(n
2
).


4. Ciclul hamiltonian de cost minim (problema comis-voiajorului)


Fie G=(X,U) un graf neorientat complet ponderat. S se determine un ciclu hamiltonian care s aib costul
total minim.

Pentru aceast problem se cunosc algoritmi care necesit un timp exponenial (exemplu metoda
backtracking). Din acest motiv se renun la condiia de optimalitate i se caut un ciclu care s treac prin
toate oraele cu un cost pe ct posibil mai mic.

Paii algoritmului:
1. Se citete matricea costurilor A i nodul de pornire v
1

2. Dac v
1
,v
2
,........,v
k
este un lan deja ales, dup caz se procedeaz astfel:
a) dac k=n se alege muchia (v
k
,v
1
)
b) dac kn, se alege muchia de cost minim care are o extremitate n v
k
iar cealalt extremitate
n mulimea nodurilor neselectate nc
Informatic clasa a XI-a Teorie

16
Odat cu selectarea unei muchii se selecteaz un nou nod i nu se revine asupra acestei alegeri. Din acest
motiv algoritmul se ncadreaz n strategia Greedy.

Exemplu: Fie graful de mai jos i nodul de plecare v=1.





Conform algoritmului descris anterior se vor alege
pe rnd urmtoarele muchii:
(1,2), (2,3), (3,5), (5,4), (4,1)
i se obine un ciclu hamiltonian de cost total 18.
Se observ c acesta nu este ciclul de cost minim



Concluzie: Metoda Greedy nu furnizeaz soluia
optim pentru orice tip de problem. Dac se
renun la criteriul de optimalitate se obine o soluie
apropiat de soluia optim. n funcie de problem
se decide dac aceasta este acceptabil sau se
folosete un algoritm exponenial.

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