Está en la página 1de 15

”Aplicación de técnicas incompletas al problema de las N-Reinas”

Pablo Itaim Ananias

Valparaı́so, 05 de Septiembre del 2005

Resumen
El problema de las n-Reinas (n-Queens Problem) es muy antiguo. Propuesto por primera vez en el año
1848, consiste en encontrar una asignación a n reinas en un tablero de ajedrez de n x n de modo tal, que
éstas no se ataquen. El presente trabajo presenta el problema en cuestión, muestra un ejemplo sencillo
de él y profundiza en distintos métodos de resolución basados en técnicas incompletas de optimización.

1. Introducción
El problema de las n-Reinas consiste en encontrar una distribución de n reinas en un tablero de ajedrez
de n x n de modo tal, que éstas no se ataquen. Ası́, no pueden encontrarse dos reinas en la misma fila,
columna o diagonal.
Este problema tiene 2 Versiones. La más simple consiste en encontrar exactamente una solución válida
para un valor n dado. La otra versión, más difı́cil, consiste en encontrar todas las soluciones posibles para
un valor n.
Fue propuesto para n = 8 en el año 1848 en un trabajo anónimo [1], siendo posteriormente atribuido a
Max Bezzel. Sin embargo, la publicación detallada más antigua que se conoce fue realizada por Nauck [2]
en 1850. Ese mismo año, Gauss postuló la existencia de 72 soluciones para n = 8. Posteriormente, en el año
1874, Glaisher [3] probó la existencia de 92 soluciones.
La investigación sobre este tema no ha parado hasta hoy por lo que existe una amplia variedad de
algoritmos sugeridos para su resolución. Muchas de las soluciones planteadas se basan en proporcionar una
fórmula especı́fica para colocar las reinas o extrapolar conjuntos pequeños de soluciones para proporcionar
soluciones para valores de n más grandes.
Observaciones empı́ricas de problemas de pequeño tamaño muestran que el número de soluciones crece
en forma exponencial al ir aumentando el valor de n [4].
Se puede observar que este problema tiene una solución (Q(1) = 1) para n = 1, no tiene solución para
n = 2 y n = 3 y tiene 2 soluciones para n = 4.
Para una mejor lectura, el presente informe se ha organizado de la siguiente manera: en la sección 2, se
define el problema a resolver, indicando las principales caracterı́sticas de éste. En la sección 3, se describen
muy brevemente algunas de las aplicaciones que tiene el problema d las n-reinas dando un ejemplo práctico
en la sección 4. En los puntos 5 y 6 se discute respecto a las formas de modelar el problema, definiendo
además el modelo final a utilizar en la resolución de éste en el presente trabajo. En la sección 7, se describen
los distintos algoritmos implementados. En el punto 8, se presentan los casos de prueba con los cuales se
ejecutaron los algoritmos y cuyos resultados se entregan en el punto 9. Finalmente, en el punto 10, se indican
las conclusiones más importantes del presente trabajo.

2. Definición del Problema


Como se planteó anteriormente, el problema de las n-Reinas consiste en encontrar una distribución de n
reinas en un tablero de n x n de modo tal, que éstas no se ataquen. Ası́, no pueden encontrarse dos reinas
en la misma fila, columna o diagonal.
Este Problema tiene 2 Versiones. La más simple consiste en encontrar exactamente una solución válida
para un valor n dado. La otra versión, más difı́cil, consiste en encontrar todas las soluciones posibles para
un valor n. La Tabla 1 muestra el número total de Soluciones Q(n) para 4 ≤ n ≤ 20 [5, 6].

n Q(n)
4 2
5 10
6 4
7 40
8 92
9 352
10 724
11 2.680
12 14.200
13 73.712
14 365.596
15 2.279.184
16 14.772.512
17 95.815.104
18 666.090.624
19 4.968.057.848
20 39.029.188.884

Tabla 1: Número total de soluciones Q(n) para 4 ≤ n ≤ 20

