Sunteți pe pagina 1din 13

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Specialitatea: Tehnologii Informaionale

RAPORT
Lucrare de laborator Nr.3
Analiza i proiectarea algoritmilor

A efectuat:

st. gr. TI-141


Braga Eugen

A verificat:

lect. Sup.
Bagrin Veronica

Chiinu 2015

Scopul lucrrii:
1. Studierea tehnicii greedy.
2. Analiza i implementarea algoritmilor greedy
Sarcina lucrrii

de studiat tehnica greedy de proiectare a algoritmilor;


de implementat ntr-un limbaj de programare algoritmii Kruskal, Prim i Dijkstra;
de fcut analiza empiric a algoritmilor Kruskal i Prim;
de alctuit un raport.

Indicaii teoretice
Tehnica greedy
Algoritmii greedy (greedy = lacom) sunt n general simpli i sunt folosii la probleme de
optimizare, cum ar fi: s se gseasc cea mai bun ordine de executare a unor lucrri pe calculator, s se
gseasc cel mai scurt drum ntr-un graf etc. n cele mai multe situaii de acest fel avem:
o mulime de candidai (lucrri de executat, vrfuri ale grafului etc);
o funcie care verific dac o anumit mulime de candidai constituie o soluie posibil, nu
neaprat optim, a problemei;
o funcie care verific dac o mulime de candidai este fezabil, adic dac este posibil s
completm aceast mulime astfel nct s obinem o soluie posibil, nu neaprat optim, a problemei;
o funcie de selecie care indic la orice moment care este cel mai promitor dintre candidaii
nc nefolosii;
o funcie obiectiv care d valoarea unei soluii (timpul necesar executrii tuturor lucrrilor ntr-o
anumit ordine, lungimea drumului pe care l-am gsit etc); aceasta este funcia pe care urmrim s o
optimizm (minimizm/maximizm).
Pentru a rezolva problema de optimizare, se caut o soluie posibil care s optimizeze valoarea
funciei obiectiv. Un algoritm greedy construiete soluia pas cu pas. Iniial, mulimea candidailor
selectai este vid. La fiecare pas, se adaug acestei mulimi cel mai promitor candidat, conform
funciei de selecie. Dac, dup o astfel de adugare, mulimea de candidai selectai nu mai este fezabil,
se elimin ultimul candidat adugat; acesta nu va mai fi niciodat considerat. Dac, dup adugare,
mulimea de candidai selectai este fezabil, ultimul candidat adugat va rmne de acum ncolo n ea. De
fiecare dat cnd se lrgete mulimea candidailor selectai, se verific dac aceast mulime nu
constituie o soluie posibil a problemei. Dac algoritmul greedy funcioneaz corect, prima soluie gsit
va fi totodat o soluie optim a problemei. Soluia optim nu este n mod necesar unic: se poate c
funcia obiectiv s aib aceeai valoare optim pentru mai multe soluii posibile. Funcia de selecie este
de obicei derivat din funcia obiectiv; uneori aceste dou funcii sunt chiar identice.
Algoritmul lui Kruskal
Arborele parial de cost minim poate fi construit muchie, cu muchie, dup urmtoarea metoda a lui
Kruskal (1956): se alege nti muchia de cost minim, iar apoi se adaug repetat muchia de cost minim
nealeas anterior i care nu formeaz cu precedentele un ciclu. Alegem astfel #V1 muchii. Este uor de
dedus c obinem n final un arbore. Este nsa acesta chiar arborele parial de cost minim cutat?
Proprietatea 1. n algoritmul lui Kruskal, la fiecare pas, graful parial <V, A> formeaz o pdure de
componente conexe, n care fiecare component conex este la rndul ei un arbore parial de cost minim
pentru vrfurile pe care le conecteaz. n final, se obine arborele parial de cost minim al grafului G.
Pentru a implementa algoritmul, trebuie s putem manipula submulimile formate din vrfurile
componentelor conexe. Folosim pentru aceasta o structura de mulimi disjuncte i procedurile de tip find i
merge (Seciunea 3.5). n acest caz, este preferabil s reprezentm graful c o lista de muchii cu costul
asociat lor, astfel nct s putem ordona aceast list n funcie de cost. Iat algoritmul:

