Sunteți pe pagina 1din 48

Contents

1. Ce este un algoritm?................................................................................................................................1
2. Ce este o instanţă a unei probleme?.......................................................................................................1
3. Ce este pseudocodul?..............................................................................................................................1
4. Ce înseamnă studierea eficienţei unui algoritm?.....................................................................................1
5. Cum se defineşte operaţia de sortare?....................................................................................................2
6. Când spunem despre o metodă de sortare că este stabilă şi când spunem că ea este “in situ”?............2
7. Prezentaţi principiul şi pseudocodul algoritmului de sortare prin inserţie..............................................2
8. Care sunt principiile şi în ce condiţii se poate aplica metoda Divide and Conquer?................................3
9. Prezentaţi principiul şi pseudocodul algoritmului de sortare prin interclasare.......................................3
10. Ce este un heap şi ce proprietăţi îndeplinesc elementele lui?...............................................................5
11. Prezentaţi şi explicaţi algoritmul de transformare a unui şir de intrare într-un heap şi algoritmul de
creare a unui heap.......................................................................................................................................5
12. Prezentaţi şi explicaţi algoritmul de sortare utilizând un heap..............................................................6
13. Prezentaţi principiul şi algoritmul sortării rapide...................................................................................7
14. Prezentaţi şi explicaţi algoritmul de partiţionare a unui şir în cazul sortării rapide (ambele variante,
inclusiv cel cu alegerea aleatoare a elementului pivot)...............................................................................8
15. Ce sunt tehnicile de programare?..........................................................................................................9
16. Principiile programării dinamice............................................................................................................9
17. Prezentaţi şi explicaţi algoritmul recursiv al tăierii barei de oţel.........................................................10
18. Prezentaţi şi explicaţi algoritmul tăierii barei de oţel utilizând metoda top-down din programarea
dinamică....................................................................................................................................................11
19. Prezentaţi şi explicaţi algoritmul tăierii barei de oţel utilizând metoda bottom-up din programarea
dinamică cu memorarea mărimilor bucăţilor ce vor fi tăiate....................................................................11
20. Prezentaţi şi explicaţi algoritmul bottom-up de determinare a costurilor înmulţirii unui şir de matrici.
.................................................................................................................................................................. 12
21. Prezentaţi şi explicaţi algoritmul recursiv de afişare a parantezării optime pentru un produs de n
matrici.......................................................................................................................................................13
22. Principiile metodei greedy...................................................................................................................13
23. Prezentaţi cum se utilizează metoda greedy în cazul problemei selecţiei activităţilor........................14
24. Prezentaţi şi explicaţi algoritmul recursiv greedy de selecţie a activităţilor........................................14
25. Prezentaţi şi explicaţi varianta greedy iterativă a algoritmului de selecţie a activităţilor....................15
26. Care sunt paşii pe care îi vom utiliza într-o strategie greedy?.............................................................15
27. Principiile şi algoritmul metodei backtracking.....................................................................................16
28. Prezentaţi şi explicaţi algoritmul nerecursiv de rezolvare a problemei damelor.................................18

1
29. Ce este un tip de date şi ce este un tip abstract de date (ADT Abstract Data Type)?..........................19
30. Ce este o listă, cum se poate implementa o listă şi ce avantaje şi dezavantaje are fiecare modalitate
de implementare?.....................................................................................................................................19
31. Prezentaţi şi explicaţi algoritmii de căutare, inserare în capul listei şi stergere într-o listă înlănţuită. 20
32. Prezentaţi şi explicaţi algoritmul de căutare respectiv inserare într-o listă dublu înlănţuită circulară cu
santinelă....................................................................................................................................................21
33. Ce este o stivă şi care sunt procedurile de depunere şi extragere dintr-o stivă?.................................22
34. Ce este o coadă şi care sunt procedurile de depunere şi extragere dintr-o coadă?............................23
35. Ce este o tabelă direct adresabilă şi care sunt operaţiile într-o tabelă direct adresabilă?..................24
36. Ce este o tabelă de dispersie, ce este o funcţie de dispersie, ce sunt şi cum se rezolvă coliziunile?...25
37. Prezentaţi şi explicaţi procedurile de inserare şi căutare într-o tabelă de dispersie............................26
38. Ce este un arbore binar de căutare?...................................................................................................27
39. Prezentaţi modalitătile de traversare a unui arbore binar şi algoritmii pentru fiecare din această
modalitate.................................................................................................................................................27
40. Prezentaţi şi explicaţi algoritmii iterativ respectiv recursiv de căutare într-un arbore binar de căutare.
.................................................................................................................................................................. 28
41. Prezentaţi şi explicaţi algoritmii de căutare a minimului, a maximului şi a succesorului într-un arbore
binar de căutare........................................................................................................................................29
42. Prezentaţi şi explicaţi algoritmul de inserare într-un arbore binar de căutare....................................30
43. Prezentaţi şi explicaţi algoritmul de ştergere într-un arbore binar de căutare....................................31
44. Ce este un arbore roşu şi negru şi ce proprietăţi are?.........................................................................32
45. Prezentaţi şi explicaţi algoritmul de rotaţie la stânga într-un arbore binar de căutare.......................32
46. Prezentaţi şi explicaţi algoritmul de inserare într-un arbore roşu şi negru..........................................33
47. Prezentaţi şi explicaţi algoritmul de restaurare a proprietăţilor unui arbore roşu şi negru după
inserarea unui nod.....................................................................................................................................33
48. Prezentaţi şi explicaţi algoritmul de restaurare a proprietăţilor unui arbore roşu şi negru după
ştergerea unui nod....................................................................................................................................34
49. Ce este un graf şi care sunt cele două moduri de a reprezenta un graf?.............................................34
50. Prezentaţi şi explicaţi algoritmul de parcurgere în lăţime pentru un graf reprezentat cu liste de
adiacenţă...................................................................................................................................................35
51. Ce este drumul de lungime minimă şi care este algoritmul de afişare a drumurilor de lungime
minimă?.....................................................................................................................................................37
52. Prezentaţi şi explicaţi algoritmul de parcurgere în adâncime pentru un graf reprezentat cu liste de
adiacenţă...................................................................................................................................................37
53. Ce este o sortare topologică şi care este algoritmul simplu de sortare topologică?............................38
54. Ce este o componentă tare conexă şi care este algoritmul de determinare a componentelor tare
conexe dintr-un graf orientat?..................................................................................................................39

2
55. Ce este un arbore de acoperire minim şi care este algoritmul generic de determinare a unui arbore
de acoperire minim?..................................................................................................................................39
56. Prezentaţi şi explicaţi algoritmul lui Kruskal de determinare a unui arbore de acoperire minim........40
57. Prezentaţi şi explicaţi algoritmul lui Prim de determinare a unui arbore de acoperire minim............41
58. Ce este un drum minim într-un graf şi care sunt variantele problemei drumului minim?...................42
59. Ce este relaxarea şi care este procedura de relaxare a unei muchii (u,v) într-un graf cu costuri........43
60. Prezentaţi şi explicaţi algoritmul Bellman-Ford de rezolvare a problemei drumurilor minime cu sursă
unică în cazul general al unui graf care poate avea şi costuri negative.....................................................43
61. Prezentaţi şi explicaţi algoritmul de căutare a drumurilor minime într-un graf orientat acyclic.........44
62. Prezentaţi şi explicaţi algoritmul lui Dijkstra de determinare a drumurilor de lungime minimă.........44

1. Ce este un algoritm?
Un algoritm este o procedură de calcul bine definită care primeşte o valoare sau o
mulţime de valori ca date de intrare şi produce o valoare sau mulţime de valori ca
date de ieşire. Este deci un şir de paşi care transformă datele de intrare în date de
ieşire.
Putem lua ca exemplu definirea problemei de sortare a unui şir de numere. Datele
de intrare (inputul) îl reprezintă o secvenţă de n numere (a1, a2, … an).
Datele de ieşire (outputul) îl reprezintă o permutare (sau o reordonare) (a1’, a2’,…
an’) a secvenţei de numere furnizată la intrare astfel încât a1’< a2’< …<an’.
Un algoritm de sortare, pentru o anumită secvenţă de numere (reprezentând
inputul) 31, 41, 59, 26 va produce la ieşire drept output secvenţa 26, 31, 41, 59.

