Differences

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

Link to this comparison view

pp:26:teme:haskell-graphs [2026/03/25 16:23]
mihnea.muraru [Etapa 2]
pp:26:teme:haskell-graphs [2026/04/27 15:55] (current)
mihnea.muraru
Line 1: Line 1:
-====== Haskell: ​Graph Zoo ======+====== Haskell: ​Grafuri funcționale ​======
  
-  * Data publicării: ​TODO +  * Data publicării: ​27.04.2026 
-  * Data ultimei modificări: ​TODO+  * Data ultimei modificări: ​27.04.2026
   * Deadline hard: ziua laboratorului 12   * Deadline hard: ziua laboratorului 12
-  * Forum temă+  * [[https://​curs.upb.ro/​2025/​mod/​forum/​view.php?​id=169983|Forum temă]]
   * [[https://​vmchecker.cs.pub.ro/​ui/#​PP|vmchecker]]   * [[https://​vmchecker.cs.pub.ro/​ui/#​PP|vmchecker]]
  
Line 23: Line 23:
   * una pe care o veți rezolva după laboratorul 11, cu deadline în ziua laboratorului 12, la ora 08:00.   * una pe care o veți rezolva după laboratorul 11, cu deadline în ziua laboratorului 12, la ora 08:00.
  
-Așa cum se poate observa, **ziua deadline-ului variază în funcție de semigrupa în care sunteți repartizați**. **Restanțierii care refac tema și nu refac laboratorul beneficiază de ultimul deadline** (deci vor avea deadline-uri în zilele de TODO).+Așa cum se poate observa, **ziua deadline-ului variază în funcție de semigrupa în care sunteți repartizați**. **Restanțierii care refac tema și nu refac laboratorul beneficiază de ultimul deadline** (deci vor avea deadline-uri în zilele de 08.05, 15.05, 22.05 și 29.05).
  
 **Rezolvările tuturor etapelor pot fi trimise până la ora 08:00 în ziua laboratorului 12** (**deadline hard pentru toate etapele**). Orice exercițiu trimis după un **deadline soft**, dar înainte de cel hard, se punctează cu **jumătate** din punctaj. Orice exercițiu trimis după deadline-ul hard nu se mai punctează deloc. Nota finală pe etapă se calculează conform formulei: **n = (n1 + n2) / 2** (n1 = nota obținută înainte de deadline; n2 = nota obținută după deadline). Când toate submisiile sunt înainte de deadline-ul soft, nota pe ultima submisie este și nota finală (întrucât n1 = n2). **Rezolvările tuturor etapelor pot fi trimise până la ora 08:00 în ziua laboratorului 12** (**deadline hard pentru toate etapele**). Orice exercițiu trimis după un **deadline soft**, dar înainte de cel hard, se punctează cu **jumătate** din punctaj. Orice exercițiu trimis după deadline-ul hard nu se mai punctează deloc. Nota finală pe etapă se calculează conform formulei: **n = (n1 + n2) / 2** (n1 = nota obținută înainte de deadline; n2 = nota obținută după deadline). Când toate submisiile sunt înainte de deadline-ul soft, nota pe ultima submisie este și nota finală (întrucât n1 = n2).
Line 56: Line 56:
     * Funcția ''​%%splitNode%%''​ **sparge** un nod în mai multe noduri, ținând cond de arcele nodului inițial.     * Funcția ''​%%splitNode%%''​ **sparge** un nod în mai multe noduri, ținând cond de arcele nodului inițial.
     * Funcția ''​%%mergeNodes%%''​ **îmbină** mai multe noduri într-unul singur, ținând cont de arcele nodurilor inițiale.     * Funcția ''​%%mergeNodes%%''​ **îmbină** mai multe noduri într-unul singur, ținând cont de arcele nodurilor inițiale.
-  * ''​%%Algorithms%%'':​ conține algoritmii standard de **căutare**,​ BFS și DFS: +  * ''​%%Algorithms%%'':​ conține algoritmii standard de **căutare**,​ BFS și DFS, **restricționați** pentru simplitate la grafuri pentru care nu există mai multe căi între două noduri și nici cicluri. 
-    * Funcțiile ''​%%bfs%%''​ și ''​%%dfs%%''​ întorc lista de noduri parcurse în ordinea aferentă **căutării în lățime**, respectiv **în adâncime**,​ pornind de la un anumit nod, ținând cont și de posibilele cicluri. Aceste funcții vor fi **derivate** dintr-o funcție mai generală, menționată în continuare. +    * Funcțiile ''​%%bfs%%''​ și ''​%%dfs%%''​ întorc lista de noduri parcurse în ordinea aferentă **căutării în lățime**, respectiv **în adâncime**,​ pornind de la un anumit nod.
-    * Funcția ''​%%search%%''​ **generalizează** cele două strategii de căutare de mai sus, plecând de la observația că principala diferență dintre ele este modul în care se **combină** la un moment dat nodurile deja existente în structura de date utilizată (stivă/​coadă,​ ambele reprezentate ca liste standard) cu vecinii proaspăt expandați ai nodului curent. Funcția **nu este testată direct**.+
     * Funcția ''​%%countIntermediate%%''​ verifică **existența unei căi** între două noduri din graf, și calculează **numărul nodurilor intermediare** pe care le expandează cele două strategii de mai sus pentru acest scop.     * Funcția ''​%%countIntermediate%%''​ verifică **existența unei căi** între două noduri din graf, și calculează **numărul nodurilor intermediare** pe care le expandează cele două strategii de mai sus pentru acest scop.
  
Line 75: Line 74:
 Găsiți detalii despre **funcționalitate** și **implementare**,​ precum și **exemple**,​ direct în codul sursă. Aveți de completat definițiile care încep cu **''​%%*** TODO ***%%''​**. Găsiți detalii despre **funcționalitate** și **implementare**,​ precum și **exemple**,​ direct în codul sursă. Aveți de completat definițiile care încep cu **''​%%*** TODO ***%%''​**.
  
-Se impun următoarele **constrângeri** de implementare:​+Se impun următoarele **constrângeri** de implementare ​asupra funcțiilor din modulul ''​StandardGraph''​:
  
-  * Toate funcțiile din această etapă, cu excepția ''​%%search%%'', ​trebuie implementate **FĂRĂ recursivitate explicită**. +  * Toate trebuie implementate **FĂRĂ recursivitate explicită**. 
-  * Funcțiile ​trebuie să opereze **direct pe mulțimile** de noduri și arce, utilizând funcțiile specifice acestei reprezentări,​ **FĂRĂ conversii** redundante la liste și înapoi la mulțimi.+  * Ele trebuie să opereze **direct pe mulțimile** de noduri și arce, utilizând funcțiile specifice acestei reprezentări,​ **FĂRĂ conversii** redundante la liste și înapoi la mulțimi.
  
 Este suficient ca arhiva pentru **vmchecker** să conțină modulele ''​%%StandardGraph%%''​ și ''​%%Algorithms%%''​. Este suficient ca arhiva pentru **vmchecker** să conțină modulele ''​%%StandardGraph%%''​ și ''​%%Algorithms%%''​.
 +
 +**ATENȚIE!** După ce experimentați în modulul ''​Algorithms''​ cu funcțiile de **debug** din schelet, ''​appendDebug''​ și ''​concatMapDebug'',​ așa cum se precizează în comentarii, **reveniți** la versiunile obișnuite ale acestora, ''​(++)''​ și ''​concatMap'',​ pentru a evita generarea mesajelor stufoase pe vmchecker.
  
 ==== Depunctări ==== ==== Depunctări ====
  
-Funcțiile care nu respectă cele două constrângeri de mai sus vor fi **depunctate total**.+  * Funcțiile ​din modulul ''​StandardGraph'' ​care nu respectă cele două constrângeri de mai sus vor fi **depunctate total**. 
 +  * Funcțiile din modulul ''​Algorithms''​ care nu respectă constrângerile din schelet ​vor fi **depunctate total**.
 ===== Etapa 2 ===== ===== Etapa 2 =====
  
Line 163: Line 165:
 Veți implementa aspecte legate de descompunerea modulară parțial ca bonus, în cadrul etapelor 2 și 3. Deși există [[https://​www.sciencedirect.com/​science/​article/​pii/​S0166218X04002458|algoritmi eficienți (liniari)]] pentru determinarea descompunerii modulare, aceștia sunt destul de complicați,​ astfel că vom utiliza o abordare mai simplă bazată pe forță brută. Cu alte cuvinte, vom genera **toate partițiile** mulțimii de noduri, și apoi le vom filtra pentru a obține modulele. Veți implementa aspecte legate de descompunerea modulară parțial ca bonus, în cadrul etapelor 2 și 3. Deși există [[https://​www.sciencedirect.com/​science/​article/​pii/​S0166218X04002458|algoritmi eficienți (liniari)]] pentru determinarea descompunerii modulare, aceștia sunt destul de complicați,​ astfel că vom utiliza o abordare mai simplă bazată pe forță brută. Cu alte cuvinte, vom genera **toate partițiile** mulțimii de noduri, și apoi le vom filtra pentru a obține modulele.
  
-În etapa 2, **scheletul** conține următoarele module:+Ca încălzire:​ 
 +  * Gândiți-vă cum se poate **redefini** tipul ''​%%StandardGraph%%''​ din etapa 1 ca **tip de date utilizator** (''​%%data%%''​)în locul sinonimului de tip pereche. 
 +  ​Funcțiile ''​%%nodes%%''​ și ''​%%edges%%''​ pot fi definite direct drept **câmpuri** în cadrul tipului. 
 +  * Funcția ''​%%fromComponents%%''​ trebuie și ea redefinită
 +  * Schițați în comentarii redefinirea celor patru entități de mai sus. Această parte nu este testată automat, dar o veți **prezenta**. 
 +  * Nu este necesar să reimplementați celelalte funcții din acest modul.
  
-  * ''​%%StandardGraph%%'':​ implementat în etapa 1. Reprezentarea originală este de **pereche** de mulțimi de noduri, respectiv arce. Ca încălzire: +În etapa 2, **scheletul** conține următoarele module:
-    * Gândiți-vă cum se poate **redefini** tipul ''​%%StandardGraph%%''​ ca **tip de date utilizator** (''​%%data%%''​),​ în locul sinonimului de tip pereche. +
-    * Funcțiile ''​%%nodes%%''​ și ''​%%edges%%''​ pot fi definite direct drept **câmpuri** în cadrul tipului. +
-    * Funcția ''​%%fromComponents%%''​ trebuie și ea redefinită. +
-    * Schițați în comentarii redefinirea celor patru entități de mai sus. Această parte nu este testată automat, dar o veți **prezenta**. +
-    * Nu este necesar să reimplementați celelalte funcții din acest modul.+
   * ''​%%AlgebraicGraph%%'':​ conține **reprezentarea algebrică** a grafurilor, descrisă mai sus   * ''​%%AlgebraicGraph%%'':​ conține **reprezentarea algebrică** a grafurilor, descrisă mai sus
     * Tipul ''​%%AlgebraicGraph%%''​ este cel prezentat mai sus.     * Tipul ''​%%AlgebraicGraph%%''​ este cel prezentat mai sus.
     * Mai departe, veți implementa **aceleași funcții** ca în modulul ''​%%StandardGraph%%'',​ cu excepția ''​%%fromComponents%%'',​ dar de data aceasta vor opera pe reprezentarea algebrică.     * Mai departe, veți implementa **aceleași funcții** ca în modulul ''​%%StandardGraph%%'',​ cu excepția ''​%%fromComponents%%'',​ dar de data aceasta vor opera pe reprezentarea algebrică.
-    * Toate funcțiile vor fi implementate **CU recursivitate explicită**. 
     * Veți observa că implementările funcțiilor ''​%%removeNode%%'',​ ''​%%splitNode%%''​ și ''​%%mergeNodes%%''​ respectă un **tipar similar**, pe care vom căuta să îl generalizăm în etapa 3.     * Veți observa că implementările funcțiilor ''​%%removeNode%%'',​ ''​%%splitNode%%''​ și ''​%%mergeNodes%%''​ respectă un **tipar similar**, pe care vom căuta să îl generalizăm în etapa 3.
-    * **ATENȚIE!** Funcțiile de mai sus trebuie să opereze **direct pe reprezentarea algebrică** din această etapă. **NU este permisă** convertirea în reprezentarea din etapa 1 și utilizarea funcțiilor de acolo. 
   * ''​%%Modular%%'':​ conține momentan doar câteva funcții pentru determinarea **descompunerii modulare** a grafului, dar va fi îmbogățit în etapa 3:   * ''​%%Modular%%'':​ conține momentan doar câteva funcții pentru determinarea **descompunerii modulare** a grafului, dar va fi îmbogățit în etapa 3:
     * Funcția ''​%%mapSingle%%''​ este asemănătoare cu ''​%%map%%'',​ în sensul că aplică o funcție asupra fiecărui element al unei liste, dar aplicarea se face asupra unui **singur element** din listă la un moment dat, celelalte rămânând nemodificate.     * Funcția ''​%%mapSingle%%''​ este asemănătoare cu ''​%%map%%'',​ în sensul că aplică o funcție asupra fiecărui element al unei liste, dar aplicarea se face asupra unui **singur element** din listă la un moment dat, celelalte rămânând nemodificate.
     * Funcția ''​%%partitions%%''​ generează toate partițiile unei liste.     * Funcția ''​%%partitions%%''​ generează toate partițiile unei liste.
 +
 +Se impun următoarele **constrângeri** de implementare asupra funcțiilor din modulul ''​AlgebraicGraph'':​
 +
 +  * Toate trebuie implementate **CU recursivitate explicită**.
 +  * Toate trebuie să opereze **direct pe reprezentarea algebrică** din această etapă. **NU este permisă** convertirea în reprezentarea din etapa 1 și utilizarea funcțiilor de acolo.
 +
 +Este suficient ca arhiva pentru **vmchecker** să conțină modulele ''​%%AlgebraicGraph%%''​ și ''​%%Modular%%''​.
  
 ==== Depunctări ==== ==== Depunctări ====
  
-Funcțiile care nu respectă constrângerile de mai sus, și cele din scheletvor fi **depunctate total**.+Funcțiile care nu respectă constrângerile de mai sus sau pe cele din schelet vor fi **depunctate total**.
  
 ===== Etapa 3 ===== ===== Etapa 3 =====
Line 225: Line 232:
     * Funcția ''​%%maximalModularPartition%%''​ determină cea mai acoperitoare partiție, pornind de la lista tuturor partițiilor mulțimii de noduri (vedeți explicațiile din comentarii).     * Funcția ''​%%maximalModularPartition%%''​ determină cea mai acoperitoare partiție, pornind de la lista tuturor partițiilor mulțimii de noduri (vedeți explicațiile din comentarii).
     * Funcția ''​%%modularlyDecompose%%''​ este **deja implementată**,​ și vă permite să puneți cap la cap funcțiile de mai sus.     * Funcția ''​%%modularlyDecompose%%''​ este **deja implementată**,​ și vă permite să puneți cap la cap funcțiile de mai sus.
 +
 +Este suficient ca arhiva pentru **vmchecker** să conțină modulele ''​%%AlgebraicGraph%%''​ și ''​%%Modular%%''​.
  
 ==== Depunctări ==== ==== Depunctări ====
Line 233: Line 242:
 ===== Precizări ===== ===== Precizări =====
  
 +  * Pentru **rularea testelor**, încărcați în interpretor modulul ''​%%TestGraph%%''​ și evaluați ''​%%checkAll%%''​.
   * Încercați să folosiți pe cât posibil funcții **predefinite** din modulele ''​[[https://​hackage-content.haskell.org/​package/​base-4.22.0.0/​docs/​Data-List.html|Data.List]]''​ și ''​[[https://​hackage.haskell.org/​package/​containers-0.6.7/​docs/​Data-Set.html|Data.Set]]''​. Este foarte posibil ca o funcție de prelucrare de care aveți nevoie să fie deja definită aici.   * Încercați să folosiți pe cât posibil funcții **predefinite** din modulele ''​[[https://​hackage-content.haskell.org/​package/​base-4.22.0.0/​docs/​Data-List.html|Data.List]]''​ și ''​[[https://​hackage.haskell.org/​package/​containers-0.6.7/​docs/​Data-Set.html|Data.Set]]''​. Este foarte posibil ca o funcție de prelucrare de care aveți nevoie să fie deja definită aici.
   * Ca sugestie, exploatați cu încredere //**pattern matching**//,​ **''​%%case%%''​** și **gărzi**, în locul //​if//​-urilor imbricate.   * Ca sugestie, exploatați cu încredere //**pattern matching**//,​ **''​%%case%%''​** și **gărzi**, în locul //​if//​-urilor imbricate.
-  * Pentru **rularea testelor**, încărcați în interpretor modulul ''​%%TestGraph%%''​ și evaluați ''​%%checkAll%%''​. 
  
 ===== Resurse ===== ===== Resurse =====
  
-  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​22/​teme/​haskell/​etapa1.zip|Schelet etapa 1]] +  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​26/​teme/​haskell/​etapa1.zip|Schelet etapa 1]] 
-  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​22/​teme/​haskell/​etapa2.zip|Schelet etapa 2]] +  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​26/​teme/​haskell/​etapa2.zip|Schelet etapa 2]] 
-  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​22/​teme/​haskell/​etapa3.zip|Schelet etapa 3]]+  * [[https://​ocw.cs.pub.ro/​courses/​_media/​pp/​26/​teme/​haskell/​etapa3.zip|Schelet etapa 3]]
  
 ===== Referințe ===== ===== Referințe =====
pp/26/teme/haskell-graphs.1774448586.txt.gz · Last modified: 2026/03/25 16:23 by mihnea.muraru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0