Vous êtes sur la page 1sur 29

Université Abdelmalek Essaâdi

Ecole Nationale des Sciences Appliquées


Al Hoceima

Chapitre 4: Étude de la complexité


de quelques algorithmes
Plan
I. Algorithmes de tri « itératifs »
II. Algorithmes « diviser pour régner »
III.D’autres algorithmes

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 2


I. Algorithmes de tri itératifs
1. Généralités
Problème de tri : étant donné un tableau T non trié, le problème de
tri consiste à utiliser un algorithme de tri pour ranger les valeurs de
tableau T dans un ordre (un sens) donné(croissant/décroissant).
Exemple A={3, 7, 9, 2, 4, 6, 8} le trie de ce tableau dans l’ordre
croissant donne A={1, 2, 3, 4, 6, 7, 8, 9}
Plusieurs situations nécessite le tri à savoir :
établir le classement de certains élèves,
mettre en ordre un dictionnaire,
faire une sortie lisible d'un correcteur d'orthographe,
etc …
Il existe plusieurs algorithme de tri dans la littérature, à savoir : tri
par sélection, tri par insertion, tri rapide, tri fusion…
Dans la suite on va traiter le cas du tri d’un tableau dans l’ordre
croissant.

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 3


2. Tri par sélection
L’idée de cette algorithme est basée sur un autre algorithme;
celui qui permet de trouver la valeur minimale ou maximale
d’un tableau. On peut choisir d’utiliser l’un des deux
algorithme (min ou max), si l’algorithme choisit est min, le tri
commence par le début de tableau le contraire est vrai.
À chaque itération de l’algorithme tri par sélection, les étapes
à suivre sont :
Chercher le minimum (resp. maximum) du la partie de
tableau non encore trié.
Échanger le minimum (resp. maximum) avec le premier
(resp. dernier) élément de la partie du tableau non encore
trié.

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 4


…. la suite
Algorithme de tri par sélection (le cas d’utiliser l’algorithme
min_tableau)
Fonction Tri_sélection(T : Liste, n : Entier)
Var i, imin : Entier;
Début
Pour i : = 1 à n-1 Faire
imin := Obtenir_min(T, i, n);
Si(imin i) Alors Échanger(T, i, imin) FinSi
FinPour
Fin

Source :wikipedia.org

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 5


…. la suite
Fonction Obtenir_min(A : Liste, d, f : Entier) : Entier
Var i, j : Entier;
Début
j := d;
Pour i : = d + 1 à f Faire
Si(A[i] < A[j]) Alors j := i; FinSi
FinPour
Retourner(j);
Fin
Fonction Echanger(A : Liste, i, j : Entier)
Var t : Entier;
Début
t := A[i];
A[i] := A[j];
A[j] := t;
Fin

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 6


…. la suite
Exemple:

51 2 3 4 5
5 9 7 3 8

i=1 3 9 7 5 8 imin= 4, changement

i=2 3 5 7 9 8 imin= 4, changement

i=3 3 5 7 9 8 imin= 3, pas de changement

i=4 3 5 7 8 9 imin= 4, changement

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 7


…. la suite
Etude de la complexité de l’algorithme Tri_sélection :
La complexité de l’algorithme tri_selection = (n-1)*(complexité
de Obtenir_min + complexité de Echanger)
La complexité de l’algorithme Obtenir_min est linéaire; il dépend
directement de la taille de l’entrée. Si on considère la taille de
l’entrée est k alors C(k)=k.
La complexité de la fonction Echanger est constante.
D’où C(n) = (n+c)+((n-1)+c)+ …+(2+c)
= n+(n-1)+…+2+n*c
= n*c+ n*(n-1)/2
= n(c+(n-1)/2)
= n((n-1+2c)/2) ≤ (1+c) n2
Ce qui implique que C(n)= O(n²).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 8