2. Ce este o instanţă a unei probleme?


O instanţă a problemei reprezintă mulţimea tuturor datelor de intrare (care
satisface restricţiile impuse în definirea problemei) date necesare pentru a
determina o soluţie a problemei.

3. Ce este pseudocodul?
Pseudocodul este o modalitate de a descrie algoritmi; este similar cu schemele
logice. Un algoritm descris în pseudocod poate apoi să fie implementat în orice
limbaj de programare (C, Pascal etc).

3
4. Ce înseamnă studierea eficienţei unui algoritm?
Eficiența unui algoritm se referă la resursele de calcul și memorie necesare
pentru execuția algoritmului. Practic este un studiu teoretic al performanţei (în
primul rând) şi al resurselor utilizate. Progresele tehnologice din ultima perioadă
fac ca importanţa mărimii memoriei solicitate de un algoritm să scadă ca
importanţă. Ceea ce trebuie să intereseze programatorul este reducerea timpului de
execuţie al programului. Există aplicaţii “real time” la care constrângerile de timp
sunt cruciale.

5. Cum se defineşte operaţia de sortare?


Sortarea este o operaţie des întâlnită în rezolvarea problemelor de natură
algoritmică. Problema sortării unei mulţimi de obiecte se poate reduce la problema
sortării cheilor asociate acestora. După ce cheile sunt sortate, folosind informaţia
de asociere (care leagă cheia de obiectul căreia îi aparţine), se pot rearanja
obiectele în ordinea în care au fost aranjate cheile lor.

6. Când spunem despre o metodă de sortare că este stabilă şi când


spunem că ea este “in situ”?
O metodă de sortare se spune că este stabilă dacă după sortare, ordinea relativă a
elementelor cu chei egale coincide cu cea iniţială, element esenţial în special în
cazul în care se execută sortarea după mai multe chei.
O cerinţă fundamentală care se formulează faţă de metodele de sortare a tablourilor
se referă la utilizarea cât mai economică a zonei de memorie disponibile. Astfel,
algoritmii care utilizează doar zona de memorie alocată tabloului, fără a fi necesar
un tablou suplimentar se numesc sortări "în situ".

7. Prezentaţi principiul şi pseudocodul algoritmului de sortare prin


inserţie.
Principiul sortării prin inserţie este următorul:
 Pornim cu un şir gol de numere
 Luăm câte un număr din șirul inițial și îl plasăm în şirul sortat la poziția
corespunzătoare

4
 Plasarea numărului în șir la poziția corespunzătoare se face prin comparare
succesivă de la stânga la dreapta sau invers
 Pseudocodul aferent sortării prin inserţie este prezentat în figura 1

8. Care sunt principiile şi în ce condiţii se poate aplica metoda


Divide and Conquer?
Numită şi divide et impera (divide şi stăpâneşte), aceasta este o tehnică sau o
metodă de programare în care - principii:
 problema iniţială se sparge în subprobleme cu structură similară cu problema
originală, dar de dimensiune mai mică.
 aceste subprobleme sunt rezolvate recursiv
 soluţiile recursive sunt combinate pentru a produce soluţia problemei iniţiale
Metoda se poate aplica în rezolvarea unei probleme care îndeplineşte următoarele
condiţii:
 se poate descompune în două sau mai multe subprobleme
 aceste suprobleme sunt independente una faţă de alta (o subproblemă nu se
rezolvă pe baza alteia şi nu foloseşte rezultatele celeilalte)
 aceste subprobleme sunt similare cu problema iniţială
 la rândul lor subproblemele se pot descompune (dacă este necesar) în alte
subprobleme mai simple
 aceste subprobleme simple se pot soluţiona imediat prin algoritmul
simplificat

5
9. Prezentaţi principiul şi pseudocodul algoritmului de sortare prin
interclasare.
Sortarea prin interclasare se bazează pe următorul principiu: pentru a sorta un
vector cu n elemente, îl împărţim în 2 vectori, care, odată sortaţi, se interclasează.
Conform strategiei Divide and Conquer, descompunerea unui vector în alţi doi
vectori care urmează a fi sortaţi are loc până când avem de sortat vectori de un
element.
Sortarea prin interclasare are deci 3 paşi:

 Divide –şirul A de n elemente se împarte în două subşiruri de n/2 elemente


(în cazul în care n este impar dimensiunea primului şir este cu 1 mai mare
decât dimensiunea celui de al doilea şir)
 Conquer –se sortează recursiv cele două subşiruri
 Combine –se combină prin interclasare cele două şiruri sortate obţinute la
pasul Conquer, rezultând un singur şir sortat
Recursivitatea se încheie la şiruri de lungime 1, care sunt implicit deja sortate.
În continuare vom descrie procedura MERGE(A,p,q,r) care primeşte ca şi
parametruşirul A, poziţia p de la care începe sortarea, poziţia r la care se încheie
sortarea şi q o valoare între p şir, valoare care va împărţi şirul A[p]..A[q] în două
subşiruri A[p..q] şi A[q+1]..A[r].
Complexitatea procedurii Merge este ϴ(n) unde n=r-p+1 este numărul elementelor
interclasate. Merge sort nu este o sortare “in situ”, ea necesită spaţiu suplimentar
pentru a păstra subşirurile care apoi se vor interclasa.
Figura 1 prezintă algoritmul procedurii MERGE(A,p,q,r):

6
În figura 2 este prezentat algoritmul procedurii Merge-Sort:

10. Ce este un heap şi ce proprietăţi îndeplinesc elementele lui?


Un heap (o movilă) este un vector care poate fi vizualizat sub forma unui arbore
binar aproape complet cu proprietatea că cheia fiecărui nod din arbore este mai
mare decât cheile descendenţilor (deci fiecare nod are o cheie mai mică sau egală
cu cea a tatălui său). Ultimul rând al arborelui se completează de la stânga la
dreapta.

7
Un heap poate fi reprezentat sub forma unui arbore binar sau sub forma unui
vector. Astfel, dacă v este un vector care conţine reprezentarea unui heap avem
următoarea proprietate:
Elementele v[left]..v[n] îndeplinesc condiţia de structură a heapului:
i>left avem: v[i]>v[2*i], dacă 2*in, respectiv
v[i]>v[2*i+1] dacă 2*i+1n.
Evident, pentru valori ale lui i mai mari decât n/2 nu se pune problema îndeplinirii
condiţiilor de mai sus.

11. Prezentaţi şi explicaţi algoritmul de transformare a unui şir de


intrare într-un heap şi algoritmul de creare a unui heap.
Ca să putem folosi Heap Sort va trebui să transformăm şirul de intrare într-un heap.
Vom crea iniţial procedura MAX-HEAPIFY(A,i) care primeşte ca şi parametri un
vector A şi un indice i din vector.
Atunci când apelăm MAX-HEAPIFY se presupune că subarborii având ca rădăcini
nodurile Left(i) şi Right(i) sunt heapuri.
Dacă elementul A(i) este mai mic decât cel puţin unul din descendenţii Left(i) şi
Right(i), înseamnă că acest element nu respectă proprietatea de heap (deci nu avem
un heap şi va trebui transformat ca să devină heap).
Sarcina procedurii MAX-HEAPIFY este să “scufunde” în heap valoarea A(i) astfel
încât subarborele care are în rădăcină valoarea eleme ntului de indice i sa devină
un heap.

Figura 1 prezintă algoritmul MAX-HEAPIFY:

8
Vom construi heapul de jos în sus (de la frunze) (care sunt heap-uri de heapsize=1)
(figura 2).

12. Prezentaţi şi explicaţi algoritmul de sortare utilizând un heap.


Algoritmul de sortare utilizând un heap bazat pe algoritmii BUILD-MAX-HEAP şi
MAX-HEAPIFY.

13. Prezentaţi principiul şi algoritmul sortării rapide.


Quick Sort este un algoritm de sortare care pentru un şir de n elemente are un timp
de execuţie ϴ(n2) în cazul cel mai defavorabil. În ciuda acestei comportări proaste
pentru cazul cel mai defavorabil, acest algoritm este deseori cea mai bună soluţie
practică deoarece are o comportare medie remarcabilă: timpul mediu de execuţie
este ϴ(nlgn) şi constanta ascunsă în formula lui ϴ(nlgn) este destul de mică. Este o
sortare in situ (adică e o sortare în spaţiul alocat şirului de intrare).

