280 likes | 430 Views
Grafuri orientate. Elevi: Badea Constantin Cătălin Bădulescu Ştefan Leonard Milotin Gheorghe Cătălin Urs Daniela Vitejanu Vasile Mădălin. Algoritmul lui Dijkstra.
E N D
Grafuri orientate Elevi: Badea Constantin Cătălin Bădulescu Ştefan Leonard Milotin Gheorghe Cătălin Urs Daniela Vitejanu Vasile Mădălin AlgoritmulluiDijkstra
După câţivaani de la terminarealiceului, treifoşticolegi(Bogdan,Alin şi Adrian) se întâlnesc întâmplător pe stradă. Bucuroşi că s-auintâlnit, ei propun să meargă la un suc şi să povestească ce au mai făcut de când nu s-au mai văzut. Din vorbă in vorbă, Bogdan îi intreabă pe ceilalţi doi dacă au un loc de muncă. Alin îi spune că a lucrat timp de doi ani la o firmă care in urmă cu 2 luni dăduse faliment ,că era in şomaj, şi că plănuieşte sa plece in străinătate. Adrian, ii zice că a depus deja cateva CV-uri, dar nu a primit nici un răspuns şi era foarte dezamăgit. După câteva idei despre cum ar putea să câştige bani, mai in glumă, mai in serios, Adrian propune, dat fiind faptul că fiecare deţinea câte un autoturism, să realizeze o firmă de Taxi. Firma mergea bine, insă cei trei erau dezamăgiţi că nu reuşeau să aleagă mereu traseul cel mai scurt. Într-una din zile, Alin şi-a amintit că în timpul liceului la orele de informatică a aflat despre noţiunea de GRAF, pe care pentru a o înţelege, îşi imagina Graful ca fiind reţeaua de străzi a unui oraş, in care intersecţiile erau echivalentul nodurilor din graf, iar străzile echivalentul arcelor grafului. Plecând de la această idee, Alin a încercat să realizeze un program, in MinGW, care calculeazădrumurileminime de la un nod al unuigraf la cel care trebuia sa fienodulfinal din graf . După ce şi-a amintit toate acestea,Alin a intrat pe internet si a descoperit că există un algoritm care realizează ceea de ce el avea nevoie. Acel algoritm numindu-se AlgoritmulluiDijkstra .
Pentru a ştimultmai bine ce au de făcut cu acelalgortim, el a căutatşi catevadefiniţii generaledespregrafurile orientate, aşa ca el şi-a amintiturmatoarele : • ● Un graf orientat este o pereche ordonată de mulţimi, notată G=(X,U), unde • X={x|xX} estemulţimeanodurilor (vârfurilor) iar U={(x,y)| x,yX}, mulţimeaarcelor • ● Drum este o succesiune de noduri cu proprietatea că oricare două noduri consecutive sunt adiacente(arcelepastreazăaceeaşi orientare) • * drum simplu = drum în care fiecare arc apare o singură dată dar nodurile se pot repeta • * drum elementar = drum în care nodurilesuntdistincte • ● Un graf conex reprezintă un grafîn careoricare ar fi două noduri distincte, există lanţ(succesiune de noduri cu proprietatea că oricare două noduri consecutive din lanţ sunt adiacente) între ele. • ● Se numestegrafponderat ("weighted graph") un graf in cadrul căruiafiecărui arc îi esteasociată o valoare. Valoareaasociatăarcului are semnificaţia de "cost" a legaturiiîntrecele 2 nodurisau de "distanţa" intrenoduri. • ●Prinmodurile de reprezentare ale grafurilor orientate se numară : • * Matricea de adiacentă: este o matricepatratică cu n liniisi n coloane, in care elementele a[i,j] se definescastfel: a[i,j]=1 dacă existăarcul (i,j) în U, cu x diferit de y şi 0 daca nu existăarcul (i,j) in U. • * Matricea de incidenţă este o matrice cu n linii (numărul vârfurilor) şi m coloane (numărul arcelor), notate cu uj, în ordinea • în care aparînmulţimea L. Elementelesunt definite astfel : a i,j = 1, dacă [i,j] suntincluseîn U, sau a i,j =0, altfel • * Listamuchiilorunuigrafeste formată din m elemente care conţin , fiecare, cate o pereche de douanoduri , xi şi xj, care formeaza o muchie, adicăpentru care [xi, xj] aparţin lui U. • * Lista de adiacentăeste formată din listele Li care conţin toţi veciniiunui nod xi la care se poateajunge direct din nodul xi, adicătoatenodurilexjpentru care [xi, xj]aparţin lui U. • * Matriceacosturilor
Grafurilepe care poatelucraalgoritmulluiDijkstrasunt, în general, ponderatesi orientate . • Dacăgrafulesteneponderat (arcele nu au costuriasociate) atunci drum minim întredouănoduri se considerădrumulalcătuitdin număr minim de arce. • Pentru a găsidrumul minim de la un nod X la un nod Y se poateaplica o căutareprincuprinderepornind de la nodul X – prima apariţiea lui Y în coadaalgoritmului de căutareprincuprinderepresupuneexistenţa unui drum cu număr minim de arce de la X la Y, care poate fi reconstituit. • Pe un astfel de graf se poateaplicasialgoritmulluiDijkstra, dacă transformăm în prealabilgrafulîntr-unulponderat, asociindfiecăruiarc acelasicost. • Drumul de cost minim intredouănoduriobţinutîn urmaaplicăriialgoritmuluiluiDijkstravaaveaşi număr minim de arce din moment cetoatearcele au acelasicost. • AlgoritmulluiDijkstrafuncţionează atât pegrafuriconexe cât sipegrafurineconexe. • Dacă nu existănici un drum de la nodul de start la un alt nod al grafuluiatuncialgoritmulluiDijkstravaraportaexistenţa unui drum de lungimeinfinităîntreele – acestrezultatindică, de fapt, lipsaoricărui drum întreceledouănoduri.
Intrare: • Algoritmulporneştede la un graforientatşiponderat cu N noduri. • De asemenea, e nevoie de un nod de start aparţinândgrafului – acestaestenodul de la care se doreşteaflareadrumurilorminimepânăla celelaltenoduri din graf. • Iesire: • Rezultatulalgoritmului se prezintăsub forma unuitablou D cu N intrări, conţinânddistanţeleminime de la nodul de start la toatecelelaltenoduri din graf. • De asemenea, tot carezultat se poateobţinesiarboreledrumurilorminime(în cazulîn care ne intereseazănu numailungimileminime ale drumurilor, ci şi drumurilepropriu-zise) – acestaeste un arbore generalizat care se vaobţinesub forma unuitablou T cu N intrări(implementarea cu indicatorisprepărinte) • Fie X nodul de start – acesta se marchează ca vizitat • Ideea găsiriidrumului minim de la X la un un alt nod este căutareatreptată: se presupune cădrumul minim estealcătuitdintr-un singur arc (arcul direct între X sinodulţinta, care poatesa nu existe, costul său fiindinfinit in acestcaz), apoi se cautădrumurimaiscurtealcătuite din 2 arce, apoi din 3, etc. – un drum minim nu poateaveamaimult de N-1 arce, decialgoritmul are N-1 pasi (al N-lea este banal) • Dupăpasul k (1 ≤ k ≤ N-1), tabloul D va conţinelungimiledrumurilorminime de la nodul X la celelaltenoduri, toateacestedrumurifiindalcătuite din maxim k arce. • Astfel, D[Y] = L dupăpasul k înseamnă că de la X la Y există un drum minim de lungime L alcătuit din maxim k arce • Deci, dupăpasul k, au fost găsite numaidrumurileminimealcătuite din maxim k arce – abia la finalulalgoritmului (dupapasul N-1) drumurileminime obţinutesunt definitive, elefiinddrumuriminimealcătuite din maxim N-1 arce.
La începutulfiecăruipas k avem un set de k-1 nodurimarcate (in cadrulpasilorprecedenţi) – nodurilemarcatesuntcelepentru care se cunoastedrumul minim (initial, doarnodul de start estemarcatdeoarecedoarpentru el se cunoaştedrumul minim) • In cadrulpasului k trebuieexecutate 3 operatiuni: • Se găsesteacel nod Y nemarcat care are D[Y] minim (acestaestesinguruldintrenodurilenemarcatepentru care se poatespunesigurcă drumulminim are lungimea D[Y]) – pentrucelelaltenodurinemarcatevaloareacorespunzătoaredin tabloul D s-arputeasănu reprezintelungimeadrumului minim ci un drum minim intermediar (alcătuitdin maxim k-1 arce) care poate fi imbunătăţit in cadrulpaşilorviitoriaialgoritmului • Nodul Y se marcheazăca vizitat • Logicaesteurmătoarea: • D[Y] conţinelungimeadrumului minim de la nodul de start la nodul Y care trecenumaiprinnodurimarcate (Y fiind, la inceputulpasului k, nodulnemarcat care avea D[Y] minim) – acest drum estealcătuit din maxim k-1 arce – D[Y] fiind minim, ilmarcampe Y deoarece nu poateexista un drum maiscurt de la X la Y • D[Z] conţinelungimeaceluimaiscurt drum de la nodul de start la nodul Z alcătuit din maxim k-1 arce – acest drum trecedoarprinnodurimarcate, fără săţină cont că, întretimp, şi Y a fostmarcat. • S-arputeasaexiste un drum maiscurtdecât D[Z] de la nodul de start la Z alcătuit din maxim k arce care trecenumaiprinnodurimarcate, inclusivnodul Y – unicul drum cu aceastăproprietate care poatefimaiscurtdecât D[Z] estecel care include drumul minim până la Y siarcul direct intre Y si Z, decilungimeasaeste D[Y] + Arc(Y , Z)
EXEMPLU: • Fie graful din figura: Vrem săaflăm drumurileminime de la nodul A la nodul H. 3 D A 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1
- 7 1 3 3 4 5 ∞ A E A A C E F - B A C D E F G H • Algoritmultrebuiesăreturnezeurmatorulrezultat: D = • T = • Tabloul D are câteo intrarepentrufiecare nod al grafului, corespunzândlungimiidrumului minim de la nodul A pânăla respectivulnod. • Astfel, drumul minim de la A la A nu interesează(-), drumul minim de la A la F are lungimea 4, drumul minim de la A la H nu exista (∞), etc.
D: - 9 1 3 ∞ ∞ 9 ∞ 3 D T: A A A A A A A A A 9 5 1 A B C D E H F G 1 G 9 C 5 1 Nodurile marcate astfel sunt noduri vizitate in graf de algoritmul lui Dijkstra 2 H 2 F 4 B 4 E 1 • A estenodul de start – îl marcăm cavizitat • Fiindprimul pas, initializăm tablourile D si T astfel: • D[x] estelungimeaarcului direct de la A la nodul x pentrufiecare nod x. • T[x] estenodul de start (sauindicelenodului de start in T – dacăse doreşteun tablou de indicatorisprepărinteclasic).
D: - 9 1 3 ∞ ∞ 9 ∞ 3 D A A B C D E H F G 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1 Cu altecuvinte, presupunem cădrumurileminime de la nodul A la celelaltenoduri din grafsuntalcătuitedintr-un singur arc, adicăarcul direct de la A la fiecare din nodurile respective (simbolul ∞ semnificălipsaarcului) Astfel, drumurileminimegăsite dupăprimul pas suntceleîngrosatepefiguraanterioară Se alegenodul C şi se marchează, deoarecenodul C estenodulnemarcat care are intrarea in tabloul D minimă– drumul minim de la A la C are lungimea 1 (nu vomgăsialtulmaiscurtpânăla final).
Tabloul D este: • Pentrutoatenodurilenemarcatetrebuie săverificăm dacă nu există un drum maiscurt care treceprinnodul C • Exemplupentrunodul B: • D[B] = 9 estedrumulcelmaiscurt de la A la B pe care-l aveam. • D[C] + Arc(C , B) = 1 + ∞ = ∞ estedrumulalternativ care treceprinnodul C (nodul ales). • Acest al doilea drum estemai lung decât drumulpe care-l aveamdeci D[B] nu se modifică la acest pas. • Exemplupentrunodul E: • D[E] = ∞ estedrumulcelmaiscurt de la A la E pe care-l aveam. • D[C] + Arc(C , E) = 1 + 2 = 3 estedrumulalternativ care treceprinnodul C (nodul ales). • Deoarecenoul drum estemaiscurtdecât drumulpe care-l aveamrezultă că D[E] se modifică din ∞ in 3 şi T[E] se modifică in C (nodul ales). • Se observă cădrumulalternativtreceprinnodul C (nodul ales). • Drumul de la A la C de lungime D[C] fiind minim, dacăadaugăm arcul C->E obţinemobligatoriudrumul minim de la A la E care treceprin C. - 9 1 3 ∞ ∞ 9 ∞ E G A B C H D F
Procedând la felpentrutoatenodurilenemarcate, obţinemurmatorulrezultat: D: - 9 1 3 3 6 9 ∞ 3 D T: A A A A C C A A A 9 5 1 A B C D E H F G 1 G 9 C Din nodul C au fostdescoperiteaceste 2 drumurinoi (maiscurte) catre E si F 5 1 2 H 2 F 4 B E 4 1
Se alegenodul D şi se marchează, deoarecenodul D are intrareaîn tabloul D minimă (chiardacăegală cu intrareanodului E, alegereaestearbitrară) – drumul minim de la A la D are lungimea 3 (nu vom găsialtulmaiscurt până la final) D: - 9 1 3 3 6 9 ∞ 3 D B C D E H F G A 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1
Tabloul D este: • Pentrutoatenodurilenemarcatetrebuie săverificăm dacă nu există un drum maiscurt care treceprinnodul D • Exemplupentrunodul F: • D[F] = 6 estedrumulcelmaiscurt de la A la F pe care-l aveam. • D[D] + Arc(D , F) = 3 + ∞ = ∞ estedrumulalternativ care treceprinnodul D (nodul ales). • Acest al doilea drum estemai lung decât drumulpe care-l aveamdeci D[F] nu se modifică la acest pas. • Exemplupentrunodul G: • D[G] = 9 estedrumulcelmaiscurt de la A la G pe care-l aveam. • D[D] + Arc(D , G) = 3 + 5 = 8 estedrumulalternativ care treceprinnodul D (nodul ales). • Deoarecenoul drum estemaiscurtdecât drumulpe care-l aveamrezultă că D[G] se modifică din 9 în 8 şi T[G] se modificăîn D (nodul ales). • Se observă cădrumulalternativtreceprinnodul D (nodul ales). • Drumul de la A la D de lungime D[D] fiind minim, dacă adaugăm arcul D->G obţinemobligatoriudrumul minim de la A la G care treceprin D. - 9 1 3 3 6 9 ∞ A B C D E H F G
Procedând la felpentrutoatenodurilenemarcate, obţinemurmătorulrezultat: D: - 9 1 3 3 6 8 ∞ 3 D T: A A A A C C D A A 9 5 1 A B C D E H F G 1 G 9 C 5 1 Din nodul D a fost descoperit acest drum nou (mai scurt) catre G 2 H 2 F 4 B 4 E 1
Se alegenodul E şi se marchează, deoarecenodul E are intrareaîn tabloul D minimă – drumul minim de la A la E are lungimea 3 (nu vom găsialtulmaiscurt până la final) D: - 9 1 3 3 6 8 ∞ 3 D A B C D E H F G A 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1
- 9 1 3 3 6 8 ∞ A B C D E H F G • Tabloul D este: • Pentrutoatenodurilenemarcatetrebuiesăverificăm dacănu existăun drum maiscurt care treceprinnodulE. • Exemplupentrunodul G: • D[G] = 8 estedrumulcelmaiscurt de la A la G pe care-l aveam. • D[E] + Arc(E , G) = 3 + ∞ = ∞ estedrumulalternativ care treceprinnodul E (nodul ales). • Acest al doilea drum estemai lung decât drumulpe care-l aveamdeci D[G] nu se modificăla acestpas. • Exemplupentrunodul B: • D[B] = 9 estedrumulcelmaiscurt de la A la B pe care-l aveam. • D[E] + Arc(E , B) = 3 + 4 = 7 estedrumulalternativ care treceprinnodul E (nodul ales). • Deoarecenoul drum estemaiscurtdecât drumulpe care-l aveamrezultă că D[B] se modifică din 9 în 7 şi T[B] se modificăîn E (nodul ales). • Se observă cădrumulalternativtreceprinnodul E (nodul ales). • Drumul de la A la E de lungime D[E] fiind minim, dacăadaugăm arcul E->B obţinemobligatoriudrumul minim de la A la B care treceprin E.
Procedând la felpentrutoatenodurilenemarcate, obtinemurmatorulrezultat: D: - 7 1 3 3 4 8 ∞ 3 D T: A E A A C E D A A 9 5 1 A B C D E H F G 1 G 9 C 5 1 Din nodul E au fostdescoperiteaceste 2 drumurinoi (maiscurte) catre B si F 2 H 2 F 4 B 4 E 1
Se alegenodul F şi se marchează, deoarecenodul F are intrareaîn tabloul D minimă – drumul minim de la A la F are lungimea 4 (nu vom găsialtulmaiscurt până la final). D: - 7 1 3 3 4 8 ∞ 3 D A B C D E H F G A 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1
Tabloul D este: • Pentrutoatenodurilenemarcatetrebuie săverificăm dacă nu există un drum maiscurt care treceprinnodul F. • Exemplupentrunodul B: • D[B] = 7 estedrumulcelmaiscurt de la A la B pe care-l aveam. • D[F] + Arc(F , B) = 4 + ∞ = ∞ estedrumulalternativ care treceprinnodul F (nodul ales). • Acest al doilea drum estemai lung decât drumulpe care-l aveamdeci D[B] nu se modifică la acest pas. • Exemplupentrunodul G: • D[G] = 8 estedrumulcelmaiscurt de la A la G pe care-l aveam. • D[F] + Arc(F , G) = 4 + 1 = 5 estedrumulalternativ care treceprinnodul F (nodul ales). • Deoarecenoul drum estemaiscurtdecât drumulpe care-l aveamrezultă că D[G] se modifică din 8 în 5 şi T[G] se modificăîn F (nodul ales). • Se observă cădrumulalternativtreceprinnodul F (nodul ales). • Drumul de la A la F de lungime D[F] fiind minim, dacăadaugăm arcul F->G obţinemobligatoriudrumul minim de la A la G care treceprin F. - 7 1 3 3 4 8 ∞ A B C D E H F G
Procedând la felpentrutoatenodurilenemarcate, obţinemurmătorulrezultat: D: - 7 1 3 3 4 5 ∞ 3 D T: A E A A C E F A A 9 5 1 A B C D E H F G 1 G 9 C 5 1 Din nodul F a fost descoperit acest drum nou (mai scurt) catre G 2 H 2 F 4 B 4 E 1
Se alegenodul G şi se marchează, deoarecenodul G are intrareaîn tabloul D minimă – drumul minim de la A la G are lungimea 5 (nu vom găsialtulmaiscurt până la final). D: - 7 1 3 3 4 5 ∞ 3 D A B C D E H F G A 9 5 1 1 G 9 Nu exista drumuri mai scurte spre B sau H trecand prin G, deci tablourile D si T raman nemodificate C 5 1 2 H 2 F 4 B 4 E 1
Se alegenodul B şi se marchează, deoarece nodul B are intrarea in tabloul D minima – drumul minim de la A la B are lungimea 7 (nu vomgasialtulmaiscurtpana la final) D: - 7 1 3 3 4 5 ∞ 3 D A B C D E H F G A 9 5 1 1 G 9 Nu existădrum maiscurtspre H trecândprin B, decitablourile D si T rămân nemodificate C 5 1 2 H 2 F 4 B 4 E 1
Se alegenodul H si se marchează, deoarecenodul H are intrareaîn tabloul D minima – drumul minim de la A la H are lungimea ∞ (adică nu există), cazîn care punem T[H] = ‘–’. D: - 7 1 3 3 4 5 ∞ 3 D A B C D E H F G A 9 5 1 1 G 9 Nu maiexistănodurinemarcate care sa fie actualizate, decitablourile D si T ramannemodificate C 5 1 2 H 2 F 4 B 4 E 1
D: - 7 1 3 3 4 5 ∞ A E A A C E F - T: • Algoritmul se încheiedeoarece nu maisuntnodurinemarcate • Rezultatuleste: • Lungimiledrumurilorminime de la A la celelaltenoduri din grafsuntdisponibile in tabloulD. • Tabloul T serveştela reconstituireadrumurilor. • Putemreconstituidrumurile in douămoduri: • intuitiv, urmărind arceleîngroşate de pegraf (de exemplu, drumul minim de la A la G este A -> C -> E -> F -> G). • formal, utilizândtabloul T rezultatîn urmaaplicăriialgoritmului. A B C D E H F G 3 D A 9 5 1 1 G 9 C 5 1 2 H 2 F 4 B 4 E 1
A E A A C E F - • Tabloul T este: • Dacăconsideram căacesttabloureprezintă un arbore generalizatîn implementarea cu indicatorispre părinte, atuncidrumul minim de la A la G poate fi reconstituitpornind de la G: • T[G] = F • T[F] = E • T[E] = C • T[C] = A • Mergând invers, obtinem: A -> C -> E -> F -> G. • Arborelegeneralizatobţinutîn tabloul T conţinetoatedrumurileminime cu origineaîn A. • Algoritmul găseştedoardrumuriminime cu origineaîntr-un anumit nod al grafului. • Dacă se dorescdrumuriminime cu origineaîn alt nod, trebuierepornitalgoritmul cu respectivul nod pe post de nod de start. • Drumurileminimeobţinute pot fi reprezentate ca un arbore generalizat, deoareceele se suprapunîn mare parte. • Astfel, dacădrumul minim de la X la Y treceprin Z, el trebuieobligatoriu săcuprindăsidrumul minim de la X la Z. A B C D E H F G
După ce a înţeles cum funcţiona acest algoritm, Alin,le-a spus şi celorlalţi doi despre ideea lui,iar aceştia s-au oferit să îi dea o mână de ajutor in realizarea programului. Cei trei, au considerat fiecare nod al grafului ca fiind câte o staţie TAXI, arcele reprezentând străzile din oraş, iar costurile erau reprezentate de distanţa dintre noduri. Şi uite aşa ei au reuşit să mulţumească clienţii şi profitu lor să fie mult mai prosper. Întotdeauna ceea ce vei învăţa la şcoală, te va ajuta şi-n viaţa de zi cu zi. Învaţă şi vei fi pe DRUMUL cel bun!
d[start]=0; for (i=1;i<=n;i++){ minim=99999; for (j=1;j<=n;j++){ if (!viz[j] && d[j]<minim){ minim=d[j];nodminim=j; } }viz[nodminim]=1; for (j=1;j<=n;j++){ if (a[nodminim][j] && d[j]>minim+a[nodminim][j]) d[j]=minim+a[nodminim][j]; } }}int main (){inti;citire ();drum_minim (); for (i=1;i<=n;i++){cout<<"Distanta minima dintre "<<start<<" si "<<i;cout<<" este "<<d[i]<<'\n'; } return 0;} #include <iostream>#include <fstream>int a[20][20],d[20],viz[20],n,m,start;void citire (){inti,x,y,c;ifstream fin ("graf.in"); fin>>n>>m>>start; for (i=1;i<=m;i++){ fin>>x>>y>>c; a[x][y]=c; }}void drum_minim (){inti,j,minim,nodminim;viz[start]=1; for (i=1;i<=n;i++){ if (a[start][i]) d[i]=a[start][i]; else d[i]=99999; }