3. Tri à bulles
Idée : le tri à bulles consiste à permuter les éléments adjacents s’ils
ne sont pas ordonnés. À chaque itération i, on parcourt le tableau de
droite à gauche (ou bien de gauche à droite) pour placer le minimum
(ou le maximum) dans la position i par une suite d’échange
d’éléments adjacents.
51 2 3 4 5
5 9 7 3 8

i=1 3 5 9 7 8

i=2 3 5 7 9 8

i=3 3 5 7 8 9

i=4 3 5 7 8 9

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 9


…. la suite
Algorithme :
Fonction Tri_bulles(T : Tableau, n : Entier)
Var i, j : Entier;
Début
Pour i : = 1 à (n - 1) Faire
Pour j := n à (i + 1) Faire
Si(T[j] < T[j - 1]) Alors Échanger(T, j - 1, j); FinSi
FinPour
FinPour
Fin
Complexité :
Soit C(n) le nombre de comparaisons effectuées par le tri à bulles.
À chaque itération i (de 1 à n-1), on effectue (n - i) comparaisons.
C(n) = (n-1) + … + 1 = i=1,..,n-1(n-i)= (n-1)n/2
C(n) = O(n2).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 10


4. Tri par insertion
Idée : À chaque itération de l’algorithme : on prend un élément et
on le compare avec ceux qui lui précèdent puis on décale ceux qui
sont supérieur pour placer l’élément en question à sa place
convenable, comme un joueur tiens des cartes à jouer.
1 2 3 4 5
i=2 5 9 7 3 8 5 9 7 3 8

i=3 5 9 7 3 8 5 7 9 3 8

i=4 5 7 9 3 8 3 5 7 9 8

i=5 3 5 7 9 8 3 5 7 8 9

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 11


…. la suite
Fonction Tri_insertion(T : Tableau, n : Entier)
Var i, j, clé : Entier;
Début
Pour i : = 2 à n Faire
clé:= T[i]; // sauver T[i]
j := i - 1;
Tant Que((j > 0) et (T[j] > clé)) Faire
T[j + 1] := T[j]; // Décalage
j--;
FinTQ
T[j+1] = clé;
FinPour
Fin

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 12


…. la suite
Soit C(n) le nombre de comparaisons effectuées par le tri par
insertion.
Dans le pire des cas :
Configuration : un tableau trié dans l’ordre décroissant.
Placer T[i] dans T[1…i-1] nécessite (i-1) comparaisons.
C(n) = 1 + … + (n-1) = i=2,..,n(i-1) = (n-1)n/2
C(n) = O(n2).
Dans le meilleur des cas :
Configuration : un tableau trié dans l’ordre croissant.
Placer T[i] dans T[1…i-1] nécessite 1 comparaison.
C(n) = i=2,..,n(1) = (n-1)
C(n) = (n).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 13


5. Tri PRAM
Idée :
Le tableau à trier est placé sur la première ligne d'une grille. Son
transposé (Le même tableau) est aussi placé en colonne. Puis, de 1
jusqu’à n, on compare chaque élément avec les n autres de tableau (les
comparaisons entre chaque couple formé par une valeur ligne et une
valeur colonne). Si la comparaison est vraie on met à l'emplacement
correspondant de la grille, la valeur 1, sinon 0.
Après avoir terminé, on somme les éléments des lignes de la grille
(matrice de 0 et 1) dans un nouveau vecteur. Ces sommes donnent la
position (l’ordre de tri) de chacune des valeurs du tableau à trier.
C’est un algorithme de tri très adapté à la parallélisation. Il permet
de faire le tri de façon très rapide sur des machines multi-cœurs,
Stations multiprocesseurs, Grille de calculs…
NB: cet algorithme fonctionne mieux lorsque tous les éléments d’un
tableau sont différents.

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 14


…. la suite
Exemple :

≥ 5 9 7 3 8 P
5 1 0 0 1 0 2 On obtient
9 1 1 1 1 1 5 l’ordre de tri