Para solucionar este problema, se han diseñado numerosos Algoritmos basados en algunos como Back-
tracking, Algoritmos Genéticos, Búsqueda local con resolución de conflictos, programación entera y redes
neuronales entre otros. Además, el Problema de las n reinas pertenece a la clase de problemas NP-completos
[7], pero se resuelve fácilmente en tiempo polinomial cuando solamente se busca una solución [4].
Existen soluciones analı́ticas donde se da una fórmula explı́cita para la localización de las reinas o bien
se encadenan soluciones obtenidas para valores menores de n [8, 9]. El problema con estas soluciones es que
generan un número muy pequeño de soluciones.
Backtracking es, en general, ineficiente y para el problema de las n-reinas no es fácil encontrar soluciones
para n > 100 en tiempos razonables [10], sin embargo, Kalé [11] diseñó un algoritmo especializado de
backtracking que consigue resolver el problema hasta tamaños del orden de 1.000. Se han realizado numerosas
aplicaciones de algoritmos genéticos para resolver el problema de las n-reinas [7, 12, 13, 14], pero se han visto
ineficientes aún cuando se hayan probado diversas representaciones del problema y diversos operadores.
Por otra parte, los Algoritmos para Programación Entera son tı́picamente exponenciales y consecuente-
mente consiguen resolver problemas de tamaño muy pequeño [15].
Un Algoritmo de Redes Neuronales utilizando un modelo modificado de Hopfield [16] parece funcionar
mejor que otros modelos de redes neuronales presentados, pero solo se publican resultados para valores de n
pequeños.
La Búsqueda local con minimización de conflictos [4] parece ser el mejor algoritmo encontrado hasta
ahora. Este algoritmo de Socic y Gu tiene tiempo de ejecución lineal por lo que es extremadamente rápido.
En su articulo, ellos muestran que su algoritmo es capaz de obtener una solución para cualquier valor de
n, n < 1000 en menos de 0.1 segundo y 55 segundos para n = 3,000,000, en un computador del año 94
(IBM RS 6000/530). Ahora, dada la naturaleza probabilı́stica del algoritmo, no se tiene garantı́a del tiempo
del peor caso del algoritmo, pero en la práctica muestra un excelente desempeño y un comportamiento muy
robusto. Hynek [14] diseñó una Heurı́stica basada en una fase de preprocesamiento y posteriormente aplica un
operador de mutación basado en búsqueda local. Los resultados computacionales muestran que el algoritmo
es efectivo y logra soluciones hasta n = 1000 en tiempos razonables.

3. Aplicaciones
El Problema de las n-reinas es conocido usualmente como uno relacionado a un juego y también como
un problema apropiado para probar algoritmos nuevos. Sin embargo, tiene otras aplicaciones ya que se le

2
considera como un modelo de máxima cobertura. Una solución al problema de las n-reinas garantiza que cada
objeto puede ser accesado desde cualquiera de sus ocho direcciones vecinas (dos verticales, dos horizontales
y cuatro diagonales) sin que tenga conflictos con otros objetos.
Algunas aplicaciones posibles son:
Control de Tráfico Aéreo
Sistemas de Comunicaciones
Programación de Tareas Computacionales
Procesamiento Paralelo Óptico
Compresión de Datos
Balance de Carga en un Computador multiprocesador
Ruteo de mensajes o datos en un Computador multiprocesador
etc.
Un ejemplo práctico de una aplicación del problema de las n-reinas es el siguiente: para lograr el mayor
ancho de banda posible en un sistema de comunicaciones de banda estrecha y direccional, se deben ubicar los
n transceptores de forma tal que no se interfieran entre ellos. Con los n transceptores ubicados en patrones sin
conflictos, lo que corresponde a una solución del problema de las n-reinas, cada transceptor puede comunicarse
con el mundo exterior en forma libre en 8 direcciones sin que sea inhibido por otro transceptor. La Figura 1
muestra una distribución para 10 transceptores. Esta distribución corresponde a una de las soluciones para
el problema de las 10-reinas.

Figura 1: Ubicación de 10 Transmisores/Receptores sin conflicto entre ellos (Cada uno puede comunicarse
en cualquier dirección vertical, horizontal o diagonal

4. Ejemplo
Para visualizarlo mejor, analizaremos el problema de las n reinas para n = 6. Como ya hemos visto, esto
consiste en ubicar 6 reinas en un tablero de 6x6 sin que ellas se ataquen. Se sabe que para este caso existen
4 soluciones válidas, las que se presentan en los gráficos de la figura 2.
Con algún método, comenzamos la búsqueda de una solución y encontramos la a). A partir de ella
podemos encontrar las otras 3 de la siguiente forma:
La solución b) se obtiene rotando la solución a), 90 grados a la derecha.
La solución c) es el reflejo de la solución b) respecto al borde derecho de ésta. Es decir, si se coloca un
espejo en el borde derecho de la solución b), se observa la solución c).
La solución d) es el reflejo de la solución a) respecto del borde derecho de ésta.

3
Figura 2: Soluciones al problema de las 6-reinas

Si bien estos métodos ayudan a encontrar soluciones válidas del problema, no las encuentran todas, por lo
que se hace necesario contar con otros métodos para solucionar el problema. Además, es necesario encontrar
una solución inicial para poder aplicarlos.

5. Modelo en Extenso
El problema de las n-reinas tiene, básicamente, dos modelos asociados que cumplen con lo siguiente:
La Función Objetivo no tiene un uso práctico ya que se sabe a priori el valor de n.
Dos reinas no pueden estar en la misma Fila.
Dos reinas no pueden estar en la misma Columna.
Dos reinas no pueden estar en la misma Diagonal.
Para efectos de mejor entendimiento, se van a dividir las diagonales según el signo de su pendiente. De
esta forma, tendremos diagonales positivas y diagonales negativas. Además, vamos a definir el número de
reinas y ancho del tablero de ajedrez como N , con N = {1, . . . , n}.
Si bien la cantidad de formas de modelar son pocas, estos modelos se resuelven o desarrollan de muchas
formas y con varios métodos distintos.

