This shows you the differences between two versions of the page.
sda-ab:laboratoare:09 [2021/03/06 20:26] smaranda.bogoi |
sda-ab:laboratoare:09 [2021/04/18 11:54] (current) gabriel.rusu [1. Obiectivele laboratorului] |
||
---|---|---|---|
Line 6: | Line 6: | ||
*Definirea structurii și elementelor unui graf neorientat | *Definirea structurii și elementelor unui graf neorientat | ||
*Definirea structurii și elementelor unui graf orientat | *Definirea structurii și elementelor unui graf orientat | ||
+ | *Modalitati de parcurgere a grafurilor | ||
- | Structura laboratorului se gaseste in **[[http://gooogle.com|acest link.]]** | + | Structura laboratorului se gaseste in **[[https://github.com/sda-ab/lab-08-tasks|acest link.]]** |
====== 2. Grafuri neorientate ====== | ====== 2. Grafuri neorientate ====== | ||
Line 81: | Line 82: | ||
***0**,dacă nodul i nu este o extremitate a arcului | ***0**,dacă nodul i nu este o extremitate a arcului | ||
{{ :sda-ab:laboratoare:graf3.png?400 |}} | {{ :sda-ab:laboratoare:graf3.png?400 |}} | ||
+ | |||
+ | ====== 4.Parcurgerea grafurilor ====== | ||
+ | |||
+ | **Parcurgere** (traversal) = metoda de vizitare sistematica a fiecarui varf sau arc din graf. | ||
+ | <note important>Parcurgerile pot sa tina loc de cautare (Search/Traversal)</note> | ||
+ | |||
+ | Tipuri de parcurgeri: | ||
+ | ***în lățime/pe nivel** - Breadth First Search/Traversal (BFS/T) | ||
+ | ***în adâncime** - Depth First Search/Traversal (DFS/T) | ||
+ | |||
+ | === 4.1.Parcurgerea în lățime === | ||
+ | Parcurgerea in latime (Breadth First Traversal) a unui graf e similara cu parcurgerea pe niveluri a unui arbore cu diferenta ca intr-un graf putem sa avem **cicluri**. | ||
+ | Parcurgerea în lățime (**Breadth-First-Search -BFS**) este o metodă ce presupune vizitarea nodurilor în următoarea ordine: | ||
+ | *Nodul sursa | ||
+ | *nodul sursă (considerat a fi pe nivelul 0) | ||
+ | *vecinii nodului sursă (reprezentând nivelul 1) | ||
+ | *vecinii încă nevizitați ai nodurilor de pe nivelul 1 (reprezentând nivelul 2) | ||
+ | *ș.a.m.d | ||
+ | === 4.1.1 Implementare === | ||
+ | |||
+ | Pe masură ce algoritmul avansează,se colorează nodurile în felul următor: | ||
+ | *alb - nodul este nedescoperit încă | ||
+ | *gri - nodul a fost descoperit și este în curs de procesare | ||
+ | *negru - procesarea nodului s-a încheiat Se păstrează informațiile despre distanța până la nodul sursă. Se obține arborele BFS | ||
+ | {{ :sda-ab:laboratoare:animated_bfs.gif?400 |}} | ||
+ | |||
+ | Pentru implementarea BFS se utilizează o coadă (Q) în care inițial se află doar nodul sursă.Se vizitează pe rând vecinii acestui nod și se pun și ei în coadă.În momentul în care nu mai există vecini nevizitați,nodul sursă este scos din coadă. | ||
+ | |||
+ | <code c> | ||
+ | Pentru fiecare nod u din graf | ||
+ | { | ||
+ | culoare[u]=alb | ||
+ | d[u] = infinit //in d se retine distanta pana la nodul sursa | ||
+ | p[u] = null // | ||
+ | } | ||
+ | |||
+ | culoare[sursă]=gri | ||
+ | d[sursă]=0 | ||
+ | enqueue(Q,sursă) //punem nodul sursă în coada Q | ||
+ | |||
+ | Cât timp coada Q nu este vidă | ||
+ | { | ||
+ | v=dequeue(Q) //extragem nodul v din coadă | ||
+ | pentru fiecare u dintre vecinii lui v | ||
+ | dacă culoare[u] == alb | ||
+ | { | ||
+ | culoare[u] = gri | ||
+ | p[u] = v | ||
+ | d[u] = d[v] + 1 | ||
+ | enqueue(Q,u) //adăugăm nodul u în coadă | ||
+ | } | ||
+ | culoare[v] = negru //am terminat explorarea vecinilor lui v | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | {{ :sda-ab:laboratoare:bfs.jpg?500 |}} | ||
+ | |||
+ | **Aplicatii BFS/T** | ||
+ | *Gasirea celui mai scurt drum intre 2 varfuri | ||
+ | *Identificarea arborelui minim de acoperire (ca si DFT) | ||
+ | *Identificarea componentelor conexe (ca si DFT) | ||
+ | |||
+ | === 4.2.Parcurgerea în în adâncime === | ||
+ | |||
+ | Parcurgea în adâncime (**Depth-First-Search -DFS**) presupune explorarea nodurilor în următoarea ordine: | ||
+ | *Nodul sursă | ||
+ | *Primul vecin nevizitat al nodului sursă (îl numim V1) | ||
+ | *Primul vecin nevizitat al lui V1 (îl numim V2) | ||
+ | *ș.a.m.d | ||
+ | *În momentul în care am epuizat vecinii unui nod Vn, continuăm cu următorul vecin nevizitat al nodului anterior,Vn-1 | ||
+ | |||
+ | Această metoda de parcurgere pune prioritate pe explorarea **în adâncime** (pe distanțe **tot mai mari față** de nodul sursă). | ||
+ | |||
+ | {{ :sda-ab:laboratoare:dfs.gif?500 |}} | ||
+ | |||
+ | === 4.2.1 Implementare === | ||
+ | |||
+ | Spre deosebire de BFS, DFS utilizează o **stivă** în loc de o **coadă**. Putem defini o stivă sau ne putem folosi de stiva compilatorului, prin apeluri recursive. | ||
+ | |||
+ | <code c> | ||
+ | funcţie pasDFS(curent) | ||
+ | { | ||
+ | pentru fiecare u dintre vecinii nodului curent | ||
+ | dacă culoare[u] == alb | ||
+ | { | ||
+ | culoare[u] = gri | ||
+ | p[u] = curent | ||
+ | d[u] = d[curent] + 1 | ||
+ | pasDFS(u); //adăugăm nodul u în "stivă" şi începem explorarea | ||
+ | } | ||
+ | culoare[curent] = negru //am terminat explorarea vecinilor nodului curent | ||
+ | //ieşirea din funcţie este echivalentă cu eliminarea unui element din stivă | ||
+ | } | ||
+ | Pentru fiecare nod u din graf | ||
+ | { | ||
+ | culoare[u]=alb | ||
+ | d[u] = infinit //in d se retine distanta pana la nodul sursa | ||
+ | p[u] = null | ||
+ | } | ||
+ | culoare[sursă] = gri; | ||
+ | d[sursă] = 0; | ||
+ | |||
+ | //se apelează iniţial pasDFS(sursă) | ||
+ | </code> | ||
+ | |||
+ | {{ :sda-ab:laboratoare:df1.jpg?400 |}} | ||
+ | |||
+ | **Aplicatii DFS/T** | ||
+ | *determinarea unui drum intre 2 varfuri u si v | ||
+ | *daca un graf neorientat este conex sau nu | ||
+ | *daca graful are cicluri | ||
+ | *componente tare conexe in grafuri orientate (**OBS** spunem ca un graf orientat se numeste **tare conex** daca exista drum intre oricare doua varfuri) | ||
+ | *daca un graf este bipartit | ||
+ | *pentru determinarea componentelor conexe dintr-un graf neorientat | ||
+ | *pentru generarea unui arbore de acoperire (**nu** este neaparat unic) | ||
+ | |||
+ | ====== 5. Exercitii ====== | ||
+ | Implementaţi, pentru fiecare cerinţă, câte o funcţie care: | ||
+ | *creează matricea de adiacenţă pentru un graf neorientat cu N noduri, folosindu-se de o listă(sau o matrice cu 2 coloane) de muchii(la alegere - muchiile citite în funcţie sau primite printr-un parametru). | ||
+ | *calculează gradul fiecărui nod. Afişaţi numărul de noduri izolate şi numărul de noduri terminale. | ||
+ | *primeşte un şir de noduri şi verifică dacă acesta poate reprezenta un lanţ. | ||
+ | *primeşte un şir de noduri şi afişează matricea de adiacenţă a subgrafului format cu nodurile respective | ||
+ | **OBS** - Cerintele 2, 3, 4 se vor folosi de matricea de adiacenţă a grafului de la cerinţa 1. | ||