Differences

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

Link to this comparison view

sd-ca:laboratoare:lab-08 [2026/05/11 21:55]
valentin.carauleanu [Sortarea topologică]
sd-ca:laboratoare:lab-08 [2026/05/11 22:09] (current)
valentin.carauleanu [Interviu]
Line 4: Line 4:
   * [[stef.dascalu@gmail.com|Ștefan-Teodor Dascălu]]   * [[stef.dascalu@gmail.com|Ștefan-Teodor Dascălu]]
   * [[melih.riza03@gmail.com|Melih Riza]]   * [[melih.riza03@gmail.com|Melih Riza]]
 +  * [[valentin.carauleanu@stud.fim.upb.ro|Cărăuleanu Valentin Gabriel]]
  
 ===== Obiective ===== ===== Obiective =====
Line 106: Line 107:
  
 Pentru a reține distanța și drumul exact de la ''​A''​ la ''​B'',​ se păstrează pentru fiecare nod: Pentru a reține distanța și drumul exact de la ''​A''​ la ''​B'',​ se păstrează pentru fiecare nod:
-  * ''​d[x]'' ​— distanța de la sursă la nodul ''​x''​ +  * ''​d[x]'' ​distanța de la sursă la nodul ''​x''​ 
-  * ''​p[x]'' ​— părintele lui ''​x''​ în drumul de la sursă spre ''​x''​+  * ''​p[x]'' ​părintele lui ''​x''​ în drumul de la sursă spre ''​x''​
  
 În momentul descoperirii unui nod ''​y''​ al cărui părinte este ''​x'',​ se fac atribuirile:​ În momentul descoperirii unui nod ''​y''​ al cărui părinte este ''​x'',​ se fac atribuirile:​
Line 176: Line 177:
  
 Sortarea topologică se realizează printr-o parcurgere **DFS**, în care se rețin pentru fiecare nod: Sortarea topologică se realizează printr-o parcurgere **DFS**, în care se rețin pentru fiecare nod:
-  * ''​tDesc[u]'' ​— momentul descoperirii nodului ''​u''​ +  * ''​tDesc[u]'' ​momentul descoperirii nodului ''​u''​ 
-  * ''​tFin[u]'' ​— momentul finalizării procesării nodului ''​u''​+  * ''​tFin[u]'' ​momentul finalizării procesării nodului ''​u''​
  
 La final, nodurile sunt sortate **descrescător** după ''​tFin''​. Nodul care se finalizează cel mai târziu trebuie să apară primul în sortare, deoarece nu depinde de niciun alt nod nedescoperit încă. La final, nodurile sunt sortate **descrescător** după ''​tFin''​. Nodul care se finalizează cel mai târziu trebuie să apară primul în sortare, deoarece nu depinde de niciun alt nod nedescoperit încă.
Line 310: Line 311:
 ==== Ciclu hamiltonian ==== ==== Ciclu hamiltonian ====
  
-Un lanţ hamiltonian într-un graf orientat sau neorientat ''​G = (V, E)''​este o cale ce trece prin fiecare nod din ''​V''​ o singură dată. Dacă nodul de început ​şi cel de sfârşit coincid ​(este vizitat de două ori) vom spune că lanţul formează un **ciclu hamiltonian**.+Un **lanț hamiltonian** într-un graf orientat sau neorientat ''​G = (V, E)''​ este o cale ce trece prin fiecare nod din ''​V''​ o singură dată. Dacă nodul de început ​și cel de sfârșit coincidlanțul formează un **ciclu hamiltonian**.
  
-Un graf ce conţine un ciclu hamiltonian se numeşte graf hamiltonian.+Un graf ce conține un ciclu hamiltonian se numește **graf hamiltonian**. 
 + 
 +<note important>​ 
 +Problema găsirii unui ciclu hamiltonian este **NP-completă**,​ ceea ce înseamnă că nu se cunoaște niciun algoritm eficient (polinomial) pentru cazul general. 
 +</​note>​
  
 === Algoritm === === Algoritm ===
  