5.1. Modelo 1
Este modelo es el más general y el más fácil de implementar. Utiliza una variable binaria xij para
representar la existencia de una reina en la casilla (i, j). Ası́, si existe, xij = 1 y si no, vale 0. Las restricciones
abarcan las filas, las columnas, diagonales positivas y diagonales negativas.
La restricción de las filas impide que existan dos reinas en la misma fila. Esto se verifica sumando todos
los valores de las casillas xij para una fila determinada. Ası́, dicha suma deberı́a ser igual a 1 para todas las
filas ya que deberı́a haber un solo 1 en cada fila. Esta restricción se puede resumir de la siguiente forma:
n
X
xij = 1 ∀i ∈ N
j=1

Del mismo modo, la restricción de las columnas impide que existan dos reinas en la misma columna.
Esto se verifica sumando todos los valores de las casillas xij para una columna determinada. Ası́, dicha
suma deberı́a ser igual a 1 para todas las columnas ya que deberı́a haber un solo 1 en cada columna. Esta
restricción se puede resumir de la siguiente forma:
n
X
xij = 1 ∀j ∈ N
i=1

4
Las diagonales son un poco más complicadas de verificar por la definición de los valores de recorrido de
la variable. En las diagonales, tanto positivas como negativas, debe haber a lo más una reina. Esto se verifica
sumando los valores de las casillas que forman las distintas diagonales.
Si analizamos la formación de las diagonales positivas, veremos que éstas estarán definidas por la suma
k = i + j. Ası́, todos los pares (i, j) que tengan el mismo valor para k, estarán en la misma diagonal positiva.

Figura 3: Ejemplo de diagonales positivas y negativas para n = 6

Por ejemplo, en la figura 3, podemos observar que todos los pares que forman la diagonal positiva suman
8. Ahora, para el mismo ejemplo, podemos observar que k se mueve dentro del rango {2, . . . , 12}. Si no
consideramos las dos diagonales de las esquinas ((1, 1) y (6, 6)), el valor de k varı́a en el rango de {3, . . . , 11}.
De esta forma, definiendo los valores de k podemos recorrer todas las diagonales positivas.
Generalizando, podemos afirmar que k = i + j varı́a en el rango de {2, . . . , 2n} o {3, . . . , 2n − 1} depen-
diendo si consideramos las casillas de las esquinas.
De esta forma, podemos definir la restricción para las diagonales positivas de la siguiente forma:
n X
X n
xij ≤ 1 ∀k = {2, . . . , 2n} o k = {3, . . . , 2n − 1}
i=1 j=1
| {z }
i+j=k

Análogamente, analizamos la formación de las diagonales negativas. Podemos verificar que éstas están
definidas por la resta k = i − j. Ası́, todos los pares (i, j) que tienen el mismo valor para k, están en la misma
diagonal negativa.
Por ejemplo, en la figura 3, podemos observar que para todos los pares que forman la diagonal negativa,
sus restas valen 1. Ahora, para el mismo ejemplo, podemos observar que k se mueve dentro del rango
{−5, . . . , 5}. Si no consideramos las dos diagonales de las esquinas ((6, 1) y (1, 6)), el valor de k varı́a en
el rango de {−4, . . . , 4}. De esta forma, definiendo los valores de k podemos recorrer todas las diagonales
negativas.
Generalizando, podemos afirmar que k = i−j varı́a en el rango de {−5, . . . , 5} o {−4, . . . , 4} dependiendo
si consideramos las casillas de las esquinas.
De esta forma, podemos definir la restricción para las diagonales negativas de la siguiente forma:
n X
X n
xij ≤ 1 ∀k = {−5, . . . , 5} o k = {−4, . . . , 4}
i=1 j=1
| {z }
i−j=k

El problema de este modelo es el tamaño del espacio de búsqueda, que es 2n∗n . Ası́, para n = 10, este
serı́a de 1030 aproximadamente, lo cual lo hace muy ineficiente a la hora de buscar todas las soluciones al
problema.

5.2. Modelo 2
Otra forma de modelar el mismo problema es considerando otro tipo de variables. Podemos utilizar la
variable xi para representar la posición de la reina en la fila i. En este caso, el dominio de xi serı́a {1, . . . , n}.
A diferencia del modelo anterior, las restricciones abarcan las columnas y todas las diagonales, sin distinguir

5
entre positivas y negativas. Las filas se verifican por defecto, al tener que asignársele un valor a la variable.
Es decir, por la forma del modelo, no pueden haber dos reinas en la misma fila, por lo que esa restricción se
omite.
La restricción de las columnas impide que existan dos reinas en la misma columna. Esto se verifica
observando los valores de las variables. Si estos son distinto, entonces se cumple con la restricción, si son
iguales, no. Otra forma análoga es calculando la diferencia entre dos valores de x. De esta forma, si xi −xj = 0
(con i 6= j) las dos reinas están en la misma columna. Esta restricción se puede resumir de la siguiente forma:

xi 6= xj ∀i 6= j con i y j ∈ N

Análogamente:

xi − xj 6= 0 ∀i 6= j con i y j ∈ N

