This shows you the differences between two versions of the page.
pp:23:teme:haskell-structuri-functionale [2023/04/24 22:45] bot.pp |
pp:23:teme:haskell-structuri-functionale [2023/05/04 10:44] (current) bot.pp |
||
---|---|---|---|
Line 2: | Line 2: | ||
* Data publicării: 11.04.2023 | * Data publicării: 11.04.2023 | ||
- | * Data ultimei modificări: 24.04.2023 | + | * Data ultimei modificări: 04.05.2023 |
* Deadline hard: ziua laboratorului 10 (11 pentru seria CB) | * Deadline hard: ziua laboratorului 10 (11 pentru seria CB) | ||
* [[https://curs.upb.ro/2022/mod/forum/view.php?id=173248|Forum temă]] | * [[https://curs.upb.ro/2022/mod/forum/view.php?id=173248|Forum temă]] | ||
Line 82: | Line 82: | ||
* primul arbore are rangul 0 și dimensiunea 1 | * primul arbore are rangul 0 și dimensiunea 1 | ||
- | * atașând la un arbore de rang ''%%r-1%%'' și dimensiune ''%%2^(r-1)%%'' o copie de-a sa, obținem un arbore de rang ''%%r%%'' și dimensiune ''%%2^r%%''. Nodurile bicolore surprind creșterea rangului unui nod de la ''%%r-1%%'' la ''%%r%%'' în urma atașării copiei. | + | * atașând la un arbore de rang ''%%r-1%%'' și dimensiune ''%%2^(r-1)%%'' o copie de-a sa, obținem un arbore de rang ''%%r%%'' și dimensiune ''%%2^r%%''; nodurile bicolore surprind creșterea rangului unui nod de la ''%%r-1%%'' la ''%%r%%'' în urma atașării copiei. |
În fig. 1, se observă mai mulți arbori binomiali, cu ranguri între 0 și 4, și că **înălțimea** unui arbore este egală cu **rangul** său. De asemenea, transpare o proprietate care derivă din modalitatea de construcție: copiii unui nod de rang ''%%r%%'' au rangurile ''%%r-1%%'', ''%%r-2%%'', ..., ''%%1%%'', ''%%0%%'', exact în această ordine **descrescătoare**. De exemplu, copiii rădăcinii de rang 4 au rangurile 3, 2, 1, 0. **Numele** de arbore binomial vine de la faptul că, pe nivelul ''%%i%%'' din arborele de rang ''%%r%%'', numărul de noduri este dat de **coeficientul binomial** „combinări de ''%%r%%'' luate câte ''%%i%%''”. | În fig. 1, se observă mai mulți arbori binomiali, cu ranguri între 0 și 4, și că **înălțimea** unui arbore este egală cu **rangul** său. De asemenea, transpare o proprietate care derivă din modalitatea de construcție: copiii unui nod de rang ''%%r%%'' au rangurile ''%%r-1%%'', ''%%r-2%%'', ..., ''%%1%%'', ''%%0%%'', exact în această ordine **descrescătoare**. De exemplu, copiii rădăcinii de rang 4 au rangurile 3, 2, 1, 0. **Numele** de arbore binomial vine de la faptul că, pe nivelul ''%%i%%'' din arborele de rang ''%%r%%'', numărul de noduri este dat de **coeficientul binomial** „combinări de ''%%r%%'' luate câte ''%%i%%''”. | ||
- | Continuăm cu prezentarea **//heap//-urilor binomiale**. Acestea nu sunt decât **liste de arbori binomiali**, cu constrângerea suplimentară că arborii trebuie să respecte și **proprietatea de //heap//**, i.e. rădăcina are **prioritate mai mică** decât copiii și analog pentru subarbori. Având în vedere faptul că toți arborii binomiali au dimensiuni puteri ale lui 2, principala întrebare este cum **distribuim** elementele //heap//-ului în cadrul acestor arbori, presupunând că numărul total de elemente nu este putere a lui 2. Aici intervine **reprezentarea binară a numerelor** din etapa 1. Dacă dimensiunea //heap//-ului este ''%%n%%'', având reprezentarea binară ''%%[b_0, b_1, ..., b_m]%%'', unde ''%%m = [lg n]%%'' (parte întreagă), atunci, pentru fiecare bit ''%%0%%'', vom avea un arbore **vid**, și pentru fiecare bit ''%%b_r%%'' egal cu ''%%1%%'' vom avea un arbore de **rang ''%%r%%''**, și implicit dimensiune ''%%2^r%%''. | + | Continuăm cu prezentarea **//heap//-urilor binomiale**. Acestea nu sunt decât **liste de arbori binomiali**, cu constrângerea suplimentară că arborii trebuie să respecte și **proprietatea de //heap//**, i.e. rădăcina are **prioritate mai mică** decât copiii și analog pentru subarbori. Având în vedere faptul că toți arborii binomiali au dimensiuni puteri ale lui 2, principala întrebare este cum **distribuim** elementele //heap//-ului în cadrul acestor arbori, presupunând că numărul total de elemente nu este putere a lui 2. Aici intervine **reprezentarea binară a numerelor** din etapa 1. Dacă **dimensiunea** //heap//-ului este ''%%n%%'', având reprezentarea binară ''%%[b_0, b_1, ..., b_m]%%'', unde ''%%m = [lg n]%%'' (parte întreagă), atunci, pentru fiecare bit ''%%0%%'', vom avea un arbore **vid**, și pentru fiecare bit ''%%b_r%%'' egal cu ''%%1%%'' vom avea un arbore de **rang ''%%r%%''**, și implicit dimensiune ''%%2^r%%''. |
**Exemplificăm** ideea de mai sus cu un //heap// cu 13 elemente, **reprezentarea binară a dimensiunii** fiind ''%%[1, 0, 1, 1]%%''. Aceasta înseamnă că avem un arbore de rang 0 (dimensiune 1), niciun arbore de rang 1, un arbore de rang 2 (dimensiune 4) și un arbore de rang 3 (dimensiune 8), ca în fig. 2. Observați de asemenea respectarea **proprietății de //heap//** de către fiecare dintre cei trei arbori. | **Exemplificăm** ideea de mai sus cu un //heap// cu 13 elemente, **reprezentarea binară a dimensiunii** fiind ''%%[1, 0, 1, 1]%%''. Aceasta înseamnă că avem un arbore de rang 0 (dimensiune 1), niciun arbore de rang 1, un arbore de rang 2 (dimensiune 4) și un arbore de rang 3 (dimensiune 8), ca în fig. 2. Observați de asemenea respectarea **proprietății de //heap//** de către fiecare dintre cei trei arbori. | ||
Line 133: | Line 133: | ||
Este suficient ca arhiva pentru **vmchecker** să conțină modulul ''%%BinomialHeap%%''. | Este suficient ca arhiva pentru **vmchecker** să conțină modulul ''%%BinomialHeap%%''. | ||
+ | |||
+ | ===== Etapa 3 ===== | ||
+ | |||
+ | În această etapă, veți continua să implementați anumite operații asupra //heap//-urilor binomiale, în continuarea celor din etapa 2. | ||
+ | |||
+ | Construcțiile și mecanismele noi de limbaj pe care le veți exploata în rezolvare, pe lângă cele din etapa 2, sunt: | ||
+ | |||
+ | * **polimorfismul ad-hoc** | ||
+ | * **clasele**. | ||
+ | |||
+ | Ultima operație fundamentală este de **eliminare** a cheii de **prioritate minimă** din //heap//. Am lăsat-o la final, deoarece utilizează operația de **combinare** (''%%mergeTrees%%'') implementată în etapa 2. Eliminarea presupune **înlăturarea primului arbore** cu rădăcină de prioritate minimă din lista de arbori ai //heap//-ului (prin înlocuirea lui cu ''%%EmptyTree%%'') și apoi **combinarea** (''%%mergeTrees%%'') noii liste de arbori cu lista de subarbori (orfani) ai rădăcinii tocmai înlăturate. Având în vedere că lista de arbori ai //heap//-ului este ordonată **crescător** în raport cu rangul, iar lista de subarbori orfani este ordonată **descrescător** (conform structurii arborilor binomiali), este necesară **inversarea** ultimeia înainte de combinarea celor două liste! Având la bază operația de combinare, rezultă că și cea de eliminare are complexitate **logaritmică**. | ||
+ | |||
+ | Scheletul etapei 3 se găsește tot în modulul ''%%BinomialHeap%%'', în continuarea operațiilor din etapa 2, începând cu linia 243: | ||
+ | |||
+ | * funcția ''%%isolate%%'' este ajutătoare, pregătind terenul pentru următoarea operație | ||
+ | * funcția ''%%removeMin%%'' înlătură prima cheie de prioritate minimă din //heap// | ||
+ | * instanțele clasei ''%%Show%%'' pentru tipurile ''%%BinomialTree p k%%'' și ''%%BinomialHeap p k%%'' oferă reprezentări mai lizibile, sub formă de șir de caractere ale celor două categorii de structuri; observați că a fost necesară eliminarea ''%%deriving Show%%'' din definiția tipurilor, pentru evitarea conflictului de instanțe | ||
+ | * instanțele clasei ''%%Functor%%'' pentru constructorii de tip ''%%BinomialTree p%%'' și ''%%BinomialHeap p%%'' generalizează funcționala ''%%map%%'' pe aceste categorii de structuri | ||
+ | * pentru **bonus**, instanța clasei ''%%Foldable%%'' pentru constructorul de tip ''%%BinomialTree p%%'' generealizează funcționala ''%%foldr%%'' pe aceste structuri. | ||
+ | |||
+ | Găsiți detaliile despre **funcționalitate** și despre **constrângerile de implementare**, precum și **exemple**, direct în schelet. Aveți de completat definițiile care încep cu ''%%*** TODO ***%%''. | ||
+ | |||
+ | Pentru **rularea testelor**, încărcați în interpretor modulul ''%%TestBinomialHeap%%'' și evaluați ''%%main%%''. | ||
+ | |||
+ | Este suficient ca arhiva pentru **vmchecker** să conțină modulul ''%%BinomialHeap%%''. Veți avea nevoie de implementarea funcției ''%%mergeTrees%%'' din etapa 2. | ||
===== Precizări ===== | ===== Precizări ===== | ||
Line 143: | Line 168: | ||
* [[https://ocw.cs.pub.ro/courses/_media/pp/23/teme/haskell/etapa1.zip|Schelet etapa 1]] | * [[https://ocw.cs.pub.ro/courses/_media/pp/23/teme/haskell/etapa1.zip|Schelet etapa 1]] | ||
* [[https://ocw.cs.pub.ro/courses/_media/pp/23/teme/haskell/etapa2.zip|Schelet etapa 2]] | * [[https://ocw.cs.pub.ro/courses/_media/pp/23/teme/haskell/etapa2.zip|Schelet etapa 2]] | ||
+ | * [[https://ocw.cs.pub.ro/courses/_media/pp/23/teme/haskell/etapa3.zip|Schelet etapa 3]] | ||
===== Changelog ===== | ===== Changelog ===== | ||
Line 148: | Line 174: | ||
* 22.04 (ora 16:10) Publicare etapa 2, doar enunț și schelet; urmează și checker-ul. | * 22.04 (ora 16:10) Publicare etapa 2, doar enunț și schelet; urmează și checker-ul. | ||
* 24.04 (ora 22:45) Publicare checker etapa 2. | * 24.04 (ora 22:45) Publicare checker etapa 2. | ||
+ | * 26.04 (ora 10:55) Actualizare checker etapa 2. Și ''%%BinomialHeap%%'' instanțiază acum ''%%Eq%%'' pentru facilitarea noilor teste. | ||
+ | * 28.04 (ora 14:50) Actualizare checker etapa 2 pt verificări mai flexibile. Dacă ați încărcat deja etapa 2 pe vmchecker, NU este necesară reîncărcarea. | ||
+ | * 30.04 (ora 10:30) Publicare etapa 3, doar enunț și schelet; urmează și checker-ul. | ||
+ | * 30.04 (ora 22:35) Actualizare checker etapa 2, în urma unor probleme semnalate de voi. Se verifică acum corespondența corectă dintre rangul arborilor și poziția acestora în lista heap-ului. | ||
+ | * 04.05 (ora 10:45) Publicare checker etapa 3. | ||