function Kruskal(G = <V, M>)


{iniializare}
sorteaz M cresctor n funcie de cost
n #V
A {va conine muchiile arborelui parial de cost minim}
iniializeaz n mulimi disjuncte coninnd fiecare cate un element din V
{bucla greedy}
repeat
{u, v} muchia de cost minim care nc nu a fost considerat
ucomp find(u)
vcomp find(v)
if ucomp vcomp then merge(ucomp, vcomp)
A A {{u, v}}
until #A = n-1
return A
Pentru un graf cu n vrfuri i m muchii, presupunnd c se folosesc procedurile find3 i merge3,
numrul de operaii pentru cazul cel mai nefavorabil este n:
O(m log m) pentru a sorta muchiile. Deoarece m n(n1)/2, rezulta O(m log m) O(m log n). Mai mult,
graful fiind conex, din n1 m rezulta i O(m log n) O(m log m), deci O(m log m) = O(m log n).
O(n) pentru a iniializa cele n mulimi disjuncte.
Cele cel mult 2m operaii find3 i n1 operaii merge3 necesita un timp n O((2mn1) lg* n). Deoarece
O(lg* n) O(log n) i n1 m, acest timp este i n O(m log n).
O(m) pentru restul operaiilor.
Deci, pentru cazul cel mai nefavorabil, algoritmul lui Kruskal necesit un timp n O(m log n).
O alt variant este s pstram muchiile ntr-un min-heap. Obinem astfel un nou algoritm, n care
iniializarea se face ntr-un timp n O(m), iar fiecare din cele n1 extrageri ale unei muchii minime se face
ntr-un timp n O(log m) = O(log n). Pentru cazul cel mai nefavorabil, ordinul timpului rmne acelai cu
cel al vechiului algoritm. Avantajul folosirii min-heap-ului apare atunci cnd arborele parial de cost
minim este gsit destul de repede i un numr considerabil de muchii rmn netestate. n astfel de situaii,
algoritmul vechi pierde timp, sortnd n mod inutil i aceste muchii.
Algoritmul lui Prim
Cel de-al doilea algoritm greedy pentru determinarea arborelui parial de cost minim al unui graf se
datoreaz lui Prim (1957). n acest algoritm, la fiecare pas, mulimea A de muchii alese mpreun cu
mulimea U a vrfurilor pe care le conecteaz formeaz un arbore parial de cost minim pentru subgraful
<U, A> al lui G. Iniial, mulimea U a vrfurilor acestui arbore conine un singur vrf oarecare din V, care
va fi rdcina, iar mulimea A a muchiilor este vid. La fiecare pas, se alege o muchie de cost minim, care
se adaug la arborele precedent, dnd natere unui nou arbore parial de cost minim. Arborele parial de
cost minim creste natural, cu cate o ramur, pn cnd va atinge toate vrfurile din V, adic pn cnd
U = V.
Proprietatea 2. n algoritmul lui Prim, la fiecare pas, <U, A> formeaz un arbore parial de cost
minim pentru subgraful <U, A> al lui G. n final, se obine arborele parial de cost minim al grafului G.
Presupunem c vrfurile din V sunt numerotate de la 1 la n, V = {1, 2, ..., n}, matricea simetric C d
costul fiecrei muchii, cu C[i, j] = , dac muchia {i, j} nu exist. Folosim dou tablouri paralele. Pentru
fiecare i V \ U, vecin[i] conine vrful din U, care este conectat la i printr-o muchie de cost minim,
mincost[i] d acest cost. Pentru i U, punem mincost[i] = 1. Mulimea U, n mod arbitrar iniializat cu
{1}, nu este reprezentat explicit. Elementele vecin[1] i mincost[1] nu se folosesc.

