Leçon 14 sur 19

Chapitre 14 — Retour sur trace

Explorer systématiquement, revenir sur un choix et élaguer les impasses

CHOISIR  →  TESTER   →  AVANCER  →   IMPASSE ?  →  ANNULER   →  ESSAYER AUTREMENT

 

Fiche pédagogique du chapitre

Objectifs d’apprentissage

À la fin de ce chapitre, l’étudiant devra être capable de :

  • expliquer le principe du retour sur trace et le distinguer de la recherche exhaustive naïve ;
  • représenter un problème de décision par un arbre de recherche ;
  • identifier les états, les choix possibles, les contraintes et les cas de succès ou d’échec ;
  • construire une solution progressivement puis annuler proprement un choix ;
  • concevoir des conditions de validité partielle pour détecter rapidement les impasses ;
  • appliquer la méthode aux permutations, aux N reines, aux labyrinthes, au Sudoku et à la somme de sous-ensembles ;
  • améliorer une recherche grâce à l’élagage, à l’ordre des choix et à la mémorisation des états ;
  • analyser la terminaison, la correction et la complexité d’un algorithme de retour sur trace.

Prérequis

  • fonctions, procédures et récursivité ;
  • tableaux, matrices, piles, ensembles et dictionnaires ;
  • arbres et parcours en profondeur ;
  • complexité temporelle et spatiale ;
  • notions de contrainte, invariant et solution partielle.

Organisation indicative

Partie

Contenu

Durée indicative

14.1Principe général, choix, annulation et schéma générique2 h
14.2Arbre de recherche, états, impasses et élagage2 h
14.3Cinq exemples classiques et traces d’exécution5 h
14.4Optimisations, heuristiques et mémorisation2 h
TD / TPConception, justification et expérimentation4 h

 

Idée directrice
Le retour sur trace construit une solution étape par étape. Lorsqu’un choix rend la solution partielle impossible, l’algorithme revient au dernier point de décision, annule ce choix et explore une autre branche. Il ne conserve donc pas une décision irréversible contrairement à une stratégie gloutonne.

 

14.1 Principe

Définition générale

Le retour sur trace, souvent appelé backtracking, est une méthode de recherche systématique adaptée aux problèmes où une solution doit être construite par une succession de décisions. Chaque décision étend une solution partielle. Dès qu’une contrainte est violée ou qu’aucune continuation n’est possible, la dernière décision est annulée.

La méthode repose sur une exploration en profondeur de l’espace des solutions. La pile des appels récursifs mémorise naturellement les décisions prises, ce qui permet de revenir à l’état précédent lorsque la branche courante échoue.

Différence essentielle
Une recherche exhaustive génère parfois toutes les solutions complètes avant de les tester. Le retour sur trace teste la validité dès la construction et abandonne immédiatement les préfixes qui ne peuvent conduire à aucune solution.

 

Construction progressive d’une solution

La solution est représentée par un état partiel : un préfixe de permutation, des reines déjà placées, un chemin partiel dans un labyrinthe, quelques cases remplies d’un Sudoku ou un sous-ensemble en cours de construction.

Élément

Rôle dans la recherche

Exemple avec les N reines

ÉtatDescription de la solution partielleReines placées sur les premières lignes
ChoixDécision disponible depuis l’état courantChoisir une colonne pour la prochaine reine
TransitionApplication du choixPlacer la reine dans la case choisie
Test de validitéVérification des contraintesAucune reine sur la même colonne ou diagonale
Cas de succèsSolution complète valideN reines placées
Cas d’échecAucun choix valide restantToutes les colonnes sont interdites

 

Test d’une possibilité

Pour chaque état, l’algorithme énumère les choix candidats. Un candidat peut être testé avant son application, après son application, ou aux deux moments. Tester avant évite une modification inutile ; tester après peut simplifier le code lorsque la validation porte sur l’état obtenu.

  • Un choix admissible respecte les contraintes locales connues.
  • Un choix prometteur possède encore une possibilité de mener à une solution.
  • Un choix complet produit une solution lorsque tous les éléments attendus sont fixés.
  • Un choix impossible doit être rejeté avant d’explorer ses descendants.

Annulation d’un choix

L’annulation restaure exactement l’état qui existait avant le choix. Cette propriété est fondamentale. Une variable, une case, une marque de visite ou une structure auxiliaire modifiée doit retrouver sa valeur précédente.

Invariant de restauration
Après le retour d’un appel récursif, l’état courant doit être identique à l’état précédant l’essai du candidat. Une annulation incomplète entraîne des erreurs discrètes : des choix valides peuvent être rejetés ou des solutions invalides peuvent être acceptées.

 

ZONE DE PSEUDO-CODE — Schéma générique du retour sur trace

Fonction Explorer(etat) : Booléen

    Si EstSolution(etat) Alors

         EnregistrerOuAfficher(etat)

         Retourner Vrai          // ou continuer pour toutes les solutions

     FinSi

 

     Pour chaque choix dans Candidats(etat) Faire

         Si EstAdmissible(etat, choix) Alors

             Appliquer(etat, choix)

             succes ← Explorer(etat)

             Annuler(etat, choix)

 

             Si succes Alors

                Retourner Vrai  // retirer ce test pour tout énumérer

             FinSi

         FinSi

     FinPour

 

     Retourner Faux

FinFonction

 

