Note de curs, clasele 9-10, 28 noiembrie 2013

From Algopedia
Jump to navigationJump to search

Definiții și terminologie

  • definiție: un graf este o pereche (V, E) unde V este o mulțime (nodurile), iar E este o relație binară pe V (muchiile).
  • reprezentare grafică
  • într-un graf neorientat, muchiile sunt perechi neordonate („linii”); spunem că muchiile sunt adiacente nodurilor
  • într-un graf orientat, muchiile sunt perechi ordonate („săgeți”); spunem că muchiile „intră” sau „ies” din noduri
  • nodul v îi este adiacent lui u dacă există o muchie (u, v) ∈ E
    • relația este simetrică dacă graful este neorientat
  • un graf se numește simplu dacă are cel mult o muchie între două noduri și nu are muchii de la un nod la el însuși
    • un graf care nu este simplu se numește multigraf; majoritarea problemelor de informatică sunt pe grafuri simple
  • gradul unui nod este numărul de muchii incidente
    • în grafuri orientate, gradul este suma gradelor la intrare și la ieșire
  • un graf G' = (V', E') este subgraf al lui G = (V, E) dacă V' ⊆ V și E' ⊆ E
  • dacă V' ⊆ V, subgraful indus de V' este graful cu nodurile V' și muchiile din E care leagă noduri din V'
  • muchiile pot avea și costuri. Costul este o funcție c : E → R

Exemple din lumea reală

  • prieteniile / cunoștințele
  • orașe cu drumuri între ele
  • conducte prin care curge apă
  • ierarhia unei companii

Conexitate

  • o cale este un șir de noduri astfel încât oricare două noduri consecutive sunt unite printr-o muchie
    • dacă există o cale de la u la v, spunem că v este accesibil din u.
    • o cale simplă conține doar vârfuri distincte
  • un ciclu este o cale de cel puțin o muchie în care primul nod este egal cu ultimul
  • un graf neorientat este conex dacă orice pereche de noduri sunt conectate printr-o cale
  • componentele conexe ale unui graf neorientat sunt o partiție a grafului astfel încât oricare două noduri sunt accesibile unul dintr-altul dacă și numai dacă sunt în aceeași submulțime
    • echivalent, componentele conexe sunt clase de echivalență în funcție de relația „este accesibil din”
  • un graf orientat este tare conex dacă oricare două noduri sunt reciproc accesibile
  • componentele tare conexe ale unui graf sunt clase de echivalență în funcție de relația „sunt reciproc accesibile”
  • (o relație de echivalență este reflexivă, simetrică și tranzitivă; exemple: =, = mod n)
  • într-un graf neorientat, un nod este nod critic sau nod de articulație dacă, prin eliminarea lui, numărul de componente conexe crește
  • similar, o muchie se numește muchie critică sau punte dacă, prin eliminarea ei, numărul de componente conexe crește
  • un graf fără noduri de articulație se numește biconex
  • componentele biconexe sunt subgrafuri biconexe maximale

Grafuri speciale

  • un graf complet este un graf neorientat în care între orice două noduri există o muchie
  • un graf bipartit este un graf neorientat în care nodurile pot fi partiționate în două submulțimi V1 și V2 astfel încât toate muchiile să ducă din V1 în V2
  • un arbore este un graf neorientat aciclic
    • o pădure este un graf aciclic (fiecare din componentele sale conexe este un arbore)
  • un dag (directed acyclic graph) este un graf orientat aciclic (folosim această prescurtare întrucât conceptul apare des)

Proprietăți

  • suma gradelor este 2 |E|
    • corolar: numărul nodurilor de grad impar este par
  • un arbore este un graf aciclic maximal
  • un arbore este un graf aciclic cu |V| - 1 muchii
  • un arbore este un graf conex minimal
  • un arbore este un graf conex cu |V| - 1 muchii

Reprezentări

În primul rând, câtă informație este într-un graf? De câte numere avem nevoie pentru a descrie în mod unic graful? De O(m). Numărul de noduri și lista muchiilor sunt suficiente.

Matricea de adiacență are marele avantaj că poate răspunde la întrebări de tipul „este u vecin cu v” în O(1). Ea are însă mari dezavantaje:

  • necesită O(n2) spațiu, asimptotic mai prost decât O(m)
  • iterarea prin toți vecinii unui nod v se face în timp O(n), în general mai prost decât grad(v)
  • iterarea prin toate muchiile se face în timp O(n2)