function Prim(C[1 .. n, 1 .. n])


{iniializare, numai vrful 1 este n U}
A
for i 2 to n do vecin[i] 1
mincost[i] C[i, 1]
{bucla greedy}
repeat n1 times
min +
for j 2 to n do
if 0 < mincost[ j] < min then min mincost[ j]
kj
A A {{k, vecin[k]}}
mincost[k] 1 {adaug vrful k la U}
for j 2 to n do
if C[k, j] < mincost[ j] then mincost[ j] C[k, j]
vecin[ j] k
return A
Bucla principal se execut de n1 ori i, la fiecare iteraie, buclele for din interior necesit un timp
n O(n). Deci, algoritmul Prim necesit un timp n O(n2). Am vzut c timpul pentru algoritmul lui
Kruskal este n O(m log n), unde m = #M. Pentru un graf dens se deduce c m se apropie de n(n1)/2. n
acest caz, algoritmul Kruskal necesit un timp n O(n2 log n) i algoritmul Prim este probabil mai bun.
Pentru un graf rar m se apropie de n i algoritmul Kruskal necesit un timp n O(n log n), fiind probabil
mai eficient dect algoritmul Prim.
Cele mai scurte drumuri care pleac din acelai punct
Fie G = <V, M> un graf orientat, unde V este mulimea vrfurilor i M este mulimea muchiilor. Fiecare muchie are o
lungime nenegativa. Unul din vrfuri este ales c vrf surs. Problema este de a determina lungimea celui mai scurt drum de la
surs ctre fiecare vrf din graf.
Se va folosi un algoritm greedy, datorat lui Dijkstra (1959). Notm cu C mulimea vrfurilor disponibile (candidaii) i
cu S mulimea vrfurilor deja selectate. n fiecare moment, S conine acele vrfuri a cror distan minim de la surs este deja
cunoscut, n timp ce mulimea C conine toate celelalte vrfuri. La nceput, S conine doar vrful surs, iar n final S conine
toate vrfurile grafului. La fiecare pas, adugam n S acel vrf din C a crui distan de la surs este cea mai mic.
Se spune, c un drum de la surs ctre un alt vrf este special, dac toate vrfurile intermediare de-a lungul drumului
aparin lui S. Algoritmul lui Dijkstra lucreaz n felul urmtor. La fiecare pas al algoritmului, un tablou D conine lungimea
celui mai scurt drum special ctre fiecare vrf al grafului. Dup ce se adaug un nou vrf v la S, cel mai scurt drum special ctre
v va fi, de asemenea, cel mai scurt dintre toate drumurile ctre v. Cnd algoritmul se termin, toate vrfurile din graf sunt n S,
deci toate drumurile de la surs ctre celelalte vrfuri sunt speciale i valorile din D reprezint soluia problemei.
Presupunem c vrfurile sunt numerotate, V = {1, 2, ..., n}, vrful 1 fiind sursa, i c matricea L d lungimea fiecrei
muchii, cu L[i, j] = , dac muchia (i, j) nu exist. Soluia se va construi n tabloul D[2 .. n]. Algoritmul este:
function Dijkstra(L[1 .. n, 1 .. n])
{iniializare}
C {2, 3, ..., n}
{S = V \C exist doar implicit}
for i 2 to n do D[i] L[1, i]
{bucla greedy}
repeat n2 times
v vrful din C care minimizeaz D[v]
C C \ {v}
{si, implicit, S S {v}}
for fiecare w C do
D[w] min(D[w], D[v]+L[v, w])
return D

Listingul programului pentru algoritmul lui Prim i al lui Kruskal


