Differences

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

Link to this comparison view

Both sides previous revision Previous revision
aa:lab:10 [2025/01/23 14:10]
dmihai
aa:lab:10 [2025/12/15 14:30] (current)
dmihai
Line 1: Line 1:
-====== ​Recurențe ​====== +====== ​Probleme "​dificile" ​======
-/* +
-<note important>​ +
-Solutii:+
  
-https://​drive.google.com/​file/​d/​11tR3YphFS73OF8QGvtorjf_dkRHPmo1y/​view?​usp=drivesdk +În acest laborator veți explora un graf realist cu date despre toate aeroporturile din lume și rutele dintre ele și veți aplica diverși algoritmi *eficienți* pe acesta
-</​note>​ +Momentan, puteți considera termenul "​eficient"​ să însemne "​fără backtracking"​ (mai precis, ne referim la conceptul de polinomial, i.e. cu o complexitate descrisă de $ O(n^k)$, pentru un $ k$ natural; vom relua conceptul la curs).
-*/+
  
-<note important>​ +Descărcați ​de aici arhiva cu datele de intrare: {{:aa:lab:lab.zip|}}
-Teorema Master se poate aplica pe recurente ​de forma:+
  
-  * $ T(n) = a * T(\frac n b) + f(n); a \ge 1; b > 1 $+Aceasta conține în directorul ''​res/''​ trei fișiere cu date despre aeroporturi și rute:
  
-In functie de $ f(n) $ apar urmatoarele cazuri: + ​- ​''​airroutes.in''​ - din lume  ​\\ 
-  ​- ​$ f(n) = \Theta(n^c) ; c < \log_ba $                                  $ \Rightarrow T(n) = \Theta(n^{\log_ba}) $  + - ''​eu-airroutes.in''​ - din Europa ​ \\ 
-  ​- $ f(n) = \Theta(n^c * \log^kn); k \geq 0; c = \log_ba $       ​        $ \Rightarrow T(n) = \Theta(n^{\log_ba}*\log^{k+1}n) $ + ​- ​''​ro-airroutes.in''​ - din România
-  $ f(n) = \Theta(n^c);​ c > \log_ba $                                   $ \Rightarrow T(n) = \Theta(f(n)) $    +
-</​note> ​+
  
 +Fișierele descriu grafuri orientate, ale căror noduri au ID-uri întregi începând de la 0; respectă următorul format:
  
