Diviser pour régner

publicité
Algorithmique et Complexité
4. Stratégie I : Diviser pour Régner et Tri
4.1 Diviser pour Régner
Nicole Bidoit
Université Paris XI, Orsay
Année Universitaire 2008–2009
1
Diviser pour régner
De l’adage politique divide ut imperes à une stratégie fondamentale de l’algorithmique
Résoudre le problème P par un algorithme A qui, pour chaque instance I de taille n
1. coupe l’instance I en 2 (ou plus!) instances I1 et I2
2.résoud le problème P pour I1 et I2 avec l’algorithme A
3. compose les solutions P(I1 ) et P(I2 ) pour produire la solution P(I).
”Diviser pour régner” versus ”algorithme récursif”
complexité : Diviser pour gagner en temps
֒→ Exploiter les propriétés des sous-instances
֒→ Bien ”couper” (sans que ce soit compliqué)
֒→ Composition facile
De nombreux exemples :
la recherche, le tri,
exponentiation (calcul de an )
la multiplication d’entiers, de matrices, de polynômes
enveloppe convexe de points, diagramme de Voronoı̈ ...
2
Stratégies algorithmiques
Diviser pour régner
Recherche dichotomique
Entrée : un tableau T
trié
Binary Search
et un élément e
1. Couper le tableau T [1..n] en 2:
T [1..⌊ n2 ⌋]
et
T [⌊ n2 ⌋+1..n]
2. Chercher e dans les 2 sous instances
(-: la recherche est triviale pour une des deux sous-instances !
3.
←− le gain est là
e est trouvé dans T si il est trouvé dans l’une des deux sous-instances.
Recherche dans une liste contiguë non triée
←− aucun gain
même stratégie que ci-dessus
Recherche d’un élément majoritaire (Exercice)
Soit T [1..n] un tableau représentant une liste d’éléments de taille n.
Un élément e de T est majoritaire si l’ensemble {i
| T [i]=e} est de cardinalité
strictement supérieure à n
2.
Proposer un algorithme simple ; analyser sa complexité ?
Proposer un algorithme ”diviser pour régner” ; analyser sa complexité ?
3
Stratégies algorithmiques
Diviser pour régner
Tri fusion
Merge Sort
Entrée : tableau T représentant un ensemble déléments muni d’un ordre
1. Couper le tableau T [1..n] en 2 :
T [1..⌊ n2 ⌋]
et
T [⌊ n2 ⌋+1..n]
2. Trier chacune des 2 sous instances avec la même méthode
3. Tri(T ) est la fusion des deux sous-instances triées.
la fusion intercale les éléments des deux tableaux
Tri rapide
Quicksort
Entrée : tableau T représentant un ensemble d’éléments muni d’un ordre
1. Couper le tableau T [1..n] en 2 en utilisant un élément pivot T [k]
tous les e dans T [1..m] sont ≤ au pivot
et
tous les e dans T [m+1..n] sont > au pivot
2. Trier chacune des 2 sous instances avec la même méthode
3. Tri(T ) est la concaténation des deux sous-instances triées.
Le gain dépend du choix du pivot
Le cas le meilleur (Exercice)
Le cas le pire (Exercice)
4
Stratégies algorithmiques
Diviser pour régner – Produit de Matrices
Cas des matrices 2×2
Méthode classique.


a
c
b
d


e
g
f
h


=
ae+bg
ce+dg
af +bh
cf +dh


8 multiplications
4 additions
Algorithme de Strassen.


a
c
b
d


e
g
f
h


=
r
t
p1 = a(f − h)
s
u


r = p5 + p4 − p2 + p6
7 multiplications
p2 = (a + b)h
s= p1 + p2
18 additions
p3 = (c + d)e
t = p3 + p4
p4 = d(g − e)
u= p5 + p1 − p3 + p7
et donc
p5 = (a + d)(e + h)
p6 = (b − d)(g + h)
p7 = (a − c)(e + f )
Strassen est meilleur, en terme de nombre de multiplications ...
5
Stratégies algorithmiques
Diviser pour régner – Produit de Matrices – Algorithme de Strassen
Cas général : matrices n×n avec n=2m
[si n n’est pas une puissance de 2 alors les matrices sont étendues avec des 0]
1. Découper des matrices M et N comme suit :
chaque matrice est découpée en 4 sous matrices de dimension 2m−1 ×2m−1

M =
M
M
M
no
M
so
ne
se


et

N no

N=
N so
N
ne
N
se
2. Calculer (avec l’algo Strassen) les produits de matrices


Pi =Ai .Bi , pour i=1 à 7, où
A1 = M no
B1 = N ne − N se
A4 = M so
B4 = N so − N no
A2 = M no + M ne
B2 = N se
A5 = M no + M se
B5 = N no + N se
A3 = M so + M se
B3 = N no
A6 = M ne + M se
B6 = N so + N so
A7 = M ne − M se
B7 = N no + N ne
֒→ les matrices Ai et Bi sont de dimensions 2m−1 ×2m−1
3. Composer comme suit pour obtenir le résultat O

Ono

O=
Oso
O
ne
O
se


= M.N :
Ono = P5 + P4 − P2 + P6
avec
One = P1 + P2
Oso = P3 + P4
Ose = P5 + P1 − P3 + P7
6
Stratégies algorithmiques
Diviser pour régner
Complexité de l’algorithme classique – nombres d’additions et de multiplications
on calcule n2 coefficients
chaque coefficient ”coûte” n additions et n produits
M ult(n) et Add(n) sont dans Θ(n3 )
Complexité de l’algorithme de Strassen
Ce qu’on gagne ?

 M ult(1) = 1
 M ult(n) = 7.M ult( n )
2
M ult(n) = 7m = 7log2 n = nlog2 (7)

 Add(1) = 0
 Add(n) = 7.Add( n ) + 18.( n )2
2
2
Add(n) = 6.(nlog2 (7) − n2 )
L’ordre de grandeur des calculs (multiplication et addition) est Θ(nlog2 (7) )
La borne inférieure ?
7
O(n2 )
Stratégies algorithmiques
[il faut ”toucher” à chaque coefficient]
Diviser pour régner
Analyse de complexité des algorithmes ”Diviser pour régner”
֒→ un squelette général pour l’analyse
֒→ après, ça (la combinatoire) se complique parfois
Hypothèse : L’algorithme A pour le problème P ”coupe” l’instance I de taille n en
s sous-problèmes de taille
n
p dont la résolution, par A, permet de résoudre l’instance I.
Squelette :

 S(1) = 1
 S(n) = Coup(n) + s . S( n ) + Comp(n)
p
Exemple : pour l’algorithme de Strassen
s=7
Coup(n) = 0
p=2
Comp(n) = 18.( n2 )2
Variations de l’algorithme de Strassen
Qu’en est-il de la version ”Diviser pour régner” de l’algorithme de multiplication classique ?
Et si on coupe chaque matrice en 9 blocs de taille n
3 ?
Quel découpage pour faire mieux que Strassen ?
8
Stratégies algorithmiques
Téléchargement