Algoritmul Quick Sort se bazează pe tehnica de programare “Divide and


Conquer”, bazându-se pe următorii 3 paşi:
 Divide: Şirul A[p..r] este împărţit (rearanjat) în două subşiruri nevide A[p..q-
1] şi A[q+1..r] astfel încât fiecare element al subşirului A[p..q-1] să fie mai
mic sau egal cu A[q] (element denumit element pivot) şi orice element al
subsirului A[q+1..r] este mai mare sau egal cu A[q]. Indicele q este calculat
9
de procedura de partiţionare. Deci elementele mai mici decât pivotul vor fi
mutate în stângam pivotului iar elementele mai mari decât pivotul vor fi
mutate în dreapta pivotului.
 Conquer: Cele două subşiruri A[p..q-1] şi A[q+1..r] sunt sortate prin apeluri
recursive ale algoritmului de sortare rapidă
 Combine: Cele două subşiruri sunt sortate pe loc, nu este nevoie de nici o
combinare, şirul A[p..r] este ordonat.

Algoritmul procedurii QUICKSORT

14. Prezentaţi şi explicaţi algoritmul de partiţionare a unui şir în


cazul sortării rapide (ambele variante, inclusiv cel cu alegerea
aleatoare a elementului pivot).
Algoritmul procedurii PARTITION care realizează partiţionarea şirului:

În Quick Sort vom selecta aleator un element din subşirul A[p..r] care va juca rolul
pivotului. La fiecare pas al sortării rapide, înainte de partiţionarea vectorului vom

10
interschimba elementul A[p] cu acest element aleator ales. Practic, această
modificare a algoritmului asigură că elementul pivot x=A[p] să fie cu aceeaşi
probabilitate orice element dintre cele r-p+1 elemente ale vectorului A[p..r].
Rezultatul este că partiţionarea vectorului de intrare va fi în medie, rezonabil de
echilibrată. Modificările în algoritmul deja prezentat sunt minore. Vom avea
implementată schimbarea elementului ce va deveni pivot înainte de apelul propriu
zis al procedurii PARTITION.
Algoritmul de alegere aleatoare a elementului pivot:

De asemenea, noua procedură QUICKSORT va apela procedura RANDOMIZED-


PARTTION în loc de vechea procedură PARTITION. Algoritmul noii proceduri
denumită RANDOMIZED-QUICKSORT:

15. Ce sunt tehnicile de programare?


Tehnicile de programare sunt modalităţi generale de elaborare a algoritmilor. Ele
reprezintă doar nişte tipare de organizare a acţiunilor ("scheme" de algoritmi), nu
garantează şi succesul acestora. Pentru a avea succes trebuie îndeplinite nişte
condiţii suplimentare, care sunt specifice şi se demonstrează separat pentru fiecare
problemă în parte.

16. Principiile programării dinamice.


Programarea dinamică este o tehnică de proiectare a unui algoritm care permite
rezolvarea unei clase de probleme. Programarea dinamică, la fel ca şi metoda

11
Divide and Conquer, rezolvă problemele combinând soluţiile unor subprobleme.
Spre deosebire de abordarea din Divide and Conquer, programarea dinamică este
aplicabilă atunci când subproblemele nu sunt independente, adică subproblemele
au în comun sub-subprobleme.
Astfel, un algoritm de tipul Divide and Conquer ar presupune mai multe calcule
decât ar fi necesar dacă s-ar rezolva repetat aceste sub-subprobleme comune.
Programarea dinamică rezolvă fiecare sub-subproblemă o singură dată şi salvează
rezultatul într-o tabelă cu rezultate. Se evită astfel ca o sub-subproblemă să fie
rezolvată de mai multe ori.
Programarea dinamică se aplică la probleme de optimizare, probleme cu
următoarele caracteristici:
 Au mai multe soluţii posibile, fiecare caracterizate printr-o valoare
 Dorim să identificăm o soluţie cu valoarea cea mai mică/cea mai mare. O
asemenea soluţie se numeşte “o soluţie optimă” a problemei, prin contrast
cu “soluţia optimă” deoarece pot fi mai multe soluţii care realizează soluţia
optimă.

17. Prezentaţi şi explicaţi algoritmul recursiv al tăierii barei de oţel.


Compania Sterling Enterprises cumpără bare de oţel lungi şi le taie în bucăţi mai
scurte pe care apoi le revinde. Se cunoaşte preţul pi cu care compania vinde o bară
de lungime i (i este o valoare întreagă). Se cere determinarea locurilor unde se vor
face tăieturile la o bară de lungime n, astfel încât să se obţină câştigul maxim rn.
 Input: n ca fiind lungimea iniţială a barei precum şi preţurile pi pentru
i=1..n. Deci pi este preţul unei bare de lungime i.
 Output: Soluţia optimă va însemna tăierea barei în k bucăţi, deci obţinerea
partiţiei i1, i2, … ik cu i1+i2+…ik=n astfel încât suma rn=pi1+pi2+…+pik
să fie maximă.
Având în vedere că din 1 în 1 avem posibilitatea de a tăia sau nu bara, înseamnă că
pentru n-1 poziţii avem posibilitatea de a tăia sau nu. Numărul maxim de partiţii
posibil pentru o bară de lungime n este deci 2n-1.

Problema tăierii barei de oţel este o problemă cu structură optimă: soluţia optimă a
acestei probleme incorporează soluţii optime ale subproblemelor. Rezolvarea
problemei se va baza pe o soluţie recursivă. Descompunerea recursivă a problemei
tăierii barei de oţel se va face astfel:
12
 Se taie o piesă de lungime i
 Bara rămasă de lungime n-i se taie în mod recursive
 rn= max1<=i<=n(pi+rn-i)

Algoritmul recursiv de tăiere a barei de oţel:

18. Prezentaţi şi explicaţi algoritmul tăierii barei de oţel utilizând


metoda top-down din programarea dinamică.
Abordarea top-down cu memo-izare: se scrie procedura recursivă în mod
obişnuit, dar o modificăm astfel încât să salvăm rezultatul fiecărei subprobleme
într-un şir. Înainte să se apeleze recursivitatea, se verifică dacă rezultatul droit este
deja salvat în şir
Algoritmul de tăiere a barei de oţel utilizând programarea dinamică cu o abordare
top-down:

13
19. Prezentaţi şi explicaţi algoritmul tăierii barei de oţel utilizând
metoda bottom-up din programarea dinamică cu memorarea
mărimilor bucăţilor ce vor fi tăiate
Abordarea bottom-up: sortăm subproblemele în funcţie de ordinul lor de mărime
și le rezolvăm cele mai mici la început.

Algoritmul de tăiere a barei de oţel utilizând programarea dinamică cu o abordare


top-down:

14
20. Prezentaţi şi explicaţi algoritmul bottom-up de determinare a
costurilor înmulţirii unui şir de matrici.
Se dă un şir (o secvenţă A1, A2,… An) de n matrici care trebuie înmulţite,
dorindu-se calcularea produsului A1A2 …An

Pentru a calcula AiAi+1..Aj (vom nota acest produs cu Ai..j) va trebui să găsim un
k optim astfel încât să punem o paranteză între Ak şi Ak+1. În consecinţă:
 Costul lui Ai..j este egal cu costul lui Ai..k plus costul lui Ak+1..j plus costul
înmulţirii acestor două matrici
 Dacă costurile lui Ai..k şi Ak+1..j sunt optime, atunci şi costul lui Ai..j este
optim.

O soluţie optimă a unei instanţe a problemei înmulţirii şirului de matrice conţine


soluţii optime pentru instanţe ale subproblemelor. Existenţa substructurilor optime
în cadrul unei soluţii optime este una din caracteristicile cadrului de aplicare a
metodei programării dinamice.

Algoritmul bottom-up de determinare a costurilor înmulţirii şirului de matrici


precum şi a indicilor pentru care s-a obţinut costul optim.