Al igual que en el modelo anterior, en las diagonales, tanto positivas como negativas, debe haber a lo
más una reina. Dada la definición del modelo, el valor de la variable me indica la columna y el ı́ndice de
la variable, la fila. Utilizando esos valores, se puede calcular la pendiente de una recta que pase por los dos
casilleros, xi y xj que estoy verificando. Sabiendo que todas las diagonales positivas forman un ángulo de
45◦ respecto a la base del tablero y que todas las diagonales negativas forman un ángulo de −45◦ respecto
a la misma base, si calculamos la pendiente y el ángulo resultante es + ◦
− 45 , entonces los dos casilleros están
en la misma diagonal.
En general, para poder encontrar la pendiente de una recta, basta con conocer dos puntos de esa recta y
calcular la diferencia entre las coordenadas de ambos puntos. Por ejemplo, si queremos calcular la pendiente
∆y
de la recta de la figura 4, calculamos el ∆x = x2 − x1 y el ∆y = y2 − y1 . Después, calculamos ∆x y al
resultado le calculamos la tangente.

Figura 4: Cálculo de la pendiente de una recta

Como la tan 45 = 1, eso significa que el ∆x y el ∆y deben ser iguales. En nuestro caso, como no queremos
que las reinas estén en la misma diagonal, vamos a exigir que esas diferencias sean distintas.
De esta forma, podemos definir la restricción para las diagonales de la siguiente forma:

|xi − xj | 6= |i − j| ∀i 6= j con i y j ∈ N

Lo bueno de este modelo, comparado con el anterior, es que reduce en forma drástica el espacio de
búsqueda, quedando en n!. De esta forma, para n = 10, el espacio de búsqueda es 106 aproximadamente.

6. Modelo General
Considerando los modelos anteriormente descritos, podemos formalizarlos de acuerdo a lo siguiente:

6.1. Modelo 1
Variables :

1 si existe una reina en la posición (i, j)
xij =
0 si no

Dominio : {0, 1}

6
Restricciones :
n
X
Xij = 1 ; ∀i = {1, . . . , n} Restricción en las Filas
j=1
Xn
Xij = 1 ; ∀j = {1, . . . , n} Restricción en las Columnas
i=1
n X
X n
Xij ≤ 1 ; ∀k = {3, . . . , 2n − 1} Restricción en las Diagonales positivas
i=1 j=1
| {z }
i+j=k
n X
X n
Xij ≤ 1 ; ∀k = {1 − n, . . . , n − 1} Restricción en las Diagonales negativas
i=1 j=1
| {z }
i−j=k

6.2. Modelo 2
Variables : xi = posición de la reina en la fila i.
Dominio : {1, . . . , n}
Restricciones :

xi =6 xj ∀i 6= j con i y j ∈ N Restricción en las Columnas


|xi − xj | = 6 |i − j| ∀i 6= j con i y j ∈ N Restricción en las Diagonales

Este modelo se puede implementar como un vector de largo n con una secuencia correspondiente a una
permutación de los valores de 1 . . . n. De esta forma no es necesario verificar las restricciones en las filas o
las columnas ya que el mismo modelo se encarga de asegurar que no existan violaciones en este sentido. Ası́,
se pueden abocar todos los esfuerzos a la verificación de las restricciones en las diagonales.

7. Descripción de los Algoritmos


Los algoritmos implementados para la resolución del problema planteado fueron básicamente tres: el
desarrollado por Minton [17], que se basa en Hill-Climbing, el GRASP [18, 19, 20], que se basa en una etapa
de preproceso y en otra de postproceso de una solución y en Simulated Annealing [21], que se basa en un
proceso de enfriamiento. Además, cada uno de los algoritmos anteriores fue modificado para comprobar el
aporte de sus distintos componentes a la resolución del problema. El detalle de cada algoritmo se describe a
continuación.

7.1. Algoritmo de Minton


El algoritmo de Minton posee dos etapas:
Etapa de Preproceso: Una etapa de preproceso crea una asignación inicial usando un algoritmo
greedy que itera dentro de las filas, ubicando cada reina en la columna donde tenga menos conflictos
con las reinas previamente ubicadas.
Etapa de Reparación: Para hacer una reparación, el programa selecciona una reina que este en
conflicto y la mueve a otra columna donde tenga menos cantidad de conflictos utilizando un algoritmo
Hill-Climbing. Esta fase se repite hasta que se encuentre una solución.
A continuación se describirán las implementaciones efectuadas del algoritmo de Milton.

7
7.1.1. Algoritmo original
Lo primero fue implementar el algoritmo de acuerdo a la descripción que se hace en [17]. Éste comienza con
la generación de una solución inicial mediante un greedy, el cual va ubicando las reinas en las posiciones donde
menos conflictos produzcan respecto a las reinas previamente instanciadas. Una vez que se ha construido
la solución inicial, ésta se repara utilizando un Hill-Climbing. Para ello, el algoritmo posee un registro con
las reinas en conflicto, el cual va actualizando después de cada movimiento. Ası́, en cada iteración, se toma
la reina con más conflictos y se mueve a una posición donde produzca el menor número de violaciones a
las restricciones. Esto se repite hasta que se encuentre una solución válida o se efectúen una cantidad de
iteraciones determinadas.
Si al término de la etapa de reparación no se ha encontrado una solución factible, el algoritmo comienza
desde cero con la aplicación del greedy ubicando la primera reina al azar para evitar que siempre se construya
la misma solución inicial. Esto se repite hasta que se encuentre una solución final factible o se cumpla con
un número determinado de restart.
El Algoritmo se define de acuerdo a lo siguiente:
Representación: Xi la columna donde se ubica la reina en la fila i.
Función de evaluación: cantidad de restricciones violadas.
Movimiento: cambio de posición de la reina a otra columna en la misma fila.