7 1 0 1 1 0 3
3 0 0 0 1 0 1
8 1 0 1 1 1 4

T[ ]= 5 9 7 3 8

P[ ]= 2 5 3 1 4 Tableau trié

i=1, TT[2]=T[1]
i=2, TT[5]=T[2]
TT[P[i]]= T[i] => i=3, TT[3]=T[3] => 3 5 7 8 9
i=4, TT[1]=T[4]
i=5, TT[4]=T[5]

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 15


…. la suite
Algorithme :
Fonction Tri_PRAM(T : Tableau, n : Entier)
Var i, j : Entier;
Début
Pour i : = 1 à n Faire
S:=1;
Pour j := 1 à n Faire
Si(T[i] > T[j]) Alors S+:=1; FinSi
FinPour
TTrie[S]:=T[i]
FinPour
//T:=TTrie;
Fin
Il est bien clair que la complexité de Tri_PRAM est en O(n²).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 16


II. Algorithmes «diviser pour régner»
1. Présentation
Ce sont les algorithmes récursifs qui utilisent une stratégie de type Diviser pour
régner « D&R ».
Elle suit une approche de décomposition descendante d’un problème en sous-
problèmes de tailles plus petites.
Elle repose sur trois étapes fondamentales :
Diviser : on partitionne le problème initial en un certain nombre de sous-
problèmes identiques, mais de tailles plus petites.
Régner : on résout les sous-problèmes d’une manière récursive. Cependant, un
sous-problème peut être résolu directement si sa taille est suffisamment réduite.
Combiner : on combine les solutions partielles des sous-problèmes pour
construire la solution globale du problème initial.
Exemples: Recherche dichotomique, Tri par fusion, Algorithme de Karatsuba,
Algorithme de Strassen…

La complexité d’un algorithme de type D&R est donnée par la résolution de


l’équation de récurrence de partitions correspondante T(n) = aT(n/b) + f(n).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 17


2. Algorithme de tri par fusion
Idée :
Diviser le tableau de taille n, en 2 sous-tableaux de taille n/2 chacun.
Trier chacun des 2 sous-tableaux séparément.
Interclasser les deux sous-tableaux déjà triés pour obtenir un seul
tableau trié. 51 2 3 4 5
Algorithme : 5 9 7 3 8
Fonction Tri_fusion(T : Tableau, d, f : Entier)
5 9 7 3 8
Var m : Entier;
Début 5 9 7 3 8
Si(d < f) Alors
m := (d + f) / 2; 5 9 7 3 8
Tri_fusion(T, d, m);
Tri_fusion(T, m + 1, f); 5 9 7 3 8
Fusion(T, d, f, m);
FinSi 5 7 9 3 8
Fin
3 5 7 8 9

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 18


…. la suite
Algorithme :
Fonction Fusion(T : Tableau, d, f, m : Entier)
Var i, j, k : Entier;
A : Tableau;
Début
Pour i := d à m Faire
A[i] := T[i];
FinPour
Pour i := (m + 1) à f Faire
A[i] := T[f-i+m+1];
FinPour
i := d; j := f; k := d;
Tant Que(i < j) Faire
Si(A[i] < A[j]) Alors { T[k] := A[i]; i++; }
Sinon { T[k] := A[j]; j--; }
FinSi
k++;
FinTQ
Fin

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 19


…. la suite
Complexité de l’algorithme Tri_Fusion: Pour déterminer la formule de
récurrence qui nous donnera la complexité de cet algorithme, nous étudions
ses trois phases « diviser pour régner » :
Diviser: cette étape se réduit au calcul du milieu de l’intervalle [d; f], sa
complexité est donc en O(1).
Régner: l’algorithme résout récursivement deux sous-problèmes de tailles
respectives n/2, d’où une complexité en 2*T(n/2).
Combiner: la complexité de cette étape est celle de l’algorithme de fusion qui
est de O(n) pour la construction d’un tableau solution de taille n.
Par conséquent, la complexité du tri_Fusion est donnée par la récurrence :
 1; si n  1

