Vous êtes sur la page 1sur 21

AAC cours n°02 du 28/12/2020

Annonces :
Les exercices cités dans ce cours doivent être préparés.
Préparer les exercices 6,7,8,9,10 de la série 01
Si l’audio de la présentation n’est pas audible utiliser un casque audio
Ce cours est disponible en PDF sur ma page professionnelle
Pr. Allaoua Refoufi
email: allaoua.refoufi@univ-setif.dz
UFAS Sétif
Dpt Informatique
Lien du cours sur Youtube :
https://www.youtube.com/watch?v=8FdSNW0RJNo
Paradigme « diviser pour régner »

Introduction
Exemple1 : le tri par fusion (mergesort)
Exemple2 : le tri rapide (quicksort)
Master théorème T(n) = aT(n/b) + nc
Multiplication de matrices : algorithme de Strassen
(nlogn) : une borne minimale pour les algorithmes de tri
Paradigme diviser pour régner
Le paradigme diviser pour régner (“divide & conquer”) résoud un problème
P de taille n en :
1. Le divisant en “a” sous problèmes, chacun de taille n/b, qui sont des instances
du meme type que le problème initial P.
2. Ces sous problèmes sont résolus récursivement
3. Les solutions de ces sous problèmes sont combinées d’une façon appropriée
pour composer (construire) la solution du problème initial P.
Si on note T(n) la complexité du problème P, alors on peut écrire que :
T(n)=aT(n/b) + f(n) où :
a est le nombre de sous problèmes
n/b est la taille de chacun des sous problèmes
T(n/b) est la complexité de chaque sous problème
f(n) est la quantité de travail (la complexité) liée à la composition de la
solution au problème P.
Le travail effectif est executé à différents niveaux :
 Dans le partitionement du problème P en “a” sous problèmes
 en fin de la recursion (return statement) quand les sous problèmes sont
assez petits et leur solution est triviale
 enfin dans la recomposition des solutions partielles pour donner la
solution du problème principal P. Tout ceci est coordonné par la structure
recursive de l’algorithme.
Comme exemple introductif on va examiner deux algorithmes de tri assez
performants : le tri par fusion et le tri rapide.
Lorsque on souhaite concevoir un algorithme basé sur le paradigme “diviser
pour régner”, on cherche à formuler le problème en termes de sous versions du
problème initial jusqu’à ce que les sous versions deviennent triviales à résoudre.
Par conséquent l’algorithme aura une structure récursive. L’analyse de la
complexité de ces algorithmes consiste à dériver une relation de récurrence qu’il
faut ensuite résoudre.
Tri par fusion
Le problème du tri conduit naturellement à utiliser la stratégie « diviser pour
régner » : partager la liste en deux sous listes, trier ces sous listes récursivement,
puis fusionner ces sous listes triées en une liste triée.
Tri par fusion : exemple d’exécution
Taille n [10 2 5 3 7 13 1 6]
n/2 [10 2 5 3] [7 13 1 6]
n/4 [10 2] [5 3] [7 13] [1 6]
n/8 [10] [2] [5] [3] [7] [13] [1] [6]
Fusion des sous problèmes
[2,10] [3,5] [7,13] [1,6]

[2,3,5,10] [1,6,7,13]

[1,2,3,5,6,7,10,13]
Tri par fusion

Input: Un tableau de nombres A[1 . . n]


Output: Une version du tableau trié
function tri_fusion(A[1 .. n])
if n > 1:
return fusion(tri_fusion(A[1 . . n/2]), tri_fusion(A[n/2 + 1 . . n]))
else: return A
Analyse de mergesort
La correction de mergesort est évidente si toutefois la procedure fusion se
déroule correctement.
Si on a deux tableaux triés X[1 . . k] et Y[1 . . l], on les fusionne tout simplement
en un tableau trié Z[1 . . k + l] où le premier élément de Z est le
minimum(X[1],Y[1]), et ainsi de suite.
Par exemple la fusion de [2,5,7,88] et de [4,9,12,33,55] nous donne le liste
[2,4,5,7,9,12,33,55,88]
Analyse de mergesort
Soit T(n) la complexité de l’algorithme
Le nombre de sous problèmes est égal à 2
La taille de chacun des sous problèmes est égale à n/2
L’effort fourni pour reconstituer la solution principale, qui est la fusion, est
égal à n. Car il s’agit de fusionner 2 listes de taille n/2
On peut alors écrire que T(n) = 2T(n/2)+ n et T(1) = 1
Solution de la relation T(n)=2T(n/2)+n

