Sunteți pe pagina 1din 9

ALGORTIMI DE PRELUCRARE A

GRAFURILOR
Realizat de: Botezat Gheorghe
Un graf G se definește ca fiind o pereche (V, E), unde V = {node / un nod oarecare din
graf}, iar E = {(x, y) / (x, y) muchie in graf}.

Un graf este neorientat dacă relațiile dintre noduri sunt bidirecționale: oricare ar fi (x,y)


(x,y) în EE, există și (y,x)(y,x) în EE. Relațiile se numesc muchii.

Un graf este orientat dacă relațiile dintre noduri sunt unidirecționale: (x,y)(x,y) este


Definiții în EE nu implică neapărat (y,x)(y,x) în EE. Relațiile se numesc arce.

O componentă conexă (CC) este o submulțime maximală de noduri, cu proprietatea că


oricare ar fi două noduri x și y din aceasta, există drum de la x la y. Pentru grafuri orientate,
o componentă conexă se numește componentă tare conexă (CTC).

Un graf aciclic este un graf (orientat/neorientat) care nu conține cicluri.


Reprezentare

• Problemele care se modelează folosind grafuri, de obicei, presupun explorarea spațiului. O parcurgere
explorează fiecare nod al grafului, exact o singură dată, pornind de la un nod ales, numit în continuare
nod sursă (EN: source). Modul de reprezentare ar grafului, poate influența performanța unei
parcurgeri/unui algoritm.
Un graf poate fi modelat în mai multe moduri:

• printr-o pereche de mulțimi G=(V,E)G=(V,E)


• VV = {v / v este un nod în graf} = mulțimea nodurile grafului (EN:
nodes / vertices)
• EE = {e / e=(x,y)e=(x,y) este o muchie în graf între nodurile x și y} =
mulțimea muchiile/arcelor (EN: edges), fiecare muchie stabilind o
relație de vecinătate între doua noduri.
• printr-o pereche G=(nodes,a)G=(nodes,a)
• nodesnodes = {node / node este un nod în graf}
• a[x][y]=0/1a[x][y]=0/1
• 1 = există muchia/arcul (x, y)
• 0 = NU există muchia/arcul (x, y)
• printr-o pereche de mulțimi G=(nodes,adj)G=(nodes,adj)
• nodesnodes = {node / node este un nod în graf}
• adjadj = {adj[node]adj[node] /
unde adj[node]adj[node] este lista de adiacență a lui
node} = reprezentarea grafului ca liste de adiacențe
• adj[node]=...,neigh,...adj[node]=...,neigh,... ⇒
există muchie/arc (node, neigh)
Colorare
Algoritmii de parcugere se pot folosi de o colorare a
nodurilor:

white (alb) = nod care nu a fost încă vizitat (nu este în


coadă)

gray (gri) = nod care este în curs de vizitare (a fost


adăugat în coadă)

black (negru) = nod care a fost complet vizitat (node


scos din coadă și pentru care s-a vizitat tot subarborele)
• Problemă: Să se parcurgă un graf dat. Fiecare
Algoritmi de nod se parcuge (exact) o singură dată. Algoritmi:
• BFS
parcurgere • DFS
BFS - Parcurgerea în lățime

• Parcurgerea în lățime (Breadth-first Search -


BFS) este un algoritm de căutare în graf, în care, atunci
când se ajunge într-un nod oarecare node, nevizitat, se
vizitează toate nodurile nevizitate adiacente lui (notate
pe rand cu neigh), apoi toate vârfurile nevizitate
adiacente vârfurilor adiacente lui node, etc.
• BFS depinde de nodul de start source
• Pentru implementarea BFS se folosește o coadă.
Algoritm
// do a BFS traversal from source

//

// source    = the source for the BFS traversal

// nodes     = list of all nodes from G

// adj[node] = the adjacency list of node

//             example: adj[node] = {..., neigh, ...} => edge (node, neigh)

BFS(source, G=(nodes, adj)) {

    // STEP 0: initialize results

    // d[node] = distance from source to node

    // p[node] = parent of node in the BFS traversal started from source

    // [optional] color[node] = white/gray/black

    //                              * white = not yet visited

    //                              * gray  = visit in progress

    //                              * black = visited

    foreach (node in nodes) {

        d[node] = +oo;                          // distance not yet computed

        p(node) = null;                         // parent not yet found

        // [optional] color[node] = white;

    }

    // STEP 1: initialize a queue

    q = {}
DFS - Parcurgerea în adâncime
• Parcurgerea în adâncime (Depth-First Search - DFS) pornește de la
un nod dat (node), care este marcat ca fiind în curs de procesare. Se
alege primul vecin nevizitat al acestui nod (neigh), se marchează și
acesta ca fiind în curs de procesare, apoi și pentru acest vecin se caută
primul vecin nevizitat, și așa mai departe. În momentul în care nodul
curent nu mai are vecini nevizitati, se marchează că fiind deja procesat
și se revine la nodul anterior. Pentru acest nod se caută primul vecin
nevizitat. Algoritmul se repetă până când toate nodurile grafului au
fost procesate.

• Pentru fiecare nod se vor reține:


• start[node]start[node] = timestamp-ul / timpul descoperirii
• finish[node]finish[node] = timestamp-ul / timpul finalizării
• p[node]p[node] = părintele din parcugerea DFS a lui node
• Spre deosebire de BFS, pentru implementarea DFS se folosește o stivă
(abordare LIFO în loc de FIFO). În practică, stiva nu va fi reținută
explicit - ci ne vom baza pe recursivitate.

S-ar putea să vă placă și