Sunteți pe pagina 1din 4

Corectitudinea algoritmilor

21 noiembrie 2016

Introducere

Un algoritm trebuie analizat din cel put, in dou puncte de vedere:


Eficient, (complexitate): cantitatea de resurse (timp s, i memorie) solicitate.
Corectitudine: pe orice date de intrare corecte (care respect un set de precondit, ii) algoritmul
ntoarce rezultate corecte (care respect un set de postcondit, ii).
Pentru a demonstra acest "orice" este nevoie de o analiz formal, bazat pe urmtorii pas, i:
Idenficarea precondit, iilor algoritmului. Totalitatea acestora constituie asert, iunea de intrare PI : PI : I > {0, 1} (I = domeniul datelor de intrare)
Identificarea postcondit, iilor algoritmului. Totalitatea acestora constituie asert, iunea de
ies, ire PO : PO : I O > {0, 1} (O = domeniul rezultatelor)
Demonstrat, ia c, plecnd din starea init, ial a algoritmului, n care se respect asert, iunea de
intrare, pas, ii descris, i de algoritm ne duc ntr-o stare final n care se respect asert, iunea de
ies, ire.
Cnd demonstrm s, i c algoritmul se termin ntr-un numr finit de pas, i, demonstrm c
algoritmul este total corect: d I PI (d) (termin(Alg(d)) PO (d, Alg(d))). Alternativa
este s demonstrm c algoritmul este part, ial corect: d I (PI (d) termin(Alg(d)))
PO (d, Alg(d)).
Ideea demonstrat, iei este s identificm strile intermediare prin care ar trebui s treac algoritmul s, i s ne asigurm c fiecare act, iune efectueaz trecerea dintr-o asemenea stare n starea
urmtoare. Demonstrat, ia este n general simpl pe algoritmi secvent, iali, s, i ceva mai dificil n
cazul algoritmilor recursivi sau care cont, in bucle. Construirea unei asemenea demonstrat, ii poate
ajuta la identificarea s, i corectarea erorilor.

Invariant, i la ciclare

2.1

Definit, ie

Cea mai frecvent tehnic de demonstrare a corectitudinii algoritmilor recursivi, respectiv iterativi,
este induct, ia. n cazul algoritmilor iterativi, metoda const n identificarea (s, i demonstrarea) de
invariant, i la ciclare: propriett, i valabile la intrarea ntr-o bucl s, i conservate pe durata s, i la
ies, irea din bucl.
Invariant, ii la ciclare se demonstreaz n 3 pas, i (corespunznd, practic, unei induct, ii matematice
dup variabila de ciclare):
Init, ializare: invariantul se respect nainte de prima intrare n bucl (iterat, ia 0).
Ment, inere: dac invariantul se respect nainte de iterat, ia k, atunci el se va respecta s, i dup
iterat, ia k (nainte de iterat, ia k+1).
Terminare: invariantul se respect la ies, irea definitiv din bucl, ceea ce reprezint o proprietate util n demonstrarea corectitudinii algoritmului.

2.2
2.2.1

Exemple
Suma elementelor dintr-un vector

suma ( v , n ) {
s = 0;
i = 0;
while ( i < n) {
s = s + v[ i ];
i ++;
}
}
Pi1
Invariant: si = j=0 v[j].
Init, ializare: nainte de prima iterat, ie, s0 = 0 =

P1

v[j].
Pi1

j=0

Ment, inere: Presupunem c nainte de iterat, ia i si =

j=0 v[j].
Pi1
si+1 = j=0 v[j]

Pi
+ v[i] = j=0 v[j].
Dup iterat, ia i (nainte de iterat, ia i+1) vom avea
Pn1
Terminare: La ies, irea definitiv din bucl (nainte de iterat, ia n): sn = j=0 v[j], adic suma
tuturor elementelor din vector.
2.2.2

Sortarea prin select, ie