On a T(n/2)=2T(n/22)+n/2
Donc T(n)=2(2T(n/22)+n/2)+n = 22T(n/22)+2n
En développant encore une fois on obtient T(n)=23T(n/23)+3n
En général on a T(n) = 2kT(n/2k)+kn
On s’arrete lorsque n/2k =1, pour utiliser T(1)=1; donc k=logn pour avoir
T(n)=2kT(1)+ kn = n + nlogn = (nlogn)
Tri par fusion en python
def tri_fusion(Liste) :
if len(Liste) < 2:
return Liste[:]
else :
middle = len(Liste)//2
left = tri_fusion(Liste[:middle])
right = tri_fusion(Liste[middle:])
return fusion(left,right)
Quicksort
Quicksort est un algorithme de tri basé sur le paradigme “diviser pour régner”
Quicksort opère comme suit :
Choisir dans le tableau un élémént au hasard: le pivot
Diviser: partitionner le tableau en 2 sous tableaux : tel que tout élément dans le
sous tableau gauche est inférieur ou égal au pivot et tout élément du sous
tableau droit est supérieur au pivot. Le pivot est placé au milieu du tableau
Régner : trier récursivement les deux sous tableaux
Reconstruction :automatique
Algorithme quicksort
p et r sont les bornes du tableau courant
q est l’indice du pivot après la partition
Quicksort (A, p, r)
1: if p ≥ r then return
2: q = Partition(A, p, r)
3: Quicksort (A, p, q − 1)
4: Quicksort (A, q + 1, r)
quicksort : exemple
Exemple d’exécution sur la liste
[12 8 21 4 14 15 9 7 10]
On prend comme pivot le dernier élément 10
[8 4 9 7] [10] [12 21 14 15]

[4] [7] [8 9] [10] [12 14] [15] [21]

[4] [7] [8] [9] [] [10] [12] [14] [] [15] [21] []


La procédure partition (exercice)
Soit le tableau A[p .. r] tel que p ≤ r − 1, cette procedure rearrange le tableau
en deux sous tableaux, A[p .. q − 1] et A[q + 1 .. r], tels que :
• chaque élément de A[p .. q − 1] est  à A[q] et
• chaque élément de A[q + 1 .. r] est > à A[q]
La procedure renvoie la valeur de l’indice q.
Utiliser comme pivot initial A[r]
La procédure scanne A[p .. r − 1] de gauche à droite et déplace à gauche les
éléments ≤ au pivot.
partition : l’algorithme
partition(A, p, r)
1: x = A[r]
2: i←p−1
3: for j ← p to r − 1 do
4: if A[j] ≤ x then {
5: i←i+1
6: Exchange( A[i] and A[j]) }
7: Exchange (A[i + 1] and A[r])
8: return i + 1
Analyse de quicksort
Cas le plus favorable

C’est le cas où les deux sous tableaux sont équilibrés ≈ n/2 chacun.
Dans ce cas on peut écrire que T(n) =2T(n/2) + n
Où n est la complexité de la procedure partition (EXERCICE)
Dans ce cas la complexité est T(n)= O(n log n)
Cas le plus défavorable
Le cas le plus défavorable arrive quand les deux sous tableaux sont désequilibrés
totalement; dans cette situation on peut écrire que :
T(n) = T(1) + T(n − 1) + Ω(n).
En développant la recursion on arrive à :
T(n) = nT(1) + Ω( 𝑛2 𝑛).
comme T(1) = O(1), on obtient T(n) = Ω(n2 ).
Théorème
La complexité de Quicksort dans le cas le plus défavorable est Ω(n2).

Vous aimerez peut-être aussi