Bonjour,
J'ai décidé de m'initier à la programmation par contraintes et j'ai voulu essayer de réaliser un programme qui trouverait une solution au problème des reines, par backtracking.
Pour ceux qui ne connaitraient pas, le problème des reines consiste à placer N reines sur un équiquier de taille NxN sans qu'aucune ne soit menacée par les autres.
J'ai tenté de résoudre ce problème avec un échiquier de taille 8x8, mais mon programme semble tourner en rond sans me donner de réponse et je ne comprends pas pourquoi.
Mon programme:
ligneok : Vérification qu'il n'y a aucune reine sur la ligne correspondant à la case étudiée:
Diagok : Vérification qu'il n'y a aucune reine sur les diagonales associées à la case étudiée:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 function ok=ligneok(placement,position) if sum(placement==position)>=1 ok=false; else ok=true; end
Affichage du résultat:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 function ok=diagok(placement,p) n=length(placement); grille=zeros(n+1); for i=1:n grille (placement(i),i)=1; end grille(p,n+1)=1; for i=1:n %diagonale NO-SE if (i-placement(i)==n+1-p) ok=false; return end %diagonale SO-NE if (i+placement(i)==n+1+p) ok=false; return end end ok=true;
Algorithme de backtrack:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 function affichage(placement) n=length(placement); disp('solution :') grille=zeros(n); for i=1:n grille (placement(i),i)=1; end for i=1:n fprintf(1,'%i\t',grille(i,:)); fprintf(1,'\n') end
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 function ok=positionvalide(placement,colonne) %fin de l'equiquier atteinte. if colonne==9 affichage(placement); ok = true; return; end %cas général for position=1:9 if ligneok(placement,position) && diagok(placement,position) placement=[placement position] % pause() if positionvalide(placement, colonne+1) ok=true; return; end end end placement=placement(1:end-1); ok=false; return
Main.m
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 colonne=1; %initialisation placement=[]; positionvalide(placement,colonne);
dans l'algo de backtrack, j'ai volontairement laissé l'affichage de la ligne "placement=[placement position]" afin de voir l'évolution de la recherche, et je vois mon code tourner en rond avant de s'arrêter:
placement =
1 3 5 7 2 4
placement =
1 3 5 7 2 4 6
placement =
1 3 5 7 2 4 6
placement =
1 3 5 7 2 4
placement =
1 3 5 7 2 4 6
placement =
1 3 5 7 2 4 6
Si quelqu'un savait me dire pourquoi mon programme tourne en rond alors que normalement avec la boucle "for" il ne devrait pas pouvoir tester plusieurs fois la même branche, cela m'arrangerait beaucoup.
Mon programme n'étant quasiment pas commenté, n'hésitez pas à me poser des questions si vous ne saisissez pas ce que j'ai voulu faire.
Merci d'avance !
Partager