Diviser pour régner

Du latin divide ut imperes (ou ses variantes divide et impera, divide ut reges), le principe divise pour commander (ou divise pour régner) est attribué au Sénat romain, et relève de la stratégie militaire suivante : semer la discorde parmi ses opposants permet de les contrôler, les manipuler et les soumettre plus aisément. Cette machiavélique1 expression était inculquée aux enfants destinnés à prendre les rênes du pouvoir.

La division de l'opposant réduit ses forces, diminue sa confiance en l'opposition du fait du manque d'unité, et le déstabilise par des conflits internes.

Si en politique l'utilisation récurente de cette tactique peut avoir pour conséquence la révélation de la stratégie répétitive auprès des opposants, il n'en est pas de même en informatique, et nous pouvons continuer à affaiblir la difficulté d'une opération en la divisant.

Cette stratégie est fortement employée dans les alorithmes récursifs et sera généralement de type dichotomique (division en deux éléments, mais dont la taille n'est pas forcément égale).

Inhaltsverzeichnis Haut

Exemple de diviser pour régner

Si nous devons chercher une définition dans un dictionnaire, nous pouvons parcourir les pages depuis la première jusqu'au moment où nous trouvons la définition. Espérons que l'on ne doive pas trop souvent chercher la définition des zygomatiques.

Intuitivement, lorsque nous cherchons une définition, nous ouvrons le dictionnaire à un endroit où il y a une forte probabilité que les mots définis ne soient pas trop éloignés du mot que nous cherchons, nous comparons les mots de la page ouverte avec celui cherché, et puis nous sautons encore quelques pages en avant ou en arrière jusqu'à trouver la bonne page.

Inhaltsverzeichnis Haut

Principe de diviser pour régner

Nous allons à chaque fois diviser la quantité de données à traiter, jusqu'au moment où nous atteindrons le cas de base. A chaque fois nous devons respecter le fait que la division mène à un cas plus simple : nous dirons qu'il s'agit d'une relation bien fondée.

Nous atteignons le cas de base (minimal) de cette relation bien fondée "<" quand il n'est plus possible de diviser, ce qui peut s'écrire a minimal ⇔ Il n'existe pas deb : b < a

Ensuite, nous devrons combiner tous les éléments.

Nous pouvons employer des boucles pour implémenter ce genre de concept, mais la récursion est vraiment indiquée car nous effectuons la division lors de "la descente" dans la pile des appels récursifs, et nous effectuons la combinaison lors de" la remontée" de la pile.

L'algorithme résoudre(v) de type diviser pour régner peut donc se résumer de la manière suivante :

  • v est un cas de base ?
    • si oui : résoudre_directement(v)
    • si non :
      • Phase de décomposition : (v1, v2, ..., vn) := diviser(v) pour lequel v1, v2, etc. sont des sous ensembles de v obtenus après division.
      • Phase de récurtion : pour chaque i : ri = résoudre(vi) appel à la récursion pour encore diviser notre sous ensemble
      • Phase de recomposition : r = combiner(r1, r2, ..., rn)

Inhaltsverzeichnis Haut

Trier en appliquant diviser pour régner

Nous pouvons appliquer le principe "diviser pour régner" aux différents algorithmes de tri, en remplaçant résoudre(v) par trier(liste_in). Pour nos exemples, nous allons définir certaines conditions:

liste_in : Liste<T>
liste_out : Liste<T>
Post-condition : liste_out est triée2, liste_in est une permutation3 de liste_out, et l'ordre de tri est réflexif.

  • Le tri par sélection :
    • Info : comme l'algorithme est récursif et retourne à chaque fois une nouvelle liste, listei correspond à la liste utilisée au moment i.
    • combiner = cons(v, listei) {v est l'élément à mettre en tête si il possède la plus petite valeur des éléments de la liste triée}
    • Cas de base : listei = null
    • "diviser" correspond ici à la recherche de la plus petite valeur, en Ordre de grandeur(n)
    • Nous pouvons en déduire que le temps total (diviser + résoudre + combiner) sera de l'ordre de Ordre de grandeur(n2), car il est fait n fois appel à "diviser".
  • Le tri par insertion :
    • diviser(listei) = {head(listei), tail(listei)}
    • Cas de base : listei = null
    • "combiner" correspond ici à l'insertion d'un élément dans une liste triée, et le temps est proportionnel à la taille de la liste Ordre de grandeur(n)4
    • Le temps total sera de l'ordre de Ordre de grandeur(n2)
    • Nous ne constatons donc aucune différence en ordre de grandeur avec le tri par sélection
  • Le tri par fusion :
    • Le tri par fusion est par définition un cas typique de diviser pour régner.
    • diviser(listei) = listei1, listei2 tel que listei1 + listei2 = listei et |listei1| = |listei1| ± 1 en Ordre de grandeur(log n)
    • Cas de base : |listei| = 1
    • "combiner" correspond ici à la fusion de deux listes triées en Ordre de grandeur(n)
    • Le temps total sera de l'ordre de Ordre de grandeur(n log n)
    • Le tri par fusion est donc nettement plus efficace en ordre de grandeur que le tri par sélection ou le tri par insertion.

Deutsche Übersetzung

Sie haben gebeten, diese Seite auf Deutsch zu besuchen. Momentan ist nur die Oberfläche übersetzt, aber noch nicht der gesamte Inhalt.

Wenn Sie mir bei Übersetzungen helfen wollen, ist Ihr Beitrag willkommen. Alles, was Sie tun müssen, ist, sich auf der Website zu registrieren und mir eine Nachricht zu schicken, in der Sie gebeten werden, Sie der Gruppe der Übersetzer hinzuzufügen, die Ihnen die Möglichkeit gibt, die gewünschten Seiten zu übersetzen. Ein Link am Ende jeder übersetzten Seite zeigt an, dass Sie der Übersetzer sind und einen Link zu Ihrem Profil haben.

Vielen Dank im Voraus.

Dokument erstellt 16/10/2009, zuletzt geändert 04/12/2018
Quelle des gedruckten Dokuments:https://www.gaudry.be/de/programmer-divide-ut-imperes.php

Die Infobro ist eine persönliche Seite, deren Inhalt in meiner alleinigen Verantwortung liegt. Der Text ist unter der CreativeCommons-Lizenz (BY-NC-SA) verfügbar. Weitere Informationen auf die Nutzungsbedingungen und dem Autor.

Aufzeichnungen
  1.  Machiavel : Machiavel use de cette stratégie dans son ouvrage "Le Prince" (ISBN : 2-7427-3241-1)

  2.  Trié vs strictement trié : Une liste(simplement) triée peut contenir des doublons alors qu'une liste strictement triée ne peut en contenir (car une valeur ne peut être plus petite ou plus grande qu'elle-même

  3.  Permutation vs contient : Si liste_out une permutation de liste_in, tous les éléments de liste_in seront présents dans liste_out
    alors que si nous déclarons que liste_out contient toutes les valeurs de liste_in, les doublons contenus dans liste_in ne seront présents qu'une seule fois dans liste_out

  4.  Combiner : L'ordre de grandeur du temps de combiner dépend de l'implémentation utilisée pour notre liste. Dans le cas par exemple d'un arbre Rouge/Noir "combiner" sera de Ordre de grandeurlogn)

Inhaltsverzeichnis Haut

Referenzen

  1. Buch Sprache des Dokuments:fr IHDCB331 - Méthodes de Programmation : PY Schobbens, Cours de Méthodes de Programmation (September 2009)
  2. Zeigen Sie - html-Dokument Sprache des Dokuments:fr Diviser pour régner : Wikipedia (version 16/10/09)
  3. Buch Sprache des Dokuments:uk Introduction to Algorithms : Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest (2000)

Diese Verweise und Links verweisen auf Dokumente, die während des Schreibens dieser Seite konsultiert wurden, oder die zusätzliche Informationen liefern können, aber die Autoren dieser Quellen können nicht für den Inhalt dieser Seite verantwortlich gemacht werden.
Der Autor Diese Website ist allein dafür verantwortlich, wie die verschiedenen Konzepte und Freiheiten, die mit den Nachschlagewerken gemacht werden, hier dargestellt werden. Denken Sie daran, dass Sie mehrere Quellinformationen austauschen müssen, um das Risiko von Fehlern zu reduzieren.

Inhaltsverzeichnis Haut