-În cadrul acestui laborator, vom folosi metoda backtracking pentru găsirea unui ciclu hamiltonian. ​Pentru contruirea soluţiei, se menţine o listă în care sunt adăugate nodurile parcurse:+În cadrul acestui laborator, vom folosi metoda ​**backtracking** pentru găsirea unui ciclu hamiltonian. ​Se menține o listă în care sunt adăugate nodurile parcurse: 
 + 
 +  * La fiecare pas, se adaugă unul dintre nodurile care nu se află deja în listă. 
 +  * Se construiește recursiv lanțul de ''​lungime_lant + 1''​. 
 +  * Dacă dimensiunea listei este ''​n'',​ se verifică dacă există o muchie de la ultimul nod din listă către primul. Dacă nu există o astfel de muchie, lanțul curent nu poate fi închis într-un ciclu hamiltonian și se continuă cu backtracking. 
 +  * Pentru a afla **toate** ciclurile hamiltoniene,​ la revenirea din apelul recursiv nu se iese din funcție la prima potrivire, ci se încearcă în continuare alte posibilități. 
 + 
 +=== Complexitate ===
  
-  * La fiecare pas, vom adăuga unul dintre nodurile care nu se află deja in listă +^ Complexitate ^ Valoare ^ 
-  Se construieşte recursiv lanţul de lungime_lanţ + 1 +**Timp** ​  ​| ​''​O(|V|!)'' ​în cazul cel mai defavorabil | 
-  ​Dacă dimensiunea listei este ''​n''​ (numărul de noduri din graf), se verifică dacă primul şultimul nod din listă sunt adiacente. În caz contrar, s-a găsit un lanţ hamiltonian,​ dar nu şi un ciclu hamiltonian. +^ **Spațiu** | ''​O(|V|)''​ pentru stiva de recursivitate și lanț |
-  * Pentru a afla toate ciclurile hamiltoniene,​ la revenirea cu succes din apelul recursiv nu se iese din funcţie la găsirea primei potriviri, ci se încearcă în continuare alte posibilităţi.+
  
 === Pseudocod === === Pseudocod ===
Line 327: Line 338:
 <​code>​ <​code>​
 // Inițializări // Inițializări
-număr_noduri ​= număr de noduri din V+numar_noduri ​= număr de noduri din V
  
-// Verifica ​dacă un nod este nou în lanţ +// Verifică ​dacă un nod este nou în lanț 
-nouÎnLanţ(nod, lanţ)+nouInLant(nod, lant)
 { {
-    return !lanţ.conţine(nod)+    return !lant.contine(nod)
 } }
  