Exploration d’une autre possibilité

Lorsqu’une branche échoue, la boucle reprend avec le candidat suivant. L’ordre de cette boucle ne change pas l’ensemble des solutions théoriquement accessibles, mais il peut modifier fortement le temps nécessaire pour trouver la première solution.

Objectif

Comportement après une solution

Résultat

Trouver une solutionArrêt immédiat et propagation de VraiUne solution quelconque
Trouver toutes les solutionsPoursuite après enregistrementListe ou nombre de solutions
Trouver la meilleure solutionPoursuite avec comparaison et borneSolution optimale
Décider l’existenceArrêt dès le premier succèsVrai ou Faux

 

Récursivité et pile explicite

La récursivité exprime naturellement la profondeur de l’arbre de recherche. Chaque appel correspond à un nœud et mémorise l’état local. Une version itérative peut utiliser une pile explicite contenant les états à explorer, mais l’annulation doit alors être remplacée par la création ou la copie d’états indépendants.

Approche

Avantages

Limites

RécursiveProche de la définition, code concis, annulation naturelleRisque de dépassement de pile, état partagé à gérer
Itérative avec pileContrôle explicite de la mémoire, reprise possibleÉtats à copier ou encoder, code plus complexe
Générateur / itérateurProduit les solutions à la demandeImplémentation dépendante du langage

 

14.2 Arbre de recherche

Nœud de décision

Un nœud représente un état partiel. La racine correspond à l’état initial, avant toute décision. La profondeur indique le nombre de choix déjà réalisés. Une feuille peut être une solution complète, une impasse ou un état terminal ne nécessitant plus de décision.

Lecture d’un nœud
Pour comprendre un arbre de recherche, il faut préciser ce que mémorise un nœud, quels choix créent ses enfants et quelle condition distingue une solution d’une impasse.

 

Branche

Une branche est une séquence de décisions allant de la racine vers un nœud. Elle décrit donc une solution partielle. L’exploration en profondeur suit une branche aussi loin que possible avant de revenir vers un ancêtre possédant encore un enfant non exploré.

ZONE DE PSEUDO-CODE — Parcours en profondeur avec une pile explicite

Procédure ExplorerAvecPile(etatInitial)

     pile ← PileVide()

     Empiler(pile, etatInitial)

 

     TantQue NON EstVide(pile) Faire

         etat ← Depiler(pile)

         Si EstSolution(etat) Alors

             Afficher(etat)

         Sinon

             Pour chaque choix admissible de etat Faire

                suivant ← Copier(etat)

                Appliquer(suivant, choix)

                Empiler(pile, suivant)

             FinPour

         FinSi

     FinTantQue

FinProcédure

 

Solution partielle

Une solution partielle doit contenir suffisamment d’informations pour poursuivre la recherche et vérifier les contraintes. Elle ne doit pas nécessairement stocker tout l’historique si certaines informations peuvent être reconstruites ou maintenues dans des structures auxiliaires.

Problème

Solution partielle

Informations auxiliaires utiles

PermutationPréfixe de valeurs choisiesTableau utilisé
N reinesColonne choisie pour chaque ligne traitéeColonnes et diagonales occupées
LabyrintheChemin courantCases visitées
SudokuGrille partiellement remplieChiffres autorisés par ligne, colonne et bloc
Sous-ensemblesDécisions inclure / exclureSomme courante et bornes restantes

 

Impasse

Une impasse est un état non complet qui ne peut être prolongé vers une solution. Elle apparaît lorsqu’aucun candidat n’est admissible, lorsqu’une contrainte est déjà violée ou lorsqu’une borne prouve qu’un objectif ne peut plus être atteint.

  • Dans les N reines, une ligne sans colonne sûre constitue une impasse.
  • Dans un labyrinthe, une case dont toutes les voisines sont bloquées ou déjà visitées est une impasse.
  • Dans un Sudoku, une case vide sans chiffre possible révèle une contradiction.
  • Dans la somme de sous-ensembles à valeurs positives, une somme courante supérieure à la cible peut être abandonnée.

Élagage

L’élagage supprime une branche sans visiter tous ses descendants. Il est correct uniquement si l’on peut démontrer qu’aucun descendant supprimé ne peut produire une solution recherchée ou une solution meilleure que la meilleure déjà connue.

Type d’élagage

Question posée

Exemple

Par contrainteLa solution partielle est-elle encore valide ?Deux reines se menacent
Par impossibilitéPeut-on encore compléter la solution ?Case de Sudoku sans candidat
Par borneCette branche peut-elle battre la meilleure solution ?Coût partiel déjà trop élevé
Par symétrieCette branche est-elle équivalente à une déjà explorée ?Première reine reflétée horizontalement
Par mémorisationCet état a-t-il déjà été résolu ?Même position et mêmes ressources restantes

 

Attention terminologique
L’élagage ne consiste pas à supprimer arbitrairement des choix pour accélérer le programme. Chaque branche éliminée doit être justifiée par une propriété du problème, une borne sûre ou une équivalence d’états.

 

Exemple d’arbre de recherche

Pour former des suites de longueur 3 avec les symboles A et B, chaque nœud choisit le prochain symbole. Si l’on interdit deux B consécutifs, les branches contenant le préfixe BB sont immédiatement élaguées.

