Backtracking : Les cavaliers
Le problème des cavaliers consiste à déplacer un cavalier sur un échiquier pour qu'il parcourt l'intégralité des cases, sans passer deux fois au même endroit. Il existe de nombreuses solutions à ce problème : Wikipedia indique 26 534 728 821 064 possibilités. Ce programme est capable de les calculer, mais en raison du nombre colossal de possibilités, le processus est extrêmement long.
// pb du cavalier #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define DIM 8 int dx[]={1, 1, 2, 2, -1, -1, -2, -2}; int dy[]={2, -2, 1, -1, 2, -2, 1, -1}; FILE *fichier; typedef struct { int maxcase; int nombreCasesExplorees; int libre[DIM][DIM]; int chemin_x[DIM*DIM]; int chemin_y[DIM*DIM]; } Situation; void afficher (Situation *sit) { int i; static n=0; fprintf (fichier,"\n----%d\n",n++); for (i= 0 ; i< DIM*DIM; i++) fprintf (fichier,"%d-%d\n",sit->chemin_x[i],sit->chemin_y[i]); printf ("%d\n",n); } inline int case_ok (Situation *sit, int x, int y) { return (x>0) && (x<9) && (y<9) && (y>0) && sit->libre[x-1][y-1]; } inline void deplace (Situation *sit, int x, int y) { sit->libre[x-1][y-1] = 0; sit->chemin_x[sit->nombreCasesExplorees] = x; sit->chemin_y[sit->nombreCasesExplorees++] = y; if (sit->nombreCasesExplorees > sit->maxcase) { sit->maxcase = sit->nombreCasesExplorees; printf ("\a"); } } inline void revient (Situation *sit) { sit->nombreCasesExplorees--; sit->libre[sit->chemin_x[sit->nombreCasesExplorees]-1] [sit->chemin_y[sit->nombreCasesExplorees]-1] = 1; sit->chemin_x[sit->nombreCasesExplorees]=0; sit->chemin_y[sit->nombreCasesExplorees]=0; } void Cavalier (Situation *sit) { int x,y,xs,ys,i; gotoxy (1,1); printf ("%2.2d",sit->maxcase); if (sit->nombreCasesExplorees == DIM*DIM) afficher (sit); else { x = sit->chemin_x[sit->nombreCasesExplorees -1]; y = sit->chemin_y[sit->nombreCasesExplorees -1]; for (i=0; i<8; i++) { xs = x + dx[i]; ys = y + dy[i]; if (case_ok (sit, xs, ys)) { deplace (sit, xs, ys); Cavalier (sit); revient (sit); } } } } void Init (Situation *sit,int x, int y) { int i; int j; for (i=0; i<DIM; i++) for (j=0; j<DIM; j++) { sit->libre [i][j] = 1; sit->chemin_x[i+j*DIM] = 0; sit->chemin_y[i+j*DIM] = 0; } sit->maxcase = 0; sit->nombreCasesExplorees = 1; sit->libre[x-1][y-1] = 0; sit->chemin_x[0] = x; sit->chemin_y[0]= y; } main () { Situation situation; int xinit,yinit; time_t t1,t2; clrscr (); fichier = fopen ("cavalier.out", "a"); if (fichier == NULL) { printf ("Erreur d'ouverture du fichier\n"); exit (1); } for (xinit=4; xinit > 0; xinit--) for (yinit=1; yinit <= xinit; yinit++) { Init (&situation, xinit, yinit); t1 = time(NULL); Cavalier (&situation); t2 = time(NULL); printf ("temps = %f", difftime(t2,t1)); } fclose (fichier); return 0; }
Une solution
42 | 51 | 40 | 37 | 44 | 49 | 56 | 35 |
61 | 38 | 43 | 50 | 55 | 36 | 45 | 48 |
52 | 41 | 60 | 39 | 30 | 47 | 34 | 57 |
1 | 62 | 29 | 54 | 59 | 32 | 23 | 46 |
28 | 53 | 2 | 31 | 22 | 25 | 58 | 33 |
63 | 8 | 17 | 26 | 3 | 12 | 21 | 24 |
16 | 27 | 6 | 9 | 14 | 19 | 4 | 11 |
7 | 64 | 15 | 18 | 5 | 10 | 13 | 20 |