Fiche de révision

Méthode « diviser pour régner »


Une technique souvent efficace, lorsqu'elle est possible, consiste à diviser un problème en plusieurs sous-problèmes indépendants, puis à les résoudre récursivement.

IPrincipe

Le paradigme de programmation « diviser pour régner » (ou divide and conquer) consiste à ramener la résolution d'un problème dépendant d'un entier n à la résolution de un ou plusieurs sous-problèmes indépendants dont la taille des entrées passe de n à n2 ou une fraction de n.

Les algorithmes ainsi conçus s'écrivent de manière naturelle de façon récursive. Le procédé « diviser pour régner » est un cas particulier de la récursivité, où la taille du problème est divisée à chaque appel récursif plutôt que seulement réduite d'une unité.

IIExemple de l'exponentiation rapide

Le calcul de la puissance d'un nombre définie par a0=1 et an=a×an1 n'est pas optimal. Il peut être amélioré de la manière suivante :

a0=1 ;

si n est pair, an=a×an/2 ;

sinon an=a×a×an1/2.

La taille du problème est divisée par deux à chaque appel récursif. On a donc une relation de récurrence de la forme Tn+1Tn2 et T1=1 qui mène à Tn=Θlog2n.

IIITri fusion

Le tri fusion permet de trier une liste lst selon le principe « diviser pour régner ».

Pour rassembler deux listes lst1 et lst2 déjà triées, on peut les interclasser de manière suivante : on compare les plus petits éléments de chacune d'elles, on place le plus petit des deux dans une nouvelle liste lstn et on poursuit cette opération jusqu'à épuisement de l'une des deux listes. On complète alors lstn en ajoutant à la fin de celle-ci les éléments de la liste non vide.

Le tri fusion est alors défini de la manière suivante :

si la liste lst a au plus un élément elle est déjà triée ;

si la liste lst a deux éléments ou plus, on partage lst en deux sous-listes de même taille, à un élément près, puis on appelle récursivement la fonction sur chacune des sous-listes et on interclasse les sous-listes triées.

Exemple illustré par un schéma :

06461_chap02_fiche09_i01

Exemple de programme en Python :

Tableau de 18 lignes, 2 colonnes ;Corps du tableau de 18 lignes ;Ligne 1 : ; def interclassement(lst1, lst2):; Ligne 2 : ;     lstN = []; Ligne 3 : ;     n1, n2 = len(lst1), len(lst2); Ligne 4 : ;     i1, i2 = 0, 0 # i1 et i2 sont les indices dans lst1 et lst2; Ligne 5 : ;     while i1 < n1 and i2 < n2:; Ligne 6 : ;         if lst1[i1] < lst2[i2]:; Ligne 7 : ;            lstn.append(lst1[i1]); Ligne 8 : ;            i1 += 1; Ligne 9 : ;         else:; Ligne 10 : ;            lstn.append(lst2[i2]); Ligne 11 : ;            i2 += 1; Ligne 12 : ;     return lstn + lst1[i1:] + lst2[i2:] ; Ligne 13 : ; ; Ligne 14 : ; def fusion(lst):; Ligne 15 : ;     if len(lst) <= 1:; Ligne 16 : ;         return lst; Ligne 17 : ;     m = len(lst) // 2; Ligne 18 : ;     return interclassement(fusion(lst[:m]), fusion(lst[m:]));

IVComplexités typiques

Tableau de 5 lignes, 2 colonnes ;Corps du tableau de 5 lignes ;Ligne 1 : Relation de récurrence; Complexité; Ligne 2 : Tn=Tn/2+Θ1; Θlogn; Ligne 3 : Tn=2Tn/2+Θ1; Θn; Ligne 4 : Tn=2Tn/2+Θn; Θnlogn; Ligne 5 : Tn=aTn/b+Θn (a≥2, b≥2 et a > b); Θnlogba;

Pour lire la suite

Je m'abonne

Et j'accède à l'ensemble
des contenus du site