ZONE DE PSEUDO-CODE — Schéma de l’arbre des suites sans « BB »

                         ε

                    /         \

                   A           B

                /    \        /  \

               AA      AB     BA    BB ×

              / \    / \   / \

           AAA AAB ABA ABB× BAA BAB

 

× : branche élaguée dès que le préfixe contient deux B consécutifs.

 

Profondeur, facteur de branchement et taille de l’espace

Si chaque nœud possède au plus b enfants et si la profondeur maximale est d, l’arbre brut peut contenir de l’ordre de b^d feuilles. Cette croissance exponentielle explique pourquoi les vérifications anticipées et les heuristiques d’ordre sont essentielles.

Paramètre

Signification

Effet sur le coût

bNombre moyen de choix par étatUne petite réduction de b peut produire un gain exponentiel
dNombre de décisions nécessairesDétermine la profondeur de récursion
kNombre de branches effectivement visitéesDépend directement de l’efficacité de l’élagage
sTaille de l’état sauvegardéInfluence la mémoire et le coût d’annulation

 

14.3 Exemples

Exemple 1 — Génération de permutations

Une permutation de n éléments est un ordre possible contenant chaque élément exactement une fois. Le retour sur trace choisit successivement une valeur non encore utilisée. Lorsque la longueur du préfixe atteint n, une permutation complète est obtenue.

Étape

Préfixe

Éléments disponibles

Décision possible

0[ ]{A, B, C}A, B ou C
1[A]{B, C}B ou C
2[A, B]{C}C
3[A, B, C]Permutation complète

 

ZONE DE PSEUDO-CODE — Permutations avec tableau « utilisé »

Procédure Permuter(valeurs, position, resultat, utilise)

    n ← Longueur(valeurs)

    Si position = n Alors

         Afficher(resultat)

         Retourner

     FinSi

 

     Pour i ← 0 à n - 1 Faire

         Si NON utilise[i] Alors

             resultat[position] ← valeurs[i]

             utilise[i] ← Vrai

 

             Permuter(valeurs, position + 1, resultat, utilise)

 

             utilise[i] ← Faux      // annulation du choix

         FinSi

     FinPour

FinProcédure

 

Pour n éléments distincts, il existe n! permutations. L’algorithme ne peut donc pas être asymptotiquement plus rapide que Θ(n · n!) si chaque permutation complète doit être affichée, car l’écriture d’une solution coûte Θ(n).

Gestion des doublons
Si le tableau contient des valeurs identiques, il faut trier les valeurs et ignorer un candidat égal au précédent lorsque le précédent n’a pas été utilisé au même niveau. Cette règle évite de générer plusieurs fois la même permutation.

 

Exemple 2 — Problème des N reines

Le problème demande de placer N reines sur un échiquier N × N sans que deux reines partagent une ligne, une colonne ou une diagonale. En plaçant exactement une reine par ligne, l’algorithme ne doit choisir qu’une colonne pour chaque ligne.

Structure

Index utilisé

Interprétation

colonnes[c]cUne reine occupe la colonne c
diag1[l - c + N - 1]l - cUne diagonale descendante est occupée
diag2[l + c]l + cUne diagonale montante est occupée
position[l]lColonne de la reine placée sur la ligne l

 

ZONE DE PSEUDO-CODE — Résolution des N reines

Fonction PlacerReine(ligne, N, position, colonnes, diag1, diag2) : Booléen

    Si ligne = N Alors

         AfficherEchiquier(position)

         Retourner Vrai

     FinSi

 

     Pour colonne ← 0 à N - 1 Faire

         d1 ← ligne - colonne + N - 1

         d2 ← ligne + colonne

 

         Si NON colonnes[colonne] ET NON diag1[d1] ET NON diag2[d2] Alors

             position[ligne] ← colonne

             colonnes[colonne] ← Vrai

             diag1[d1] ← Vrai

             diag2[d2] ← Vrai

 

             Si PlacerReine(ligne + 1, N, position, colonnes, diag1, diag2) Alors

                Retourner Vrai

             FinSi

 

             colonnes[colonne] ← Faux

             diag1[d1] ← Faux

             diag2[d2] ← Faux

         FinSi

     FinPour

 

     Retourner Faux

FinFonction

 

Le pire cas reste exponentiel, mais les tableaux de colonnes et de diagonales transforment le test de sécurité en O(1). Une version naïve qui parcourt toutes les reines déjà placées effectuerait un test en O(N) à chaque candidat.

Réduction par symétrie

Pour compter les solutions, on peut limiter la première reine à la moitié des colonnes, puis doubler les solutions obtenues par réflexion. Si N est impair, la colonne centrale doit être traitée séparément. Cette réduction exploite une symétrie sûre sans perdre de solutions distinctes à réflexion près.

Exemple 3 — Résolution d’un labyrinthe

Le labyrinthe est modélisé par une matrice. Une case peut être libre, bloquée, visitée, appartenir au chemin courant ou constituer la sortie. Depuis une case, l’algorithme essaie les déplacements disponibles dans un ordre choisi.

Symbole

Signification

0Case libre
1Mur
2Case du chemin courant
3Case visitée puis abandonnée
SDépart
ESortie

 

ZONE DE PSEUDO-CODE — Recherche d’un chemin dans un labyrinthe

