Вы находитесь на странице: 1из 12

IMPLEMENTACIÓN DEL 

ALGORITMO A* 
EN 8‐PUZZLE Y 8‐REINA 

Trabajo realizado por:


Alonso García, Rubén
Sanz Fernández, Rafael
1. INTRODUCCIÓN
1.1. Introducción a los algoritmos de búsqueda informada y exploración

Los algoritmos de búsqueda informada son más eficientes que los algoritmos de
búsqueda no informada, debido a que éstos últimos pueden encontrar soluciones a
problemas generando sistemáticamente nuevos estados y probándolos con el objetivo.

Los algoritmos de búsqueda informada son muy útiles en problemas donde lo que
importa es el estado de solución en sí mismo, no el camino. Utilizan métodos inspirados en
la física estadística (temple simulado) y la biología evolutiva (algoritmos genéticos).

Un primer contacto con éstos algoritmos es el siguiente: “búsqueda primero el


mejor”, que es un caso particular del algoritmo general de “búsqueda de árboles” o
“búsqueda de grafos”, en el cuál se selecciona un nodo para la expansión basada en una
función de evaluación, f(n). La evaluación mide la distancia al objetivo.

Otro algoritmo importante es el “búsqueda voraz primero el mejor” que expande


el nodo más cercano al objetivo. Evalúa los nodos utilizando solamente la función
heurística:

f(n) = h(n)

En nuestro trabajo nos centraremos en la búsqueda A* y sus variantes.

2. CARACTERIZACIÓN DEL ALGORITMO A*.


Un algoritmo de búsqueda por el mejor nodo combina las características de los
métodos en anchura y en profundidad. Se caracteriza porque para cada nodo se generan
todos los posibles sucesores y de estos sólo se expande aquel que sea más prometedor
después de la aplicación sobre ellos de una función heurística h(n) que estima el coste del
camino desde cada nodo al objetivo. El uso de este tipo de algoritmo, al minimizar el coste
estimado hasta el objetivo, disminuye considerablemente el coste de la búsqueda.
Desafortunadamente, no es ni óptimo ni completo.

Por otra parte, la búsqueda de coste uniforme minimiza el coste del camino hasta
el nodo, g(n) , es decir, expande para cada conjunto de sucesores aquel cuyo camino desde
el nodo raíz tenga un menor coste. Este es un algoritmo óptimo y completo, pero puede ser
muy ineficiente.

Sería bueno poder combinar estas dos estrategias para conseguir las ventajas de
ambos. Afortunadamente, podemos hacer eso exactamente, combinando las dos funciones
de evaluación simplemente sumándolas:

f(n) = g(n) + h(n).


Ya que g(n) proporciona el coste del camino desde el nodo de inicio hasta el nodo
n, y h(n) es el coste estimado del camino de menos coste desde n hasta el objetivo, f(n) es el
coste estimado de la solución de menor coste que atraviesa el nodo n.

Si se intenta encontrar la solución de menor coste, es razonable intentar primero el


nodo con el menor valor de f. Lo bueno de esta estrategia, es que es más que razonable. Se
puede comprobar que es completa y óptima, dando una simple restricción de la función h.

La restricción es escoger una función h que nunca sobreestime el coste para


alcanzar el objetivo. Una función h de este tipo es una heurística admisible.

A este algoritmo se le conoce con el nombre de A*.

Los algoritmos de búsqueda heurística tradicionales como A* pueden llegar a


necesitar un espacio de almacenamiento que crece de manera exponencial con la longitud
de la solución del problema. Esto puede propiciar que, a pesar de que el problema tenga un
coste temporal relativamente asequible, el coste espacial lo convierta en un problema
intratable.

2.1. Optimalidad de A*

Definir f* - el costo de la solución óptima para la ruta

¾ A* expande todos los nodos con f(n)<f*

¾ A* podría expandir algunos de los nodos a la derecha del “contorno de la


