Vous êtes sur la page 1sur 16

Chapitre 4

Optimisation Combinatoire
Plan du cours
 1. Programmation dynamique
 2. Algorithmes « retour en arrière »
 3. Algorithmes gloutons.
 4. Algorithmes non déterministes.
Algorithmes retour en arrière
Backtracking

 Le backtracking est une technique


de résolution de problème où on
construit petit à petit la solution par
essais/erreurs.
Algorithmes retour en arrière Backtracking

 Définition: Le backtracking s'applique


lorsque
 • Le problème à résoudre est fait d'une suite
d’étapes
 • A chaque étape, plusieurs choix sont
possibles mais il est impossible de ≪ calculer
le bon ≫
Algorithmes retour en arrière Backtracking

 Pour résoudre un tel problème


• Il faudra procéder par essais.
• Si, a une certaine étape, on arrive a une impasse, il
faudra revenir en arrière et remettre en doute un
choix précédent.
• Il faudra bien sur être précis pour être sur de tout
tenter une et une seule fois.
Algorithmes retour en arrière Backtracking
 Un exemple courant, en forme d'analogie, est celui du labyrinthe
dont il faut trouver une sortie.
 • Il est formé de couloirs et de carrefours. A chaque carrefour il faut
choisir une direction
 • Si on arrive à une impasse ou si on revient à endroit dejà visité, le
chemin n'est pas le bon. Il faut revenir sur ses pas et faire un autre choix
à un carrefour.
 • Comment s'assurer d'explorer toutes les voies sans réessayer des
chemins déjà tentés ?

6
Structure générale de l'algorithme
// on s'arrete quand on trouve UNE solution
Fonction backtracking( solution en construction, ...) : Booleen
Debut
Reussite:=faux
Initialiser les voies de recherche
répéter Choisir une voie non encore choisie
si la voie est acceptable alors L'ajouter à la solution en cours
si la solution est incomplète alors reussite := backtracking( solution en construction, ...)
si non reussite alors Enlever cette voie de la solution
fsi
sinon reussite := vrai
fsi
fsi
jusqu'à ce que reussite ou toutes les voies ont été explorées
backtracking :=reussite
Fin

7
Algorithmes retour en arrière Backtracking

 Les questions fondamentales auxquelles il faut


répondre dans un cas précis sont :
1. A quoi correspond une étape ? Quelles sont les
voies possibles à chaque étape ?
 2. Comment représenter la solution en cours de
construction ?
 3. Comment examiner toutes les voies possibles
? Quand une voie est-elle acceptable ?
Algorithmes retour en arrière Backtracking

 Et pour obtenir toutes les solutions ?


 Dans ce cas, la variable ≪ reussite ≫ n'est
plus d'aucune utilité. Quand une solution est
complète, on peut la traiter (l'afficher ou la
sauver quelque part) et enlever le dernier
morceau de la solution.
Algorithmes retour en arrière Backtracking
// version ou on cherche TOUTES les solutions
Procédure backtracking( solution en construction, ...)
Initialiser les voies de recherche
répéter Choisir une voie non encore choisie
si la voie est acceptable alors L'ajouter à la solution en cours
si la solution est incomplète
alors backtracking( solution en
construction, ...)
sinon On a une solution, la traiter
fsi
Enlever cette voie de la solution
fsi
jusqu'à ce que toutes les voies ont été explorées
Fin;
Exemple (les 8 reines)

 Il s'agit d'un exemple classique pour


présenter le backtracking : Peut-on placer 8
reines sur un échiquier de manière à ce
qu’elles ne soient pas en prise mutuellement?
 Pour rappel, aux échecs les reines se
déplacent d'un nombre de cases quelconque
en ligne droite mais aussi en diagonale.
Exemple (les 8 reines)
 Étapes et voies de recherche
 A chaque étape, on va placer une reine. Il
n'est pas difficile de se rendre compte que
dans la solution, si elle existe, chaque reine
est placée dans une ligne différente. Dès lors,
à chaque étape la ligne est fixée et il reste à
choisir la colonne.
Exemple (les 8 reines)

 Comment représenter la solution ?


 La solution peut simplement se représenter
par un tableau de 8 entiers indiquant la
colonne ou se trouve la reine de la ligne i.
 • cols : tableau de 8 entiers (col[i] indique la
colonne de la reine en ligne i)
 • ligne : entier indiquant la ligne de la reine
suivante a placer
Exemple (les 8 reines)

 Quelles sont les voies à explorer ?


 A l‘étape i, on l'a dit, on va ajouter la reine de la
ligne i. Les possibilités sont toutes les cases de cette
ligne (toutes les colonnes donc). Un simple compteur
permettra de savoir où on en est. Une reine pourra
être placée dans une case donnée si elle n'entre pas
en conflit avec les reines déjà placées jusqu'ici (elle
ne peut être ni dans la même colonne ni dans la
même diagonale)
Solution
Procédure 8reines();
Début
cols : tableau [1 a 8] d'entiers
backtracking (cols, 1)
afficher cols
fin
Fonction estAcceptable( cols : tableau [1 a 8] d'entiers; ligne,
colonne : entier) : Booleen;
Début
pour i de 1 à ligne – 1 faire
si cols[i] = colonne alors retourner faux fsi
si ligne – i = |cols[i] – colonne| alors retourner faux fsi
fin pour
retourner vrai
Fin;
Solution
Fonction bactracking( cols : tableau [1 a 8] d'entiers, ligne : entier ):Booleen
reussite := faux
colonne :=0
répéter
Incrémenter (colonne)
si estAcceptable( cols, ligne, colonne ) alors cols[ ligne ] := colonne
si ligne < 8 alors
reussite := backtracking( cols, ligne+1
)
// rien à faire si pas réussi, le choix suivant va écraser celui-ci
sinon reussite := vrai
fsi;
fsi
jusqu'à ce que reussite ou colonne = 8
Bactracking:= reussite;
Fin;

Vous aimerez peut-être aussi