Listele de adiacență inversează avantajele și dezavantajele:

  • pot răspunde la întrebări de tipul „este u vecin cu v” în O(grad(u))
  • necesită O(m + n) memorie, deci optim
  • iterarea prin toți vecinii unui nod v se face în timp O(grad(v)), deci optim
  • iterarea prin toate muchiile se face în timp O(m + n)

Dacă ni se specifică la intrare gradele fiecărui nod, putem prealoca vectori de adiacență. Altfel trebuie să lucrăm cu liste înlănțuite. Listele se creează într-un vector prealocat de 2m muchii, nu prin alocare dinamică!

Parcurgerea în lățime a unui graf

Este o generalizare a algoritmului lui Lee pe matrice, pe care îl cunoașteți. În engleză, se numește breadth-first search (BFS). Ea pornește dintr-un nod ales s și explorează toate nodurile accesibile. Pe parcurs, ea calculează o informație importantă pentru fiecare nod descoperit: distanța minimă față de s.

  • folosește o coadă de noduri descoperite, dar încă neexplorate
  • folosește, conceptual, trei culori pentru fiecare nod: alb (nod nedescoperit), gri (nod descoperit, dar neexplorat), negru (nod explorat complet)
    • aceste culori nu sunt reprezentate explicit în algoritm
  • exemplu grafic
  • vedem că algoritmul expandează o frontieră de noduri tot mai depărtate de s; de aceea se numește parcurgere în lățime
  • algoritmul calculează distanța fiecărui nod până la s și drumul pe care se obține această distanță

Cod aici.

Timpul de rulare este O(m + n). Inițializarea este O(n), apoi fiecare nod și fiecare muchie sunt parcurse o singură dată. Remarcăm, în special, că valorile p și d sunt atribuite o singură dată pentru fiecare nod.

Demonstrația de corectitudine a distanțelor calculate

Fie δ(s, u) distanța minimă teoretică (cel mai scurt drum între s și u). Dorim să demonstrăm că δ(s, u) = d[u] pentru fiecare nod u.

  • trebuie să ținem cont și de nodurile inaccesibile din s, pentru care δ(s, u) = ∞
  • pentru orice muchie (u, v), δ(s, v) ≤ δ(s, u) + 1 -- evident
  • d[v] ≥ δ(s, v)
    • demonstrație: inductiv, pentru tot graful, după numărul de modificări în d
    • cazul de bază: la început, d[s] = 0 și d[v] = ∞ pentru celelalte noduri
    • la modificarea lui d[v] avem d[v] = d[u] + 1 ≥ δ(s, u) + 1 ≥ δ(s, v)
  • coada conține mereu noduri cu d crescător și cu diferență de cel mult 1
    • demonstrație: prin inducție după operațiile pe coadă
  • d[v] = δ(s, v)
    • demonstrație: presupunem că există noduri care nu respectă această proprietate. Fie v unul dintre ele, cu δ(s, v) minim.
    • cum d[v] ≥ δ(s, v), rezultă că d[v] > δ(s, v)
    • fie u nodul anterior pe una din cele mai scurte căi de la s la v, așadar δ(s, v) = δ(s, u) + 1
    • prin alegerea lui v, rezultă că d[u] = δ(s, u) și deci d[v] > d[u] + 1
    • cum s-ar putea întâmpla așa ceva?
    • ce culoare poate avea v în momentul în care algoritmul îl scoate pe u din coadă? Pe toate cele trei cazuri ajungem la contradicții.

Probleme

  • pentru avansați: problemele de la Șumen 2013 (căutați 2013-11-24, seturile de probleme A și B)
  • implementare BFS: Capitala, Graf, Barbar
  • orice arbore este bipartit
  • într-un graf neorientat cu >= 2 noduri există două noduri cu același grad
  • într-un graf cu 6 noduri există un subgraf complet cu trei noduri sau un subgraf cu 3 noduri fără muchii
  • problema celebrității O(n)
  • Un ciclu eulerian este un ciclu care vizitează fiecare muchie a grafului exact o dată. Care este condiția necesară și suficientă ca un graf să admită un ciclu eulerian?