Fonction ResoudreLabyrinthe(grille, ligne, colonne, sortie) : Booléen

    Si (ligne, colonne) = sortie Alors

         grille[ligne][colonne] ← 2

         Retourner Vrai

     FinSi

 

    Si HorsLimites(ligne, colonne) OU grille[ligne][colonne] ≠ 0 Alors

         Retourner Faux

     FinSi

 

     grille[ligne][colonne] ← 2

 

     Pour chaque (dl, dc) dans [(0,1), (1,0), (0,-1), (-1,0)] Faire

         Si ResoudreLabyrinthe(grille, ligne + dl, colonne + dc, sortie) Alors

             Retourner Vrai

         FinSi

     FinPour

 

     grille[ligne][colonne] ← 3

     Retourner Faux

FinFonction

 

Visité ou chemin courant ?
Une case du chemin courant doit être restaurée lorsqu’une branche échoue. Pour une simple recherche d’existence, une case déjà visitée peut rester définitivement marquée si l’état futur ne dépend que de la position. Si l’état inclut d’autres ressources, la position seule ne suffit plus pour mémoriser un échec.

 

Pour trouver le chemin le plus court dans un labyrinthe non pondéré, le parcours en largeur est généralement préférable. Le retour sur trace convient à la recherche d’un chemin quelconque, à l’énumération de tous les chemins ou à des variantes comportant des contraintes supplémentaires.

Exemple 4 — Sudoku simplifié

Un Sudoku 4 × 4 utilise les chiffres 1 à 4 et des blocs 2 × 2. Le principe est identique à celui d’un Sudoku 9 × 9 : choisir une case vide, essayer chaque chiffre autorisé, poursuivre, puis effacer le chiffre si une contradiction apparaît.

Vérification

Contrainte

LigneLe chiffre ne doit pas apparaître dans la ligne
ColonneLe chiffre ne doit pas apparaître dans la colonne
BlocLe chiffre ne doit pas apparaître dans le bloc 2 × 2
DomaineChaque case reçoit un chiffre compris entre 1 et 4

 

ZONE DE PSEUDO-CODE — Sudoku simplifié

Fonction ResoudreSudoku(grille) : Booléen

     case ← ChoisirCaseVide(grille)

    Si case = AUCUNE Alors

         Retourner Vrai

     FinSi

 

     (ligne, colonne) ← case

     Pour valeur ← 1 à Taille(grille) Faire

         Si Autorisee(grille, ligne, colonne, valeur) Alors

             grille[ligne][colonne] ← valeur

 

             Si ResoudreSudoku(grille) Alors

                Retourner Vrai

             FinSi

 

             grille[ligne][colonne] ← 0

         FinSi

     FinPour

 

     Retourner Faux

FinFonction

 

Heuristique de la case la plus contrainte

Choisir la première case vide est correct mais parfois inefficace. L’heuristique MRV, Minimum Remaining Values, sélectionne la case possédant le moins de chiffres autorisés. Une contradiction est alors détectée plus tôt et le facteur de branchement est réduit.

Propagation de contraintes
Après avoir placé un chiffre, on peut retirer ce chiffre des domaines des cases de la même ligne, colonne et bloc. Si un domaine devient vide, la branche est abandonnée. Si un domaine contient une seule valeur, celle-ci peut parfois être imposée.

 

Exemple 5 — Somme de sous-ensembles

Étant donné un tableau de nombres et une cible, il faut déterminer s’il existe un sous-ensemble dont la somme vaut la cible. Pour chaque élément, deux décisions sont possibles : l’inclure ou l’exclure.

ZONE DE PSEUDO-CODE — Somme de sous-ensembles — version booléenne

Fonction ExisteSousEnsemble(T, indice, sommeCourante, cible) : Booléen

    Si sommeCourante = cible Alors

         Retourner Vrai

     FinSi

 

    Si indice = Longueur(T) Alors

         Retourner Faux

     FinSi

 

    // Branche 1 : inclure T[indice]

    Si ExisteSousEnsemble(T, indice + 1, sommeCourante + T[indice], cible) Alors

         Retourner Vrai

     FinSi

 

    // Branche 2 : exclure T[indice]

     Retourner ExisteSousEnsemble(T, indice + 1, sommeCourante, cible)

FinFonction

 

Sans élagage, l’arbre comporte jusqu’à 2^n feuilles. Si tous les nombres sont positifs, une branche peut être abandonnée lorsque la somme courante dépasse la cible. On peut également utiliser la somme des éléments restants pour détecter une cible devenue inatteignable.

ZONE DE PSEUDO-CODE — Version avec solution et bornes positives

Fonction Chercher(T, i, somme, reste, cible, choix) : Booléen

    Si somme = cible Alors

         Afficher(choix)

         Retourner Vrai

     FinSi

 

    Si i = Longueur(T) OU somme > cible OU somme + reste < cible Alors

         Retourner Faux

     FinSi

 

     Ajouter(choix, T[i])

    Si Chercher(T, i + 1, somme + T[i], reste - T[i], cible, choix) Alors

         Retourner Vrai

     FinSi

     RetirerDernier(choix)

 

     Retourner Chercher(T, i + 1, somme, reste - T[i], cible, choix)

FinFonction

 

Limite de la borne « somme > cible »
Cette règle n’est correcte que lorsque les valeurs restantes sont non négatives. Avec des nombres négatifs, une somme actuellement trop grande pourrait ensuite diminuer et atteindre la cible.

 

