This shows you the differences between two versions of the page.
|
sd-ca:laboratoare:lab-07 [2025/05/13 10:45] alexia.oprisan [Exerciţii] |
sd-ca:laboratoare:lab-07 [2026/05/12 18:39] (current) roberto_giulio.pal [Exerciţii] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Laborator 7 - Grafuri - Basics ====== | + | ====== Laborator 10 - Grafuri - Basics ====== |
| Responsabili | Responsabili | ||
| - | * [[popaiarina13@gmail.com|Iarina-Ioana Popa]] | + | * [[alexiaops2014@gmail.com|Oprisan Alexia-Ioana]] |
| - | * [[stef.dascalu@gmail.com|Ștefan-Teodor Dascălu]] | + | * [[-@gmail.com|Macovei Nicolae-Cristian]] |
| + | * [[valentin.carauleanu@stud.fim.upb.ro|Cărăuleanu Valentin Gabriel]] | ||
| ===== Obiective ===== | ===== Obiective ===== | ||
| Line 27: | Line 28: | ||
| În funcţie de problemă şi de tipul grafurilor, avem 2 reprezentări: liste de adiacenţă sau matrice de adiacenţă. | În funcţie de problemă şi de tipul grafurilor, avem 2 reprezentări: liste de adiacenţă sau matrice de adiacenţă. | ||
| - | ==== Liste de adiacenţă ==== | + | == Liste de adiacență == |
| - | Reprezentarea prin liste de adiacenţă constă într-un tablou ''Adj'' cu ''|V|'' liste, una pentru fiecare vârf din ''V''. Pentru fiecare ''u'' din ''V'', lista de adiacenţă ''Adj[u]'' conţine referinţe către toate vârfurile ''v'' pentru care există muchia ''(u, v)'' în ''E''. Cu alte cuvinte, ''Adj[u]'' este formată din totalitatea vârfurilor adiacente lui ''u'' în ''G''. | + | Reprezentarea prin **liste de adiacență** folosește un tablou ''Adj'' cu ''|V|'' liste, câte una pentru fiecare vârf din ''V''. Pentru fiecare vârf ''u'' din ''V'', lista de adiacență ''Adj[u]'' conține referințe către toate vârfurile ''v'' pentru care există muchia ''(u, v)'' în ''E''. |
| - | Această reprezentare este preferată pentru grafurile rare ( ''|E|'' este mult mai mic decât ''|V|x|V|''). | + | Cu alte cuvinte, ''Adj[u]'' conține totalitatea vârfurilor adiacente lui ''u'' în graful ''G''. |
| + | |||
| + | Această reprezentare este preferată pentru **grafurile rare**, adică atunci când ''|E|'' este mult mai mic decât ''|V| × |V|''. | ||
| {{sd-ca:laboratoare:undirected_graph.gif}} | {{sd-ca:laboratoare:undirected_graph.gif}} | ||
| - | Pentru graful de mai sus, lista de adiacenţă este următoarea: | + | Pentru graful de mai sus, lista de adiacență este: |
| * **0**: 1->2 | * **0**: 1->2 | ||
| Line 42: | Line 45: | ||
| * **3**: 1->2->4 | * **3**: 1->2->4 | ||
| * **4**: 1->3 | * **4**: 1->3 | ||
| + | ==== Matrice de adiacență ==== | ||
| - | ==== Matrice de adiacenţă ==== | + | Reprezentarea prin **matrice de adiacență** a unui graf constă într-o matrice ''A[i][j]'' de dimensiune ''|V| × |V|'' astfel încât: |
| + | * ''A[i][j] = 1'', dacă muchia ''(i,j)'' aparține lui ''E'' | ||
| + | * ''A[i][j] = 0'', în caz contrar. | ||
| - | Reprezentarea prin matrice de adiacenţă a unui graf constă într-o matrice ''A[i][j]'' de dimensiune ''|V|x|V|'' astfel încât: | + | Această reprezentare este preferată pentru **grafurile dense**, adică atunci când ''|E|'' este aproximativ egal cu ''|V| × |V|''. |
| - | *''A[i][j] = 1'', dacă muchia ''(i,j)'' aparţine lui ''E'' | + | |
| - | *''A[i][j] = 0'', în caz contrar. | + | |
| - | Această reprezentare este preferată pentru grafurile dense ( ''|E|'' este aproximativ egal cu ''|V|x|V|''). | + | Pentru graful de mai sus, matricea de adiacență este următoarea: |
| - | + | ||
| - | Pentru graful de mai sus, matricea de adiacenţă este următoarea: | + | |
| ^ ^0^1^2^3^4^ | ^ ^0^1^2^3^4^ | ||
| ^0|0|1|1|0|0| | ^0|0|1|1|0|0| | ||
| ^1|1|0|1|1|1| | ^1|1|0|1|1|1| | ||
| - | ^2|1|1|0|1|0| | + | ^2|1|1|0|1|0| |
| - | ^3|0|1|1|0|0| | + | ^3|0|1|1|0|0| |
| - | ^4|0|1|0|1|0| | + | ^4|0|1|0|1|0| |
| <note important> | <note important> | ||
| - | În general, preferăm reprezentarea prin liste de adiacență deoarece au o complexitate mai bună în cazul parcurgerilor (cea mai comună operație pe grafuri). Totuși, există situații în care alegerea reprezentării prin matrice de adiacență simplifică mult rezolvarea unei probleme. Un exemplu ar fi algoritmul [[https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm|Floyd-Warshall]] care se bazează pe faptul că putem obține ușor distanța dintre două noduri pe baza matricei în care reținem, adițional, și costurile muchiilor. | + | În general, preferăm reprezentarea prin **liste de adiacență** deoarece oferă o complexitate mai bună în cazul parcurgerilor (cea mai comună operație pe grafuri). Totuși, pentru **grafurile dense**, reprezentarea prin **matrice de adiacență** devine avantajoasă din mai multe motive: |
| - | </note> | + | |
| + | * **Acces direct**: verificarea existenței unei muchii ''(i,j)'' se face în ''O(1)'', față de ''O(grad(i))'' în cazul listelor de adiacență. | ||
| + | * **Simplitate**: mulți algoritmi pe grafuri dense sunt mai ușor de implementat și de înțeles cu o matrice de adiacență. | ||
| + | |||
| + | Un exemplu concret este algoritmul [[https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm|Floyd-Warshall]], care calculează distanțele minime între toate perechile de noduri. Acesta se bazează pe accesul rapid la distanța dintre două noduri, reținând adițional și costurile muchiilor direct în matrice. Pe un graf dens, complexitatea ''O(|V|³)'' a algoritmului este dificil de îmbunătățit oricum, deci costul de memorie ''O(|V|²)'' al matricei devine acceptabil. | ||
| + | </note> | ||
| ===== Parcurgerea grafurilor ===== | ===== Parcurgerea grafurilor ===== | ||
| Line 231: | Line 236: | ||
| </note> | </note> | ||
| - | ===== Algoritmul Floyd-Warshall ===== | ||
| - | Algoritmul Floyd-Warshall este un algoritm folosit pentru căutarea celor mai scurte căi într-un graf orientat ce are cost pe fiecare muchie (costul poate fi pozitiv sau negativ, dar nu pot exista cicli negativi). | ||
| - | Algortimul compară toate căile posibile din graf între toate perechile de noduri. | ||
| - | === Pseudocod === | ||
| - | <code> | ||
| - | |||
| - | dist[V][V] // Matricea de distanțe minime, inițializate cu INFINIT | ||
| - | pentru fiecare nod v | ||
| - | dist[v][v] = 0 | ||
| - | |||
| - | pentru fiecare pereche de noduri (u, v) | ||
| - | dist[u][v] = cost(u, v) | ||
| - | |||
| - | pentru k între 0 și |V| – 1 | ||
| - | pentru i între 0 și |V| – 1 | ||
| - | pentru j între 0 și |V| – 1 | ||
| - | dacă (dist[i][k] + dist[k][j]) < dist[i][j] | ||
| - | dist[i][j] = dist[i][k] + dist[k][j] | ||
| - | </code> | ||
| - | |||
| - | |||
| - | ===== Schelet ===== | ||
| - | <note important> | ||
| - | Daca folositi **Github Classroom**, va rugam sa va actualizati scheletul cu cel de mai jos. Cel din repo-ul clonat initial nu este la cea mai recenta versiune. | ||
| - | </note> | ||
| - | {{:sd-ca:laboratoare:lab6_skel_v2.zip|Scheletul de laborator}} | ||
| ===== Exerciţii ===== | ===== Exerciţii ===== | ||
| <note> | <note> | ||
| - | Trebuie să vă creați cont de [[https://lambdachecker.io | 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/72/problems?page=1 |SDA-Lab-10]]** | + | Trebuie să vă creați cont de [[https://lambdachecker.io | Devmind]], dacă nu v-ați creat deja, pe care îl veți folosi la SD pe toată durata semestrului. |
| </note> | </note> | ||
| Line 272: | Line 251: | ||
| 4) [**1p**] Implementați parcurgerea in lățime (BFS) a unui graf implementat cu listă de adiacență (**BFS** pe Devmind). | 4) [**1p**] Implementați parcurgerea in lățime (BFS) a unui graf implementat cu listă de adiacență (**BFS** pe Devmind). | ||
| - | 5) [**2p - bonus**] Implementați algoritmul Floyd-Warshall pe un graf reprezentat printr-o matrice de adiacență (**FloydWarshall** pe Devmind). | ||
| ===== Interviu ===== | ===== Interviu ===== | ||
| - | Această secțiune nu este punctată și încearcă să vă facă o oarecare idee a tipurilor de întrebări pe care le puteți întâlni la un job interview (internship, part-time, full-time, etc.) din materia prezentată în cadrul laboratorului. | + | Această secțiune nu este punctată și încearcă să vă ofere o idee despre tipurile de întrebări pe care le puteți întâlni la un job interview (internship, part-time, full-time, etc.) din materia prezentată în cadrul laboratorului. |
| + | |||
| + | Multe dintre companiile mari folosesc date stocate sub formă de grafuri (Facebook Open Graph, Google Social Graph și Page Rank, etc.), astfel că la angajare vor dori să vadă că știți să lucrați cu grafuri: | ||
| + | * cum se reprezintă grafurile (liste de adiacență vs. matrice de adiacență) | ||
| + | * cum funcționează și cum se implementează parcurgerile (BFS, DFS) | ||
| + | * când este preferată o reprezentare față de cealaltă | ||
| + | * complexitatea timp și spațiu a algoritmilor de parcurgere | ||
| + | |||
| + | === Probleme recomandate === | ||
| - | Cum multe din companiile mari folosesc date stocate sub formă de grafuri (Facebook Open Graph, Google Social Graph şi Page Rank, etc.) la angajare vor dori să vadă ca ştiţi grafuri: | + | **Ușoare:** |
| + | * [[https://leetcode.com/problems/find-if-path-exists-in-graph/description|1971. Find if Path Exists in Graph]] - verificarea existenței unui drum între două noduri (BFS/DFS) | ||
| + | * [[https://leetcode.com/problems/flood-fill/description|733. Flood Fill]] - parcurgere BFS/DFS pe o matrice | ||
| + | * [[https://leetcode.com/problems/number-of-islands/description|200. Number of Islands]] - identificarea componentelor conexe | ||
| - | * cum se reprezintă grafurile | + | **Medii:** |
| - | * cum funcţionează şi cum se implementează parcurgerile (BFS, DFS) | + | * [[https://leetcode.com/problems/clone-graph/description|133. Clone Graph]] - clonarea unui graf folosind BFS/DFS |
| + | * [[https://leetcode.com/problems/rotting-oranges/description|994. Rotting Oranges]] - BFS multi-sursă | ||
| + | * [[https://leetcode.com/problems/course-schedule/description|207. Course Schedule]] - detectarea ciclurilor într-un graf orientat | ||
| + | * [[https://leetcode.com/problems/number-of-provinces/description|547. Number of Provinces]] - componente conexe cu BFS/DFS | ||
| + | * [[https://leetcode.com/problems/shortest-path-in-binary-matrix/description|1091. Shortest Path in Binary Matrix]] - cel mai scurt drum cu BFS | ||
| - | Puteţi căuta mai multe întrebări pe https://leetcode.com/, http://www.careercup.com/ şi http://www.glassdoor.com/ | + | **Grele:** |
| + | * [[https://leetcode.com/problems/word-ladder/description|127. Word Ladder]] - BFS pe graf implicit | ||
| + | * [[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 at a Threshold Distance]] - Floyd-Warshall aplicat | ||
| ===== Bibliografie ===== | ===== Bibliografie ===== | ||