This is an old revision of the document!


Haskell: Graph Zoo

Obiective

  • Aplicarea mecanismelor funcționale, de tipuri (inclusiv polimorfism) și de evaluare leneșă din limbajul Haskell.
  • Exploatarea evaluării leneșe pentru decuplarea conceptuală a prelucrărilor realizate.

Descriere generală și organizare

Tema urmărește familiarizarea cu două modalități de reprezentare a grafurilor orientate, una standard (prin mulțimi de noduri și de arce) și alta constructivă (algebrică), adecvată unei abordări funcționale. Veți avea ocazia să implementați diverse operații de manipulare a grafurilor sub ambele reprezentări, astfel încât să puteți compara punctele lor tari și slabe.

Tema este împărțită în 3 etape:

  • una pe care o veți rezolva după laboratorul 7, cu deadline dependent de ziua în care aveți laboratorul:
    • laborator marți ⇒ deadline 26 aprilie
    • laborator miercuri ⇒ deadline 27 aprilie
    • laborator joi ⇒ deadline 28 aprilie
    • laborator vineri ⇒ deadline 29 aprilie
    • laborator luni ⇒ deadline 2 mai
  • una pe care o veți rezolva după laboratorul 8, cu deadline la o săptămână după deadline-ul etapei 1
  • una pe care o veți rezolva după laboratorul 9, cu deadline la o săptămână după deadline-ul etapei 2.

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 02.05, 09.05, 16.05).

Rezolvările tuturor etapelor pot fi trimise până în ziua laboratorului 10, dar orice exercițiu trimis după deadline se punctează cu jumătate din punctaj. 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, nota pe ultima submisie este și nota finală (întrucât n1 = n2).

În fiecare etapă, veți folosi ce ați învățat în săptămâna anterioară pentru a dezvolta aplicația.

Pentru fiecare etapă există un schelet de cod (dar rezolvarea se bazează în mare măsură pe rezolvările anterioare). Enunțul caută să ofere o imagine de ansamblu atât la nivel conceptual, cât și în privința aspectelor care se doresc implementate, în timp ce detaliile se găsesc direct în schelet.

Etapa 1

În această etapă:

  • veți lucra cu una dintre reprezentările standard ale grafurilor orientate, bazată pe mulțimi de noduri și arce
  • veți defini funcții de manipulare a acestei reprezentări și veți implementa câțiva algoritmi uzuali.

Construcțiile și mecanismele de limbaj pe care le veți exploata în rezolvare sunt:

  • liste, pentru reprezentarea ordinii nodurilor într-o parcurgere etc.
  • mulțimi, pentru unicitatea nodurilor și a arcelor într-un graf, pentru verificarea facilă e egalității a două grafuri, fără a ține cont de ordinea nodurilor și a arcelor etc.
  • funcționale, atât pe liste, cât și pe mulțimi, ocazie cu care veți vedea conceptul în acțiune și pe alte structuri decât listele standard
  • list comprehensions, unde le veți considera utile
  • evaluare leneșă, implicită în Haskell, pentru decuplarea conceptuală a construcției unei structuri de parcurgerea acesteia.

În schelet veți găsi două module:

  • StandardGraph: conține reprezentarea grafului orientat și funcții de acces și manipulare:
    • tipul StandardGraph a, deja definit ca pereche între o mulțime de noduri și una de arce
    • funcția fromComponents construiește un graf pe baza nodurilor și arcelor
    • funcțiile nodes și edges întorc cele două mulțimi de mai sus
    • funcțiile outNeighbors și inNeghbors întorc mulțimile de vecini înspre care ies, respectiv dinspre care intră arce către nodul curent
    • funcția removeNode înlătură un nod și toate arcele sale din graf
    • 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
  • Algorithms: conține algoritmii standard de căutare, BFS și DFS:
    • 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ția search generalizează cele două strategii de căutare de mai sus, plecând de la observația că singura 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.

Găsiți detalii despre funcționalitate și implementare, precum și exemple, direct în codul sursă. Veți avea de completat definițiile care încep cu *** TODO ***.

Pentru reprezentarea mulțimilor, veți folosi tipul predefinit Set a, similar tipului listă [a]. Având în vedere că există funcții pe mulțimi cu același nume ca cele pe liste (de exemplu, map, filter), pentru evitarea conflictului de nume, abordarea standard, adoptată și în temă, este de a importa etichetat modulul necesar (import qualified Data.Set as S), urmând ca toate tipurile și funcțiile din acest modul să fie utilizate cu numele prefixat: S.Set a, S.map, S.filter etc.

ATENȚIE! Toate funcțiile din această etapă, cu excepția search, vor fi implementate FĂRĂ recursivitate explicită. Nerespectarea acestei cerințe va conduce la o depunctare de 10p/100 per funcție.

Este suficient ca arhiva pentru vmchecker să conțină modulele StandardGraph și Algorithms.

Precizări

  • Încercați să folosiți pe cât posibil funcții predefinite din modulele Data.List și Data.Set. Este foarte posibil ca o funcție de prelucrare de care aveți nevoie să fie deja definită aici.
  • 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

Changelog

  • 17.04 (12:47) - Etapa 1 - Actualizare checker cu ordinea corectă a valorilor testate și corecte. În versiunea anterioară erau inversate, lucru ce ducea la mesaje de eroare confuze.
pp/22/teme/haskell-graph-zoo.1650189069.txt.gz · Last modified: 2022/04/17 12:51 by bot.pp
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