#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<conio.h>
#include<time.h>
#include<Windows.h>
using namespace std;
typedef unsigned int uint;
const int INFINIT=100000000;
class Muchie {
public:
uint u,v;
int cost;
Muchie(uint u=1,uint v=2,int cost=0) : u(u),v(v),cost(cost) {}
bool operator < (const Muchie &M) const { return cost<M.cost; }
friend istream &operator >> (istream &in,Muchie &M) { return in>>M.u>>M.v>>M.cost; }
friend ostream &operator << (ostream &out,Muchie &M) { return
out<<"("<<M.u<<","<<M.v<<",cost="<<M.cost<<")"; }
};
uint n,m;
vector<Muchie> muchie;
vector<vector<pair<uint,int>>> listaVecini;
vector<Muchie> A;
int costMin;
DWORD startTime,endTime;
void creareListe() {
uint u,v;
int cost;
listaVecini.resize(n+1);
for(uint i=0;i<m;i++) {
u=muchie[i].u;
v=muchie[i].v;
cost=muchie[i].cost;
listaVecini[u].push_back(make_pair(v,cost));
listaVecini[v].push_back(make_pair(u,cost));
}
}
bool genereazaGraf(uint noduri,uint muchii,char *numeFisier="apm.in") {
vector<uint> adaugate,neadaugate,parinte,ult;
int p,f;
n=noduri;
m=min(max(muchii,n-1),n*(n-1)/2);
parinte.resize(n+1);
for(uint i=1;i<=n;i++)
neadaugate.push_back(i);
srand((uint)time(NULL));
for(uint i=0;i<5*n;i++) {
p=rand()%n;
f=rand()%n;
swap(neadaugate[p],neadaugate[f]);
}
muchie.clear();
adaugate.push_back(neadaugate.back());
neadaugate.pop_back();
parinte[adaugate[0]]=0;
while(neadaugate.size()>0) {
p=adaugate[rand()%adaugate.size()];

adaugate.push_back(f=neadaugate.back());
neadaugate.pop_back();
parinte[f]=p;
muchie.push_back(Muchie(p,f,rand()%101-50));
}
ult.resize(n+1);
for(uint i=1;i<=n;i++)
ult[i]=i+1;
for(uint i=1;i<=m-(n-1);i++) {
p=rand()%adaugate.size();
while(ult[adaugate[p]]<=n && (ult[adaugate[p]]==parinte[adaugate[p]] ||
parinte[ult[adaugate[p]]]==adaugate[p]))
++ult[adaugate[p]];
if(ult[adaugate[p]]>n) {
swap(adaugate[p],adaugate[adaugate.size()-1]);
adaugate.pop_back();
--i;
}
else {
muchie.push_back(Muchie(adaugate[p],ult[adaugate[p]],rand()%101-50));
++ult[adaugate[p]];
}
}
ofstream fo(numeFisier);
if(fo.is_open()) {
fo<<n<<' '<<m<<endl;
for(uint i=0;i<muchie.size();i++)
fo<<muchie[i].u<<' '<<muchie[i].v<<' '<<muchie[i].cost<<endl;
fo.close();
creareListe();
return true;
}
cout<<"Eroare la deschiderea fisierului \""<<numeFisier<<"\" !!!"<<endl;
return false;
}
bool citeste(char *numeFisier="apm.in") {
ifstream fi(numeFisier);
Muchie M;
if(fi.is_open()) {
fi>>n>>m;
for(uint i=0;i<m;++i) {
fi>>M;
muchie.push_back(M);
}
fi.close();
creareListe();
return true;
}
cout<<"Eroare la deschiderea fisierului \""<<numeFisier<<"\" !!!"<<endl;
return false;
}
void scrie(char *numeFisier) {
ofstream fo(numeFisier);
if(fo.is_open()) {
if(A.size()==n-1) {
fo<<"Costul arborelui partial de cost minim este: "<<costMin<<endl;
fo<<"Muchiile arborelui sunt:"<<endl;
for(uint i=0;i<A.size();i++)
fo<<A[i]<<endl;
}
else
fo<<"Graful nu este conex!"<<endl;
fo.close();
}
else
cout<<"Eroare la deschiderea fisierului \""<<numeFisier<<"\" !!!"<<endl;

}
vector<uint> celMaiApropiatVecin,nodNeadaugat,pozitieInHeap;
vector<int> costVecin;
void upHeap(int k) {
int k2,p,f;
while(k>0) {
k2=(k+1)/2-1;
f=nodNeadaugat[k];
p=nodNeadaugat[k2];
if(costVecin[f]<costVecin[p]) {
swap(nodNeadaugat[k],nodNeadaugat[k2]);
swap(pozitieInHeap[f],pozitieInHeap[p]);
k=k2;
}
else break;
}
}
void downHeap(int k) {
uint k1,k2,kmin,p,f;
while((k1=2*k+1)<nodNeadaugat.size()) {
k2=k1+1;
kmin=k;
if(costVecin[nodNeadaugat[k1]]<costVecin[nodNeadaugat[kmin]]) kmin=k1;
if(k2<nodNeadaugat.size())
if(costVecin[nodNeadaugat[k2]]<costVecin[nodNeadaugat[kmin]]) kmin=k2;
if(kmin!=k) {
p=nodNeadaugat[k];
f=nodNeadaugat[kmin];
swap(nodNeadaugat[k],nodNeadaugat[kmin]);
swap(pozitieInHeap[p],pozitieInHeap[f]);
k=kmin;
}
else break;
}
}
int celMaiApropiatNod() {
uint ultimulDinHeap,rez=nodNeadaugat.front();
pozitieInHeap[rez]=INFINIT;
ultimulDinHeap=nodNeadaugat.back();
nodNeadaugat.pop_back();
if(nodNeadaugat.size()>0) {
nodNeadaugat[0]=ultimulDinHeap;
pozitieInHeap[ultimulDinHeap]=0;
downHeap(0);
}
return rez;
}
void actualizareCeiMaiApropiatiVecini(int nod) {
uint poz,nodVecin;
int costVec;
for(uint i=0;i<listaVecini[nod].size();i++) {
nodVecin=listaVecini[nod][i].first;
poz=pozitieInHeap[nodVecin];
costVec=listaVecini[nod][i].second;
if(poz!=INFINIT)
if(costVec<costVecin[nodVecin]) {
costVecin[nodVecin]=costVec;
celMaiApropiatVecin[nodVecin]=nod;
upHeap(poz);
}
}
}

