Caballo
Caballo
Caballo
INDICE
A continuación podemos observar distintas soluciones para tableros de tamaño 5x5 hasta 8x8:
2 Solución secuencial
El tablero lo guardaremos como una matriz de NxN (siendo N el número de filas y columnas)
de tal forma que inicialmente tendrá valores cero (casillas todavía no visitadas). El programa
recibe como único parámetro la posición de partida del caballo, donde se ubicará el primer
caballo marcándolo con un 1 en el tablero para indicar esta circunstancia.
A partir de la posición inicial, habría ocho movimientos posibles para poner un segundo
caballo. El orden en el que se explorarán estos posibles movimientos se refleja a continuación
en la Figura 4.
Para cada uno de estos segundos movimientos, imprimiremos la primera solución encontrada
así como el total de soluciones existentes y el tiempo invertido en ello. Un ejemplo de salida
para este mismo ejemplo de la figura 4 sería:
El algoritmo consistirá en un procedimiento “saltoCaballo (int x, int y)” que se invoca con la
posición inicial del caballo y que, a su vez, llamará al procedimiento recursivo saltoCaballoR
con cada uno de los ocho movimientos posibles.
3 Tabla de tiempos
Los datos que figuran en la tabla siguiente se han obtenido ejecutando el programa
“caballoSec” para un tablero de 6x6 con caballo inicial en [3, 3] y en un equipo del lab4401
con Intel i5-4460 a 3,2 GHz con 6MB de caché L3 compartida por los cuatro cores y 8GB de
memoria. Se repiten las pruebas en un equipo del lab4406 con Intel i3-8100 a 3,66 GHz con
6MB de caché L3 compartida por los cuatro cores y 8GB de memoria.
5 Listado de programas
El conjunto de ficheros de apoyo que se suministran son los siguientes:
5.1 caballoSec.c
//-------------------------------------------------------------------
// PCM Arquitecturas Avanzadas Curso 16/17 08/02/16 |
// |
// Problema del caballo en version secuencial |
//-------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define TRUE 1
#define FALSE 0
#define N 5
// variables globales
static int MovX[8], MovY[8];
static int tablero[N][N];
static int numSoluciones, totSoluciones;
//------------------------------------------------------------------------
void dibujarTablero(void) {
int i, j;
printf ("---------- SOLUCION ----------\n");
for (i = 0;i < N; i++) {
for (j = 0; j < N; j++)
printf ("%2d ", tablero[i][j]);
printf("\n");
}
}
//------------------------------------------------------------------------
void formarMov(void){
MovX[0] = -2; MovY[0] = 1;
MovX[1] = -1; MovY[1] = 2;
MovX[2] = 1; MovY[2] = 2;
MovX[3] = 2; MovY[3] = 1;
MovX[4] = 2; MovY[4] = -1;
MovX[5] = 1; MovY[5] = -2;
//------------------------------------------------------------------------
int siguienteCasilla(int x, int y, int movimiento) {
int f, c;
f = x + MovX[movimiento];
c = y + MovY[movimiento];
if ( ((f >= 0) && (f < N))
&& ((c >= 0) && (c < N))
&& (tablero[f][c] == 0) )
return f*N+c; // Se devuelve como indice de array lineal
return -1;
}
//------------------------------------------------------------------------
void saltoCaballoR (int x, int y, int salto) {
int i,f,c,fc;
//------------------------------------------------------------------------
void saltoCaballo (int x, int y) {
int i,f,c,fc;
struct timeval t0, tf, t;
totSoluciones = 0;
for (i=0; i<8; i++) {
numSoluciones = 0;
fc = siguienteCasilla(x, y, i);
if (fc >= 0) {
f = fc / N; c = fc % N;
tablero[f][c] = 2; // anotar
printf ("Ensayando en %d:%d\n", f, c);
gettimeofday (&t0, NULL);
saltoCaballoR (f,c,3);
gettimeofday (&tf, NULL);
timersub (&tf, &t0, &t);
printf ("NumSoluciones = %d Tiempo ensayo => %3ld:%3ld seg:miliseg\n",
numSoluciones, t.tv_sec, t.tv_usec/1000);
tablero[f][c] = 0; // se desanota el ultimo movimiento
}
totSoluciones += numSoluciones;
}
}
if (argc != 3) {
printf ("Uso: caballoSec filaInicial columnaInicial\n");
return 0;
}
filaInicial = atoi (argv[1]);
colInicial = atoi (argv[2]);
if ((filaInicial < 0) || (filaInicial >= N)) {
printf ("Fila debe estar en el rango 0..%d\n", N);
return 0;
}
if ((colInicial < 0) || (colInicial >= N)) {
printf ("Columna debe estar en el rango 0..%d\n", N);
return 0;
}
formarMov();
for (i = 0;i < N; i++)
for (j = 0; j < N; j++)
tablero[i][j] = 0;
tablero[filaInicial][colInicial] = 1;