-// Construieste ​lanţul hamiltonian +// Construiește ​lanțul hamiltonian 
-construireLanţ(lanţlungime_lanţ)+construireLant(lantlungime_lant)
 { {
-    dacă lungime_lanţ ​== număr_noduri+    dacă lungime_lant ​== numar_noduri
     {     {
-        ​început ​lanţ[0] +        ​inceput ​lant[0] 
-        ​sfârşit ​= ultimul element din lanţ +        ​sfarsit ​= ultimul element din lant 
- +        // Verifică dacă există muchie ​de la sfarsit spre inceput 
-        // Există muchie ​între cele 2 noduri +        dacă muchie(sfarsitinceput)
-        dacă muchie(începutsfârşit)+
         {         {
-            ​// Lanţul este ciclu +            ​afiseaza ​ciclul
-            afişează ​ciclul+
             return true             return true
         }         }
Line 355: Line 364:
         pentru orice nod u din V         pentru orice nod u din V
         {         {
-            ​sfârşit ​= ultimul element din lanţ +            ​sfarsit ​= ultimul element din lant 
-            dacă muchie(u, sfârşitşi nouÎnLanţ(u, lanţ)+            ​// Verifică ​dacă există muchie ​de la sfarsit spre u 
 +            dacă muchie(sfarsitusi nouInLant(u, lant)
             {             {
-                addLast(lanţ, u)    // Adaugă u la lanţ +                addLast(lant, u)       ​// Adaugă u la lanț
-                 +
-                construireLanţ(lanţ,​ lungime_lanţ + 1)+
  
-                // Pentru afişarea unui singur ciclu hamiltonian linia anterioară ​este inlocuită ​cu: +                ​construireLant(lant,​ lungime_lant + 1) 
-                // dacă construireLanţ(lanţlungime_lanţ ​+ 1) == true +                ​// Pentru afișarea unui singur ciclu hamiltonian
-                //       ​return true +                // linia anterioară ​se înlocuiește ​cu: 
-                 +                // dacă construireLant(lantlungime_lant ​+ 1) == true 
-                removeLast(lanţ, u) // Backtrack+                //     ​return true 
 + 
 +                removeLast(lant, u)    // Backtrack
             }             }
         }         }
Line 374: Line 384:
  
 // Apelează construirea ciclurilor hamiltoniene // Apelează construirea ciclurilor hamiltoniene
-cicluriHamiltoniene+cicluriHamiltoniene()
 { {
-    // Din moment ce ar trebui să formeze ​un ciclu, lanţul poate incepe ​cu orice nod +    // Din moment ce formează un ciclu, lanțul poate începe ​cu orice nod 
-    ​sursă ​= alegem un nod aleator din V +    ​sursa = alegem un nod aleator din V 
-    addLast(lanţsursă+    addLast(lantsursa
-    ​construireLanţ(lanţ, 1)+    ​construireLant(lant, 1)
 } }
 </​code>​ </​code>​
- 
  
 === Exemplu === === Exemplu ===
  
-{{sd-ca:​laboratoare:​hamilton.png}} +{{sd-ca:​laboratoare:​hamilton.png?400}}
- +
 ===== Exerciții ===== ===== Exerciții =====
  
 <​note>​ <​note>​
-Trebuie să vă creați cont de [[https://​code.devmind.ro/​ | Devmind]], dacă nu v-ați creat deja, pe care îl veți folosi la SD pe toată durata semestrului. ​Aveti grija sa selectati contestul corect la submit, si anume **[[https://​beta.lambdachecker.io/​contest/​34 |SD-CA-LAB-11 Grafuri (Advanced) ]]**+Trebuie să vă creați cont de [[https://​code.devmind.ro/​|Devmind]],​ dacă nu v-ați creat deja, pe care îl veți folosi la SD pe toată durata semestrului.
 </​note>​ </​note>​
  
 1) [**3.5p**] Rezolvați problema **Connected Components**. 1) [**3.5p**] Rezolvați problema **Connected Components**.
 +2) [**3.5p**] Rezolvați problema **Minimum Path**.
 +3) [**3p**] Rezolvați problema **Check Bipartite**.
  
 +===== Interviu =====
  
-2) [**3.5p**] Rezolvați problema **Minimum Path**.+Această secțiune nu este punctată șîncearcă să vă ofere o idee despre tipurile de întrebări pe care le puteți întâlni la un job interview din materia prezentată în cadrul laboratorului.
  
 +=== Probleme recomandate ===
  
-3) [**3p**] Rezolvati problema **Check Bipartite**.+**Sortare topologică:​** 
 +  * [[https://​leetcode.com/​problems/​course-schedule-ii/​description|210. Course Schedule II]] (returnarea ordinii topologice efective) 
 +  ​[[https://​leetcode.com/​problems/​longest-increasing-path-in-a-matrix/​description|329. Longest Increasing Path in a Matrix]] (DAG implicit pe matrice)
  
 +**Componente conexe și grafuri bipartite:​**
 +  * [[https://​leetcode.com/​problems/​is-graph-bipartite/​description|785. Is Graph Bipartite?​]] (verificare bipartitivitate cu BFS/DFS)
 +  * [[https://​leetcode.com/​problems/​accounts-merge/​description|721. Accounts Merge]] (componente conexe cu Union-Find)
 +  * [[https://​leetcode.com/​problems/​satisfiability-of-equality-equations/​description|990. Satisfiability of Equality Equations]] (componente conexe pe graf implicit)
  
 +**Drumuri minime:**
 +  * [[https://​leetcode.com/​problems/​network-delay-time/​description|743. Network Delay Time]] (Dijkstra clasic)
 +  * [[https://​leetcode.com/​problems/​find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/​description|1334. Find the City with the Smallest Number of Neighbors]] (Floyd-Warshall)
 +  * [[https://​leetcode.com/​problems/​cheapest-flights-within-k-stops/​description|787. Cheapest Flights Within K Stops]] (Bellman-Ford cu constrângeri)
  
 +**Probleme avansate:**
 +  * [[https://​leetcode.com/​problems/​reconstruct-itinerary/​description|332. Reconstruct Itinerary]] (circuit eulerian pe graf orientat)
 +  * [[https://​leetcode.com/​problems/​critical-connections-in-a-network/​description|1192. Critical Connections in a Network]] (punți în graf cu algoritmul Tarjan)
 +  * [[https://​leetcode.com/​problems/​swim-in-rising-water/​description|778. Swim in Rising Water]] (BFS/​Dijkstra pe matrice cu cost variabil)
  
 ===== Bibliografie ===== ===== Bibliografie =====
sd-ca/laboratoare/lab-08.1778525730.txt.gz · Last modified: 2026/05/11 21:55 by valentin.carauleanu
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