El problema de las 8 reinas B anch an chez ez Cr uz Pabl o Zai Za i d, Ramí Ram ír ez Vásquez Hebert H ebert,, Rodr íguez gu ez M ar tín ez L u i s F eli el i pe I nstitu to Tecnológico de Oaxaca Oax aca, aca , M é x i co
[email protected] [email protected] [email protected]
I. Introducción El problema de las 8 reinas se trata de un acertijo en el que se colocan ocho reinas sin que se amenacen. Fue propuesto por el ajedrecista ale mán Max Bezzel en 1848. En el juego de ajedrez, la reina amenaza a aquellas fichas que se encuentren en su misma fila, columna o diagonal. Aquellas fichas que se encuentren en su misma fila, columna o diagonal. El problema de las 8 reinas consiste en colocar sobre un tablero de ajedrez ocho r einas sin que estas se den jaques entre ellas. II. Planteamiento Del Problema
fila y el valor una columna. Así cada reina estaría en la posición (i,v[i]) para i=1-8. El vector (3, 1, 6, 2, 8, 6, 4, 7) significa que la reina 1 está en la columna 3, fila 1; la reina 2 en la columna 1, fila 2; la reina 3 en la columna 6, fila 3; la reina 4 en la columna 2, fila 4; etc... Como se puede apreciar esta solución es incorrecta ya que estarían la reina 3 y la 6 en la misma columna. Por tanto el vector correspondería a una permutación de los ocho primeros números enteros. El problema de las filas y columnas lo tenemos cubierto, ¿pero qué ocurre con las diagonales? Para las posiciones sobre una misma diagonal descendente se cumple que tienen el mismo valor fila-columna, mientras que para las posiciones en la misma diagonal ascendente se cumple que tienen el mismo valor fila+columna. Así, si tenemos dos rei reinas nas colocadas en posiciones (i,j) y (k,l) entonces están en la misma diagonal si y solo si cumple: i-j=k-l o i+j=k+l j-l=i-k o j-l=k-i
Fig. 1 Movimiento de la Reina
Se busca encontrar el acomodo de 8 reinas en un tablero de 8 por 8, donde ninguna reina de jaque a otra. Como cada reina puede amenazar a todas las reinas que estén en la misma fila, cada una ha de situarse en una fila diferente. Podemos representar las 8 reinas mediante un vector[1-8], teniendo en cuenta que cada índice del vector representa una
Teniendo en cuenta todas estas consideraciones, podemos aplicar el esquema de retroactivamente para implementar las ocho reinas de una manera realmente eficiente. Para ello, reformulamos el problema como problema de búsqueda en un árbol. Decimos que en un vector V1…k de enteros entre 1 y 8 es k-prometedor, para 0≤k≤8, 0≤k≤8, si ninguna de las k reinas colocadas en las posiciones (1, V1), (2, V2), ..., (k, Vk ) amenaza a ninguna de las otras. Las soluciones a nuestro
problema se corresponden con aquellos vectores que son 8-prometedores. III Establecimiento Del Problema El problema de las 8 reinas puede ser resuelto con un diseño Vuelta Atrás (asemejan al recorrido en profundidad dentro de un árbol) Disponemos de un tablero de ajedrez de tamaño 8x8, y se trata de colocar en él ocho reinas de manera que no se amenacen según las normas del ajedrez. Numeramos las reinas del 1 al 8. Cualquier solución a este problema estará representada por una 8-tupla [x1, x2, x3, x4, x5, x6, x7, x8] en la que cada xi representa la columna donde la reina de la fila i-ésima es colocada. Para decidir en cada etapa cuáles son los valores que puede tomar cada uno de los elementos xi hemos de tener en cuenta lo que hemos denominado restricciones a fin de que el número de opciones en cada etapa sea el menor posible. En los algoritmos Vuelta Atrás podemos diferenciar dos tipos de restricciones:
Restricciones explícitas. Formadas por reglas que restringen los valores que pueden tomar los elementos xi a un conjunto determinado. En nuestro problema este conjunto es: S = {1, 2, 3, 4, 5, 6, 7, 8}. Restricciones implícitas. Indican la relación existente entre los posibles valores de los xi para que éstos puedan formar parte de una n-tupla solución. En el problema que nos ocupa podemos definir dos restricciones implícitas. En primer lugar sabemos que dos reinas no pueden situarse en la misma columna y por tanto no puede haber dos xi iguales (obsérvese además que la propia definición de la tupla impide situar a dos reinas en la misma fila, con lo cual tenemos cubiertos los dos casos, el de las filas y el de las columnas). Por otro lado sabemos que dos reinas no pueden estar en la misma diagonal, lo cual reduce el número de opciones. Esta condición se refleja en la segunda restricción implícita que, en forma de ecuación, puede ser expresada como |x – x’| ≠ |y – y’|, siendo (x,y) y (x’,y’) las coordenadas de dos reinas en el tablero.
De esta manera, y aplicando las restricciones, en cada etapa k iremos generando sólo las k-tuplas con posibilidad de solución. A los prefijos de longitud k de la n-tupla solución que vamos construyendo y que verifiquen las restricciones expuestas los denominaremos k-prometedores, pues a priori pueden llevarnos a la solución buscada. Obsérvese que todo nodo generado es o bien fracaso o bien k-prometedor. Con estas condiciones queda definida la estructura del árbol de expansión, que representamos a continuación para un tablero 4x4: A. Búsqueda En Profundidad La raíz empezaría cuando ninguna reina se encuentra en el tablero, el nodo sería igual a 0
Pila = 0 Para el siguiente nodo se pondrá a la reina en la fila ,1 columna 1.
Pila = 0,1 Como el nodo uno cumple con las restricciones se añadirá un nodo sucesivo a este donde la reina se pondrá en la columna 2 fila 2, este nodo sería el número 2.
Pila = 0, 1,2 El nodo dos viola las restricciones establecidas, ya que coincide diagonalmente con el nodo uno por lo que ya no tendrá más nodos sucesivos, se regresara al nodo uno y se colocara una reina en la columna 3, fila 2, al igual que se quitara el nodo dos de la pila, ya que la pila contendrá los nodos correctos para la solución.
TABLA I Resultados del recorrido del árbol
Pila = 0, 1, 3 Como el nodo tres cumple con restricciones se añadirá el nodo cuatro a este.
las
Conforme vamos construyendo el árbol debemos identificar los nodos que corresponden a posibles soluciones y cuáles por el contrario son sólo prefijos suyos. Ello será necesario para que, una vez alcanzados los nodos que sean posibles soluciones, comprobemos si de hecho lo son. Por otra parte es posible que al alcanzar un cierto nodo del árbol sepamos que ninguna prolongación del prefijo de posible solución que representa va a una solución (debido a las restricciones). En tal caso es absurdo que prosigamos buscando por ese camino, por lo que retrocederemos en el árbol (vuelta atrás) para seguir buscando por otra opción. Tales nodos son los que habíamos denominado nodos fracaso. A continuación se mostrara el árbol completo donde ya muestra la solución.
P1 = 0
P2 = 0, 1
P5 = 0,1,3,4 P9 = 0,1,6,7,8 P13 = 0,10,12
P6 = 0,1,3,5 P10 = 0,1,6,9 P14 = 0,10,13
P3 = 0,1,2 P7 = 0,1,6 P11 = 0,10 P15 = 0,10,13
P4 = 0,1,3 P8 = 0,1,6,7 P12 = 0,10,11 P14 = 0,10,13,14,15
B. Técnica De Búsqueda Primero En Amplitud Para realizar esta técnica se tomara de ejemplo el árbol que se originó por medio de la búsqueda en profundidad en este caso se tomara solo los nodos. Se tiene el árbol en un estado inicial, y la meta es llegar al nodo 15.
Se introduce 0 como el primer elemento en la lista.
Pila = 0, 10, 13, 14, 15 Como podemos observar se construyen 15 nodos hasta dar con una solución al problema. El orden de generación de los nodos se indica con el subíndice que acompaña a cada tupla.
L1 = 0 Como 0 no es la meta, se borrara de la lista y se agregaran los hijos de 0 recorriendo el árbol de izquierda a derecha.
L5 = 0-10-12, 0-10-11, 0-1-6, 0-1-3, 0-1-2, 0-1013-14. Como 0-10-12 y 0-10-11 no son la meta y tampoco tienen hijos, se eliminaran de la lista y se pasara con 0-1-6.
L2 = 0-10,0-1 0-10 no es una meta por lo que se sacara de la lista y se analizaran los hijos de 10 agregándolos al final de ella. L6 = 0-1-3, 0-1-2, 0-10-13-14, 0-1-6-9, 0-1-6-7.
L3 = 0-1, 0-10-13, 0-10-12, 0-10-11 Se siguen eliminando los nodos que no son estados meta y agregando a los hijos al final de la lista.
L4 = 0-10-13, 0-10-12, 0-10-11, 0-1-6, 0-1-3, 0-1-2.
L7 = 0-1-2, 0-10-13-14, 0-1-6-9, 0-1-6-7, 0-1-3-5, 0-1-3-4.
L8 = 0-1-6-9, 0-1-6-7, 0-1-3-5, 0-1-3-4, 0-10-1314-15.
L9 = 0-1-3-5, 0-1-3-4, 0-10-13-14-15, 0-1-6-7-8.
Como 0-1-3-5 y 0-1-3-4 no son soluciones y no tienen hijos, se eliminaran de la cola, y como enfrente quedara 0-10-13-14-15 el cual es la solución se detendrá el algoritmo. L10 = 0-10-13-14-15, 0-1-6-7-8. Meta: 0, 10, 13, 14, 15.
IV Conclusiones En conclusión podemos decir que el método vuelta atrás se asemeja a lo que es la operación de profundidad de un árbol, todo es cuestión de ensayo y error, como se muestra en este problema de las 8 reinas no se puede ver a simple vista como colocar a las piezas de tal manera que no se amenacen, por lo que este tipo de método es ideal, podremos hacer el desglose colocando una posición de la pieza para comprobar si acierta a la solución y si no aprender del error y retroceder al nodo anterior, la técnica de búsqueda en primero en amplitud es un poco más tedioso de realizar, pero su ventaja es que si la meta a buscar está dentro de las primeras hojas, el resultado se encontrara más pronto. Comparando los dos métodos para este problema, el mejor algoritmo sería la de vuelta atrás, ya que sabemos que el resultado estará en el octavo nivel. Es verdad que hacer el desglose a mano para buscar la solución en un árbol es sumamente tedioso, por suerte contamos con herramientas de programación para que un sistema pueda hacerlo por nosotros y nos arroje el resultado deseado en cuestión de segundos, solo es cuestión de tomar los algoritmos de estos métodos para poder implementarlo en un programa.