Comparaison des exemples

Problème

Décision à chaque niveau

Profondeur maximale

Élagage principal

PermutationsChoisir un élément non utilisénÉviter doublons et valeurs déjà utilisées
N reinesChoisir une colonneNColonnes et diagonales occupées
LabyrintheChoisir un déplacementNombre de casesMurs et états déjà visités
SudokuChoisir un chiffre autoriséNombre de cases videsContraintes et domaines vides
Sous-ensemblesInclure ou exclure un élémentnBornes sur la somme

 

14.4 Optimisations

Vérification anticipée

Une vérification anticipée détecte une contradiction immédiatement après une décision, avant de descendre plus profondément. Elle réduit la taille de l’arbre sans modifier les solutions valides.

Niveau de vérification

Principe

Exemple

Avant le choixTester si le candidat est admissibleColonne libre pour une reine
Après le choixTester les conséquences immédiatesDomaine vide dans le Sudoku
Avant la récursionTester une borne globaleSomme maximale restante insuffisante
À chaque niveauVérifier un invariantAucune valeur utilisée deux fois

 

Réduction des possibilités

La réduction de domaine consiste à supprimer les candidats incompatibles avec les décisions déjà prises. Elle peut être appliquée explicitement au moyen d’ensembles de candidats ou implicitement grâce à des tableaux de disponibilité.

  • Maintenir les colonnes et diagonales occupées au lieu de rescanner l’échiquier.
  • Pré-calculer les voisins accessibles d’une case de labyrinthe.
  • Maintenir les chiffres disponibles pour chaque unité d’un Sudoku.
  • Trier les éléments d’un problème de somme afin d’obtenir des bornes plus fortes.
  • Exploiter les symétries pour ne visiter qu’un représentant de chaque classe équivalente.

Ordre des choix

L’ordre des candidats n’affecte pas la correction lorsque toutes les branches restent explorables, mais il peut déterminer si une solution est trouvée rapidement ou après une exploration très longue.

Heuristique

Idée

Application

Variable la plus contrainteChoisir l’état ayant le moins de possibilitésCase MRV dans le Sudoku
Valeur la moins contraignanteEssayer le choix qui préserve le plus d’optionsAffectation de ressources
Choix proche de l’objectifExplorer d’abord les candidats prometteursLabyrinthe avec distance à la sortie
Valeurs décroissantesAtteindre rapidement une somme ou une borneSomme de sous-ensembles
Ordre aléatoireDiversifier les recherches répétéesProblèmes possédant de nombreuses solutions

 

Heuristique versus preuve
Une heuristique d’ordre change la vitesse moyenne mais ne permet pas d’éliminer une branche. Un élagage, au contraire, doit être justifié pour garantir qu’aucune solution pertinente n’est perdue.

 

Mémorisation des états

Deux chemins différents peuvent conduire au même état abstrait. Recalculer cet état répète inutilement le même sous-problème. Une table de mémorisation associe alors une représentation canonique de l’état à son résultat.

ZONE DE PSEUDO-CODE — Retour sur trace avec mémoïsation des échecs

Fonction ExplorerMemo(etat, memoire) : Booléen

     cle ← Encoder(etat)

    Si cle appartient à memoire Alors

         Retourner Faux

     FinSi

 

    Si EstSolution(etat) Alors

         Retourner Vrai

     FinSi

 

     Pour chaque choix admissible Faire

         Appliquer(etat, choix)

         Si ExplorerMemo(etat, memoire) Alors

             Annuler(etat, choix)

             Retourner Vrai

         FinSi

         Annuler(etat, choix)

     FinPour

 

     Ajouter(memoire, cle)     // état démontré sans solution

     Retourner Faux

FinFonction

 

La clé doit contenir toutes les informations influençant les décisions futures. Mémoriser uniquement la position dans un labyrinthe est correct si aucune autre ressource n’existe ; ce serait incorrect si le joueur possède des clés, une énergie ou des portes déjà ouvertes.

Branch and bound

Pour un problème d’optimisation, le retour sur trace peut maintenir la meilleure solution trouvée. Une borne estime la meilleure valeur encore théoriquement atteignable depuis un état. Si cette borne ne peut pas améliorer le meilleur résultat courant, la branche est abandonnée.

Élément

Minimisation

Maximisation

Solution couranteCoût déjà accumuléGain déjà obtenu
Meilleure solutionPlus petit coût connuPlus grand gain connu
BorneSous-estimation du coût finalSurestimation du gain final
ÉlagageBorne ≥ meilleur coûtBorne ≤ meilleur gain

 

Coût des optimisations

Une vérification plus forte réduit le nombre de nœuds mais demande davantage de calcul par nœud. L’optimisation pertinente minimise le coût total, et non uniquement le nombre de branches.

Technique

Gain possible

Coût / risque

Structures auxiliairesTests en O(1)Mémoire et mises à jour lors de l’annulation
Propagation de contraintesRéduction importante du domaineImplémentation et restauration complexes
MémorisationÉvite les sous-problèmes répétésTable volumineuse et coût d’encodage
HeuristiquesPremière solution trouvée plus tôtEffet dépendant des instances
SymétriesRéduction parfois spectaculairePreuve d’équivalence nécessaire

 

Analyse de la complexité