15
21. Prezentaţi şi explicaţi algoritmul recursiv de afişare a
parantezării optime pentru un produs de n matrici.
Algoritmul recursiv prezentat în figura urmatoare ne oferă afişarea parantezării
optime a produsului (AiAi+1…Aj) pe baza tabelului s calculate de procedura
MATRIX-CHAIN-ORDER şi a indicilor i şi j. Apelul initial PRINT-OPTIMAL-
PARENS(s,1,n) ne oferă parantezarea optima pentru produsul (A1A2..An).

22. Principiile metodei greedy.


Metoda Greedy (greedy = lacom) este o metodă generală de proiectare a
algoritmilor care constă în construirea soluţiei globale optimale printr-un şir de
soluţii cu caracter de optim local atunci când este posibilă exprimarea “optimului
global” ca o combinaţie de o “optime locale”. Algoritmii greedy sunt în general
simpli şi sunt folositi la probleme de optimizare, cum ar fi: să se găsească cea mai
bună ordine de executare a unor lucrări, să se găsească cel mai scurt drum într-un
graf etc.

23. Prezentaţi cum se utilizează metoda greedy în cazul problemei


selecţiei activităţilor.
Se pune problema planificării unor activităţi care necesită utilizarea unei resurse
comune.

 Datele de intrare (inputul) este reprezentat de o mulţime S={a1, a2, …an}


de activităţi care necesită o resursă ce poate fi utilizată doar de o singură
activitate la un moment dat. Fiecare activitate ai are un moment de start si şi
un moment de terminare fi cu 0<=si<fi<∞.
16
O activitate ai are loc în intervalul [si,fi). Două activităţi ai şi aj sunt compatibile
dacă si>=fj sau sj>=fi (intervalele lor nu se suprapun).
 Datele de ieşire (outputul) reprezintă subsetul maximal de activităţi
compatibile.
Prezentăm în figura urmtoare un exemplu format din 11 activităţi (i=1,2, ..11)
fiecare cu momentul său de start si şi momentul de terminare fi.
Un exemplu de 11 activităţi având şirul momentelor de terminare sortat ascendant:

În exemplul prezentat {a3, a9, a11} reprezintă un subset de activităţi compatibile;


acesta nu este un subset maximal deoarece {a1, a4, a8, a11} este mai mare. Acesta
din urmă este cel mai mare subset de activităţi compatibile; în acelaşi timp un alt
subset maximal este şi {a2, a4, a9, a11}.

24. Prezentaţi şi explicaţi algoritmul recursiv greedy de selecţie a


activităţilor.
O soluţie greedy recursivă care rezolvă problema selecţiei activităţilor este
prezentată în figura 2.12. Procedura RECURSIVE-ACTIVITY-SELECTOR
primeşte ca parametric timpii de început şi de sfârşit al activităţilor (reprezentaţi de
vectorii s şi f), indicele i care defineşte subproblema care trebuie rezolvată şi
mărimea j a problemei originale. Această procedură va returna mulţimea maximă
de activităţilor compatibile din Si. Presupunem că cele j activităţi primite ca date
de intrare sunt deja ordonate crescător după timpul de terminare a lor. Dacă nu sunt
sortate, am putea face sortarea lor într-un timp de complexitate O(nlgn).

17
25. Prezentaţi şi explicaţi varianta greedy iterativă a algoritmului de
selecţie a activităţilor.
Procedura GREEDY-ACTIVITY-SELECTOR este o versiune iterativă a
procedurii RECURSIVE-ACTIVITY-SELECTOR. Şi ea presupune că pornim de
la un şir de activităţi sortat ascendent după timpul de finalizare a activităţilor.
Procedura prezentată în figura urmatoare colectează activităţile selectate într-o
mulţime A şi o returnează când această activitate este finalizată:

26. Care sunt paşii pe care îi vom utiliza într-o strategie greedy?
???
Proprietatea alegerii greedy poate fi enunţată astfel: alegem alternativa care apare
ca şi cea mai promiţătoare la problema curentă, fără a rezolva subproblemele. De
fapt, aceasta diferenţiază tehnica greedy de programarea dinamică prin faptul că
aceasta din urmă rezolvă subproblemele (câte o singură dată) pentru a putea decide
care este cea mai bună alegere. Utilizând greedy, facem alegerea care ni se pare
cea mai bună la un anumit moment, după care rezolvăm subproblema rămasă.
Intuitiv, alegerea greedy este acea activitate care lasă resursele disponibile pentru
cât de multe activităţi disponibile, deci vom alege activitatea cu cel mai devreme
moment de terminare (dacă mai mult de o activitate din S are cel mai devreme
moment de terminare atunci vom putea alege oricare din aceste activităţi). Altfel
spus, dacă activităţile sunt sortate în ordinea crescătoare a timpului de terminare,
atunci alegerea greedy este activitatea a1.
Făcând o alegere greedy, ne rămâne o singură subproblemă de rezolvat: găsirea
activităţilor care pornesc după ce a1 s-a terminat. De ce nu putem considera
activităţile care se termină înainte ca a1 să înceapă? Deoarece avem s1<f1 şi f1
este cel mai devreme moment de terminare al oricărei activităţi şi deci nici o
18
activitate nu poate avea timp de terminare mai mic sau egal decât s1. Deci toate
activităţile compatibile cu a1 trebuie să înceapă după ce a1 se termină.
Condiţia structurii optimale ne spune că dacă alegerea greedy este optimală atunci
şi rezultatul optim al problemei se compune din alegerea greedy şi rezultatul
optimal al subproblemei rămase.

27. Principiile şi algoritmul metodei backtracking.

Principii
În practică se întâlnesc un număr mare de probleme care au un număr mare de
variante ce se pot încerca, dar doar o parte din ele îndeplinesc condiţiile specific
problemei.

O astfel de problemă poate fi caracterizată astfel:


 soluţia lor poate fi pusă sub forma unui vector

 mulţimile S1,S2,S3…Sn sunt multimi finite, iar elementele lor se consideră


că se află într-o relaţie de ordine bine stabilită există anumite relaţii între
componentele v1, v2,… vn, numite condiţii interne
Practic, dacă nu cunoaştem tehnica backtracking, suntem tentaţi să generăm toate
elementele produsului cartezian S1xS2xS3…xSn şi fiecare element să fie testat
dacă este soluţie.
În cadrul tehnicii backtracking nu se generează toate soluţiile posibile, ci numai
acelea care îndeplinesc anumite condiţii specifice problemei, numite condiţii
interne (în unele lucrări de specialitate acestea mai
sunt numite şi condiţii de validare). În cadrul acestei tehnici, elementele vectorului
x primesc pe rând valori, în sensul că lui vk i se atribuie o valoare numai dacă au
fost atribuite deja valori lui v1, v2, vk-1. Odată o valoare pentru vk stabilită, nu se
trece direct la atribuirea de valori lui vk+1, ci se verifică condiţiile de continuare
referitoare la v1, v2, vk care stabilesc situaţiile în care are sens să trecem la
determinarea unei valori pentru vk+1. Conceptual, tehnica backtracking caută
sistematic soluţia într-un spaţiu al soluţiilor organizat sub forma unui arbore.
Fiecare nod din arbore defineşte o stare a problemei.

19
Toate drumurile de la rădăcină la frunze formează spaţiul stărilor. O soluţie a
problemeireprezintă acele stări pentru care există drum de la rădăcină la un nod
etichetat cu un nuplu.
Pot exista arbori statici (în cazul în care arborele astfel construit nu depinde de
instanţa problemei) şi arbori dinamici (în cazul în care alegerea valorii vi depinde
de una sau mai multe valori din mulţimea {v1, v2, …vi-1})

Algoritmul acestei tehnici poate fi descris astfel:


1)se alege primul element v1 ce aparţine lui S1
2)se presupun generate elementele v1,v2,v3…vk-1 aparţinând mulţimilor S1 S2
S3…Sk-1 pentru generarea lui vk se alege primul element din Sk disponibil şi
pentru valoarea aleasă se,testează îndeplinirea condiţiilor de continuare. Pot apărea
următoarele situaţii :
a)nu s-a găsit un astfel de element, caz în care se reia căutarea considerând
generate elementele v1,v2,v3…vk-1 iar vk se reia de la urmatorul element al
mulţimii Sk rămas netestat
b)a fost găsit, caz în care se testează dacă acesta îndeplineşte condiţiile de
continuare, aparând astfel alte două posibilităţi:
b1) vk îndeplineşte condiţiile de continuare. Dacă s-a ajuns la soluţia
finală (k=n) atunci se afişează soluţia obtinută. Dacă nu s-a ajuns la soluţia
finală se trece la generarea elementului următor vk+1;
b2) vk nu îndeplineste condiţiile de continuare. Se încearcă
următoarea valoare disponibilă din Sk. Dacă nu se găseşte nici o
valoare în Sk care să îndeplinească condiţiile de continuare, se revine la
elementul vk-1 şi se reia algoritmul pentru o nouă valoare a acestuia.
Algoritmul se încheie când au fost luate în considerare toate elementele lui v1.