Criterio de selección de las variables: mayor cantidad de conflictos.


Criterio de aceptación: mejor mejora.
Criterio de término: máximo número de iteraciones o encuentro de una solución factible.
Número de restarts: 10
Solución inicial: creada por un Greedy
En Pseudo código:
Procedimiento Minton (n reinas)
s =crear una configuración inicial (greedy)
// instanciar el arreglo violaciones
for i<n
for j+i<n
si reina i y j están en la misma diagonal
violaciones[i]++;
violaciones[j]++;
while((violaciones!=vacı́o) AND ejecuciones <Max Iter)
selecciona reina con mayor número de conflictos
mueve reina a columna donde produzca menor número de conflictos
reinstanciar violaciones (crear el arreglo de nuevo)
ejecuciones++
return s

7.1.2. Algoritmo modificado


Para verificar el aporte de la minimización de conflictos en el algoritmo de Minton, se modificó la forma
en que el Hill-Climbing efectuaba sus movimientos. Ası́, en vez de mover la reina a una posición con el menor
número de conflictos, se aplica una función swap(i, j) que invierte la posición de dos reinas de forma tal
que la cantidad de restricciones violadas sea menor. Este concepto es utilizado por el algoritmo de Socic [22]
dando excelentes resultados.
El Algoritmo se define de acuerdo a lo siguiente:
Representación: Xi la columna donde se ubica la reina en la fila i.
Función de evaluación: cantidad de restricciones violadas.

8
Movimiento: intercambio de posición (en las columnas) de dos reinas.
Criterio de selección de las variables: mayor cantidad de conflictos.
Criterio de aceptación: mejor mejora.
Criterio de término: máximo número de iteraciones o encuentro de una solución factible.
Número de restarts: 10
Solución inicial: creada por un Greedy

En Pseudo código:
Procedimiento Minton modificado (n reinas)
s =crear una configuración inicial (greedy)
// instanciar el arreglo violaciones
for i<n
for j+i<n
si reina i y j están en la misma diagonal
violaciones[i]++;
violaciones[j]++;
while(!isEmpty(violaciones) AND ejecuciones <cota sup)
selecciona la reina con más conflictos (i)
selecciona una reina al azar (j)
si swap(i,j) produce menos o igual violaciones
swap(i,j)
reinstanciar violaciones (crear el arreglo de nuevo)
ejecuciones++
return s

7.2. Heurı́stica GRASP


El GRASP (Greedy Randomized Adaptive Search), es un proceso multi-inicio (multi-start) o iterativo en
donde cada iteración posee dos fases:
Construcción(preproceso): en esta fase se genera una solución factible. En cada etapa, el algoritmo
construye una lista de candidatos (Lista restringida de candidatos(LRC )) con los movimientos admi-
sibles, ordenados de manera decreciente con respecto a su beneficio medido a través de la función de
evaluación. Si el largo de la lista es 1, esta etapa se convierte en un Greedy estándar. Por otro lado, si
el largo de la lista es máximo, se convierte en un ”Random Walk ”. Una vez generada la lista, GRASP
elige aleatoriamente un movimiento desde la LRC. Además, dicha lista se puede reducir en cantidad y
calidad. En el primer caso, se permite que el algoritmo seleccione un valor dentro de un conjunto de
k valores de la lista. En el segundo caso, se ordenan los valores de acuerdo a su beneficio y se permite
que se elija un valor dentro de los k primeros.
Búsqueda Local(postproceso): en esta fase se busca el óptimo local a partir de la solución inicial pre-
viamente generada. Para ello se utiliza un algoritmo que repare la solución inicial como Hill-Climbing,
Tabu-Search y Simulated Annealing, entre otros.
A continuación se describirán las implementaciones efectuadas de la heurı́stica GRASP.

7.2.1. GRASP original


Primero se implementó la heurı́stica completa, con sus fases de pre y postproceso. Como en el problema
de las n-reinas no existen mejores soluciones, para la etapa de preproceso se utilizó un greedy con largo de
lista máximo. Por otro lado, para la etapa del postproceso, se utilizó el mismo Hill-Climbing implementado
con mı́nimos conflictos de Minton.
El Algoritmo se define de acuerdo a lo siguiente:
Representación: Xi la columna donde se ubica la reina en la fila i.

9
Función de evaluación: cantidad de restricciones violadas.
Movimiento: cambio de posición de la reina a otra columna en la misma fila.
Criterio de selección de las variables: mayor cantidad de conflictos.
Criterio de aceptación: mejor mejora.
Criterio de término: máximo número de iteraciones o encuentro de una solución factible.
Número de restarts: 10

Solución inicial: creada por un Greedy de acuerdo a la LRC.