void Prim() {
uint nodAles;
celMaiApropiatVecin.resize(n+1);
costVecin.resize(n+1);
pozitieInHeap.resize(n+1);
startTime=GetTickCount();
nodNeadaugat.clear();
for(uint i=2;i<=n;i++) {
nodNeadaugat.push_back(i);
pozitieInHeap[i]=i-2;
celMaiApropiatVecin[i]=0;
costVecin[i]=INFINIT;
}
pozitieInHeap[1]=INFINIT;
A.clear();
costMin=0;
actualizareCeiMaiApropiatiVecini(1);
while(nodNeadaugat.size()>0) {
actualizareCeiMaiApropiatiVecini(nodAles=celMaiApropiatNod());
if(costVecin[nodAles]==INFINIT) break;
A.push_back(Muchie(celMaiApropiatVecin[nodAles],nodAles,costVecin[nodAles]));
costMin+=costVecin[nodAles];
}
scrie("prim.out");
}
vector<int> nrComp;
int nrComponenta(uint x) {
if(nrComp[x]==x) return x;
return nrComp[x]=nrComponenta(nrComp[x]);
}
void reuneste(uint u,uint v) {
nrComp[nrComponenta(u)]=nrComponenta(v);
}
void Kruskal() {
Muchie M;
A.clear();
costMin=0;
nrComp.resize(n+1);
for(uint i=1;i<=n;++i)
nrComp[i]=i;
sort(muchie.begin(),muchie.end());
for(uint i=0;i<muchie.size();i++) {
M=muchie[i];
if(nrComponenta(M.u)!=nrComponenta(M.v)) {
A.push_back(M);
costMin+=M.cost;
reuneste(M.u,M.v);
}
}
scrie("kruskal.out");
}
int main() {
cout<<"Introduceti numarul de noduri: ";
cin>>n;
cout<<"Introduceti numarul de muchii: ";
cin>>m;
cout<<"Se genereaza graful... ";
startTime=GetTickCount();
if(genereazaGraf(n,m)) {
endTime=GetTickCount();
cout<<endTime-startTime<<" ms"<<endl;
startTime=GetTickCount();

Prim();
endTime=GetTickCount();
cout<<"Timpul executiei algoritmului Prim: "<<endTime-startTime<<" ms"<<endl;
startTime=GetTickCount();
Kruskal();
endTime=GetTickCount();
cout<<"Timpul executiei algoritmului Kruskal: "<<endTime-startTime<<" ms"<<endl;
}
_getch();
return 0;
}