20
28. Prezentaţi şi explicaţi algoritmul nerecursiv de rezolvare a
problemei damelor.
Problema reginelor (sau a damelor) are următorul enunţ: Să se afişeze toate
posibilităţile de a aşeza pe o tablă de şah de dimensiune nxn, n dame astfel încât
oricare 2 din acestea să nu se atace reciproc. Două dame se atacă una pe cealaltă
dacă sunt aşezate pe aceeaşi linie sau pe aceeaşi coloană sau pe aceeaşi diagonală
(principală sau secundară).
Vom considera xi linia pe care vom aşeza dama de pe coloana i. Printr-o astfel de
reprezentare ne asigurăm că nu vom aşeza două dame pe aceeaşi coloană. Atunci,
pentru o soluţie parţială Sk={x1, x2, … xk} condiţiile de continuare includ:
 xi≠xj oricare ar fi j=1,..k –{i} (sau altfel spus 1<=i≠j<=k) (prin acesta
verificăm că nu am aşezat dama k pe o linie pe care să se găsească deja o
altă damă)

 |xi-xj|≠|i-j| pentru orice j=1,..k-{i} (prin aceasta ne asigurăm că dama k pe


care am aşezat-o nu se atacă pe una din diagonale cu damele deja aşezate).

Un algoritm nerecursiv de rezolvare a problemei damelor se prezintă astfel:

29. Ce este un tip de date şi ce este un tip abstract de date (ADT


Abstract Data Type)?

21
Tipurile de date reprezintă tipul de informație care poate fi stocat într-o variabilă.
Un tip de data definește atât gama de valori pe care o poate lua o variabilă de un
anume tip cât și operațiile care se pot efectua asupra ei.Exemplu: char, int, etc

Un tip abstract de date (Abstract Data Type ADT) este un tip de date necesar
unui analist, dar care este posibil să nu existe în limbajul de programare ceea ce
impune necesitatea implementării lui.

30. Ce este o listă, cum se poate implementa o listă şi ce avantaje şi


dezavantaje are fiecare modalitate de implementare?
O listă este o secvenţă de 0 sau mai multe elemente de acelaşi tip denumite noduri
noduri între care există o relaţie de ordine determinată de poziţia lor relativă. Ea
este deci o mulţime eşalonată de elemente de acelaşi tip având un număr arbitrar de
elemente.
Numărul n al nodurilor se numeşte lungimea listei. Dacă n=0, lista este vidă. Dacă
n>=1, a1 este primul nod iar an este ultimul nod. Pentru 1<i<n, ai precede pe ai+1
şi succede pe ai-1.

O listă se poate implementa în 2 moduri: folosind un şir sau folosind pointeri.

Implementarea unei liste utilizând un şir prezintă avantaje şi dezavantaje.


 Avantajul este accesul rapid la oricare din elementele listei, acces care se
face cu ajutorul indicelui elementului din şir. Dacă dorim o regăsire pe baza
numărului de ordine al elementelor, vom utiliza indici (sau indecşi), în acest
caz timpul de acces la oricare din elementele listei (elemente de tablou) este
constant, indiferent de poziţie.
 Dezavantajul unei astfel de structuri statice de memorie este că dimensiunea
ei trebuie specificată la compilare, nemaiputându-se apoi modifica această
dimensiune. Deci este necesară estimarea dimensiunii tabloului (cu ajutorul
căreia se va implementa lista) înainte de compilare. Tot ca dezavantaj,
operaţiile de insert şi delete sunt de complexitate sporită.

În cazul implementării unei liste ca şi structura dinamică (utilizând pointeri)


 Dezavantaje: accesul la elementele unei liste liniare se face secvenţial,
pornind de la capul listei (adresa primului nod al listei) până la ultimul
22
element al ei, ceea ce măreşte uneori considerabil timpul de acces la un
anumit element. Regăsirea unui element se face destul de încet, vorbind de o
complexitate O(n).
 Avantaje: operaţiile de insert şi delete se fac uşor. Un alt avantaj al
implementării unei liste folosind pointeri este că nu trebuie specificată
dimensiunea maximă, gestiunea spaţiului de stocare este optimă, utilizând
alocarea dinamică de memorie.

31. Prezentaţi şi explicaţi algoritmii de căutare, inserare în capul


listei şi stergere într-o listă înlănţuită.
Lista înlănţuită este o structură de date în care obiectele sunt aranjate într-o ordine
liniară. La implementarea prin şiruri, ordinea este determinată de indici în timp ce
la implementarea prin pointeri, ordinea este determinată de un pointer care arată
către obiectul următor.
Pentru o listă liniară este obligatoriu să existe o variabilă, declarată în timpul
compilării, denumită cap de listă (head) care să păstreze adresa primului element al
listei. Pierderea acestei valori va duce la imposibilitatea accesării elementelor listei
liniare.
Algoritmul de cautare a elementului k în lista L folosind o căutare liniară simplă
şi returnând un pointer către primul element cu cheia k din lista L. Dacă nu se
găseşte nici un obiect cu cheia k în listă, atunci se returnează NIL.

Algoritmul de inserare in capul listei:

23
Algoritmul de stergere:
Pentru a şterge un element dintr-o listă avem nevoie de un pointer către acesta.
Dacă nu avem acest pointer, atunci va trebui găsit prin LIST-SEARCH.

32. Prezentaţi şi explicaţi algoritmul de căutare respectiv inserare


într-o listă dublu înlănţuită circulară cu santinelă
Santinela este un obiect dummy care marchează începutul sau sfârşitul listei. De
exemplu, noi vom introduce în lista L un obiect L.NIL care reprezintă un NIL dar
care are toate atributele celorlalte elemente din listă. De câte ori vom avea în
pseudocod o referinţă către NIL noi o vom înlocui cu o referinţă către L.NIL.
Atributul L.nil.next indică capul listei (head) iar L.nil.prev indică coada (sfârşitul)
listei (tail). Atributul next al lui tail respectiv atributul prev al lui tail indică spre
L.nil.
Procedura de căutare respectiv inserare într-o listă dublu înlănţuită circulară cu
santinelă.

24
33. Ce este o stivă şi care sunt procedurile de depunere şi extragere
dintr-o stivă?
Stiva este o structură de tip LIFO (Last In First Out) –elementul ce ar urma să fie
şters este ultimul element adăugat într-o astfel de structură. Există două modalităţi
de a implementa o stivă: folosind un şir (un array) sau folosind o structură
înlănţuită cu pointeri.
Operaţia de inserare într-o stivă este cel mai adesea denumită PUSH iar operaţia
de extragere este denumită POP. Şirul are un atribut S.top care indexează ultimul
element adăugat în stivă. Stiva conţine elementele S[1..S.top], unde S[1] este
elementul de la baza stivei iar S[S.top] este elementul din vârf. Când S.top=0 stiva
nu conţine nici un element şi este deci goală.

25
34. Ce este o coadă şi care sunt procedurile de depunere şi extragere
dintr-o coadă?
Coada este o structură de tip FIFO (First In First Out). Într-o elementul care va fi
şters este întotdeauna cel mai vechi element adăugat în coadă. Operaţia de
adăugare a unui element într-o coadă se numeşte ENQUEUE iar operaţia de
extragere a unui element dintr-o coadă se numeşte DEQUEUE. La fel ca operaţia
POP de extragere a unui element dintr-o stivă, şi operaţia DEQUEUE de extragere
a unui element dintr-coadă nu primeşte nici un argument.