La complexité du retour sur trace s’exprime souvent en fonction du nombre de nœuds explorés. Dans le pire cas, l’élagage peut être inefficace et l’algorithme visite l’ensemble de l’espace de recherche.

Problème

Taille brute de l’espace

Remarque

Permutationsn!Chaque ordre est une solution candidate
Sous-ensembles2^nDeux décisions par élément
N reinesAu plus N^N, puis N! avec colonnes uniquesLes diagonales élaguent fortement
SudokuJusqu’à 9^k pour k cases videsLes contraintes réduisent les domaines
LabyrintheExponentielle dans le nombre de casesDépend de la structure du graphe

 

La mémoire récursive est généralement O(d), où d représente la profondeur, à laquelle s’ajoutent les structures de l’état. Lorsqu’une copie complète de l’état est créée à chaque appel, le coût mémoire peut devenir O(d × s).

Méthode de conception d’un algorithme de retour sur trace

1. Définir précisément une solution complète et les contraintes qu’elle doit satisfaire.

2. Choisir une représentation compacte de la solution partielle.

3. Identifier les décisions disponibles à chaque niveau.

4. Écrire le cas de succès et les cas d’échec immédiat.

5. Définir l’application et l’annulation exactes d’un choix.

6. Construire un test d’admissibilité aussi précoce que possible.

7. Choisir un ordre de candidats pertinent sans compromettre l’exhaustivité.

8. Ajouter progressivement des bornes, symétries ou mémorisations sûres.

9. Tester sur des cas vides, impossibles, uniques et possédant plusieurs solutions.

10. Mesurer le nombre de nœuds explorés en plus du temps d’exécution.

Checklist avant validation
À chaque retour récursif, l’état a-t-il été restauré ? Le cas de base est-il atteignable ? Toutes les décisions possibles sont-elles couvertes ? Chaque élagage est-il sûr ? Une solution complète est-elle vérifiée avant d’être acceptée ?

 

Applications guidées

Application 1 — Générer les mots binaires sans deux 1 consécutifs

La solution partielle est un préfixe. Le chiffre 0 est toujours admissible. Le chiffre 1 est admissible uniquement si le préfixe est vide ou si son dernier chiffre vaut 0.

ZONE DE PSEUDO-CODE — Mots binaires contraints

Procédure Generer(prefixe, n)

    Si Longueur(prefixe) = n Alors

         Afficher(prefixe)

         Retourner

     FinSi

 

     Ajouter(prefixe, 0)

     Generer(prefixe, n)

     RetirerDernier(prefixe)

 

    Si prefixe est vide OU Dernier(prefixe) = 0 Alors

         Ajouter(prefixe, 1)

         Generer(prefixe, n)

         RetirerDernier(prefixe)

     FinSi

FinProcédure

 

Application 2 — Coloration d’un graphe

Chaque sommet doit recevoir une couleur différente de celles de ses voisins. Le retour sur trace choisit un sommet non coloré, essaie les couleurs autorisées et annule la couleur en cas d’échec.

ZONE DE PSEUDO-CODE — Coloration avec au plus K couleurs

Fonction Colorier(sommet, graphe, couleurs, K) : Booléen

    Si sommet = NombreSommets(graphe) Alors

         Retourner Vrai

     FinSi

 

     Pour couleur ← 1 à K Faire

         Si CouleurAutorisee(sommet, couleur, graphe, couleurs) Alors

             couleurs[sommet] ← couleur

             Si Colorier(sommet + 1, graphe, couleurs, K) Alors

                Retourner Vrai

             FinSi

             couleurs[sommet] ← 0

         FinSi

     FinPour

 

     Retourner Faux

FinFonction

 

Application 3 — Affectation de salles

Pour chaque cours, il faut choisir une salle compatible avec la capacité et l’horaire. L’heuristique consiste à traiter d’abord le cours possédant le moins de salles compatibles. Une salle déjà utilisée au même horaire est retirée des candidats.

Application 4 — Itinéraire avec contraintes

Un voyageur doit atteindre une destination avec une quantité limitée de carburant et sans revisiter certaines villes. L’état inclut la ville courante, le carburant restant et les villes visitées. La mémorisation doit utiliser l’ensemble de ces informations, et pas seulement la ville.

Travaux dirigés

TD 1 — Identifier les composants d’une recherche

Pour chacun des problèmes suivants, préciser l’état, les candidats, le cas de succès, les impasses et l’annulation : permutations, N reines, labyrinthe et somme de sous-ensembles.

TD 2 — Trace d’une permutation

Tracer les appels de l’algorithme de permutations pour [A, B, C]. Indiquer les valeurs du préfixe et du tableau utilisé avant et après chaque annulation.

TD 3 — Arbre des sous-ensembles

Construire l’arbre de recherche pour T = [3, 5, 6] et cible = 8. Marquer les branches qui atteignent la cible et celles qui se terminent sans solution.

TD 4 — N reines

Pour N = 4, représenter les colonnes choisies pour la première solution trouvée lorsque les colonnes sont essayées de gauche à droite. Montrer les retours sur trace nécessaires.

TD 5 — Labyrinthe

Expliquer pourquoi une case visitée doit être marquée. Donner un exemple de boucle infinie obtenue si cette marque est oubliée.

TD 6 — Sudoku

Comparer le choix de la première case vide avec l’heuristique MRV. Expliquer sur une grille partielle pourquoi MRV peut détecter une contradiction plus tôt.