-1. FolosițTeorema Master pentru a rezolva ​următoarele ​recurențe:+ - pe prima linia, numărul de noduri ''​N''​ șnumărul de muchii din graf, separate de un spațiu. \\ 
 + - pe următoarele ​''​N''​ linii, informații despre un nod  \\ 
 + - pe linia ''​i''​ (probabil indexată de la 1 în editorul de text), găsiți informații despre nodul cu ID ''​i - 2''​\\ 
 +    - [[https://​www.iata.org/​en/​publications/​directories/​code-search/​|codul IATA]] al aeroporturlui \\ 
 +    - toate rutele de la acel aeroport exprimate folosind trei numere: ID-ul aeroportului destinație,​ distanța zborului în kilometri, durata zborului în minute.
  
-   * $ T_1(n) = 4T_1(n/4) + 1$ +<note
-<hidden Exemplu de cod cu aceasta recurenta>​ +Fișierele sunt doar o versiune parser-friendly a datelor din acest JSON: https://github.com/Jonty/airline-route-data/blob/main/airline_routes.json
-<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_2(n) = 4T_2(n/2) + n^2$ +
-   * $ T_3(n) = 8T_3(n/2) + 2n^4$+
  
-2. Fie următorul algoritm de căutare a unei valori ​''​v'' ​într-un array sortat ''​arr'':​+În ''​tools/​extract_c_friendly.py'' ​găsiți scriptul care a realizat extragerea. 
 +</​note>​
  
-<code c> +==== Exerciții ====
-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>​+1. Scrieți un program care parsează un fișier de intrare cu formatul descris și reține graful în memorie. Programul apoi primește un singur cod IATA al unui aeroport(de la ''​stdin''​ sau ca argument în linia de comandă), determină toți vecinii și printează codurile lor IATA pe o singură linie separate de câte un spațiu.
  
-  * Determinați relația de recurență a algoritmului ​de căutare prezentat. +2. Scrieți un program cu același input ca mai sus dar care scrie ''​N''​ linii într-un fișier: pentru fiecare aeroport, linia corespunzătoare ID-ului trebuie să conțină codul IATA urmat de numărul minim de noduri prin care se poate ajunge acolo (pentru aeroportul de referință primit ca input, printați "​-"​ în loc de număr, iar pentru aeroporturile la care nu se poate ajunge printați "​unreachable"​).
-  * 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.+
  
-3Folosiți cele 3 metode ​(metoda arborilor, metoda substituției, teorema masterpentru a rezolva recurențele:​+BONUS: folosiți [[https://​web.stanford.edu/​class/​archive/​cs/​cs161/​cs161.1182/​Lectures/​Lecture11/​CS161Lecture11.pdf|algoritmul lui Djikstra]] pentru a calcula cea mai scurtă rută din punct de vedere al distanței șal timpului ​(scrieți rezultatele în fișiere diferite).
  
-   * $ T_a(n) = 2T_a(n-1) + 1$ +3. Care sunt cele mai îndepărtate aerporturi de OTP pentru fiecare metrică? Dar de LHR (London Heathrow)? 
-   * $ T_b(n) = T_b(n-1) + 1$ +Care e cea mai mare distanță posibilă între oricare două aeroporturi,​ pentru fiecare metrică? 
-   * $ T_c(n) = 2T_c(n/2) + \log(n)$ +Care este cel mai izolat aeroport, pentru fiecare metrică? ​(aeroportul cu cea mai mare distanță medie către toate celelalte aeroporturi)
-   * $ T_d(n) = T_d(n/9) + T_d(8n/9) + n$ +
-   * $ T_e(n) = T_e(2n/3) + 1$ +
-   * $ T_{Strassen}(n) = 7T_{Strassen}(n/​2) + n^2 $\\ +
-Aceasta recurenta descrie [[https://​en.wikipedia.org/​wiki/​Strassen_algorithm| Algoritmul Strassen]] +
-   * $ T_{Karatsuba}(n= 3T_{Karatsuba}(n/​2) + 1 $\\ +
-Aceasta recurenta descrie [[https://​en.wikipedia.org/​wiki/​Karatsuba_algorithm| Algoritmul Karatsuba]] +
-   * $ T_{Quicksort}(n= T_{Quicksort}(n-1) + O(n) $\\ +
-Aceasta recurenta descrie [[https://​en.wikipedia.org/​wiki/​Quicksort| Algoritmul Quicksort]]+
  
-4. Rezolvați următoarea recurență folosind metoda substituției: $math[T(n) = 2 T(\frac{n}{2}) + 1].+4. Determinați toate componentele conexe ale grafului folosind BFS sau DFS la alegere. 
 +Scrieți componentele într-un alt fișier de output, câte una pe linie; fiecare componentă conexă e descrisă de codurile IATA a tuturor aeroporturilor din care e formată, separate de un spațiu.
  
-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].+5. Creați un graf neorientat pe baza grafului inițial. Vom crea muchii neorientate doar între acele aeroporturi între care există muchii în ambele sensuri (pentru weight, folosiți media celor două muchii orientate). 
 +Determinați dacă există o clică de dimensiune 20 în graful rezultat. Dar de 30? 
 +Folosiți o căutare exhaustivă de forma: 
 + 
 +- inițializați o mulțime goală \\ 
 +- la fiecare pas: \\ 
 +    - adăugați un nod (e.g. următorul în ordinea IDîn mulțime; dacă nu mai sunt noduri, reveniți la pasul anterior ​\
 +    - verificați dacă mulțimea e clică; dacă nu, înapoi la pasul anterior \\ 
 +    - verificați dacă sunt k$ elemente în mulțime; dacă nu, treceți la pasul următor; altfel printați clica 
 + 
 +Scrieți clica într-un fișier separat într-un format similar cu al fișierelor ''​*.in''​. 
 + 
 +BONUS: încercați să implementați orice fel de euristică ce ar grăbi procesarea (în general, sau pe anumite tipuri de grafuri), **păstrând însă garanția că răspunsul întors este cel corect**. 
 + 
 +6. Scrieți un alt program care citește un graf neorientat complet dintr-un fișier ​(clica anterioarăși rezolvă problema comisului voiajor (Traveling Salesman Problem), prin căutare exhaustivă. 
 +Încercați grafuri mici întâi și încercați să determinați cât timp durează rularea în funcție de numărul de noduri.
  
  
-<​note>​ 
-Soluțiile acestui laborator se găsesc [[https://​ocw.cs.pub.ro/​ppcarte/​doku.php?​id=aa:​lab:​sol:​10|aici]] 
-</​note>​