Rezultatul:
Kruskal:
Introduceti numarul de virfuri : 7
introduceti numarul de arce : 6
introduceti arcul si costul acestuia
012
156
2 5 14
238
349
463
Nr de iteratii este:37
The time was: 0.000000
Nodurile cercetate sunt: 0 1 2 3 4 5 6
-------Arborele minimizat-----{0-> 1 cost 2}
{4-> 6 cost 3}
{1-> 5 cost 6}
{2-> 3 cost 8}
{3-> 4 cost 9}
{2-> 5 cost 14}
Lungimea minima este L=42

Prim
Introduceti numarul de virfuri : 7
Introduceti numarul de arce : 6
Introduceti arcul si costul acestuia
012
156
2 5 14
238
349
463
The time was: 0.000000
Nodurile cercetate sant: 0 1 2 3 4 5 6
---------Arborele minimizat-------{0->1 cost 2}
{1->5 cost 6}

{2->5 cost 14}


{2->3 cost 8}
{3->4 cost 9}
{4->6 cost 3}
Lungimea minima este L=42
nr.de iteratii este:85

Listingul programului pentru algoritmul lui Dijkstra


#include<iostream>
#include<fstream>
#include<vector>
#include<time.h>
#include<conio.h>
#include<Windows.h>
using namespace std;
const unsigned int INFINIT=100000000;
vector<vector<int>> L;
vector<int> d,T;
vector<unsigned int> heap;
unsigned int n,sursa;
DWORD startTime,endTime;
void generareGraf(unsigned int noduri,char *numeFisier="graf.in") {
L.clear();
n=noduri;
L.resize(n);
srand((unsigned int)time(NULL));
for(unsigned int i=0;i<n;i++)
for(unsigned int j=0;j<n;j++)
if(i==j) L[i].push_back(0);
else
if(rand()%5==0) L[i].push_back(INFINIT);
else L[i].push_back(1+rand()%100);
T.clear();
T.resize(n);
d.resize(n);
ofstream fo(numeFisier);
if(fo.is_open()) {
fo<<n<<endl;
for(unsigned int i=0;i<n;i++) {
for(unsigned int j=0;j<n;j++)
fo<<L[i][j]<<' ';
fo<<endl;
}
}
else
cout<<"Eroare la deschiderea fisierului \""<<numeFisier<<"\" !!!"<<endl;
}
void reconstructieDrum(ostream &file,int j) {
if(T[j]==INFINIT)
file<<"Nu exista drum.";
else
if(sursa==j) file<<j+1;
else {
reconstructieDrum(file,T[j]);
file<<" -> "<<j+1;
}
}