TD 7 — Correction de l’annulation

L’algorithme place une valeur dans un tableau et ajoute cette valeur à un ensemble utilisé, mais lors du retour il efface seulement le tableau. Identifier l’erreur et ses conséquences.

TD 8 — Élagage sûr ou dangereux

Classer chaque règle : sûre, sûre sous condition ou incorrecte. a) arrêter si somme > cible ; b) ignorer les symétries des N reines ; c) abandonner un Sudoku si une case n’a aucun candidat ; d) ne jamais revenir sur une case de labyrinthe déjà visitée.

TD 9 — Complexité

Donner la taille maximale de l’espace de recherche pour n décisions binaires, une permutation de n éléments et une affectation de n variables possédant chacune k valeurs.

TD 10 — Concevoir une recherche

Concevoir un algorithme générant toutes les combinaisons de k éléments parmi n. Préciser les bornes permettant d’abandonner une branche lorsqu’il ne reste pas assez d’éléments.

Corrigés indicatifs des travaux dirigés

Correction du TD 1

Problème

État

Candidats

Succès

Impasse

PermutationPréfixe + utilisésÉléments non utilisésLongueur nAucun candidat avant longueur n
N reinesColonnes des lignes placéesColonnes sûresN lignes traitéesAucune colonne sûre
LabyrinthePosition + chemin / visitesVoisins accessiblesSortie atteinteAucun voisin valide
Sous-ensemblesIndice + somme + choixInclure / exclureSomme cibleFin du tableau ou borne impossible

 

Correction du TD 2

L’ordre des solutions est ABC, ACB, BAC, BCA, CAB, CBA si les candidats sont parcourus dans l’ordre du tableau. Après l’affichage de ABC, C est désélectionné, puis B est désélectionné ; le candidat C est ensuite choisi en deuxième position. Chaque retour restaure exactement la disponibilité du candidat annulé.

Correction du TD 3

ZONE DE PSEUDO-CODE — Arbre partiel pour [3, 5, 6] et cible 8

                     somme 0

                 / inclure 3   \ exclure 3

               somme 3              somme 0

           / +5       \ -5      / +5       \ -5

        somme 8 ✓   somme 3   somme 5      somme 0

                    /  \        /  \         /   \

                  +6   -6     +6   -6      +6    -6

 

La branche {3,5} atteint immédiatement la cible.

 

Correction du TD 4

Une solution est [1, 3, 0, 2] en indices commençant à 0. En essayant d’abord la colonne 0 pour la première ligne, les lignes suivantes finissent dans une impasse ; la première reine est retirée, puis la colonne 1 est essayée. La restauration concerne la colonne et les deux diagonales.

Correction du TD 5

Sans marque de visite, deux cases voisines A et B peuvent s’appeler mutuellement : A explore B, puis B réexplore A, ce qui répète indéfiniment les appels. La marque de visite empêche de revenir sur la même case dans le chemin courant.

Correction du TD 6

La première case vide peut avoir quatre candidats et créer quatre branches. Une autre case peut n’avoir qu’un seul candidat, ou aucun. MRV choisit cette seconde case : la valeur forcée est appliquée, ou l’impasse est détectée sans créer de branches inutiles.

Correction du TD 7

L’ensemble utilisé doit être restauré en retirant la valeur. Sinon, cette valeur reste interdite dans les branches sœurs. L’algorithme perd alors des solutions valides et peut conclure à tort qu’aucune solution n’existe.

Correction du TD 8

Règle

Classement

Justification

Somme > cibleSûre sous conditionUniquement si toutes les valeurs restantes sont non négatives
Ignorer les symétriesSûre sous conditionIl faut définir l’équivalence et ajuster le comptage
Case Sudoku sans candidatSûreAucune complétion ne peut satisfaire cette case
Ne jamais revenir sur une case visitéeDépend de l’étatSûr si la position détermine tout ; incorrect avec ressources ou portes

 

Correction du TD 9

  • Décisions binaires : 2^n feuilles.
  • Permutation : n! feuilles.
  • n variables avec k valeurs : k^n affectations complètes.
  • Ces bornes brutes peuvent être fortement réduites par les contraintes.

Correction du TD 10

ZONE DE PSEUDO-CODE — Combinaisons de k éléments parmi n

Procédure Combinaisons(T, debut, k, courant)

    Si Longueur(courant) = k Alors

         Afficher(courant)

         Retourner

     FinSi

 

     manque ← k - Longueur(courant)

     Pour i ← debut à Longueur(T) - manque Faire

         Ajouter(courant, T[i])

         Combinaisons(T, i + 1, k, courant)

         RetirerDernier(courant)

     FinPour

FinProcédure

 

La borne Longueur(T) - manque garantit qu’après le choix de i, il restera suffisamment d’éléments pour atteindre une combinaison de taille k.

Travail pratique — Laboratoire de retour sur trace

Objectif

Développer une petite bibliothèque de résolution par retour sur trace et mesurer l’influence des optimisations. Le langage peut être Python, C ou Java, mais l’analyse doit être formulée indépendamment du langage.

Travail demandé

1. Implémenter le schéma générique avec instrumentation du nombre de nœuds explorés.

2. Implémenter les permutations et vérifier que n! solutions sont obtenues pour des valeurs distinctes.

3. Résoudre le problème des N reines et compter les solutions pour plusieurs valeurs de N.