T ( n)   n
2T ( )  ( n )
 2
En utilisant le théorème de Master, la complexité de l’algorithme est en
O(nlog2 n).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 20


3. Algorithme de Karatsuba
C’est un algorithme permettant de calculer le produit de deux grands
nombres entiers avec un temps d’exécution réduit par rapport à
l’algorithme scolaire.
Soient deux entiers x et y, ayant chacun n chiffres. On veut calculer
leur produit x × y.
On s’intéresse aux nombres de multiplications élémentaires (par pair
de chiffres).
Avec un algorithme scolaire (algorithme naïf), on effectue n2
multiplications  algorithme en (n2).
L’algorithme scolaire en mode D&R :
On divise les deux nombres x et y en deux sous-nombres, chacun
ayant n/2 chiffres :
x = a.10n/2 + b et y = c.10n/2+ d
xy = ac.10n + (ad + bc).10n/2+ bd

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 21


…. la suite
Algorithme Multiplication scolaire
Fonction Multi_scolaire(x, y : Entiers ) Entier
Var a, b, c , d , n : Entiers;
Début
n :=min(size(x),size(y));
Si (n = 0) alors Retourner x*y;
Sinon
p:=puissance(10,n/2);
a :=x/p;
Avec ce mode opératoire, on a un algorithme
b := x%p;
diviser pour régner dont la complexité est
c :=y/p;
T(n) = 4T(n/2) +O(n) => T(n) = (n2)
d :=y%p;
s0 := Multi_scolaire (a, c);
s1 := Multi_scolaire (a, d);
s2 := Multi_scolaire (b, c);
s3 := Multi_scolaire (b, d);
Retourner s0*10n+(s1+s2)*10n/2 + s3;
FinSi
Fin

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 22


…. la suite
Amélioration de Karatsuba :
Le mathématicien A.A. Karatsuba a proposé une amélioration de
l’algorithme de multiplication en mode D&R : la remarque qu’il
a fait est la suivante : « Faire 3 multiplications pour le calcul de
xy au lieu de 4 ». Explications :
On a xy = ac.10n + (ad + bc).10n/2+ bd
On remarque que ad + bc = (a + b)(d + c) - ac - bd.
Alors xy= ac.10n+((a + b)(d + c)-ac - bd).10n/2+ bd.
Cela signifie qu’au lieu de faire 4 multiplications (ac, ad, bc
et bd) on peut faire que 3 (ac, (a + b)(d + c), bd)
On diminuera la complexité de cet algorithme au lieu d’avoir 4
appel récursif, n’utiliser que 3 (a = 3).

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 23


…. la suite
Exemple :
Pour calculer le produit 12345×6789, on choisit B = 10 et
n = 4. Puis on décompose les deux nombres comme suit :
12345 = 123 · 100 + 45
6789 = 67· 100 + 89
k0 = 123 × 67 = 8241
k1 = (123 + 45) × (67 + 89) = 168 × 156 = 26208
k2 = 45 × 89 = 4005
k1 - k0 - k2 = 26208 − 8241 − 4005 = 13962
12345×6789 = k0 ·Bn + (k1 - k0 - k2 )Bn/2 + k2 = 8241
× 10000+ 13962 × 100 + 4005 = 83810205.

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 24


…. la suite
Algorithme :
Fonction karatsuba(x, y : Entiers ) Entier
Var a, b, c , d , n,k0,k1,k2,p : Entiers;
Début
n=min(size(x),size(y));
Si (n = 0) alors Retourner x*y;
Sinon Complexité :
T(n) = 3T(n/2)+O(n)
p:=puissance(10,n/2);
La solution de cette équation est :
a :=x/p;
T(n) = (nlog(3)/log(2)) = (n1.59).
b := x%p;
c :=y/p;
d :=y%p;
k0 := karatsuba(a , c);
k1 := karatsuba((a +b), (c +d));
k2 := karatsuba (b , d)
Retourner k0*10n+(k1-k0-k2)*10n/2 + k2;
FinSi
Fin

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 25