26
35. Ce este o tabelă direct adresabilă şi care sunt operaţiile într-o
tabelă direct adresabilă?
Adresarea directă este o tehnică care funcţionează bine dacă universul U al cheilor
este rezonabil de mic. Presupunem că o aplicaţie necesită elemente dintr-un
dicţionar în care fiecare element are o cheie asociată din mulţimea U={0,1,…m-1}.
Vom presupune că nu există două elemente cu aceeaşi cheie. Pentru reprezentarea
mulţimii dinamice se foloseşte un şir (o tabelă direct adresabilă) T[0..m-1] în care
fiecare poziţie (sau slot) corespunde unei chei din U.
Exemplu:

27
Fiecare element din universul U={0,1,…9} corespunde unui index în tabela direct
adresabilă T. Mulţimea
K={2,3,5,8} a elementelor mulţimii determină sloturi în tabelă care conţin pointeri
către elemente. Slotul k pointează spre un element din mulţime având cheia k.
Dacă mulţimea K nu conţine un element cu cheia k, atunci valoarea din tabela T
este T[k]=NIL.

36. Ce este o tabelă de dispersie, ce este o funcţie de dispersie, ce


sunt şi cum se rezolvă coliziunile?

O tabelă de dispersie (hash table) este o structură de date care implementează


dicţionare. Deşi căutarea unui element într-o tabelă de dispersie poate ţine (în
anumite condiţii) la fel de mult ca şi căutarea unui element într-o listă înlănţuită
(ϴ(n)), în practică această structură se comportă foarte bine.
Dacă universul de chei U este mare (adică m are o valoare mare), alocarea unui şir
de dimensiune m nu este fezabilă iar uneori este imposibilă. În general în aceste
cazuri, numărul de chei K care se stochează este mic în comparaţie cu mărimea lui
U.

În cazul tabelelor de dispersie, pentru a determina locul în care va fi stocat


elementul cu cheia k, vom utiliza o funcţie de dispersie (hash function): h:U-
>{0,1,…m-1}
Funcţia h mapează universul U al cheilor în sloturile tabelei hash T[0..m-1].
Mărimea m a tabelei T este în mod obişnuit mult mai mică decât universul U.
Fiecare element cu cheia k este salvat în locaţia T[h[k]]. Se spune că h[k] este
valoarea hash a cheii k.

Exemplu:

28
Cheile k2 şi k5 ocupă acelaşi slot –în acest caz spunem că cele 2 valori intră în
coliziune. Există tehnici de rezolvare a conflictelor create de coliziuni.
Cea mai folosită tehnică de rezolvare a coliziunilor este cea prin înlănţuire.
Toate elementele care au acelaşi cod hash vor fi plasate în aceeaşi listă înlănţuită.
Slotul j conține un pointer către lista care salvează elementele care au j ca şi
valoare hash. Dacă nici un element nu are valoare de hash pe j, atunci T[j] = NIL.
Exemplu:

37. Prezentaţi şi explicaţi procedurile de inserare şi căutare într-o


tabelă de dispersie.
Presupunem că elementele tabelei de dispersie T sunt chei fără informaţii
adiţionale, cheile k sunt identice cu elementele conţinând conţinând cheia k.
Fiecare slot conţine o cheie sau NIL dacă slotul este gol.

29
38. Ce este un arbore binar de căutare?
Un arbore binar de căutare se poate reprezenta ca o structură înlănţuită în care
fiecare nod este un obiect. Fiecare nod al arborelui conţine cheia, date auxiliare şi 3
referinţe: left care pointează spre nodul copil stânga, right care pointează spre
nodul copil dreapta şi p care pointează spre nodul rădăcină. Dacă un copil lipseşte
atunci referinţa spre acel copil va fi NIL.

39. Prezentaţi modalitătile de traversare a unui arbore binar şi


algoritmii pentru fiecare din această modalitate.
 Traversare în preordine: se vizitează nodul rădăcină, apoi subarborele stâng
şi în final subarborele drept (R St Dr).
 Traversare în inordine: se vizitează subarborele stâng, apoi nodul rădăcină
şi în final subarborele drept (St R Dr)
 Traversare în postordine: se vizitează subarborele stâng, apoi subarborele
drept şi în final nodul rădăcină (St Dr R)
Pentru fiecare din cele 3 traversări, la vizitarea fiecărui subarbore se aplică din nou
aceeaşi regulă de vizitare.
Algoritmul de afişare a elementelor unui arbore binar traversat în inordine:

30
40. Prezentaţi şi explicaţi algoritmii iterativ respectiv recursiv de
căutare într-un arbore binar de căutare.

Algoritmul recursiv de căutare într-un arbore binar de căutare:

Procedura primeşte un pointer către rădăcina arborelui şi o cheie dată k care


urmează să fie căutată în arbore. Procedura va returna un pointer către nodul cu
cheia k (dacă acest nod există) sau NIL în caz contrar.

Algoritmul iterativ de căutare într-un arbore binar de căutare:

31
41. Prezentaţi şi explicaţi algoritmii de căutare a minimului, a
maximului şi a succesorului într-un arbore binar de căutare.
Într-un arbore binar de căutare, întotdeauna vom putea găsi elementul minim
folosind un pointer care porneşte de la rădăcină şi urmează întotdeauna copilul din
stânga.

Elemenul maxim: de data aceasta se urmareste copilul din dreapta:

Succesorul intr-un arbore de cautare:


Dându-se un nod într-un arbore binar de căutare, uneori dorim să cunoaştem
“succesorul” acestui element în ordinea sortată determinată de parcurgerea în
inordine a acestui arbore. Dacă toate cheile sunt distincte, atunci succesorul unui
nod cu cheia x este nodul cu cea mai mică cheie mai mare decât x.key. Proprietatea
unui arbore binar de căutare ne permite să determinăm succesorul unui nod fără să
comparăm cheile. Procedura prezentată în figura 4.7 returnează un pointer către
succesorul nodului x (dacă acesta există) şi NIL în cazul în care x deja conţine cea
mai mare cheie în arborele binar de căutare.

32
42. Prezentaţi şi explicaţi algoritmul de inserare într-un arbore
binar de căutare.
Inserarea unui element va trebui să menţină proprietatea de bază a unui arbore
binar de căutare.
Procedura TREE-INSERT din figura de mai jos primeşte ca şi parametru un nod z
pentru care z.key=v (unde v este valoarea care urmează să fie inserată), z.left=NIL
şi z.right=NIL.

33
43. Prezentaţi şi explicaţi algoritmul de ştergere într-un arbore
binar de căutare.
In cadrul operaţiei de ştergere a unui nod într-un arbore binar de căutare vom avea
nevoie de un algoritm care înlocuieşte un subarbore cu un alt subarbore.
Procedura TRANSPLANT din figura 1 înlocuieşte un subarbore ca şi copil al
părintelui său cu un alt subarbore. Procedura înlocuieşte subarborele având ca
rădăcină nodul pointat de u cu subarborele pointat de v. Astfel, părintele nodului u
va deveni părintele nodului v.

Figura 2 prezintă algoritmul de ştergere a unui nod dintr-un arbore binar de


căutare.

34
44. Ce este un arbore roşu şi negru şi ce proprietăţi are?
Un arbore roșu-şi-negru este un arbore binar de căutare la care fiecare nod are bit
suplimentar, reprezentând culoarea: roșu sau negru. Fiecare nod de arbore conține
următoarele campuri: cheia, culoarea, nodul stâng, nodul drept și părintele.
Un arbore roșu şi negru este un arbore binar de căutare cu următoarele proprietăţi:
1. Fiecare nod este sau roșu sau negru
2. Rădăcina este negru
3. Fiecare frunză (NIL) este neagră
4. Dacă un nod este roșu, atunci amândoi copii sunt negrii
5. Pentru fiecare nod, toate căile simple de la nodul respectiv la frunzele
descendentemconțin același număr de noduri negre

45. Prezentaţi şi explicaţi algoritmul de rotaţie la stânga într-un


arbore binar de căutare.
Când facem o rotaţie la stânga a unui nod x, presupunem că copilul dreapta y nu
este T.nil; x poate fi orice nod în arbore a cărui copil dreapta nu este T.nil. Operaţia
de rotaţie la stanga îl face pe y noua rădăcină a subarborelui, cu x ca şi copilul
stânga a lui y iar copilul stânga a lui y (adică β) devine copilul dreapta a lui x.
Algoritmul LEFT-ROTATE din figura urmatoare presupune că x.right≠T.nil şi că
părintele rădăcinii este T.nil.