En Pseudo código:
procedimiento GRASP(Maxiter, n reinas)
for k = 1, . . . ,Maxiter do
s =Greedy (n reinas)
s =búsqueda local (s)
actualiza solución(s, Mejor Solución)
return Mejor Solución
A su vez, el greedy se define de la siguiente forma:
procedimiento Greedy(n reinas)
s←0
Inicializa el conjunto de candidatos: C ← E
Evalúa el costo incremental c(e)∀e ∈ C
while C 6= 0 do
cmin ← min{c(e)|e ∈ C}
cmax ← max{c(e)|e ∈ C}
Lista ← {e ∈ C|c(e) ≤ cmin + a(cmax − cmin )}
selecciona
S un elemento t de Lista en forma aleatoria
s ← s {t}
actualiza el conjunto candidato C
re-evalúa los costos incrementales c(e)∀e ∈ C
return s
La calidad del valor seleccionado se puede restringir de acuerdo a la siguiente cota: c(e) ∈ {cmin , cmin +
max
a(c − cmin )}. Con a = 0 se vuelve un algoritmo greedy, mientras que con a = 1 se vuelve un Random
Walk. El valor de a sirve para establecer un balance entre costo computacional y calidad de las soluciones.

7.2.2. GRASP sin postproceso


Para verificar el real aporte de la etapa de postproceso, se implementó el GRASP sin dicha etapa,
quedando el algoritmo como sigue:
procedimiento GRASP(Maxiter, n reinas)
for k = 1, . . . ,Maxiter do
s =Greedy (n reinas)
actualiza solución(s, Mejor Solución)
return Mejor Solución
En este caso, el algoritmo construye una solución de la misma forma que el GRASP original, pero no la
repara.

10
7.2.3. GRASP sin preproceso
Por su parte y para verificar el aporte de la etapa de preproceso, se implementó el GRASP sin dicha
etapa,quedando el algoritmo de la siguiente forma:
procedimiento GRASP(Maxiter, n reinas)
for k = 1, . . . ,Maxiter do
s =Generación aleatoria de una permutación de {1, . . . , n}
s =búsqueda local (s)
actualiza solución(s, Mejor Solución)
return Mejor Solución
En este caso, el algoritmo genera una solución inicial en forma aleatoria y la repara de la misma forma
que el GRASP originas, es decir, con el Hill-Climbing utilizado por Minton.

7.3. Simulated Annealing


Simulated annealing (SA) es una meta-heurı́stica para problemas de optimización, es decir, encontrar
una buena aproximación al óptimo global de una función en un espacio de búsqueda grande.
El nombre e inspiración viene del proceso de templado (annealing en inglés) en metalurgia, una técnica
que incluye calentar y luego enfriar controladamente un material para aumentar el tamaño de sus cristales
y reducir sus defectos. El calor causa que los átomos se salgan de sus posiciones iniciales(un mı́nimo local
de energı́a) y se muevan aleatoriamente; el enfriamiento lento les da mayores probabilidades de encontrar
configuraciones con menor energı́a que la inicial.
En cada paso, el SA considera algunos vecinos del estado actual s, y probabilı́sticamente decide si cambiar
el sistema al estado s0 o quedarse en el estado s. Las probabilidades se escogen para que el sistema tienda
finalmente a estados de menor energı́a. Tı́picamente este paso se repite hasta que se alcanza un estado
suficientemente bueno para la aplicación o hasta que se cumpla cierto tiempo computacional dado.
Los vecinos de cada estado son especificados dependiendo del problema y del modelo utilizado. Usual-
mente es una pequeña variación en la representación escogida, lo que deseablemente, representa una pequeña
variación en el espacio real de soluciones.
La probabilidad de hacer la transición al nuevo estado s0 es una función P (∆E, T ) de la diferencia de
energı́a ∆E = E(s0 ) − E(s) entre los dos estados, y de la variable T , llamada temperatura.
Una cualidad importante del método SA es que la probabilidad de transición P es siempre distinta de
cero, aún cuando ∆E sea positivo, es decir, el sistema puede pasar a un estado de mayor energı́a(peor
solución) que el estado actual. Esta cualidad impide que el sistema se quede atrapado en un óptimo local.
Cuando la temperatura tiende al mı́nimo, la probabilidad tiende a cero asintóticamente. Ası́, cada vez el
algoritmo acepta menos movimientos que aumenten la energı́a.
Si ∆E es negativo, es decir, la transición disminuye la energı́a, el movimiento es aceptado con probabilidad
P = 1.
Otra cualidad del SA es que la temperatura va disminuyendo gradualmente conforme avanza la búsqueda.
Hay muchas maneras de disminuir la temperatura, siendo la más usual la exponencial, dónde T disminuye
por un factor α < 1 en cada paso.
En general, para definir un SA se deben definir los siguientes parámetros:
Temperatura: se debe definir tanto la temperatura inicial como la velocidad de disminución de ésta.
Longitud de la Cadena: se refiere a por cuantas iteraciones se va a mantener la misma temperatura.
Ası́, hay que definir el largo inicial de la cadena y la velocidad de crecimiento. La Figura 5muestra un
ejemplo de la relación que existe entre el largo de la cadena y los cambios en la temperatura. Cabe
destacar que mientras la temperatura va disminuyendo(T0 > T1 > T2 > . . . > Tk ), el largo de la cadena
va aumentando (N0 < N1 < N2 < . . . < Nk ).
Criterio de parada: existen diversos criterios de parada y éstos dependen del problema especifico
que se trata de resolver. Sin embargo, existen algunos que son universales y son los siguientes:
• Se fija un número determinado de niveles de temperatura y el algoritmo se detiene cuando haya
alcanzado esa cantidad.
• El algoritmo se detiene si la función objetivo no mejora para varios niveles consecutivos.

