2. Plan
1) Diviser pour Régner
2) Algorithme de Gloutonne
3) Méthode Branch and Bound
4) Programmation Dynamique
2
3. ParadigmesAlgorithmiques
• Diviser pour Régner : divise un problème en sous-problèmes
indépendants (qui ne se chevauchent pas), résout chaque sous-
problème, et combine les solutions des sous-problèmes pour
former une solution du problème initial.
• Algorithme Glouton : construit une solution de manière
incrémentale, en optimisant un critère de manière locale.
• Branch & Bound : Séparation et Évaluation.
• Programmation Dynamique : divise un problème en sous-
problèmes qui sont non indépendants (qui se chevauchent), et
cherche (et sauvgarde) des solutions de sous-problèmes de
plus en plus grands.
3
5. Diviser pour régner (Divide-and-Conquer)
• Est une stratégie militaire.
• Est une méthode de conception d’algorithmes qui a mené à la
création d’algorithmes efficaces pour de nombreux problèmes:
• La recherche d'un élément dans un tableau trié (recherche dichotomique),
• Le tri (tri par fusion, tri rapide),
• Le produit de polynômes (algorithme de Karatsuba),
• La transformation de Fourier discrète (transformation de Fourier rapide),
• Exponentiation Rapide,
• Multiplication naïve de matrices (matrices carrées de taille n), etc.
5
6. Introduction
Construire un algorithme pour résoudre le problème avec la
complexité optimale en temps
Converger vers la complexité minimale.
6
L’approche DpR est une approche classique permettant
l’optimisation du temps dans le cas d’un problème polynomial
7. L’approche diviser pour régner sépare le problème
en plusieurs sous problèmes similaires au problème
initial, résolve les sous problèmes de façon
récursive, puis combine ces sous solutions pour
construire la solution du problème initial.
7
Algorithme Récursif
Principe de Diviser pour Régner
8. Schéma général d’un algorithme DpR
Cette approche est basée sur 3 étapes :
Étape 1 Diviser : diviser le problème (les données
du problème) en sous-problèmes similaires au
problème initiale,
Étape 2 Régner : régner les sous problèmes en les
résolvants de façon récursive,
Étape 3 Combiner : combiner les solutions des
sous-problèmes en une solution générale du
problème initial.
8
Elle permet d’obtenir des algorithmes de meilleur complexité.
9. Analyse des algorithmes DpR
Un algo récursif : la complexité en temps est décrite par une
équation de récurrence.
• T(n) : Complexité du problème initial : temps d’exécution du problème de
taille n.
La récurrence est fondé sur les 3 étapes diviser, régner et combiner :
1. Si la taille du problème est suffisamment réduite, n ≤ n0 pour une certaine
constante n0, la résolution est directe et consomme un temps constant O(1).
2. Sinon, on divise le problème en a sous-problèmes chacun de taille 1/c de la
taille du problème initial. Le temps d’exécution total se décompose alors en
trois parties :
a. D(n) : le temps nécessaire à la division du problème en sous-problèmes.
b. aT(n/c) : le temps de résolution des a sous-problèmes.
c. C(n) : le temps nécessaire pour construire la solution finale à partir des
solutions aux sous-problèmes.
9
10. Analyse des algorithmes DpR
O(1) si n n0
aT(n/c) + D(n) + C(n) sinon
10
Formule de récurrence :
T(n) =
Diviser
Régner Combiner
11. Théorème et forme générale
• Diviser : on découpe le problème en sous-problèmes de taille
𝑛/𝑐, qui sont de même nature, avec 𝑎 ≥ 1 𝑒𝑡 𝑐 > 1.
• Régner : les sous-problèmes sont résolus récursivement.
• Combiner : on utilise les solutions aux sous-problèmes pour
reconstruire la solution au problème initial en temps 𝑂 𝑛𝑘
,
avec 𝑘 ≥ 0.
On a,
𝑇 1 = 𝐶𝑜𝑛𝑠𝑡𝑎𝑛𝑡𝑒,
𝑇 𝑛 ≅ 𝑎 𝑇
𝑛
𝑐
+ 𝑂(𝑛𝑘)
11
12. Théorème et forme générale
Soit T(n) une fonction définie par l’équation de récurrence. La complexité en
temps d’exécution d’un algorithme DpR sur une instance de taille n peut
s’écrire :
𝑇 𝑛 = 𝑎 𝑇
𝑛
𝑐
+ 𝑓(𝑛)
Où 𝑓(𝑛) est le temps nécessaire pour Diviser et Combiner. Si on peut montrer
que 𝑓(𝑛) ∈ 𝑂(𝑛𝑘
) pour un certain k, alors le théorèmes suivant nous donne la
complexité de l’algorithme DpR.
𝑇 𝑛 = 𝑎 𝑇
𝑛
𝑐
+ 𝑏 . 𝑛𝑘
∀𝑛 > 𝑛0
Où
𝑛0
𝑛
est une puissance de c. Alors,
• Si 𝑎 > 𝑐𝑘
𝑎𝑙𝑜𝑟𝑠 𝑇 𝑛 = Θ(𝑛log𝑐 𝑎
)
• Si 𝑎 = 𝑐𝑘
𝑎𝑙𝑜𝑟𝑠 𝑇 𝑛 = Θ(𝑛𝑘
log(𝑛))
• Si 𝑎 < 𝑐𝑘
𝑎𝑙𝑜𝑟𝑠 𝑇 𝑛 = Θ 𝑛𝑘
12
13. Exemple : Tri par fusion
• Diviser : la séquence de n éléments à
trier en deux sous séquences de n/2
éléments.
• Régner : en triant les 2 sous séquences
récursivement, la récursivité prend fin
quand la séquence triée a une longueur 1.
• Combiner : en fusionnant les 2 sous
séquences triées pour produire le résultat
final.
13
Tri-fusion (T, p, q)
Si p < q alors
r (p+q) div 2
Tri-fusion (T,p,r)
Tri-fusion (T,r+1,q)
fusionner (T,p,q,r)
Fin si
Diviser
Régner
Combiner
15. Exemple: Algorithme de Tri par fusion (Merge Sort)
Algorithme Tri par fusion
Procédure TriFusion (Var T:Tab; deb, fin : entier)
si deb<fin alors
milieu ← (deb+fin)div 2
Trifusion(T, deb, milieu)
Trifusion(T, milieu+1, deb)
Fusion(T, deb, milieu+1,fin)
FinSi
Fin TriFusion
15
→ 𝑇 0, … ,
𝑛
2
→ 𝑇
𝑛
2
+ 1, … , 𝑛 − 1
Diviser
Régner
Combiner
16. Exemple: Algorithme de Tri par fusion (Merge Sort)
Algorithme Fusionner
Procédure Fusionner (Var T:Tab; deb_gauche, deb_droit, fin : entier)
i← deb_droit
Tantque (T[i]<T[i-1]) et (i<=fin) Faire
j ← i
aux ← T[j]
Tantque (aux<T[j-1]) et (j>deb_gauche) Faire
T[j] ← T[j-1]
j ← j-1
Fin Tantque
T[j] ←aux
i ← i+1
Fin Tantque
Fin Fusionner
16
17. Exemple: Algorithme de Tri par fusion (Merge Sort)
Complexité :
Pour trier un tableau de taille n, on le découpe en deux
tableau de taille
𝒏
𝟐
et l’étape de fusion permet de recombiner
les deux solutions en 𝒏 − 𝟏 opérations.
Soit, 𝑻(𝒏) est le nombre de comparaisons effectuées par
l’algorithme.
On a,
𝑻 𝟎 = 𝟎,
𝑻 𝟏 = 𝟎,
𝑻 𝒏 ≅ 𝟐𝑻
𝒏
𝟐
+ (𝒏 − 𝟏)
17
18. Analyse Tri par fusion
18
a = c= 2
n0=1 D(n)=O(1) C(n)=O(n)
O(1) si n = 1
T(n) =
2T(n/2) + O(n) sinon
T(n)= O(nlog2n)
O(1) si n n0
aT(n/c) + D(n) + C(n) sinon
T(n) =
Diviser
Régner Combiner
19. Exercice 1 : Matrice carrée
Soient A et B deux matrices carrées (n*n)
1. Écrire un algorithme qui calcule C=A*B.
2. Calculer sa complexité : en nombre d’addition + nombre de
Multiplication.
19
20. Exercice 2 : Recherche
• Soit un tableau T d’entiers, et on veut chercher un élément x
dans T.
1. Recherche séquentielle : écrire l’algorithme et déterminer sa
complexité.
2. Recherche dichotomique : écrire l’algorithme et déterminer sa
complexité, sachant que T est trié.
20
21. Exercice 2 : Exponentiation rapide
• L’exponentiation rapide peut être utilisée pour des
« multiplications » plus compliquées, comme la multiplication
de matrices.
• Le principe de l’algorithme récursif est le suivant, pour le calcul
de 𝑥𝑁:
𝑥0
= 1,
𝑠𝑖 𝑁 𝑒𝑠𝑡 𝑝𝑎𝑖𝑟 𝑎𝑙𝑜𝑟𝑠 𝑥𝑁
= (𝑥 ∗ 𝑥)[
𝑁
2
]
,
𝑆𝑖𝑛𝑜𝑛 𝑎𝑙𝑜𝑟𝑠 𝑥𝑁
= 𝑥 ∗ (𝑥 ∗ 𝑥)[
𝑁
2
]
,
1) Calculer la complexité de l’algorithme récursif de l’exponentiation rapide
21
22. Exercice 3 : Algorithme de Tri Rapide (QuickSort)
• Principe: Choisir un élément du tableau T comme pivot, puis
mettre les éléments plus grand que ce pivot à sa droite et les autres
éléments à sa gauche. Par appels récursifs, on ordonne les éléments
de chaque côté du pivot.
• Deux pointeurs : k initialisé à 1, l initialisé à taille (L).
• Bouger k vers la droite jusqu’à un élément > pivot.
• Bouger l vers la gauche jusqu’à un élément ≤ pivot.
• Échanger L[k] et L[l] et répéter tant que k < l.
• Échanger pivot et L[l] .
22
4 1 2 6 9 1 3 8 7 5 9
pivot
k l
23. Exercice 3 : Algorithme de Tri Rapide (QuickSort)
• Deux pointeurs : k initialisé à 1, l initialisé à taille (L).
• Bouger k vers la droite jusqu’à un élément > pivot.
• Bouger l vers la gauche jusqu’à un élément ≤ pivot.
• Échanger L[k] et L[l] et répéter tant que k < l.
• Échanger pivot et L[l] .
23
4 1 2 6 9 1 3 8 7 5 9
k l
Itération 1
1 2 1 3 4 6 9 8 7 5 9
Itération 2
1 1 2 3 4 6 7 5 8 9 9
Itération 3
1 1 2 3 4 6 5 7 8 9 9
Itération 4
1 1 2 3 4 5 6 7 8 9 9
Itération 5
24. Exercice 3 : Algorithme de Tri Rapide (QuickSort)
24
1. Diviser : Si la séquence S a plus d’un élément, sélectionner
un élément x de S comme pivot. Retirer tous les éléments de
S et diviser les en 3 séquences :
• L, contient les éléments de S plus petits que x,
• E, contient les éléments de S égaux à x,
• G, contient les éléments de S plus grands que x.
2. Régner : Trier récursivement L et G.
3. Combiner : Afin de remettre les éléments de S en ordre :
insérer les éléments de L, suivis de ceux de E, et enfin de
ceux de G.
25. Exercice 3 : Algorithme de Tri Rapide (QuickSort)
Analyse du temps d’exécution
Un arbre QuickSort T : Si(n) indique la somme des tailles
d’entrée des nœuds à la profondeur i dans T.
• S0(n)=n car la racine de T est associée avec l’ensemble des entrées
tout entier.
• S1(n)=n-1 car le pivot n’est pas propagé.
• S2(n)=n-3 ou n-2 (si l’un des nœuds a une taille d’entrée à zéro).
25
26. Exercice 3 : Algorithme de Tri Rapide (QuickSort)
Analyse du temps d’exécution (le meilleur des cas)
• QuickSort se comporte de façon optimale si la séquence S est
divisée en sous-séquences L et G de tailles égales.
• T a une hauteur O(log n).
• Complexité temporelle dans le meilleur des cas : O(n log n).
26
𝑆0 𝑛 = 𝑛
𝑆1 𝑛 = 𝑛 − 1
𝑆2 𝑛 = 𝑛 − 1 + 2 = 𝑛 − 3
𝑆3 𝑛 = 𝑛 − 1 + 2 + 22
= 𝑛 − 7
…
𝑆𝑖 𝑛 = 𝑛 − 1 + 2 + 22
+ ⋯ + 2𝑖
− 1 = 𝑛 − 2𝑖
+ 1
…
27. Exercice 3 : Algorithme de Tri Rapide (QuickSort aléatoire)
• La sélection d’un élément de la séquence au hasard comme pivot.
• Le temps d’exécution attendu d’un tel tri sur une séquence de
taille n est O(n log n). Le temps de parcours d’un arbre
QuickSort est O(n).
• La hauteur escomptée d’un arbre QuickSort est O(log n).
27