35
46. Prezentaţi şi explicaţi algoritmul de inserare într-un arbore roşu
şi negru.
Procedura de inserare va insera în arborele roşu şi negru T nodul z (cu cheia deja
încărcată în acest nou nod):

47. Prezentaţi şi explicaţi algoritmul de restaurare a proprietăţilor


unui arbore roşu şi negru după inserarea unui nod.
Datorită faptului că colorarea în roşu a nodului proaspăt inserat ar putea încălca
proprietatea de colorare a arborilor roşu şi negru, vom apela procedura RB-
INSERTFIXUP(T,z) (prezentată în figura de la pct 46) la linia 17 pentru a restaura
această proprietate.

36
48. Prezentaţi şi explicaţi algoritmul de restaurare a proprietăţilor
unui arbore roşu şi negru după ştergerea unui nod.
Procedura de înlocuire a unui arbore cu un alt subarbore pentru un arbore roşu şi
negru:

49. Ce este un graf şi care sunt cele două moduri de a reprezenta un


graf?

Vom considera un graf G=(V,E) unde V reprezintă mulţimea nodurilor iar E


reprezintă mulţimea arcelor (sau mulţimea muchiilor).
37
Există două moduri standard de a reprezenta un graf G: ca o mulţime de liste de
adiacenţă sau ca o matrice de adiacenţă.
O listă de adiacenţă ca modalitate de reprezentare a unui graf reprezintă un şir
Adj de V liste, câte una pentru fiecare nod din graf. Pentru fiecare nod uϵV, Adj[u]
conţine toate nodurile v din graf pentru care există o muchie (un arc) (u,v)ϵE. Deci
Adj[u] este format din totalitatea vârfurilor adiacente lui u în G. Notaţia G.Adj[u]
se foloseşte pentru a ne referi la lista de adiacenţă a nodului u.
Dacă G este un graf orientat, suma lungimilor tuturor listelor de adiacenţă este |E|
deoarece un arc (u,v) este reprezentat doar prin vϵ Adj[u]. Dacă G este un graf
neorientat, suma lungimilor tuturor listelor de adiacenţă este 2|E| deoarece un arc
(u,v) apare atât in lista de adiacenţă a lui u (v apare în Adj[u]) cât şi în lista de
adiacenţă a lui v (u apare în Adj[v]).

Într-o matrice de adiacenţă presupunem că nodurile sunt numerotate arbitrar cu


1,2,…|V|. Vom folosi o matrice A de dimensiuni |V|x|V| astfel încât elementele aij
îndeplinesc condiţia

La un graf neorientat, (u,v) şi (v,u) reprezintă aceeaşi muchie, în consecinţă


matricea este simetrică faţă de diagonala principală (deci matricea de adiacenţă
este propria sa transpusă AT=A).

50. Prezentaţi şi explicaţi algoritmul de parcurgere în lăţime pentru


un graf reprezentat cu liste de adiacenţă.
În cazul parcurgerii în lăţime, pornind de la un graf G(V,E) şi un nod s de start,
vom explora în mod sistematic arcele din G pentru a descoperi fiecare nod care
este accesibil pornind de la nodul s. Algoritmul calculează distanţa (cel mai mic
număr de muchii) de la nodul s la fiecare nod care este conectat la s. Algoritmul
explorează frontiera dintre nodurile descoperite şi cele nedescoperite în lăţime,
adică descoperă toate nodurile la distanţă k, apoi cele la distanţă k+1 etc.
Algoritmul este funcţional atât pentru un graf neorientat cât şi pentru un graf
orientat.
Parcurgerea în lăţime colorează fiecare nod cu alb, gri sau negru pentru a ţine
evidenţa avansării. Se presupune că iniţial toate nodurile din graf sunt colorate în

38
alb (adică sunt nedescoperite), devin mai târziu gri şi apoi negre. Nodurile gri şi
negru sunt noduri care au fost descoperite. Dacă avem arcul (u,v)ϵE şi u este nod
negru, atunci v va fi negru sau gri (toate nodurile adiacente unui nod negru au fost
descoperite).
Algoritmul produce un “arbore de lăţime” având ca rădăcină nodul s, care conţine
toate aceste vârfuri conectate la s. Pentru fiecare vârf v accesibil din s, calea din
“arborele de lăţime” de la s la v corespunde celui mai scurt drum de la s la v în G,
adică un drum care conţine un număr minim de muchii. De fiecare dată când
căutarea descoperă un nod alb v în cursul scanării listei de adiacenţă al unui nod
deja descoperit u, nodul v şi arcul (u,v) este adăugat în acest arbore. Vom spune că
u este predecesorul sau părintele lui v în arborele de lăţime.

51. Ce este drumul de lungime minimă şi care este algoritmul de


afişare a drumurilor de lungime minimă?
Vom defini calea cea mai scurtă (sau drumul de lungime minimă) δ(s,v) din s în v
ca fiind numărul minim de muchii ale oricărui drum de la s la v sau ∞ dacă nu
există un drum de la s la v.
39
Dacă avem un graf G=(V,E) şi s un nod arbitrar din V, atunci pentru orice arc
(u,v)ϵE avem δ(s,v)<=δ(s,u)+1. (dacă u este accesibil din s atunci şi v este accesibil
din s. În acest caz, cel mai scurt drum de la s la v nu poate fi mai lung decât cel mai
scurt drum de la s la u la care se adaugă 1 corespunzător muchiei (u,v)).
Dacă se execută BFS pornind de la un nod s, la terminare, pentru fiecare nod v
pentru care există o cale de la s, valoarea v.d calculată de algoritmul BFS satisfice
v.d=δ(s,v).
Procedura PRINT-PATH din figura urmatoare prezintă algoritmul de afişare a
drumurilor de lungime minimă pornind de la nodul sursă s până la nodul destinaţie
v.

52. Prezentaţi şi explicaţi algoritmul de parcurgere în adâncime


pentru un graf reprezentat cu liste de adiacenţă.
Parcurgerea în adâncime presupune o căutare în graf cât mai adâncă oricând acest
lucru este posibil. În căutarea in adâncime, muchiile sunt explorate pornind de la
vârful v cel mai recent descoperit care mai are încă muchii neexplorate care pleacă
din el.
Dacă toate muchiile unui nod v au fost explorate, atunci algoritmul face back-
tracking la
următorul nod care trebuie explorat după v. Această operaţie continuă până când au
fost descoperite toate nodurile accesibile din vârful sursă iniţial.
Vom folosi aceeaşi convenție de colorare şi anume alb, gri şi negru. Pentru fiecare
nod folosim 2 ştampile de timp:
 v.d momentul în care nodul a fost descoperit pentru prima dată (când este
marcat gri)
 v.f momentul în care parcurgerea termină lista de adiacență a lui v (când
nodul va fi marcat negru)
40
Acest marcaj de timp este o valoare întreagă cuprinsă între 1 şi 2|V| deoarece există
un moment de descoperire şi un moment de terminare pentru fiecare din cele |V|
noduri ale grafului.

53. Ce este o sortare topologică şi care este algoritmul simplu de


sortare topologică?
O sortare topologică a unui graf orientat aciclic G=(V,E) este o ordonare liniară a
tuturor vârfurilor sale astfel încât, dacă G conţine o muchie (u,v) atunci u apare
înaintea lui v în ordonare. Dacă graful nu este aciclic, atunci nu este posibilă
sortarea topologică. O sortare topologică a unui graf poate fi văzută ca o ordonare a
vârfurilor sale de-a lungul unei linii orizontale astfel încât toate muchiile sale merg
de la stânga la dreapta.
Algoritmul simplu de sortare topologică a unui graf orientat acyclic

41
54. Ce este o componentă tare conexă şi care este algoritmul de
determinare a componentelor tare conexe dintr-un graf orientat?
O componentă tare conexă a unui graf orientat G=(V,E) este o mulţime maximală
de vârfuri U V, astfel încât, pentru fiecare pereche de vârfuri u şi v din U există un
drum de la u la v precum şi de la v la u. Altfel spus, între oricare două noduri din
componentă există cel puţin un drum şi nu mai există nici un nod în afara
componentei legat printr-un drum de un nod al componentei.

