This shows you the differences between two versions of the page.
pp:25:teme:racket-ph [2025/03/15 08:44] mihaela.balint |
pp:25:teme:racket-ph [2025/03/21 12:16] (current) mihaela.balint [Racket: Heap-uri de împerechere] |
||
---|---|---|---|
Line 2: | Line 2: | ||
* Data publicării: 01.03.2025 | * Data publicării: 01.03.2025 | ||
- | * Data ultimei modificări: 15.03.2025 ([[pp:25:teme:racket-ph#changelog]]) | + | * Data ultimei modificări: 21.03.2025 ([[pp:25:teme:racket-ph#changelog]]) |
* Tema (o arhivă .zip cu toate fișierele .rkt folosite în etapa curentă) se va încărca pe [[https://vmchecker.cs.pub.ro/ui/#PP|vmchecker]] | * Tema (o arhivă .zip cu toate fișierele .rkt folosite în etapa curentă) se va încărca pe [[https://vmchecker.cs.pub.ro/ui/#PP|vmchecker]] | ||
===== Descriere generală și organizare ===== | ===== Descriere generală și organizare ===== | ||
Line 291: | Line 291: | ||
* -20p*n: unde n = numărul de funcții dintre ''best-k'', ''update-pairs'', ''best-k-ratings-overall'' rezolvate fără a folosi named let conform enunțului | * -20p*n: unde n = numărul de funcții dintre ''best-k'', ''update-pairs'', ''best-k-ratings-overall'' rezolvate fără a folosi named let conform enunțului | ||
* -0p: Vă încurajăm să folosiți let și let* pentru a evita calculele duplicate, chiar dacă nu există depunctări referitoare la acest aspect. | * -0p: Vă încurajăm să folosiți let și let* pentru a evita calculele duplicate, chiar dacă nu există depunctări referitoare la acest aspect. | ||
+ | |||
+ | ===== Etapa 4 ===== | ||
+ | |||
+ | Când interesează percepția "tipică" a utilizatorilor asupra unui film, mediana rating-urilor poate fi mai relevantă decât media, cu precădere când lista de rating-uri conține valori extreme, care pot distorsiona semnificativ media. | ||
+ | Întrucât rating-urile pentru un film sosesc în flux continuu, pe măsură ce filmul înregistrează noi vizionări, și valoarea medianei trebuie actualizată frecvent. În loc să recalculăm această valoare de fiecare dată când filmul primește o nouă recenzie, ea poate fi menținută în mod dinamic, cu ajutorul a două heap-uri de împerechere: | ||
+ | * un max-PH care reține jumătatea cu cele mai mici rating-uri | ||
+ | * un min-PH care reține jumătatea cu cele mai mari rating-uri | ||
+ | * cele două PH-uri trebuie să rămână echilibrate: în cel mai nebalansat caz, max-PH va conține o valoare mai mult decât min-PH | ||
+ | * fiecare nouă recenzie implică inserarea noului rating în PH-ul aferent (cel cu rating-uri mai mari sau mai mici, după caz) și reechilibrarea celor două PH-uri | ||
+ | * pentru a implementa cu ușurință acest proces, la un anumit moment t unui film îi va corespunde un cvartet ''(nume-film delta max-ph min-ph)'', unde ''delta'' reprezintă diferența dintre dimensiunea lui ''max-ph'' și dimensiunea lui ''min-ph'' (0 sau 1) | ||
+ | * mediana va fi: | ||
+ | * media rădăcinilor celor 2 PH-uri, pentru număr par de recenzii | ||
+ | * rădăcina lui max-PH, pentru număr impar de recenzii | ||
+ | |||
+ | În etapa 4 veți implementa acest algoritm pentru calculul dinamic al medianei, pe baza unui flux de recenzii modelat ca flux Racket. | ||
+ | |||
+ | Noutatea etapei constă în lucrul cu **fluxuri**: | ||
+ | * Recenziile care intră în sistem sunt modelate ca flux | ||
+ | * Stadiile de evoluție ale medianelor sunt modelate ca flux | ||
+ | * Fiecare nouă recenzie corespunde unui moment de timp t, iar pentru fiecare moment de timp t vom depune un "stadiu" în fluxul rezultat - informația despre cât erau medianele filmelor la momentul t | ||
+ | Este important sa discerneți între situațiile în care operați cu liste și cele în care operați cu fluxuri: | ||
+ | * Intrările și ieșirile algoritmului sunt fluxuri - reflectă o evoluție temporală potențial infinită | ||
+ | * Fiecare element din fluxul rezultat este o listă - este necesară o listă pentru că interesează "starea" tuturor filmelor la un anumit moment t | ||
+ | |||
+ | Aveți de implementat următoarele funcții: | ||
+ | * ''(add-rating quad rating)'' - primește un cvartet tip ''(nume-film delta max-ph min-ph)'' și un rating, și întoarce cvartetul actualizat prin inserarea rating-ului în PH-ul aferent și reechilibrarea PH-urilor | ||
+ | * ex: <code scheme> | ||
+ | (add-rating '(a 0 (4) (7)) 5) | ||
+ | </code> | ||
+ | * întrucât 5 > 4 (rating > root(max-ph)), 4 este inserat în min-ph => \\ ''%%'(a -1 (4) (5 (7)))%%'' | ||
+ | * întrucât delta < 0, root(min-ph) este mutat în max-ph => \\ ''%%'(a 1 (5 (4)) (7))%%'' | ||
+ | * ''%%(reviews->quads reviews)%%'' - transformă un flux de recenzii (recenzie = pereche (nume-film . rating)) într-un flux de stadii (stadiu = listă de cvartete: câte un cvartet pentru fiecare film care a primit recenzii până în acest moment) | ||
+ | * ex: <code scheme> | ||
+ | (reviews->quads (stream '(a . 4) '(b . 1) '(a . 2))) | ||
+ | </code> | ||
+ | * la început nu avem informații despre niciun film | ||
+ | * la momentul t = 1, avem de adăugat rating-ul ''4'' pentru filmul '''a'' => \\ se creează un cvartet pentru filmul '''a'', în care doar max-PH-ul conține valoarea ''4'' => \\ ''%%'((a 1 (4) ()))%%'' este primul stadiu de evoluție (o listă care conține un singur cvartet) | ||
+ | * la momentul t = 2, avem de adăugat rating-ul ''1'' pentru filmul '''b'' => \\ se creează un cvartet pentru filmul '''b'', în care doar max-PH-ul conține valoarea ''1'' => \\ ''%%'((b 1 (1) ()) (a 1 (4) ()))%%'' este al doilea stadiu de evoluție (o listă cu două cvartete) | ||
+ | * la momentul t = 3, avem de adăugat rating-ul ''2'' pentru filmul '''a'' => \\ se actualizează cvartetul pentru filmul '''a'' prin adăugarea rating-ului ''2'' => \\ ''%%'((b 1 (1) ()) (a 0 (2) (4)))%%'' este al treilea stadiu de evoluție | ||
+ | * rezultatul apelului este un flux care conține cele 3 liste de mai sus (cele 3 stadii) | ||
+ | * ''%%(quads->medians quads)%%'' - transformă un flux de stadii reprezentate folosind cvartete într-un flux de stadii reprezentate folosind mediane | ||
+ | * ex: <code scheme> | ||
+ | (quads->medians (reviews->quads (stream '(a . 4) '(b . 1) '(a . 2)))) | ||
+ | </code> | ||
+ | * lista de cvartete ''%%'((a 1 (4) ()))%%'' devine lista de perechi ''%%'((a . 4))%%'' \\ (pentru filmul '''a'', mediana coincide cu singurul rating primit) | ||
+ | * lista de cvartete ''%%'((b 1 (1) ()) (a 1 (4) ()))%%'' devine lista de perechi ''%%'((b . 1) (a . 4))%%'' | ||
+ | * lista de cvartete ''%%'((b 1 (1) ()) (a 0 (2) (4)))%%'' devine lista de perechi ''%%'((b . 1) (a . 3))%%'' \\ (pentru '''a'', mediana este media celor 2 rating-uri, conform formulei pentru număr par de rating-uri) | ||
+ | * rezultatul apelului este un flux care conține cele 3 liste de perechi de mai sus | ||
+ | |||
+ | ==== Depunctări generate de nerespectarea cerințelor din enunț ==== | ||
+ | Baremul depunctărilor posibile în etapa 4 este: | ||
+ | * -20p: dacă faceți conversii din liste în fluxuri sau din fluxuri în liste, în loc să operați direct cu interfața pentru fluxuri (când creați/manipulați fluxuri) și cu interfața pentru liste (când creați/manipulați liste) | ||
+ | * -20p: dacă funcția ''%%quads->medians%%'' folosește recursivitate explicită sau nu folosește o funcțională pe fluxuri | ||
===== Precizări ===== | ===== Precizări ===== | ||
Line 308: | Line 361: | ||
* {{:pp:25:teme:racket:etapa2.zip|etapa 2}} | * {{:pp:25:teme:racket:etapa2.zip|etapa 2}} | ||
* {{:pp:25:teme:racket:etapa3.zip|etapa 3}} | * {{:pp:25:teme:racket:etapa3.zip|etapa 3}} | ||
+ | * {{:pp:25:teme:racket:etapa4.zip|etapa 4}} | ||
/* | /* | ||
Line 317: | Line 371: | ||
===== Changelog ===== | ===== Changelog ===== | ||
+ | * 21.03 (ora 12:16) - Am publicat etapa 4. | ||
* 15.03 (ora 08:45) - Am publicat etapa 3. | * 15.03 (ora 08:45) - Am publicat etapa 3. | ||
* 07.03 (ora 15:15) - Am publicat etapa 2. | * 07.03 (ora 15:15) - Am publicat etapa 2. |