4. Multiplication matricielle: algorithme de Strassen
C’est un algorithme de type « diviser pour régner » qui permet
la multiplication de deux matrices en un temps rapide par
rapport à l’algorithme de multiplication naïf.
La multiplication de deux matrices carrées de taille n×n,
A=(aij) et B=(bij) est définie par C=A×B avec : cij = ∑ aij× bij
Algorithme « D&R »naïf: Nous supposerons que n est une
puissance exacte de 2. On décompose chaque matrice en sous-
matrices de taille n/2 . L'équation peut alors se récrire C=A×B
:
 C11 C12   A11 A12   B11 B12 
       
 C21 C22   A21 A22   B21 B22 
C11  A11B11  A12B21 C12  A11B12  A12B22 C21  A21B11  A22B21 C22  A21B12  A22B22

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 26


…. la suite
Algorithme de multiplication naïf :
Fonction Multi_Matrice(A, B : Matrices,n:entier) : Matrice
Var : Entiers;
Début
Si (n = 1) alors
Retourner A×B;
Sinon
C11:= Multi_Matrice(A11, B11) + Multi_Matrice(A12, B21);
C12 := Multi_Matrice(A11, B12) + Multi_Matrice(A12, B22 );
C21 := Multi_Matrice(A21, B11) + Multi_Matrice(A22 , B21);
C22 := Multi_Matrice(A21, B12) + Multi_Matrice(A22 , B22 );
FinSi
Fin
Avec cet algorithme diviser pour régner, on obtient un coût :
T(n) = 8T(n/2)+ (n2).
T(n) = (n3)

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 27


…. la suite
L’algorithme « D&R » de Strassen : est un algorithme «
diviser pour régner » qui n'effectue que 7 multiplications de
matrices, contrairement à 8 de l'algorithme précédent mais qui
effectue plus d'additions et de soustractions de matrices, ce qui
est sans conséquence une addition de matrices étant « gratuite
» par rapport au coût d'une multiplication.
S1=A11(B12 - B22) S5=(A11 + A22) (B11 + B22)
S2=(A11+A12)B22 S6=(A12 - A22)(B21 + B22)
S3=(A21 +A22)B11 S7=(A11 - A21 )(B11 + B12)
S4=A22 (B21- B11)

 S5  S 4  S 2  S 6 S1  S2 
A  B   
 S3  S 4 S1  S5  S3  S7 

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 28


…. la suite
Algorithme de multiplication Strassen :
Fonction Matrice_Strassen(A, B : Matrices) : Matrice
Var : Entiers;
Début
Si (n = 1) alors
Retourner A×B;
Sinon
S1 := Matrice_Strassen(A11,(B12 - B22));
S2 := Matrice_Strassen((A11+A12),B22);
S3 := Matrice_Strassen((A21 +A22),B11);
S4 := Matrice_Strassen(A22, (B21- B11));
S5 := Matrice_Strassen( (A11 + A22), (B11 + B22));
S6 := Matrice_Strassen( (A12 - A22),(B21 + B22));
S7 := Matrice_Strassen( (A11 - A21 ),(B11 + B12));
Retourner(S5 +S4 - S2 + S6 , S1 - S2 , S3 + S4 , S1 + S5 - S3 + S7);
FinSi
Fin
Avec cet algorithme diviser pour régner, on obtient un coût :
T(n) = 7T(n/2)+ (n2).
T(n) = (n2.8)

ENSAH Étude de la complexité de quelques algorithmes E.W. DADI – page : 29

Vous aimerez peut-être aussi