Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
OBS: Modul in care datele sunt organizate poate sa rezolve o buna parte din problema.
Exemplu:
Pb. 1 Se da un sir de numere intregi ce contine, in ordine, mediile studentilor dintr-o serie.
Care e a 3-a medie din serie, dar a n-a?
Pb. 2 Intr-o aplicatie se doreste stocarea temperaturilor medii zilnice. Valoarea celei mai
recente masuratori se stocheaza la inceputul structurii. Din cand in cand se afiseaza
temperatura medie din ultimele n zile.
Exista vreo structura de date pe care ati prefera-o pentru rezolvarea Pb 1 si, respectiv, Pb 2?
Daca da - care si de ce?
Notiuni introductive
=> Nu exista stuctura de date care sa fie buna pentru orice scop/ in orice situatie.
“There is no ultimate data structure...” – alegerea unei structuri se face in functie de cerinta
problemei.
Algoritm
= o procedura / o secventa de pasi care rezolva o problema data in timp finit; primeste un
Da.
Chiar daca o serie de aplicatii nu necesita explicit algoritmi (ex: aplicatii simple Web
based), multe altele se bazeaza pe ei.
Exemple:
1. Considerari o aplicatie de tip serviciu Web-based care calculeaza rute intre 2 locatii.
Implementarea se bazeaza pe cel mai rapid hardware, o interfata grafica, retea si
probabil integreaza concepte POO. Cu toate astea, va avea nevoie de algoritmi
pentru anumite operatii: gasirea rutelor optime(shortest-path algorithm), redarea
hartilor, interpolarea adreselor.
Analiza algoritmilor:
- o problema poate sa aiba mai multe solutii (sortarea elemetelor unui vector poate sa fie
facuta in multe feluri). Cum putem sa aflam care e cel mai eficient algoritm din punct de
vedere al duratei si memoriei consumate?
Solutie: folosim ca masura o functie care depinde de dimensiunea datelor de intrare - f(n)
Analiza la executie (running time analysis) - ne spune cum creste durata cu cresterea
dimensiunii problemei (a datelor de intrare)
Complexitatea algoritmilor
DAR: Numarul exact de pasi este dificil de calculat => se impun o serie de simplificari
=> in calculul de complexitate tinem cont numai de operatiile critice din algoritm
(acele operatii care, prin natura lor, consuma multe resurse sau sunt efectuate de un
numar semnificativ de ori)
Ex: Intr-un algoritm de sortare o operatie critica este compararea elementelor, intrucat
se produce de foarte multe ori.
Complexitatea algoritmilor
Definitii
OBS: In cele mai multe cazuri spatiul de stocare este un multiplu de n – iar complexitatea
se refera la durata de executie.
Complexitatea algoritmilor
Cazul cel mai nefavorabil - defineste inputul care conduce la cel mai lung timp de
rulare/ ce complexitate rezulta pentru cel mai neprietenos input = max ( f(n) )
Cazul cel mai favorabil - defineste inputul care conduce la cel mai scurt timp de
rulare/ ce complexitate rezulta pentru cel mai prietenos input = min ( f(n) )
Cazul mediu - e o predictie a duratei medii = la ce complexitate ne putem astepta in
cazul inputurilor aleatoare (dificil de calculat, ar trebui calculata media ponderata a
complexitatilor in functie de distributia statistica a inputurilor si probablilitatea lor de
de aparitie) – valoarea asteptata
Pentru un algoritm putem sa reprezentam cazul cel mai (ne)favorabil, mediu ca functii:
- f(n)= n^2+500, cel mai nefavorabil caz
- f(n) = 100n+500, cel mai favorabil caz
***Notatie: n^m = n la puterea m
Complexitatea algoritmilor
Analiza asimptotica a complexitatii
Notatii asimptotice - avand expresiile pentru cazul cel mai favorabil/ mediu/ nefavorabil – trebuiesc
depistate limitele inferioare/superioare pentru f(n)
1. Notatia O - “Big O”
• descrierea comportamentul unui algoritm in cazul cel mai nefavorabil fara a se face
referire la celelalte situatii. (Intrucat, in general, e de interes comportarea algoritmului
pentru date arbitrare de intrare este suficient sa specificam o margine superioara pentru
timpul de executie.)
• f(n) ∈ O(g(n)) implica faptul ca f(n) creste asimptotic cel mult la fel de repede ca g(n)
• O(g(n))={f(n)|exista c si no>0 astfel incat 0<=f(n)<=cg(n), orice n>=no}.
• in general, nu ne intereseaza valorile mici
ale lui n; rata de crestere pentru n<no poate
fi diferita.
Complexitatea algoritmilor
O(g(n))={f(n)|exista c si no >0 astfel incat 0<=f(n)<=cg(n), orice n>=no}
2. f(n) = n^2+1
n^2+1<=2n^2, n>=1 = > f(n)=O(n^2), c=2, no=1
3. f(n)= 410
410<=410*1, n>=1 = > f(n) = O(1), c=1, no=1?
Observatii:
1. O(n^2) include O(1), O(n), O(nlogn)
2. Valorile pentru c si no nu sunt unice!
Complexitatea algoritmilor
1. Bucle – durata de executie a unui structuri repetitive este maxim egala cu durata
instructiunilor executate (incluzand testele) inmultit cu numarul de iteratii
2. Bucle imbricate (nested loops) - se analizeaza din exterior spre interior; timpul total e
produsul dimensiunilor buclelor
4. Instructiuni if-then-else - testul + timpul cel mai defavorabil de pe ramura then sau else
}else{
Rate de crestere
o 2^n – rata exponentiala – turnurile din Hanoi
o n! – rata factoriala - permutari
o n^3 – rata cubica –inmultirea de matrice
o n^2 – rata patratica – calea cea mai scurta intre
2 noduri ale unui graf
o nlogn – rata liniar logaritmica – sortare cu
metoda merge sort
o n – rata liniara – gasirea unui element intr-un
vector nesortat
o log n – rata logaritmica - gasirea unui element
intr-un vector sortat
o 1 – rata constanta- adaugarea unui element la
inceputul unei liste
Complexitatea algoritmilor
Obs: Exista modalitati de organizare a datelor care imbunatatesc procesul de cautare => daca tinem
datele intr-o anumita ordine, gasirea elementului cautat se face usor. Sortarea colectiei in care se
face cautarea e o astfel de tehnica.
Tipuri de cautari
Cautare liniara intr-o multime neordonata ( Unordered Linear Search)
Cautare liniara intr-o multime ordonata ( Sorted/Ordered Linear Search)
Cautare binara ( Binary search)
Symbol Tables si Hashing - daca e timp*
Cautare de siruri de caractere (Tries, Ternary Search si Suffix Trees) – daca e timp*
Cautare liniara/secventiala intr-o multime neordonata
Se presupune dat un vector cu elemente intr-o ordine necunoscuta (vectorul nu e ordonat) =>
trebuie parcurs tot vectorul ca sa vedem daca elementul se gaseste acolo sau nu.
- cazul cel mai nefavorabil - algoritmul examineaza n numere pentru cautarea fara succes
- cazul mediu - sunt evaluate aproximativ n/2 numere pentru cautarea cu succes
Se presupune dat un vector cu elemente intr-o ordine cunocuta => nu trebuie parcurs tot
vectorul ca sa vedem daca elementul se gaseste acolo sau nu, ne oprim daca am gasit un
element >= fata de cel cautat
- cazul cel mai nefavorabil - algoritmul examineaza n numere pentru cautarea fara succes
- cazul mediu - se fac mai putine evaluari comparativ cu cazul precedent , dar
Cel mai nefavorabil caz - nu se examineaza mai mult de logn+1 numere => O(logN)
Complexitatea spatiala este O(1)
Tema: Considerati vectorul: 1 3 7 9 10 – se cauta 1- care sunt pasii facuti?
Cautare binara - forma recursiva
if (v[m]==data) return m;
else if (v[m]>data) return search_bin_rec(v, l, m-1, data);
else return search_bin_rec(v, m, r , data);
return -1;
}
Recurenta pentru cautarea binara e: T(n) = T(n/2) +Θ(1) pentru ca mereu consideram doar
jumatate din input => O(logN) *caz 2 Teorema master
Complexitatea spatiala – la fiecare apel recursiv o sa se puna un stack frame pe stiva =>
cazul cel mai favorabil (elementul cautat e gasit la primul apel)/nefavorabil O(1)/ O(logN)
Algoritmi de sortare
- metode elementare – potrivite unui numar mic de elemente (<1000): bubble, insertion,
selection sort - > O(n^2)
- metode avansate – potrivite pentru cazul cu multe inregistrari: quick sort, merge sort,
heap sort
Criterii de interes: timp de rulare si cantitatea de memorie suplimentara.
Sortare in-place / out- of-place – spatiul suplimentar (pe langa cel al containerului ) e
mic/mare
Metode elementare de sortare
aux=v[6]
Metode elementare de sortare
Pas 0: 9 7 6 15 16 5 10 11 -> 5 7 6 15 16 9 10 11
Pas 1: 5 | 7 6 15 16 9 10 11 -> 5 6 7 15 16 9 10 11
Pas 2: 5 6 | 7 15 16 9 10 11 -> 5 6 7 15 16 9 10 11
Pas 3: 5 6 7 | 15 16 9 10 11 -> 5 6 7 9 16 15 10 11
Pas 4: 5 6 7 9 | 16 15 10 11 -> 5 6 7 9 10 15 16 11
original
Dupa ce s-a realizat sortarea indirecta – daca se doreste- se pot rearanja inregistrarile.
Metode avansate de sortare
1. Quicksort
cel mai utilizat algoritm de sortare
1960- C.A.R. Hoare
consuma mai putine resurse decat alte metode
in medie foloseste nlogn operatii pentru a sorta n elemente, dar n^2 pentru
cazul cel mai nefavorabil.
se foloseste de paradigma divide et impera (problema se imparte in
subprobleme care sunt apoi rezolvate – iar solutiile partiale sunt recombinate
intr-o solutie finala)
Divide: daca v (vectorul de sortat) are cel putin 2 elemente, selecteaza un element
x din v – pivot (de exemplu ultimul element) si imparte elementele din v in 3 parti:
elemente < x (L) elemente = x (E) elemente > x (G)
daca low <high // pana nu se mai poate imparti (am cel putin 2 elemente)
2. Mergesort
Foloseste paradigma divide et impera
Poate fi implementat astfel incat sa acceseze elementele intr-o maniera secventiala
Avantaje: e potrivit secventelor reprezentate prin liste inlantuite
5. Parcurgeti vectorul.
III. Care dintre metodele de sortare precedente sunt stabile? Dar in-place?