11
• El algoritmo se detiene si no se cumple con un número mı́nimo de aceptaciones en el nivel de
temperatura.

Figura 5: Visualización de Largo de Cadena versus Temperatura

El Algoritmo implementado se define de acuerdo a lo siguiente:


Representación: Xi la columna donde se ubica la reina en la fila i.
Función de evaluación: cantidad de restricciones violadas.
Movimiento: enroque de dos reinas que tengan conflictos (no necesariamente entre ellas).
Criterio de selección de las variables: al azar.
Criterio de aceptación: alguna mejora o de acuerdo a la función de temperatura.

Criterio de término: máximo número de iteraciones o encuentro de una solución factible.


Número de restarts: 10
Solución inicial: generación aleatoria de una permutación de largo n
En Pseudo código:
Procedimiento SA (n reinas)
s =crear una configuración inicial (permutación)
// instanciar el arreglo violaciones
for i<n
for j+i<n
if reina i y j están en la misma diagonal:
violaciones[i]++;
violaciones[j]++;
while((violaciones!=vacı́o) AND ejecuciones <Max Iter)
selecciona dos reinas que estén en conflicto (no necesariamente entre ellas)
hacer enroque entre las dos reinas seleccionadas
verificar cantidad de restricciones violadas
if cantidad de violaciones disminuye
dejar solución actual
else
p=número aleatorio entre {0, . . . , 1}
violaciones actuales−violaciones anteriores
m= e T

if p<m:
dejar solución actual
else:
deshacer el movimiento
if cadena≥largo cadena:
disminuir temperatura
aumentar largo de cadena
ejecuciones++
return s

12
8. Casos de Prueba
Para la evaluación de los distintos algoritmos se utilizaron los siguientes valores de n: 50, 75, 90, 100,
200, 500, 600, 1000, 1500 y 2000. En todos los casos se efectuaron 5 ejecuciones y se registraron los mejores
resultados tanto en tiempos de ejecución como en la calidad de las soluciones. Cabe destacar que solo se
registraron aquellos tiempos de ejecución menores a 1 hora.
Todas las pruebas se efectuaron en un PC con procesador AMD Athlon de 900 MHz, con 512 MB en
RAM.

9. Evaluación de los resultados


Los mejores resultados obtenidos por los distintos algoritmos se muestran en las Tablas 2 y 3, donde T
indica el tiempo de ejecución del algoritmo en minutos y segundos (mm:ss) y RC indica la cantidad de reinas
que se encuentran en conflicto en la solución entregada. Además, en la Figura 6, se muestra una comparación
entre los distintos algoritmos desde el punto de vista del tiempo de ejecución necesario para dar una solución.

Algoritmo 50 75 90 100 200


T RC T RC T RC T RC T RC
Minton <1 s 0 <1 s 0 <1 s 0 00:02 0 00:03 0
Minton modif <1 s 0 <1 s 0 <1 s 0 00:02 0 00:06 0
GRASP <1 s 0 <1 s 0 <1 s 0 00:02 0 00:04 0
GRASP s/post <1 s 0 <1 s 0 <1 s 5 00:02 3 00:07 5
GRASP s/pre <1 s 0 <1 s 0 <1 s 0 00:01 0 00:03 0
Simulated Annealing <1 s 0 00:01 0 00:03 0 00:03 0 03:37 0

Tabla 2: Tiempos de ejecución para n = {0, . . . , 200}

Algoritmo 200 500 600 1000 1500 2000


T RC T RC T RC T RC T RC T RC
Minton 00:03 0 00:29 0 00:42 0 04:12 0 24:04 0 49:14 0
Minton modif 00:06 0 19:46 0 27:53 3
GRASP 00:04 0 00:38 0 01:10 0 14:17 0 41:12 0
GRASP s/post 00:07 5 01:44 5 03:00 3 13:58 2 53:16 5
GRASP s/pre 00:03 0 00:30 0 00:52 0 03:57 0 15:01 0 38:51 0
Simulated Annealing 03:37 0 18:29 0 32:25 0

Tabla 3: Tiempos de ejecución para n = {200, . . . , 2000}

