Documente Academic
Documente Profesional
Documente Cultură
21 noiembrie 2016
Introducere
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
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
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]
}
}