void scrie(char *numeFisier) {


ofstream fo(numeFisier);
if(fo.is_open())
for(unsigned int j=0;j<n;j++) {
fo<<sursa+1<<" -> ... -> "<<j+1<<" (Dmin=";
if(d[j]==INFINIT) fo<<"INFINIT): ";
else fo<<d[j]<<"): ";
reconstructieDrum(fo,j);
fo<<endl;
}
else
cout<<"Eroare la deschiderea fisierului \""<<numeFisier<<"\" !!!"<<endl;
}
void upheap(unsigned int k) {
unsigned int k2;
while(k>0) {
k2=(k+1)/2-1;
if(d[heap[k]]<d[heap[k2]]) {
swap(heap[k],heap[k2]);
k=k2;
}
else break;
}
}
void downheap(unsigned int k) {
unsigned int k1,k2,kmin;
while((k1=2*k+1)<heap.size()) {
k2=k1+1;
kmin=k;
if(d[heap[k1]]<d[heap[kmin]]) kmin=k1;
if(k2<heap.size())
if(d[heap[k2]]<d[heap[kmin]]) kmin=k2;
if(kmin!=k) {
swap(heap[k],heap[kmin]);
k=kmin;
}
else break;
}
}
unsigned int popheap() {
unsigned int rez=heap[0];
heap[0]=heap.back();
heap.pop_back();
if(heap.size()>0)
downheap(0);
return rez;
}
void Dijkstra(unsigned int sursa) {
unsigned int v,w;
heap.clear();
for(unsigned int i=0;i<n;i++) {
d[i]=L[sursa][i];
if(d[i]==INFINIT) T[i]=INFINIT;
else T[i]=sursa;
if(i!=sursa) {
heap.push_back(i);
upheap(heap.size()-1);
}
}
while(heap.size()>0) {
v=popheap();
for(unsigned int i=0;i<heap.size();i++) {
w=heap[i];
if(d[v]+L[v][w]<d[w]) {

d[w]=d[v]+L[v][w];
T[w]=v;
upheap(i);
}
}
}
scrie("dijkstra.out");
}
int main() {
cout<<"Introduceti numarul de noduri: ";
cin>>n;
cout<<"Introduceti nodul sursa: ";
cin>>sursa;
--sursa;
cout<<"Se genereaza graful... ";
startTime=GetTickCount();
generareGraf(n);
endTime=GetTickCount();
cout<<endTime-startTime<<" ms"<<endl;
cout<<"Se executa Dijkstra pentru nodul sursa "<<sursa+1<<"... ";
startTime=GetTickCount();
Dijkstra(sursa);
endTime=GetTickCount();
cout<<endTime-startTime<<" ms"<<endl;
_getch();
}

Rezultatul:
Dijkstra:
Introduceti numarul de virfuri : 5
Introduceti numarul de arce : 8
Introduceti nodurile si costul arcului dintre ele:
0 1 50
0 2 30
0 3 100
0 4 10
215
2 3 50
3 1 20
4 3 10
D=[ 35 30 20 10 ]The time was: 0.000000
nr.de iteratii este:32

Concluziile:
In urma efectuarii lucrarii de laborator 3 am facut cunostinta cu algoritmii greedy.Mai concret cu
algoritmii Kruskal,Prim si Dijkstra.Algoritmul Kruskal si Prim ne ofera posibilitatea sa construim arborele

de cost minim.Algoritmul Dijkstra ne ofera posibilitatea sa determinam drumurile minimale pina la fiecare
virf in parte.
Implementind si analizind algoritmul Kruskal si Prim, am ajuns la concluzia ca acesti algoritmi
sunt foarte rapizi si deci sunt algoritmi eficienti si foarte buni,p-ru rezolvarea problemei de construire a
arborelui de cost minim.Algoritmul Dijkstra de asemenea este un algoritm foarte eficient.Timpul de
executie necesar p-ru rezolvarea sarcinei este minimal.Initial am analizat un graf de complexitatea nu prea
inalta.Timpul de executie a fost foarte mic,si s-au utilizat 32 de iteratii.Apoi,am analizat un graf de o
complexitate mai sporita si am observat ca timpul de executie de asemenea este foarte mic.Astfel
algoritmul Dijkstra este foarte rapid si deci este un algoritm foarte bun,ce ne ofera posibilitatea sa
determinam drumurile minimale pina la fiecare virf in parte.

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