Algoritmul de determinare a componentelor tare conexe dintr-un graf orientat:

55. Ce este un arbore de acoperire minim şi care este algoritmul


generic de determinare a unui arbore de acoperire minim?
Vom folosi un graf neorientat conex, G=(V,E) unde V este mulţimea pinilor şi E
este mulţimea interconectărilor posibile dintre perechile de pini; pentru fiecare
pereche de pini (u,v)ϵE, avem un cost w(u,v) ce reprezintă costul cablului de la
pinul u la pinul v. Dorim să determinăm submulţimea aciclică T E care conectează
toate nodurile din V şi al cărei cost total w(T)=Σ(u,v)ϵT w(u,v) este minim.
Deoarece mulţimea T este aciclică şi conectează toate nodurile, ea trebuie să
formeze un arbore care va fi denumit arbore de acoperire deoarece “acoperă”
graful G.
Problema determinării arborelui T va fi numită problema arborelui de acoperire
minim.
Algoritmul generic de determinare a unui arbore de acoperire minim:

42
56. Prezentaţi şi explicaţi algoritmul lui Kruskal de determinare a
unui arbore de acoperire minim.
Algoritmul lui Kruskal de determinare a unui arbore de acoperire minim se
bazează pe algoritmul generic.
Algoritmul găseşte o muchie sigură (u,v) dintre toate muchiile care conectează 2
arbori în pădurea de arbori pentru a o adăuga la pădurea dezvoltată. Muchia sigură
(u,v) este muchia cu costul minim care uneşte doi arbori din pădurea respectivă.
Algoritmul lui Kruskal, prezentat în figura urmatoare foloseşte o structură de date
pentru mulţimi disjuncte pentru a reprezenta mai multe mulţimi de elemente
disjuncte. Fiecare mulţime conţine vârfurile unui arbore din pădurea curentă.
Funcţia FIND-SET(u) returnează un element reprezentativ din mulţimea care îl
conţine pe u. Astfel, putem determina dacă două vârfuri u şi v aparţin aceluiaşi
arbore testând dacă FIND-SET(u) este egal cu FINDSET( v). Combinarea arborilor
este realizată de procedura UNION.

43
57. Prezentaţi şi explicaţi algoritmul lui Prim de determinare a unui
arbore de acoperire minim.
Algoritmul lui Prim este un caz particular al algoritmului generic pentru
determinarea unui arbore de acoperire minim pentru un graf conex. Algoritmul lui
Prim are proprietatea că muchiile din mulţimea A formează întotdeauna un singur
arbore. Arborele se formează pornind de la un vârf arbitrar r şi creşte până acoperă
toate vârfurile din V. La fiecare pas, se adaugă arborelui o muchie uşoară care
uneşte mulţimea A cu un vârf izolat din GA=(V,A). La fel ca algoritmul lui
Kruskal, algoritmul lui Prim foloseşte o tehnică gredy deoarece arborelui ii este
adăugată la fiecare pas o muchie care adaugă cel mai mic cost la costul total al
arborelui. În procedura MST-PRIM din figura urmatoare graful G, rădăcina r a
arborelui minim de acoperire care urmează să fie dezvoltat şi costurile w sunt
parametri de intrare. În timpul execuţiei, toate vârfurile care nu sunt în arbore sunt
într-o coadă de prioritate Q bazată pe un câmp cheie. Pentru fiecare vârf v,
atributul v.key este costul minim al oricărei muchii care uneşte pe v cu un vârf din
arbore.

44
58. Ce este un drum minim într-un graf şi care sunt variantele
problemei drumului minim?
Problema drumului minim apare deseori în practică. Un exemplu ar fi găsirea
drumului cel mai scurt dintre 2 oraşe.
Fiind dat un graf orientat cu costuri G=(V,E) şi având funcţia de cost w:E->R care
asociază fiecărei muchii câte un cost exprimat printr-un număr real. Costul w(p) al
unei căi p={v0, v1, … vk} este suma costurilor de pe calea p :

Costul unui drum minim (costul optim) de la u la v se defineşte:

Un drum minim de la u la v este orice drum p cu proprietatea w(p)=δ(u,v).


În continuare ne vom axa pe problema drumului minim de sursă unică. Însă, există
mai multe variante ale problemei drumului minim, şi anume:
 Problema drumurilor minime de destinaţie unică: Să se găsească de la
fiecare nod vϵV drumul minim până la un vârf destinaţie t prestabilit.
Această problemă poate fi pusă şi invers: calea cea mai scurtă de la o sursă s
la fiecare nod v dintr-un graf.
 Problema drumurilor minime de sursă şi destinaţie unică: Să se determine un
drum minim de la u la v pentru u şi v date. Dacă rezolvăm problema
drumurilor minime de sursă unică pentru vârful u atunci rezolvăm şi această
problemă.
 Problema drumurilor minime pentru surse şi destinaţii multiple : Să se
determine drumul minim de la u la v pentru fiecare pereche de vârfuri u şi v.
Această problemă poate fi rezolvată, de exemplu, prin aplicarea algoritmului
pentru sursă unică pentru fiecare vârf al grafului.

45
59. Ce este relaxarea şi care este procedura de relaxare a unei
muchii (u,v) într-un graf cu costuri
Termenul de relaxare semnifică de fapt o operaţie care determină decrementarea
unei margini superioare. În procesul de relaxare a unei muchii (u,v) se verifică
dacă drumul minim până la vârful v (determinat până în acel moment) poate fi
îmbunătăţit pe baza unui drum care să treacă prin u, şi dacă da, atunci se
reactualizează v.d şi v.π. Practic, un pas de relaxare poate determina descreşterea
valorii v.d reprezentând valoarea drumului minim de la s la v şi reactualizarea
câmpului v.π care conţine predecesorul vârfului v. Procedura RELAX:

60. Prezentaţi şi explicaţi algoritmul Bellman-Ford de rezolvare a


problemei drumurilor minime cu sursă unică în cazul general al
unui graf care poate avea şi costuri negative.

Algoritmul Bellman-Ford rezolvă problema drumurilor minime cu sursă unică în


cazul general al unui graf care poate avea şi costuri negative. Dându-se un graf
orientat G=(V,E), un vârf sursă s şi funcţia de cost w:E->R, algoritmul Bellman
Ford returnează o valoare booleană indicând dacă există sau nu un ciclu de cost
negativ accesibil din vârful sursă s considerat. În cazul în care un astfel de ciclu
există, algoritmul semnalează că nu există soluţie iar dacă nu există un astfel de
ciclu, algoritmul produce drumurile minime şi costurile corespunzătoare lor.
Algoritmul utilizează tehnica relaxării prin descreşterea estimării valorii v.d adică
valoarea drumului minim de la vârful sursă s până la fiecare vârf vϵV până la
obţinerea adevăratului cost minim δ(s,v). Algoritmul returnează TRUE dacă şi
numai dacă nu conţine cicluri de cost negativ accesibile din sursă:

46
61. Prezentaţi şi explicaţi algoritmul de căutare a drumurilor
minime într-un graf orientat acyclic.

Algoritmul începe prin sortarea topologică a grafului pentu impunerea unei ordini
liniare a vârfurilor. Dacă există un drum de la u la v atunci u precede v în ordinea
topologică. Algoritmul efectuează o singură trecere peste vârfurile sortate
topologic şi pe măsură ce fiecare vârf este procesat, sunt relaxate toate muchiile
care pornesc din acel vârf.

47
62. Prezentaţi şi explicaţi algoritmul lui Dijkstra de determinare a
drumurilor de lungime minimă.
Algoritmul lui Dijkstra rezolvă problema drumurilor de lungime minimă cu sursă
unică într-un graf orientat G=(V,E) cu costuri nenegative. Deci în acdrul acestui
algoritm vom avea w(u,v)>=0 pentru orice arc (u,v)ϵE.
Algoritmul lui Dijkstra gestionează o mulţime S de noduri pentru a cărui elemente
algoritmul a calculat deja costurile finale ale drumurilor minime de la sursa s.
Algoritmul selectează câte un vârf u din mulţimea V-S pentru care estimarea
drumului minim este minimă, introduce acest vârf u în mulţimea S şi relaxează
arcele divergente din din vârful u.

48

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