meta”, para los cuales f(n) = f*, antes de seleccionar el estado meta.

La primera solución encontrada debe ser la óptima, dado que los nodos de todos los
contornos subsiguientes tendrán un costo f más alto y con ello un costo g más alto (todos
los estados meta tienen h(n) = 0).

Teorema: Sea h*(n) el costo real desde n hasta la meta. Si h(n) < h*(n) para todo nodo n,
entonces A* siempre va a encontrar un nodo meta óptimo.

Prueba: Sea s el nodo meta de mínimo costo. Sea que A* seleccione un nodo meta
subóptimo s’, donde g(s)<g(s’)

Sea n un nodo sin expandir en la ruta desde el nodo inicio y el nodo meta óptimo s. Notar
que ese nodo sin expandir necesariamente existe, de acuerdo con la suposición previa (en el
otro caso, s ya habría sido elegido como el nodo meta).

Puesto que n no ha sido elegido para su expansión en su ruta hacia s’, se sigue que:

f(n) = g(n) + h(n) ³ f(s') = g(s') + h(s') = g(s')


Dado que h es admisible, g(n) + h*(n) ³ g(n) + h(n) = f(n), y entonces

g(n) + h*(n) ³ f(s') = g(s')

lo cual implica que

g(s) ³ g(s')

Una heurística admisible nunca sobreestima el costo de llegar a la meta

Un estimado de costo optimista en la solución de un problema es menor -más barato- que el


real.

Si h es admisible, f(n) nunca sobreestima el costo real de la mejor solución pasando por n

La búsqueda A* - con f(n) y con h admisible es completa y óptima

2.2. Completitud de A*

A* expande nodos en el orden de un creciente f, con lo cual eventualmente expandirá hasta


llegar al estado meta salvo que haya una cantidad infinita de nodos con f(n)< f*

¾ Un nodo con un factor de ramificación infinito


¾ Una ruta con costo de ruta finito pero con un número infinito de nodos a lo
largo de ella

2.3. Complejidad A*

La búsqueda A* es OPTIMAMENTE EFICIENTE para cualquier función heurística al


contrastarse con otros algoritmos óptimos que compiten con ella.

¾ No hay otro algoritmo que expanda menos nodos que A*


¾ Cualquier algoritmo, que no expanda todos los nodos en los contornos
existentes entre el contorno del inicio y el de la meta, corre el riesgo de no
encontrar la solución óptima

Complejidad temporal: O(b^d)

Complejidad espacial: O(b^d)

El espacio de búsqueda de A* crece exponencialmente a no ser que sea

h(n)-h*(n) =< O(log h*(n))

¾ Prácticamente, el error es a lo menos proporcional al costo de la ruta


¾ El crecimiento exponencial satura a cualquier computadora
3. CARACTERIZACIÓN DEL ALGORITMO IDA*.
Es de tipo de algoritmos de búsqueda heurística con limitación de memoria. Los
más utilizados son el IDA* (Iterative Deepening A*), y SMA* (Simplified memory A*).

El IDA* (Iterative-Deepening A*) es al igual que el DFID un algoritmo basado en


la profundización iterativa. La única diferencia entre ambos algoritmos estriba en que
mientras el DFID se basa en la profundidad para cada una de sus iteraciones, el IDA se basa
en la información heurística que posee para determinar el siguiente límite de la iteración. El
tratamiento de esa información se realiza de igual forma que en el algoritmo del A*, o sea
mediante la función de evaluación f introducida anteriormente. El funcionamiento del
algoritmo es el siguiente:

¾ En cada iteración el algoritmo realiza una búsqueda en


profundidad hasta donde se lo permita su límite de coste. Cada vez que se visita
todo el grafo de búsqueda contenido dentro de ese límite sin hallar la solución
entonces, el algoritmo incrementa el límite de coste. Ese nuevo límite viene
dado por el menor de los límites de corte, o sea, por el menor valor del coste de
los nodos que tenían un valor superior en la anterior iteración.

Este algoritmo se considera limitado en profundidad, aunque esta afirmación no


sea estrictamente cierta. La razón de ello viene dado por su eficacia en cuanto al uso de
memoria pero en su funcionamiento no realiza un control estricto de la memoria.

3.1. Características de IDA*

¾ IDA* es un método de búsqueda completo y óptimo, lo que


quiere decir que siempre encuentra una solución si es que ésta existe y además
garantiza encontrar la mejor solución de entre todas las posibles.

¾ Este método tiene las mismas ventajas y desventajas que A*,


excepto en lo referente al coste espacial. En este aspecto IDA* presenta notables
ventajas ya que únicamente necesita un espacio proporcional a la longitud de la
ruta más larga que se explore.

¾ Esta limitación en el uso de la memoria resulta beneficiosa


pero también tiene sus desventajas, ya que al convertir la búsqueda de la
solución en un proceso iterativo expandiremos varias veces los mismos nodos.
Esto es algo muy a tener en cuenta, ya que dependiendo de las características de
los problemas a resolver obtendremos mejores o peores prestaciones.
¾ En el mejor caso el coste temporal de IDA* puede ser muy
similar al de A*, e incluso menor, ya que al ser un algoritmo simple y no
necesitar de inserciones, borrados y reordenamientos en listas de prioridades
tiene una menor sobrecarga por nodo. Este mejor caso ocurrirá cuando tengamos
un problema en el que las heurísticas adopten valores aproximados al coste real
desde el comienzo de la ejecución, ya que entonces se realizarán pocas
iteraciones, expandiendo además pocos nodos en las iteraciones iniciales.
Podemos asociar este caso con el problema del 8-puzzle cuando se usa la
heurística de distancias.

¾ En el peor caso el coste temporal de IDA* se acerca al de un


algoritmo de profundización iterativa habitual como el IDS (Iterative Deepening
Search), es decir, en cada iteración se profundiza únicamente un nivel más en el
árbol. Esto ocurre en problemas en los que los valores heurísticos son poco
acertados, lo que provoca que en cada iteración aumentemos el contorno en sólo
uno o dos niveles.

4. CARACTERIZACIÓN DEL ALGORITMO SMA


El SMA* (Simplified Memory-bounded A*) aparece en cierta medida debido a
los problemas del IDA* en espacios reducidos de memoria. Al contrario de éste, el SMA*
realiza un control estricto de la memoria, delimitando desde un principio el máximo de
memoria de la que dispone. En cambio, la implementación de éste resulta muy dificultosa.

El algoritmo SMA* hace un uso más inteligente del espacio de almacenamiento y


tiene la ventaja de usar toda la memoria de que disponga, de forma óptima. En este caso
podemos considerar que el coste espacial es constante, aunque deberemos tener en cuenta
que para poder obtener la solución óptima, la ruta entre el nodo inicial y el final deberá
caber en la memoria disponible. El coste temporal de este algoritmo está muy relacionado
con el tamaño de la memoria: Si en ella cabe todo el árbol de búsqueda, el algoritmo
expandirá exactamente los mismos nodos que A*. Si no es así, las prestaciones se reducen.
El uso de más memoria permite mejorar la eficiencia de la búsqueda.
5. JUEGO DEL 8-PUZZLE

5.1. Estudio de la resolución de diferentes configuraciones del 8-puzzle con


diferentes heurísticas

En la implementación del 8-Puzzle hemos creado 4 archivos diferentes en cada uno de


los cuales se ha utilizado una heurística diferente:

¾ H1 ó Suma total de fichas descolocadas: heurística minorante fácil de calcular


pero con resultados que distan mucho de ser óptimos.

¾ H2 ó Suma de distancias de Manhatan: heurística minorante bastante efectiva.


En problemas cortos es la que mejores resultados ha obtenido.

¾ H3 ó Suma de secuencias: heurística no minorante, que en nuestras pruebas no


ha demostrado ser excesivamente eficaz.

¾ H=H2+2*H3: heurística no minorante que ha demostrado ser la mas eficaz de la


cuatro utilizadas, puesto que aunque en tableros de 8-puzzle con una
configuración mas simple (con menor número de movimientos) se ha visto
superada por la H2, en tableros con una complejidad elevada (18 movimientos)
ha sido capaz de resolver los problemas un numero mucho mas pequeño de
nodos.

Para llegar a estas conclusiones nos hemos basado en la resolución de 3 tableros


diferentes de 8-puzzle con una complejidad de 6, 12 y 18 movimientos.

En todas ella se pretende llegar a la misma matriz solución:

1 2 3

8 0 4

7 6 5

5.2. 8-Puzzle de 6 movimientos

La primera matriz utilizada ha sido la siguiente (el 0 representa la casilla vacía):

1 3 0

6 2 4
8 7 5

Para resolver esta matriz de forma óptima se deben realizar 6 movimientos, los
cuales son descritos a continuación:

1 3 0 1 0 3 1 2 3

6 2 4 6 2 4 6 0 4

8 7 5 8 7 5 8 7 5

1 2 3 1 2 3 1 2 3

0 6 4 8 6 4 8 6 4

8 7 5 0 7 5 7 0 5

1 2 3

8 0 4

7 6 5

Para llegar ha este resultado se han tenido que efectuar los 6 movimientos que
acabamos de describir y que enumeramos a continuación:

Izquierda, Abajo, Izquierda, Abajo, Derecha, Arriba

Todas las heurísticas utilizadas llegan a una solución optima, pero la diferencia
principal radica en le cantidad de recursos que necesitan para resolver el problema.

Vamos a mostrar las principales diferencias obtenidas en la resolución del problema


con las diferentes heurísticas:
H1 = 5 Nº de movimientos = 6 Nodos generados = 21
H2 = 6 Nº de movimientos = 6 Nodos generados = 18
H3 = 11 Nº de movimientos = 6 Nodos generados = 20
H= H2+2H3 = 28 Nº de movimientos = 6 Nodos generados = 18

5.3. 8-Puzzle de 12 movimientos

Para la prueba de 12 movimientos hemos utilizado la siguiente matriz:

6 1 4

8 3 2

0 7 5

Para este ejercicio y para el de 18 movimientos, no vamos a escribir las


configuraciones de las matrices en la resolución de este problema pues resultaría muy
tedioso, pero si que daremos una descripción optima de los pasos a seguir

Una solución óptima encontrada para la resolución de esta matriz de forma óptima
es:

Arriba, Arriba, Derecha, Abajo, Izquierda, Abajo, Derecha, Arriba, Derecha, Arriba,
Izquierda, Abajo.

Si hacemos una comparación entre las diferentes heurísticas podremos comprobar


que:

H1 = 6 Nº de movimientos = 12 Nodos generados = 917


H2 = 10 Nº de movimientos = 12 Nodos generados = 38
H3 = 15 Nº de movimientos = 12 Nodos generados = 101
H= H2+2H3 = 40 Nº de movimientos = 12 Nodos generados = 40

5.4. 8-Puzzle de 18 movimientos

Para la prueba de 18 movimientos hemos utilizado la siguiente matriz:


6 3 1

8 0 4

7 5 2

Una solución óptima encontrada para la resolución de esta matriz de forma óptima
es:

Arriba, Izquierda, Abajo, Derecha, Arriba, Derecha, Abajo, Abajo, Izquierda,


Arriba, Izquierda, Arriba, Derecha, Abajo, Derecha, Arriba, Izquierda, Abajo.

Si hacemos una comparación entre las diferentes heurísticas podremos comprobar


que:

H1 = 5 Nº de movimientos = ¿? Nodos generados = ¿?


H2 = 10 Nº de movimientos = 18 Nodos generados = 5421
H3 = 14 Nº de movimientos = ¿? Nodos generados = ¿?
H= H2+2H3 = 38 Nº de movimientos = 18 Nodos generados = 4709

En la resolución de este problema tanto H1 como H3 provocan un desbordamiento


de memoria debido al alto grado de recursos utilizados, y no se obtiene ninguna solución.

5.5. Conclusiones de las pruebas de 8-puzzle

En problemas de complejidad pequeña (numero reducido de movimientos para


resolver el problema) la heurística más eficaz es la de Manhattan, ya que es capaz de
resolver el problema con menor consumo de memoria (utiliza menos nodos).

A medida que la que la complejidad del problema va aumentando se va


comprobando como la utilización de nodos por parte de las diferentes heurísticas va
aumentando en grandes cantidades. Así podemos ver que la utilización de nodos
resolviendo un problema de 18 movimientos por medio de la heurística de Mahattan
asciende a 5421, mientras que con la utilización de una heurística H2+2H3 el numero de
nodos se reduce a 4709. Con las otras 2 heurísticas utilizadas el número de nodos utilizados
es infinitamente mayor a estas 2 últimas, tanto que es capaz de desbordar la memoria del
ordenador impidiéndose así llegar a solución alguna.
De esta forma queda demostrado que la utilización de la heurística H2+2H3 es la
más efectiva, no solo por la menor utilización de nodos, sino porque a la larga es la única
capaz de resolver problemas de este tipo con una complejidad muy elevada utilizando al
hacerlo la menor cantidad de recursos posibles.

Se adjunta la implementación en java del Algoritmo A* del juego 8-puzzle.

6. JUEGO DE LAS 8-REINAS

El juego consiste en colocar 8 reinas en un tablero de ajedrez sin que se ataquen.

Una posibilidad es intentar lograr una solución de manera incremental,


acercándose a la meta poco a poco siguiendo una serie de decisiones locales basadas en la
información obtenida durante el proceso.

Hay que asegurarse que la secuencia de transformaciones sea sistemática, para no


generar configuraciones repetidas ni excluir configuraciones deseables.

Una forma de sistematizar la búsqueda es construyendo más que transformando


configuraciones.

Por ejemplo el hecho de que deba de haber sólo una reina por columna nos reduce
el número de alternativas a menos de 8 en cada renglón.

Sistematizamos la búsqueda para no recuperarnos de restricciones en operaciones


futras, es decir, una vez que violamos una restricción no podemos seguir añadiendo más
reinas para rectificarla.

Posibles candidatos de heurísticas:

1. Colocar reinas que dejen el mayor número de casillas sin atacar.

2. Colocar reinas cuyas diagonales amenacen menos casillas

En la implementación del algoritmo los números significan lo siguiente:

0= casilla libre
1= reina
2= casilla atacada

Se adjunta la implementación en java del Algoritmo A* del juego 8-reinas. El


usuario sólo deberá introducir la primera reina en la columna que desee de la primera fila,
el programa introducirá las siguientes reinas dependiendo de la heurística elegida.
7. BIBLIOGRAFÍA

7.1. Internet:

i http://www.angelfire.com/oh4/ohcop/ClaseCap4nu.ppt
i http://dmi.uib.es/~abasolo/intart/2-juegos.html
i http://www.ii.uam.es/~fdiez/docencia/material/bh.pdf
i http://www.dc.fi.udc.es/.aios/~barreiro/iadocen/puzzle8-
98/introalgoritmos.html
i http://www.lsi.upc.es/~luigi/docencia/2bBusquedainformadayexploracion(es).p
df

7.2. Bibliografía

i [Rich, 94].- "Inteligencia Artificial". Segunda edición. Elaine Rich. Kevin Knight.
Editorial McGraw-Hill. (1994).
i [Russell, 96].- "Inteligencia Artificial, un enfoque moderno". Stuart Russell. Peter
Norvig. Editorial Prentice Hall. (1996).

Вам также может понравиться