Sie sind auf Seite 1von 3

Chapitre 3

Analyse des algorithmes


Étude a priori des algorithmes. L’algorithme fonctionne-t-il ?

1. L’algo donne-t-il un résultat ? Termine-t-il ?


2. Est-ce le bon résultat ? (Preuve)
3. En combien de temps donne-t-il un résultat ? (Complexité temporelle)
4. De combien d’espace mémoire a-t-il besoin ? (Complexité spaciale)

3.1 Terminaison
Définition. Un programme est une suite d’instructions
Définition. Une instruction est
— L’affectation d’un calcul (let a=x;;, a.(i) <- x;;)
— L’appel d’une fonction
— if, for, while

Quand un programme peut-il ne pas terminer ?


1. Lorsqu’il fait appel à une fonction qui ne termine pas. Cela pose le problème de la récursivité.
2. Boucle while qui ne s’arrête pas
3. Boucle for qui modifie l’itérateur. (à ne jamais faire)
Exemples
a) let somme_tableau tab =
let somme = ref 0 in
let n = Array.length tab in
for i = 0 to (n-1) do somme = !somme + tab.(i) done;
!somme;;
b) let est_puissance2 n = (* n doit être strictement positif *)
let p = ref n in
while !p mod 2 = 0 do p := !p / 2 done;
!p = 1;;
c) let rec appartient x liste =
match liste with
| [] -> false
| t::q -> (t = x) || (appartient x q);;
a) L’algo termine car la boucle for termine.
b) À chaque étape, !p vaut 2k m. Le programme s’arrête si k = 0. Si k > 0, k est remplacé par k − 1. On a
k = v2 (k) la valuation dyadique de n. Si k > 0 alors k décroit de 1. Si k = 0, l’algo termine. On parle de
variant : les valeurs de k sont strictement décroissantes et positives, donc la suite est finie.
c) On utilise la longueur de la liste comme variant. On pose alors P (n) : Si la liste est de taille n, l’algo
termine.
— P (0) est vrai, on a appartient x [] = false

1
— Pour P (n + 1), si la liste est de taille n + 1, alors
— Si t 6= x, l’algo fait appel à appartient x q, avec q de taille n. Cet appel termine (hypothèse
de récurrence), donc P (n + 1) est vraie.
— Si t = x, alors P (n + 1) est vraie car l’algo termine directement.

3.2 Preuve
Sur les exemples précédents :
i−1
X
a) On note P (i) la propriété : Avant le passage pour i, !somme vaut tab.(k). On montre cette propriété
k=0
par récurrence.
−1
X
— P (0) est vraie, 0 = tab.(k)
k=0
— Si P (i) est vraie, a-t-on P (i + 1) ? En sortie, on a
i−1
X i
X
!somme= tab.(k)+tab.(i)= tab.(k)
k=0 k=0

donc P (i + 1) vraie.
!p
b) Il y a un invariant : k (!p privé de ses facteurs 2). La propriété est vraie avant la boucle. On a
2
n
n = 2k ⇐⇒ =1
2k
La propriété est conservée pendant toute l’exécution (on vérifie), donc le programme renvoie le bon résultat
n
puisqu’en sortant de la boucle, on a !p= k .
2
c) Par récurrence sur la longueur de la liste, la fonction renvoie le bon résultat.

3.3 Complexité
Il s’agit de mesurer le temps d’exécution d’un algorithme. On pourrait
— Chronométrer l’exécution. C’est une mesure a posteriori, on n’anticipe pas.
— On dénombre à l’avance le nombre d’instructions executées par le processeur (difficile).
— On compte les instructions élémentaires du langage, en supposant qu’elles ont toutes un temps d’éxecution
quasiment égal.
On veut ce résultat pour des valeurs d’entrée de plus en plus grandes. On suppose qu’on dispose d’une
mesure n de la taille d’entrée. On a cependant rarement une fonction commune à toutes les entrées de même
taille.
On peut chercher C(n) telle que pour tout entrée de taille n, T ≤ C(n) (T le temps d’exécution). On peut
chercher la moyenne C(n) pour toutes les entrées de taille n.
En général, on cherche d’abord un équivalent de C(n), par exemple

C(n) ∼ αnr =⇒ C(n) = O(nr )


+∞

On a en fait
Équivalent de C(n) Compléxité
O(n) Linéaire
O(n2 ) Quadratique
O(nr ) Polynomiale
O(exp(n)) Exponentielle
O(1) Constante
O(ln n) Quasi-constante
O(n ln n) Quasi-linéaire

2
Exemples
a)
C(n) = 1
|{z} −n · (1 + 1 + 1 + 1) + |{z}
1
| {z }
Array.length Lectures, écriture, addition !somme
En ne comptant que les additions :
C(n) = n = O(n)
b) Si n = 2r n0 , avec n0 ∧ 2 = 1, on fait r divisions.

log2 (n) = r + log2 (n0 ) =⇒ r ≤ log2 (n) =⇒ C(n) = O(log n)

c) On calcule C(n) nombre maximal de comparaisons pour le traitement d’une liste de taille n.

C(0) = 0 et C(n) = max(1, 1 + C(n − 1)) = 1 + C(n − 1) =⇒ C(n) = n = O(n)

Das könnte Ihnen auch gefallen