De los resultados obtenidos habı́an algunos esperados, como el comportamiento del GRASP sin postpro-
ceso. Al no reparar la solución encontrada, era muy difı́cil que encontrara una solución factible.
El algoritmo con mejor rendimiento fue el GRASP sin preproceso, posiblemente debido a que al no tener
que construir en forma ordenada la solución inicial, el tiempo que gana en ese proceso es mayor al que pierde
en la reparación de la solución.
Por otro lado, el algoritmo de peor desempeño, en cuanto a tiempos de ejecución, fue el de Minton
modificado. Llama la atención este resultado ya que se esperaba que este algoritmo fuese al menos igual
de eficiente que el original de Minton. Queda entonces pendiente una revisión al comportamiento de este
algoritmo.

10. Conclusiones y posibles mejoras


En este trabajo se implementaron los algoritmos de Mı́nimos conflictos propuesto por Minton, el GRASP y
el Simulates Annealing para la resolución del problema de las n-reinas. Además, se implementaron variaciones
de los algoritmos anteriores con el fin de verificar el aporte de los componentes más importantes de dichos

13
Figura 6: Comparación de los tiempos de ejecución

algoritmos. De esta forma quedo en evidencia, por ejemplo, la vital importancia que tiene la etapa de
postproceso en el GRASP.
Por su parte, queda pendiente una revision al comportamiento del algoritmo Minton modificado y el SA,
ya que en teorı́a su rendimiento deberı́a haber sido considerablemente mayor.

Referencias
[1] Anonymous. Unknown. Berliner Schachgesellschaft, 3:363, 1848.
[2] Franz Nauck. Schach. Illustrierter Zeitung, pages 361–352, 1850.
[3] J.W.L. Glaisher. Philosophical Magazine, 18:457–467, 1874.
[4] Rok Sosic and Jun Gu. Efficient local search with conflict minimization: A case study of the n-queens
problem. Knowledge and Data Engineering, 6(5):661–668, 1994.
[5] Alfredo Candia Véjar and Cesar Astudillo Hernández. Algoritmos para el problema de las n-reinas. In
Mauricio Solar, David Fernández-Baca, and Ernesto Cuadros-Vargas, editors, 30ma Conferencia Lati-
noamericana de Informática (CLEI2004), pages 160–167. Sociedad Peruana de Computación, September
2004. ISBN 9972-9876-2-0.
[6] I.Vardi I.Rivin and P. Zimmermann. The n-queens problem. The American Mathematical Monthly,
101:629–639, 1994.

14
[7] K.D. Crawford. Solving the n-queens problem using genetic algorithms. In Proceedings ACM/SIGAPP
Symposium on Applied Computing, Kansas City, pages 1039–1047, 1992.

[8] B. Abramson and M. Yung. Divide and conquer under global constraints: A solution to the n-queens
problem. J. Parallel Distrib. Comput., 6(3):649–662, 1989.
[9] B. Bernhardsson. Explicit solution to the n-queens problems for all n. ACM SIGART Bulletin, 2(7),
1991.
[10] H.S. Stone and J.M. Stone. Efficient local search with conflict minimization: A case study of the n-queens
problem. IBM J. Res. Develop., 30(3):242–258, 1986.
[11] L.V.Kalé. An almost perfect heuristic for the n nonattacking queens problem. Information Processing
Lettes., 66:375–379, 1992.
[12] A.E. Eiben, P.-E. Raué, and Zs. Ruttkay. Solving constraint satisfaction problems using genetic algo-
rithms. In Proceedings of the 1st IEEE World Conference on Computational Intelligence, pages 542–547.
IEEE Service Center, 1994.
[13] Abdollah Homaifar, Joseph Turner, and Samia Ali. The n-queens problem and genetic algorithms. In
Proceedings IEEE Southeast Conference, Volume 1, pages 262–267, 1992.
[14] J. Hynek. The n-queens problem revisited. In Proceedings of the ICSC, Symposia on Intelligent Systems
and Applications ISA 2000. ICSC Academic Press., 2000.
[15] L.R. Foulds and D.G. Johnson. An application of graph theory and integer programming: Chessboard
nonattacking puzzles. Mathematical Magazine, 57:95–104, 1984.
[16] I.N. da Silva A.N. Souza and M.E. Bordon. A modified hopfield model for solving the n-queen problem.
IJCNN, pages 509–514, 2000.
[17] Steven Minton, Mark D. Johnston, Andrew B. Philips, and Philip Laird. Minimizing conflicts: A heuristic
repair method for constraint satisfaction and scheduling problems. Artificial Intelligence, 58(1-3):161–
205, 1992.
[18] M.G.Resende y J.L.Gonzalez. Grasp: Procedimientos de busqueda miopes aleatorizados y adaptivos.
Revista Iberoamericana de Inteligencia Artificial., (19):61–76, 2003.
[19] M.G.Resende and C.C.Ribeiro. Greedy randomized adaptive search procedures. AT&T Labs Research
Technical Report, Agosto 2002.
[20] P. Festa and M.G.Resende. An annotated bibliography of grasp. AT&T Labs Research Technical Report,
Febrero 2004.
[21] P. J. M. Laarhoven and E. H. L. Aarts, editors. Simulated annealing: theory and applications. Kluwer
Academic Publishers, Norwell, MA, USA, 1987.
[22] R.Sosic and J.Gu. 3.000.000 queens in less than one minute. SIGART Bulletin, 2(2):22–24, 1991.

15

También podría gustarte