Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Nreinas

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 5

Enunciado 4

Problema de las N Reinas

INDICE

1 Definición del problema .................................................................................................................................. 1

2 Solución secuencial ......................................................................................................................................... 1

3 Tabla de tiempos ............................................................................................................................................. 2

4 Para saber más ................................................................................................................................................. 3

5 Listado de programas ...................................................................................................................................... 3


5.1 nreinas.c................................................................................................................................................... 3

Arquitecturas Avanzadas ETSISI-UPM Curso 2021/2022


1 Definición del problema

Se trata de colocar N reinas en un tablero de NxN de tal forma que no se puedan comer. En la
figura 1 se muestran los movimientos posibles de una reina en un tablero de 4x4
(movimientos horizontales, verticales y diagonales), mientras que la figura 2 muestra un
ejemplo de dos reinas que pueden comerse.

Figura 1: Movimientos de una reina Figura 2: Dos reinas que se comen

Un ejemplo de una posible solución para un tablero de 8x8 sería el siguiente:

Figura 3: Una solución para tablero de 8x8

2 Solución secuencial

Utilizaremos un algoritmo recursivo de vuelta atrás (backtracking) basado en ir colocando,


según un orden, una reina detrás de otra evitando que se coman.

Ubicada una reina en una casilla determinada por la tupla [fila, columna] (por ejemplo, en la
casilla [1,4] para la reina de arriba en la figura 3), ya no puede colocarse ninguna otra reina ni
en la fila 1 ni en la columna 4. Debido a esta propiedad, podemos representar el tablero como
un vector[N] en lugar de una matriz[N,N].

La idea es que el vector se indexe por columna, e indique en cada posición “columna” la fila
en la que está ubicada una reina.

Problema de las N Reinas 1


Para el caso de la figura 3, el vector solución tendría el aspecto siguiente:

El algoritmo consistirá en un procedimiento recursivo “NReinas (int reina)” que se invoca por
primera vez como NReinas(1) con la idea de que coloque la primera reina y luego se vaya
llamando de forma recursiva para colocar la reina 2 y sucesivas. Convenimos en que cada
reina iésima, se coloca siempre en la fila iésima y una columna donde no sea comida para lo
cual se explorará desde la columna 1 a la N.

Hemos particularizado el programa para que imprima la primera solución que encuentra, pero
informe del total de soluciones posibles.

Esta solución secuencial se suministra totalmente escrita en el fichero nreinas.c. Si


generamos el ejecutable mediante el Makefile que también se facilita, las soluciones para el
caso de 8x8 se obtendrían ejecutando:

nreinas 8
que produciría una salida como la siguiente:

Q * * * * * * *
* * * * Q * * *
* * * * * * * Q
* * * * * Q * *
* * Q * * * * *
* * * * * * Q *
* Q * * * * * *
* * * Q * * * *
Numero de soluciones: 92
Tiempo total => 0:0 seg:miliseg

3 Tabla de tiempos
Los datos que figuran en la tabla siguiente se han obtenido ejecutando el programa “nreinas”
en un equipo del lab4401 con Intel i7-10700 a 2,9 GHz con 16MB de caché L3 compartida
por los ocho cores [con el HyperThreading deshabilitado] y 8GB de memoria. Los tiempos en
los equipos del lab4406 son algo mayores.

Tablero Número de soluciones Tiempo


11x11 2.680 0:018
12x12 14.200 0:083
13x13 73.712 0:451
14x14 365.596 2:740
15x15 2.279.184 17:934
16x16 14.772.512 122:701

Problema de las N Reinas 2


4 Para saber más
http://es.wikipedia.org/wiki: Aquí puede buscarse la entrada “Problema de las 8 reinas” y
veremos una descripción del mismo y enlaces a otros sitios de interés.

5 Listado de programas
El conjunto de ficheros de apoyo que se suministran son los siguientes:

• Makefile: Para obtener los ejecutables de forma cómoda.


• nreinas.c: Programa secuencial que busca todas las soluciones.

5.1 nreinas.c
//-------------------------------------------------------------------+
// PCM. Arquitecturas Avanzadas Curso 16/17 ETSISI 08/02/17 |
// |
// nreinas: Problema de las N reinas en secuencial |
//-------------------------------------------------------------------+

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>

#define TRUE 1
#define FALSE 0
#define MAX_REINAS 25

//-------------------------------------------------------------------+
// VARIABLES GLOBALES |
//-------------------------------------------------------------------+

// Se indexa por columna e indica fila en la que hay reina


int reinaEnFila[MAX_REINAS];

int numReinas, soluciones=0;

//-------------------------------------------------------------------+
int aceptable (int reinaFila, int reinaColumna) {
int col;
if (reinaEnFila[reinaColumna]!=0)
return FALSE; // Reina en la misma columna
for(col=1; col<=numReinas; col++)
// Si hay una reina que me come en diagonal no es aceptable
if ( ((reinaEnFila[col] != 0)
&& (abs(reinaEnFila[col]-reinaFila))==(abs(reinaColumna-col))))
return FALSE;
return TRUE;
}

Problema de las N Reinas 3


//-------------------------------------------------------------------+
void NReinas(int reina) {
int fila,columna,col;

for(col=1;col<=numReinas;col++) {
if(aceptable(reina,col)) {
reinaEnFila[col]=reina; // Reina i siempre se ubica en fila i
if (reina==numReinas) {
if (soluciones==0) {
printf("\n\n");
for (fila=1;fila<=numReinas;fila++) {
for(columna=1;columna<=numReinas;columna++) {
if (fila!=reinaEnFila[columna]) printf(" *");
else printf(" Q");
}
printf("\n");
}
}
soluciones++;
}
else NReinas(reina+1);
reinaEnFila[col]=0;
}
}
}

//-------------------------------------------------------------------+
int main (int argc, char *argv[]) {
int i;
struct timeval t0, tf, t;

for (i=0; i<MAX_REINAS; i++) reinaEnFila[i] = 0;


soluciones=0;
if (argc != 2) {
printf ("Uso: nreinas numReinas\n");
return 0;
}
numReinas = atoi(argv[1]);
if (numReinas >= MAX_REINAS) {
printf ("Error: El numero de reinas no puede superar %d\n",
(MAX_REINAS-1));
return 0;
}
gettimeofday (&t0, NULL);
NReinas(1);
gettimeofday (&tf, NULL);
printf("Numero de soluciones: %d \n",soluciones);
timersub (&tf, &t0, &t);
printf ("Tiempo total => %ld:%ld seg:miliseg\n", t.tv_sec,
t.tv_usec/1000);
return 0;
}

Problema de las N Reinas 4

También podría gustarte