Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
aa:lab:6 [2023/11/16 02:03] vlad.juja |
aa:lab:6 [2024/11/28 18:12] (current) lfa |
||
---|---|---|---|
Line 13: | Line 13: | ||
Înainte de a trece la examinarea unor probleme pe grafuri, este util să recapitulăm ce sunt grafurile. \\ | Înainte de a trece la examinarea unor probleme pe grafuri, este util să recapitulăm ce sunt grafurile. \\ | ||
- | Grafurile sunt considerate a fi perechi G = (V, E), unde V reprezintă un set de noduri, iar E un set de muchii. Fiecare nod este identificat printr-un număr de la 1 la |V|. O muchie este o pereche de noduri. De obicei, ne referim la grafurile neorientate, unde o muchie este o pereche neordonată. \\ | + | Grafurile sunt considerate a fi perechi $ G = (V, E)$, unde $ V$ reprezintă un set de noduri, iar E un set de muchii. Fiecare nod este identificat printr-un număr de la 1 la $ |V|$. O muchie este o pereche de noduri. De obicei, ne referim la grafurile neorientate, unde o muchie este o pereche neordonată. \\ |
- | Vom utiliza matricele de adiacență pentru a reprezenta grafurile. O matrice de adiacență este o tabelă de dimensiune |V| pe |V|, unde nodurile indexează atât liniile, cât și coloanele; intrarea i, j a matricei este o valoare booleană care arată dacă (i, j) ∈ E. Pentru grafurile neorientate, matricea este simetrică în raport cu diagonala principală. \\ | + | Vom utiliza matricele de adiacență pentru a reprezenta grafurile. O matrice de adiacență este o tabelă de dimensiune $ |V|$ pe $ |V|$, unde nodurile indexează atât liniile, cât și coloanele; intrarea $ i$ , $ j$ a matricei este o valoare booleană care arată dacă $ (i, j) ∈ E$. Pentru grafurile neorientate, matricea este simetrică în raport cu diagonala principală. \\ |
Matricea de adiacență în sine conține toate informațiile necesare pentru a descrie graful, astfel încât poate servi ca intrare pentru algoritmii noștri.\\ | Matricea de adiacență în sine conține toate informațiile necesare pentru a descrie graful, astfel încât poate servi ca intrare pentru algoritmii noștri.\\ | ||
Line 23: | Line 23: | ||
=== 1. K Vertex Cover === | === 1. K Vertex Cover === | ||
- | Dându-se un graf neorientat G = (V, E) și un număr întreg pozitiv K, se cere găsirea unui subset V' ⊆ V, cu |V'| = K, astfel încât fiecare muchie din E să aibă cel puțin unul dintre capete în V'. \\ | + | Dându-se un graf neorientat $ G = (V, E)$ și un număr întreg pozitiv $ K$, se cere găsirea unui subset $ V' ⊆ V$, cu $ |V'| = K$, astfel încât fiecare muchie din $ E$ să aibă cel puțin unul dintre capete în $ V'$. \\ |
- | În termeni simpli, problema K Vertex Cover implică găsirea unui subset de K noduri astfel încât fiecare muchie a grafului să aibă cel puțin unul dintre capete în acel set. | + | În termeni simpli, problema K Vertex Cover implică găsirea unui subset de $ K$ noduri astfel încât fiecare muchie a grafului să aibă cel puțin unul dintre capete în acel set. |
* Propuneți o soluție greedy pentru această problemă. | * Propuneți o soluție greedy pentru această problemă. | ||
* Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | * Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | ||
Line 33: | Line 33: | ||
=== 2. K Clique === | === 2. K Clique === | ||
- | Dându-se un graf neorientat G = (V, E) și un număr întreg pozitiv K, se cere găsirea unui set V' ⊆ V, cu |V'| = K, astfel încât toate nodurile din V' sunt conectate între ele prin muchii din E. În termeni simpli, problema K Clique implică găsirea unui set de K noduri astfel încât oricare două noduri din acest set sunt conectate printr-o muchie (orice nod e conectat cu orice nod). | + | Dându-se un graf neorientat $ G = (V, E)$ și un număr întreg pozitiv $ K$, se cere găsirea unui set $ V' ⊆ V$, cu $ |V'| = K$, astfel încât toate nodurile din $ V'$ sunt conectate între ele prin muchii din $ E$. În termeni simpli, problema K Clique implică găsirea unui set de $ K$ noduri astfel încât oricare două noduri din acest set sunt conectate printr-o muchie (orice nod e conectat cu orice nod). |
* Propuneți o soluție greedy pentru această problemă. | * Propuneți o soluție greedy pentru această problemă. | ||
* Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | * Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | ||
Line 41: | Line 41: | ||
=== 3. K Coloring === | === 3. K Coloring === | ||
- | Dându-se un graf neorientat G = (V, E) și un număr întreg pozitiv K, se cere să se determine dacă este posibil să se atribuie culori nodurilor astfel încât nicio pereche de două noduri adiacente să nu aibă aceeași culoare, iar numărul total de culori utilizate să fie cel mult K. | + | Dându-se un graf neorientat $ G = (V, E)$ și un număr întreg pozitiv $ K$, se cere să se determine dacă este posibil să se atribuie culori nodurilor astfel încât nicio pereche de două noduri adiacente să nu aibă aceeași culoare, iar numărul total de culori utilizate să fie cel mult $ K$. |
* Propuneți o soluție greedy pentru această problemă. | * Propuneți o soluție greedy pentru această problemă. | ||
* Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | * Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | ||
Line 48: | Line 48: | ||
=== 4. Hamilton Path === | === 4. Hamilton Path === | ||
- | Dându-se un graf orientat G = (V, E), se cere să se determine dacă există un drum Hamiltonian în graful respectiv. Un drum Hamiltonian este un drum care vizitează fiecare nod exact o dată. | + | Dându-se un graf orientat $ G = (V, E)$, se cere să se determine dacă există un drum Hamiltonian în graful respectiv. Un drum Hamiltonian este un drum care vizitează fiecare nod exact o dată. |
* Propuneți o soluție greedy pentru această problemă. | * Propuneți o soluție greedy pentru această problemă. | ||
* Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | * Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | ||
- | * O variantă ușor modificată a acestui algoritm este TSP (The Travelling Salesman Problem): Dându-se un graf ponderat G = (V, E) și un buget B, există un drum Hamiltonian cu cost total mai mic decât B? Ce trebuie modificat în soluția anterioară pentru a obține soluția pentru TSP? | + | * O variantă ușor modificată a acestui algoritm este TSP (The Travelling Salesman Problem): Dându-se un graf ponderat $ G = (V, E)$ și un buget $ B$, există un drum Hamiltonian cu cost total mai mic decât $ B$? Ce trebuie modificat în soluția anterioară pentru a obține soluția pentru TSP? |
\\ | \\ | ||
=== 5. K Cut === | === 5. K Cut === | ||
- | Dându-se un graf G = (V, E) și un număr K, există o împărțire a nodurilor în două mulțimi astfel încât să existe k muchii cu câte un capăt în fiecare mulțime? | + | Dându-se un graf $ G = (V, E)$ și un număr $ K$, există o împărțire a nodurilor în două mulțimi astfel încât să existe $ K$ muchii cu câte un capăt în fiecare mulțime? |
* Propuneți o soluție greedy pentru această problemă. | * Propuneți o soluție greedy pentru această problemă. | ||
* Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | * Dați exemplu de o situație în care soluția greedy nu generează răspunsul corect. | ||
Line 89: | Line 89: | ||
- | ===== Programare Dinamică și Pseudopolinomiale ===== | + | ===== Probleme NPC cu mulțimi de numere ===== |
+ | |||
+ | Pentru urmatoarele probleme, propuneți o variantă de pseudocod ce verifică validitatea unui candidat. \\ | ||
+ | \\ | ||
+ | |||
+ | === 9. Subset Sum === | ||
+ | |||
+ | Dându-se un set de numere întregi $ S$ și un număr întreg $ K$, problema Subset Sum solicită determinarea dacă există un subșir $ A$ al lui $ S$ astfel încât suma elementelor din $ A$ să fie egală cu $ K$. Cu alte cuvinte, este posibil să se găsească o submulțime a numerelor din $ S$ astfel încât suma acestora să fie exact $ K$?\\ | ||
+ | \\ | ||
+ | |||
+ | |||
+ | === 10. Partitioning === | ||
+ | |||
+ | Dându-se un set $ S$ de numere întregi, se cere determinarea dacă setul poate fi împărțit în două submulțimi $ S_1$ și $ S_2$ astfel încât suma elementelor din $ S_1$ să fie egală cu suma elementelor din $ S_2$. Cu alte cuvinte, se caută o împărțire a setului în două submulțimi cu sume egale.\\ | ||
+ | \\ | ||
+ | |||
+ | |||
+ | === 11. Set Cover === | ||
+ | |||
+ | Date de intrare: Un univers $ U$ și o colecție $ S$ de submulțimi ale lui $ U$. \\ | ||
+ | Problemă: Există o subcolecție $ S'$ a lui $ S$ astfel încât fiecare element din $ U$ este acoperit de cel puțin un subset din $ S'$? \\ | ||
+ | Verificare: Verificarea constă în a asigura că fiecare element din $ U$ este acoperit de cel puțin un subset din $ S'$. \\ | ||
+ | \\ | ||
+ | |||
+ | |||
+ | ===== BONUS: Programare Dinamică și Pseudopolinomiale ===== | ||
Programarea dinamică este o tehnică de proiectare a algoritmilor care constă în rezolvarea unei probleme prin împărțirea acesteia în subprobleme mai mici și rezolvarea fiecăreia dintre acestea doar o dată, stocând rezultatele pentru a evita recalcularea lor ulterioară. Această abordare este eficientă în rezolvarea problemelor ce pot fi descompuse în subprobleme overlapped sau care prezintă o structură de optimalitate. \\ | Programarea dinamică este o tehnică de proiectare a algoritmilor care constă în rezolvarea unei probleme prin împărțirea acesteia în subprobleme mai mici și rezolvarea fiecăreia dintre acestea doar o dată, stocând rezultatele pentru a evita recalcularea lor ulterioară. Această abordare este eficientă în rezolvarea problemelor ce pot fi descompuse în subprobleme overlapped sau care prezintă o structură de optimalitate. \\ | ||
Line 97: | Line 122: | ||
- | === 9. Knapsack === | + | === 12. Knapsack === |
Avem un rucsac cu o capacitate maximă dată (exprimată într-o anumită unitate, de exemplu, greutate), și un set de obiecte, fiecare având o valoare și o greutate specifică. Scopul este să determinăm cum să umplem rucsacul astfel încât să maximizăm valoarea totală a obiectelor, având în vedere restricția de capacitate a rucsacului. | Avem un rucsac cu o capacitate maximă dată (exprimată într-o anumită unitate, de exemplu, greutate), și un set de obiecte, fiecare având o valoare și o greutate specifică. Scopul este să determinăm cum să umplem rucsacul astfel încât să maximizăm valoarea totală a obiectelor, având în vedere restricția de capacitate a rucsacului. | ||
Line 114: | Line 139: | ||
unde $ x_i$ este o variabilă binară ce indică dacă obiectul $ i$ este sau nu inclus în rucsac. Adică, $ x_i = 1$ dacă obiectul i este inclus și $ x_i = 0$ în caz contrar. | unde $ x_i$ este o variabilă binară ce indică dacă obiectul $ i$ este sau nu inclus în rucsac. Adică, $ x_i = 1$ dacă obiectul i este inclus și $ x_i = 0$ în caz contrar. | ||
- | * Implementați algoritmul în scheletul de cod oferit și verificați-vă soluția | ||
- | |||
- | |||
- | ===== Probleme NPC cu mulțimi de numere ===== | ||
- | |||
- | Pentru urmatoarele probleme, implemntați în scheletul de cod algoritmul ce verifică validitatea unui candidat și verificați-vă soluția. \\ | ||
- | \\ | ||
- | |||
- | === 10. Subset Sum === | ||
- | |||
- | Dându-se un set de numere întregi S și un număr întreg K , problema Subset Sum solicită determinarea dacă există un subșir A al lui S astfel încât suma elementelor din A să fie egală cu K . Cu alte cuvinte, este posibil să se găsească o submulțime a numerelor din S astfel încât suma acestora să fie exact K ?\\ | ||
- | \\ | ||
- | |||
- | |||
- | === 11. Partitioning === | ||
- | |||
- | Dându-se un set S de numere întregi, se cere determinarea dacă setul poate fi împărțit în două submulțimi S1 și S2 astfel încât suma elementelor din S1 să fie egală cu suma elementelor din S2. Cu alte cuvinte, se caută o împărțire a setului în două submulțimi cu sume egale. | ||
<note> | <note> | ||
- | Pentru exercițiile 9,10 și 11 veți folosi scheletul de laborator pus la dispoziție. În directorul fiecărui exercițiu există un director cu fișiere de test și încă două fișiere: Checker.Java și <NumeEx>.Java. Implementarea o veți face în <NumeEx>.Java, iar pentru a rula testele trebuie să rulați metoda main din clasa Checker. Pentru a funcționa, trebuie să deschideți directorul fiecărui exercițiu în InteliJ și să setați SDK-ul. | + | Soluțiile acestui laborator se găsesc [[https://ocw.cs.pub.ro/ppcarte/doku.php?id=aa:lab:sol:6|aici]] |
</note> | </note> | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | /* | ||
- | 1. Folosiți Teorema Master pentru a rezolva următoarele recurențe: | ||
- | |||
- | * $ T_1(n) = 4T_1(n/4) + 1$ | ||
- | <hidden Exemplu de cod cu aceasta recurenta> | ||
- | <code c> | ||
- | // O metoda destul de ineficienta de calcul al sumei elementelor unui vector | ||
- | int sum(int arr[], int lo, int hi) { | ||
- | if(lo == hi) | ||
- | return arr[lo]; | ||
- | int x = (hi - lo) / 4; | ||
- | return sum(arr, lo, lo + x) + | ||
- | sum(arr, lo + x + 1, lo + 2 * x) + | ||
- | sum(arr, lo + 2 * x + 1, lo + 3 * x) + | ||
- | sum(arr, lo + 3 * x + 1, hi); | ||
- | } | ||
- | </code> | ||
- | </hidden> | ||
- | * $ T_3(n) = 4T_3(n/2) + n^2$ | ||
- | * $ T_2(n) = 8T_2(n/2) + 2n^2$ | ||
- | |||
- | 2. Fie următorul algoritm de căutare a unei valori ''v'' într-un array sortat ''arr'': | ||
- | |||
- | <code c> | ||
- | int search(int arr[], int lo, int hi, int v) | ||
- | { | ||
- | int mid = (lo + hi) / 2; | ||
- | if (arr[mid] == v) | ||
- | return mid; | ||
- | if (lo == hi) | ||
- | return -1; | ||
- | if (arr[mid] > v) | ||
- | return search(arr, lo, mid, v); | ||
- | else | ||
- | return search(arr, mid, hi, v); | ||
- | } | ||
- | |||
- | </code> | ||
- | |||
- | * Determinați relația de recurență a algoritmului de căutare prezentat. | ||
- | * Demonstrați recurența utilizând Teorema Master. | ||
- | * Demonstrați recurența utilizând Metoda Arborilor. | ||
- | * Demonstrați recurența utilizând Metoda Substituției. | ||
- | |||
- | 3. Folosiți cele 3 metode (metoda arborilor, metoda substituției, teorema master) pentru a rezolva recurențele: | ||
- | |||
- | * $ T_a(n) = 2T_a(n-1) + 1$ | ||
- | * $ T_b(n) = T_b(n-1) + 1$ | ||
- | * $ T_c(n) = 2T_c(n/2) + \log(n)$ | ||
- | * $ T_d(n) = T_d(n/9) + T_d(8n/9) + n$ | ||
- | * $ T_e(n) = T_e(2n/3) + 1$ | ||
- | * $ T_f(n) = T_f(\sqrt{n}) + 1$ (hint: substituiți $ n$ cu $ 2^k$) | ||
- | * $ T_g(n) = 2T_g(\sqrt{n}) + n$ (hint: substituiți $ n$ cu $ 2^k$) | ||
- | * $ T_h(n) = \sqrt{n}T_h(\sqrt{n}) + n$ (hint: substituiți $ n$ cu $ 2^k$) | ||
- | |||
- | 4. Rezolvați următoarea recurență folosind metoda substituției: $math[T(n) = 2 T(\frac{n}{2}) + 1]. | ||
- | |||
- | 5. Rezolvați următoarea recurență folosind metoda arborilor: $math[T(n) = T(] $math[n \over 4] $math[) + T(] $math[3n \over 4] $math[) + n]. | ||
- | */ |