4. Résoudre un labyrinthe en affichant le chemin trouvé et les cases abandonnées.

5. Implémenter le Sudoku 4 × 4, puis comparer première case vide et MRV.

6. Résoudre la somme de sous-ensembles avec et sans bornes.

7. Mesurer le temps, le nombre d’appels et la profondeur maximale.

8. Rédiger une conclusion expliquant quelle optimisation apporte le meilleur gain selon le problème.

Instrumentation conseillée

Mesure

Description

nœudsNombre d’états visités
choix_testesNombre total de candidats examinés
elagagesNombre de branches rejetées sans récursion
profondeur_maxPlus grand nombre de décisions simultanées
solutionsNombre de solutions complètes
tempsDurée d’exécution dans les mêmes conditions

 

Jeux d’essai minimaux

Module

Cas à tester

Résultat attendu

Permutationsn = 0, 1, 3 ; valeurs dupliquées1, 1, 6 solutions distinctes selon la convention
N reinesN = 1, 2, 3, 41, 0, 0, 2 solutions
Labyrinthesortie directe, impasse, plusieurs cheminssuccès, échec, un chemin valide
Sudokugrille résolue, grille valide, grille contradictoiresuccès, solution, échec immédiat
Sous-ensemblescible 0, cible atteignable, impossibleensemble vide, solution, Faux

 

Grille d’évaluation proposée

Critère

Points

Correction des algorithmes et restauration des états6
Qualité des tests d’admissibilité et des élagages4
Instrumentation et comparaison expérimentale3
Analyse de complexité et interprétation3
Lisibilité, modularité et documentation2
Jeux de tests et gestion des cas particuliers2

 

Erreurs fréquentes et bonnes pratiques

Erreur fréquente

Conséquence

Bonne pratique

Oublier le cas de baseRécursion infinie ou aucune solution reconnueDéfinir succès et échec avant les choix
Annulation incomplèteContamination des branches sœursRestaurer toutes les structures modifiées
Tester trop tardExploration inutile de sous-arbres impossiblesVérifier les contraintes dès qu’elles deviennent évaluables
Élagage non prouvéPerte de solutions validesÉnoncer la condition de sûreté
État mal mémoriséRéutilisation de résultats incorrectsEncoder toutes les informations futures pertinentes
Copier tout l’étatCoût mémoire et temps excessifsModifier puis annuler lorsque cela reste simple
Confondre chemin courant et visité globalSolutions manquées dans certains graphesAdapter la marque au modèle d’état
Afficher sans copierToutes les solutions semblent identiquesCopier la solution avant de l’enregistrer

 

Synthèse du chapitre

  • Le retour sur trace explore en profondeur un arbre de décisions.
  • Une solution est construite progressivement à partir de choix admissibles.
  • Chaque choix doit pouvoir être annulé afin de restaurer exactement l’état précédent.
  • Une impasse déclenche le retour vers le dernier nœud possédant un candidat non exploré.
  • L’élagage correct supprime les branches incapables de produire une solution pertinente.
  • L’ordre des choix, la propagation et la mémorisation peuvent réduire fortement le temps moyen.
  • Le pire cas reste souvent exponentiel ou factoriel.
  • La qualité de la représentation de l’état conditionne la correction et les performances.
Méthode en une phrase
Choisir un candidat, vérifier qu’il reste possible, appliquer le choix, poursuivre récursivement, puis annuler le choix avant d’essayer le candidat suivant.

 

Glossaire

Terme

Définition

Retour sur traceMéthode explorant des choix et revenant en arrière après un échec
ÉtatReprésentation des décisions déjà prises et des informations utiles
Solution partielleÉtat respectant les contraintes mais encore incomplet
CandidatChoix pouvant prolonger l’état courant
ImpasseÉtat non complet ne pouvant mener à aucune solution
AnnulationRestauration de l’état précédant un choix
Arbre de rechercheArbre dont les nœuds sont des états et les arêtes des décisions
ÉlagageSuppression justifiée d’un sous-arbre inutile
Facteur de branchementNombre moyen de choix disponibles par nœud
PropagationDéduction de conséquences réduisant les domaines futurs
MémoïsationStockage du résultat d’états déjà rencontrés
MRVHeuristique choisissant la variable ayant le moins de valeurs restantes
Branch and boundRetour sur trace avec bornes pour un problème d’optimisation
SymétrieTransformation produisant un état équivalent à un autre

 

Auto-évaluation

Je peux…

Oui

À revoir

définir le retour sur trace et expliquer le rôle de l’annulation
identifier l’état, les candidats, le succès et les impasses
dessiner un arbre de recherche simple
écrire un pseudo-code générique correct
résoudre un problème de permutations
expliquer les contraintes des N reines
marquer et restaurer un chemin dans un labyrinthe
appliquer MRV à un Sudoku simplifié
concevoir des bornes pour une somme de sous-ensembles
justifier qu’un élagage est sûr
distinguer heuristique d’ordre et règle d’élagage
analyser la complexité brute d’un espace de recherche

 

Conclusion
Le retour sur trace transforme une explosion combinatoire aveugle en exploration structurée. Il ne supprime pas toujours la difficulté intrinsèque du problème, mais il permet d’exploiter immédiatement les contraintes, de restaurer les décisions et de concentrer le calcul sur les branches encore prometteuses.