s e l s o r t ( v , n ) {
f o r ( i =0; i <n1; i ++) {
min = i ;
f o r ( j=i +1; j <n ; j ++)
i f v [ j ] < v [ min ]
min = j
swap ( v [ i ] , v [ min ] )
}
}
Invariant pentru bucla interioar: nainte de iterat, ia j, minj = indexul elementului minim
din v[i..j 1].
Init, ializare: nainte de prima iterat, ie, mini+1 = i = indexul elementului minim din v[i..i].
Ment, inere: Presupunem c nainte de iterat, ia j minj = indexul elementului minim din v[i..j 1].
Dup iterat, ia j (nainte de iterat, ia j+1), dac v[j] < minj , atunci minj+1 = v[j], altfel minj+1 =
minj .
As, adar, minj+1 = indexul elementului minim din v[i..j].
Terminare: La ies, irea definitiv din bucl (nainte de iterat, ia n): minn = indexul elementului
minim din v[i..n-1].
Invariant pentru bucla exterioar: nainte de iterat, ia i, v[0..i 1] sortat s, i cont, ine cele mai
mici i elemente din v.
Init, ializare: nainte de prima iterat, ie, v[0..-1] sortat s, i cont, ine cele mai mici 0 elemente din v.
Ment, inere: Presupunem c nainte de iterat, ia i v[0..i1] sortat s, i cont, ine cele mai mici i elemente
din v.
Dup iterat, ia i (nainte de iterat, ia i+1), v[0..i-1] rmne nemodificat, iar v[i] primes, te valoarea
v[min], unde min = indexul elementului minim din v[i..n-1] (conform invariantului anterior).
As, adar, nainte de iterat, ia i+1, v[0..i] sortat s, i cont, ine cele mai mici i+1 elemente din v.
Terminare: La ies, irea definitiv din bucl (nainte de iterat, ia n-1): v[0..n-2] sortat s, i cont, ine cele
mai mici n-1 elemente din v. Rezult c v[n-1] cont, ine cel mai mare element din v, deci v[0..n-1]
sortat.

Exercit, ii
1. Cutarea binar:
bins e a r c h ( v , x , s t a r t , s t o p ) {
w h i l e ( s t a r t <= s t o p ) {
mid = ( s t a r t+s t o p ) / 2 ;
i f ( x == v [ mid ] )
r e t u r n mid ;
i f ( x > v [ mid ] )
s t a r t = mid+1;
else
s t o p = mid 1;
}
return null ;
}
2. Sortarea prin insert, ie:
i n s s o r t ( v , n ) {
f o r ( j =1; j <n ; j ++) {
x = v[ j ];
i = j 1;
w h i l e ( i >=0 && v [ i ]>x ) {
v [ i +1] = v [ i ] ;
i ;
}
v [ i +1] = x ;
}
}
3. Sortarea prin metoda bulelor:
bubbles o r t ( v , n ) {
f o r ( i =0; i <n ; i ++)
f o r ( j=n1; j >i ; j )
i f v [ j ] < v [ j 1]
swap ( v [ j ] , v [ j 1])
}
4. Funct, ia de partit, ionare din cadrul algoritmului quicksort:
p a r t i t i o n (v , start , stop ) {
x = v [ stop ] ;
i = s t a r t 1;
f o r ( j=s t a r t ; j <s t o p ; j ++)
if v[ j ] < x {
i ++;
swap ( v [ i ] , v [ j ] ) ;
}
swap ( v [ i +1] , v [ s t o p ] )
r e t u r n i +1;
}
5. Determinarea distant, ei minime prin algoritmul lui Dijkstra:

d i j k s t r a (g , c , s , adj ) {
foreach v in v e r t i c e s (g)
d[ i ] = infinity ;
d [ s ] = 0;
q = vertices (g );
while q {
u = extract_min ( q ) ;
q . remove ( u ) ;
foreach v in adj [ u ]
if d[u] + c [u,v] < d[v]
d[v] = d[u] + c [u,v]
}
}

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