Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sda-aa:laboratoare:09 [2021/04/27 09:31]
cristian.rusu [4. Drumul de cost minim între oricare 2 noduri]
sda-aa:laboratoare:09 [2021/04/28 13:55] (current)
cristian.rusu [6. Exerciții laborator]
Line 132: Line 132:
 <note tip>​Observaţii:​ <note tip>​Observaţii:​
     * costMin(i,​j,​0) = costMuchie(i,​j) (dacă există muchie de la i la j) sau infinit(altfel);​     * costMin(i,​j,​0) = costMuchie(i,​j) (dacă există muchie de la i la j) sau infinit(altfel);​
-    * costMin(i,​j,​N) = drumul de cost minim de la i la j.</​note>​+    * costMin(i,​j,​N) = drumul de cost minim de la i la j. 
 +</​note>​ 
 + 
 + 
 +Paşii algoritmului Floyd-Warshall:​ 
 +<​code>​ 
 +1. Declarăm matricile:​ 
 + dist, matrice N x N şi o iniţializăm dist[i][j] = infinit, pentru orice i şi j 
 + next, matrice N x N în care vom salva prima muchie din drumul i-j de cost minim 
 + //next este necesar doar în cazul în care ne interesează muchiile folosite 
 +//pasul k = 0 
 +2. Pentru fiecare nod v 
 + 1. dist[v][v] = 0; 
 +3. Pentru fiecare pereche (u,v) a.i. există muchie de la u la v 
 + 1. dist[u][v] = costMuchie(u,​v);​ 
 + 2. next[u][v] = v; //pentru urmărirea muchiilor ce compun drumul 
 +//am terminat pasul k = 0 
 +4. Pentru fiecare pas k (de la 1 la N) 
 + 1. Pentru fiecare nod i (de la 1 la N) 
 + 1. Pentru fiecare nod j (de la 1 la N) 
 + 1. calculăm costul nou = dist[i][k] + dist[k][j];​ 
 + 2. comparăm costul nou cu costul vechi = dist[i][j] 
 + dacă e mai bun costul nou: 
 + 1. dist[i][j] = costul nou; 
 + 2. next[i][j] = next[i][k]; //pentru urmărirea muchiilor 
 + altfel păstrăm costul vechi 
 +</​code>​ 
 + 
 +Pentru obţinerea nodurilor ce formează drumul de cost minim de la u la v, putem folosi următoarea secvenţă:​ 
 +<​code>​ 
 +funcţie afişareDrum(u,​ v) 
 +1. dacă u == v 
 + 1. print(v); STOP 
 +2. print(u); 
 +3. afişareDrum(next[u][v],​ v); 
 +</​code>​ 
 + 
 + 
 +==== 5. Observaţii finale ==== 
 + 
 +<note tip>Cei 3 algoritmi funcţionează bine atunci când toate muchiile au cost pozitiv.</​note>​ 
 + 
 +<note warning>​Drumul de cost minim NU este bine definit atunci când există cicluri cu cost negativ. 
 +    * putem ajunge de la un nod la acelaşi nod, folosind acelaşi ciclu de oricâte ori ⇒ costMinim = -infinit);​ 
 +    * în aceste cazuri, nu putem pune problema găsirii drumurilor de cost minim. 
 +</​note>​ 
 + 
 +<note warning>​O muchie cu cost negativ este echivalentă cu 2 arce cu cost negativ şi implică existenţa unui ciclu cu cost negativ.</​note>​ 
 + 
 +<note tip>​Algoritmii Bellman-Ford şi Floyd-Warshall pot detecta dacă un graf conţine cicluri cu cost negativ: 
 +    * Bellman-Ford:​ executăm încă o evaluare a tuturor muchiilor la final. Dacă găsim cel puţin o estimare nouă mai buna, graful conţine măcar un ciclu cu cost negativ. 
 +    * Floyd-Warshall:​ putem verifica, la fiecare pas, dacă avem o valoare negativă pe diagonala matricei dist. Dacă găsim cel puţin o valoare negativă, graful conţine măcar un ciclu cu cost negativ. 
 +</​note>​ 
 + 
 + 
 +<note important>​Pentru algoritmul lui Dijkstra, „garanţia“ se pierde când există chiar şi un singur arc cu cost negativ. 
 +    * Algoritmul se bazează pe ideea că, odată explorat un nod, drumul de cost minim până la acel nod a fost găsit, ceea ce NU este mereu corect în prezenţa unui arc cu cost negativ. 
 +    * De aceea, algoritmul poate produce răspunsuri greşite în acest caz. 
 +</​note>​ 
 + 
 +<note tip>În schimb, algoritmii Bellman-Ford şi Floyd-Warshall funcţionează pe grafurile cu arce cu cost negativ, atâta timp cât drumurile de cost minim sunt bine definite (fără cicluri cu cost negativ).</​note>​ 
 + 
 +==== 6. Exerciții laborator ==== 
 + 
 +Folosiți datele din fișierul {{:​sda-aa:​laboratoare:​trains_with_km.zip|}}. 
 + 
 +  - Citiți datele din arhiva atașată. 
 +  - Creați un graf neorientat și altul orientat din fișerele atașate. Creați matricea de adiancență și separat graful de costuri. La punctele următoare folosiți graful neorientat. 
 +  - Găsiți stațiile consecutive care au distanța minimă/​maximă între ele. (rezultatele în fișierele min.txt și max.txt) 
 +  - Câți km de cale ferată există în baza noastră de date? (rezultatele în fișierul total.txt) 
 +  - Calculați drumul de cost minim de la București la orașul vostru natal. (rezultatele în fișierul ruta.txt) 
 +  - Găsiți stația (nodul) cea mai departe de București și drumul. (rezultatele în fișierul departe.txt) 
 +  - Găsiți toate drumurile de la București la Oradea. (rezultatele în fișierul bucuresti_oradea.txt) 
 +  - Găsiți cele două stații din graf care sunt la distanța maximă (pe drumul de cost minim). (rezultatele în fișierul drum_lung.txt) 
 + 
 +==== 7. Probleme opționale, de interviu ==== 
 + 
 +  - Îmbunătățiți algoritmul lui Dijkstra folosind min-heap. 
 +  - Se dă un graf pentru care se cunoaşte drumul de cost minim de la un nod sursă (S) la un nod destinaţie (D). Dacă adăugăm 100 la costul fiecărei muchii, se modifică drumul de cost minim? (dacă da, daţi un exemplu; dacă nu, explicaţi de ce). 
 +  - Aceeaşi întrebare dacă înmulţim fiecare cost cu 100. 
 +  - Cum găsiţi (mai rapid decât cu cei 3 algoritmi prezentaţi) drumul de cost minim de la S la D într-un graf în care toate muchiile au acelaşi cost(1)? Cum adaptaţi soluţia în cazul în care toate muchiile au costul 1 sau 2? 
 +  - Daţi un exemplu în care folosirea algoritmului lui Dijkstra (pentru a obţine drumul de cost minim pentru toate perechile de noduri) ar fi mai rapidă decât algoritmul Floyd-Warshall. 
 + 
 +==== 8. Referințe ==== 
 +  - [[https://​en.wikipedia.org/​wiki/​Dijkstra'​s_algorithm|Algoritmul lui Dijkstra]] 
 +  - [[https://​en.wikipedia.org/​wiki/​Bellman%E2%80%93Ford_algorithm|Algoritmul lui Bellman Ford]] 
 +  - [[http://​www.algorithmist.com/​index.php/​Floyd-Warshall'​s_Algorithm|Algoritmul lui Floyd-Warshall]] 
 +  - [[https://​profs.info.uaic.ro/​~busaco/​teach/​courses/​net/​docs/​protocoale_rutare.pdf|Protocoale de rutare]]
  
sda-aa/laboratoare/09.1619505098.txt.gz · Last modified: 2021/04/27 09:31 by cristian.rusu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0