echiquier. - Informatique MP* Carnot

publicité
Lycée Carnot
MP*
P ROJET B ACKTRACKING 3 : PARCOURS D ’ ÉCHIQUIER PAR UN CAVALIER ET
PROBLÈME DES n DAMES
Parcours d’un échiquier par un cavalier
But
Le jeu d’échec se joue sur un échiquier, c’est-à-dire un plateau de 8×8
cases. Ces cases sont référencées de a1 à h8 (cf. figure).
Un pièce, appelée le cavalier, se déplace suivant un « L » imaginaire
d’une longueur de deux cases puis d’une largeur d’une case.
Exemple : un cavalier situé en d4 atteint, en un seul déplacement, une
des huit cases b5, c6, e6, f5, f3, e2, c2 et b3 (voir figure ci-contre).
On appelle case accessible toute case que le cavalier peut atteindre
en un déplacement à partir de sa position.
Le but est déterminer un parcours de l’ensemble de l’échiquier par
un cavalier en ne passant sur chaque case qu’une et une seule fois.
Heuristique de Warnsdorff
Une heuristique est un algorithme permettant d’obtenir rapidement
une solution approchée à un problème d’optimisation.
0Z0Z0Z0Z
Z0Z0Z0Z0
6
0Z0Z0Z0Z
5
Z0Z0Z0Z0
4
0Z0m0Z0Z
3
Z0Z0Z0Z0
2
0Z0Z0Z0Z
1
Z0Z0Z0Z0
8
7
a
b
c
d
e
f
g
On va utiliser ici une heuristique proposée par le mathématicien allemand Warnsdorff en 1823 qui a le
défaut de ne pas toujours fournir de solution même s’il en existe.
Le principe de cette heuristique est le suivant :
• à chaque case c de l’échiquier, on affecte un poids égal au nombre de cases accessibles à partir de c ,
• lorsque l’on parcourt l’échiquier, on choisit les cases de poids minimal.
L’idée est donc de parcourir l’échiquier en partant de la périphérie et en se rapprochant du centre.
On pourra définir une variable globale deplacement permettant d’obtenir les 8 déplacements possibles d’un cavalier sur l’échiquier (structure de données libre).
La variable parcours désigne une structure contenant des entiers égaux à 0 si on n’a pas visité une
case (i , j ) et n si on l’a visitée à l’étape n .
1. Écrire une fonction init_poids() renvoyant les poids de chaque case (structure libre).
2. Écrire une fonction Warnsdorff(position, parcours, poids) qui applique l’heuristique à la
position, c’est à-à-dire renvoie une case de poids minimal non encore visitée. Prévoir un retour lorsque
toutes les cases voisines sont déjà visitées.
3. Écrire une fonction parcourir(position, parcours, poids) qui réalise le parcours : à chaque
étape, on utilise l’heuristique pour trouver la position suivante. On s’arrête lorsque l’on a visité toutes les
cases et on renvoie le parcours, ou lorsqu’il n’y a plus de case à visiter.
4. Écrire une fonction calcul() renvoyant un parcours de l’échiquier. On pourra tester différentes
positions initiales jusqu’à obtenir un résultat.
Backtracking
Une première idée est de faire parcourir toutes les cases possibles à un cavalier en listant à chaque
déplacement les cases parcourues. Lorsque celui-ci ne peut plus avancer on consulte le nombre de cases
parcourues.
• Si ce nombre est égal à 64 = 8 × 8, alors le problème est résolu.
• Sinon, il faut revenir en arrière et tester d’autres chemins.
Projet Backtracking 3 : parcours d’échiquier par un cavalier et problème des n dames - page 1
h
1. Écrire une fonction init_casesAccessibles() qui renvoie une structure donnant, pour chaque
position, les cases accessibles à partir de cette position.
Au cours de la recherche, lorsqu’on déplace le cavalier vers une case, celle-ci doit être retirée des cases
accessibles à partir de toute case accessible depuis de la position de la case de départ.
2. Écrire une fonction OccupePosition(position, deplacements, casesAccessibles) qui
prend comme argument une position, l’ajoute aux deplacements déjà effectués, puis enlève la position
de la liste des case accessible de toutes cases accessibles depuis cette position, et enfin renvoie True si l’une
de ces liste est vide (situation critique) et False sinon.
3. Écrire une fonction LiberePosition(deplacements, casesAccessibles) qui récupère le
dernier déplacement (c’est-à-dire la position p de la dernière case occupée), l’enlève de la structure
deplacements, et rajoute p à toutes les listes des cases accessibles des cases accessibles depuis p .
À la fin de cette fonction, deplacements, casesAccessibles seront donc dans le même état qu’avant
l’exécution de la fonction OccupePosition à la position p .
4. Écrire une fonction récursive TestePosition(position, deplacements, casesAccessibles)
qui
• occupe la position,
• vérifie si la situation est critique.
Si c’est est le cas,
? la fonction vérifiera si 63 cases sont occupées et dans ce cas renverra True pour indiquer que la
recherche est terminée.
? Si 63 cases ne sont pas occupées, la fonction libérera la position et renverra False.
Dans le cas contraire,
? la fonction testera (appel récursif) toutes les positions des cases accessibles après la position
de départ.
? La fonction retournera True dès que l’un des appels à TestePosition retourne True ou li-
bérera la position et retournera False si tous les appels à TestePosition(k) retournent
False.
5. Écrire une fonction renvoyant une solution au problème initial à partir d’une position initiale donnée.
Amélioration
Proposer une amélioration en visitant d’abord les cases pour lesquelles le nombre de cases accessibles
est minimal.
Toutes les solutions
Proposer une version renvoyant toutes les solutions (pour une/toutes les positions initiales).
Généralisation
Généraliser à un échiquier de taille N × M .
Visualisation
Proposer une interface graphique permettant de visualiser un parcours.
Projet Backtracking 3 : parcours d’échiquier par un cavalier et problème des n dames - page 2
Problème des 8 dames
Le problème des 8 dames consiste à placer 8 dames sur un échiquier de façon à ce qu’aucune n’en
attaque une autre.
Voir http://www.hbmeyer.de/backtrack/achtdamen/eight.htm
Proposer, par backtracking, une résolution du problème des 8 dames.
Projet Backtracking 3 : parcours d’échiquier par un cavalier et problème des n dames - page 3
Téléchargement