You are on page 1of 5

Nombre: Hector David Morales López

Código: 1113624878

Algoritmos para búsqueda en espacio de estados

Existen varios algoritmos para encontrar un camino solución en un espacio de estados.


El esquema general de estos algoritmos es el siguiente:
procedure Búsqueda {

open {estado_inicial}

closed {}
while (open no está vacío) {
remover un estado X del conjunto open
if (X es un estado objetivo) return éxito
else {
generar el conjunto de sucesores del estado X
agregar el estado X al conjunto closed
eliminar sucesores que ya están en open o en closed
agregar el resto de los sucesores al conjunto open
}
}
return fracaso
}

El conjunto open contiene a los estados generados que todavía no han sido visitados (no
se ha verificado si son estados objetivo y no se han generado sus sucesores). El
conjunto closed contiene a los estados visitados. Al considerar sólo a los sucesores que
no han sido previamente generados se evita entrar en ciclos.

Dependiendo del orden en que se visiten los estados del conjunto open se obtienen
distintos tipos de recorrido.

Búsqueda en profundidad

En inglés, depth-first search.

Si el conjunto open se maneja como una lista LIFO, es decir, como un stack, siempre se
estará visitando primero los últimos estados en ser generados. Esto significa que,
si A genera B y C, y B genera D, antes de visitar C se visita D, que está más alejado de
la raíz A, o sea más profundo en el árbol de búsqueda. El algoritmo tiene en este caso la
tendencia de profundizar la búsqueda en una rama antes de explorar ramas alternativas.

procedure Búsqueda_en_profundidad {

open [estado_inicial]

closed {}
while (open no está vacía) {
remover el primer estado X de la lista open
if (X es un estado objetivo) return éxito
else {
generar el conjunto de sucesores del estado X
agregar el estado X al conjunto closed
eliminar sucesores que ya están en open o en closed
agregar el resto de los sucesores al principio de open
}
}
return fracaso
}

Considerando que la cantidad promedio de sucesores de los nodos visitados


es B (llamado en inglés el branching factor y en castellano el factor de ramificación), y
suponiendo que la profundidad máxima alcanzada es n, este algoritmo tiene una
complejidad en tiempo de O(Bn) y, si no se considera el conjunto closed, una
complejidad en espacio de O(B × n). En vez de usar el conjunto closed, el control de
ciclos se puede hacer descartando aquellos estados que aparecen en el camino generado
hasta el momento (basta que cada estado generado tenga un puntero a su padre).

El mayor problema de este algoritmo es que puede "perderse" en una rama sin encontrar
la solución. Además, si se encuentra una solución no se puede garantizar que sea el
camino más corto.

Búsqueda en amplitud

En inglés, breadth-first search.

Si el conjunto open se maneja como una lista FIFO, es decir, como una cola, siempre se
estará visitando primero los primeros estados en ser generados. El recorrido del espacio
de estados se hace por niveles de profundidad.

procedure Búsqueda_en_amplitud {

open [estado_inicial]

closed {}
while (open no está vacía) {
remover el primer estado X de la lista open
if (X es un estado objetivo) return éxito
else {
generar el conjunto de sucesores del estado X
agregar el estado X al conjunto closed
eliminar sucesores que ya están en open o en closed
agregar el resto de los sucesores al final de open
}
}
return fracaso
}
Si el factor de ramificación es B y la profundidad a la cual se encuentra el estado
objetivo más cercano es n, este algoritmo tiene una complejidad en tiempo y espacio de
O(Bn). Contrariamente a la búsqueda en profundidad, la búsqueda en amplitud garantiza
encontrar el camino más corto.

Búsqueda iterativa en profundidad

En inglés, iterative deepening.

La idea es combinar las buenas características de la búsqueda en profundidad, en cuanto


a la complejidad en espacio, con las ventajas de la búsqueda en amplitud. Esto se logra
haciendo una búsqueda en profundidad acotada por una profundidad máxima i que se
hace variar iterativamente de 1 en adelante con incrementos de 1. Si el estado objetivo
más cercano se encuentra a una profundidad n, se hacen n búsquedas en profundidad, a
nivel 1, a nivel 2, hasta el nivel n.

Esta búsqueda iterativa garantiza encontrar el camino más corto. Su complejidad en


espacio es de O(B × n). Su complejidad en tiempo es la suma de la complejidad en
tiempo de cada una de las búsquedas en profundidad acotadas que fueron necesarias,
i n
esto es i=1,...,nO(B ), o sea O(B ). La complejidad en tiempo es por lo tanto
equivalente a hacer una sola búsqueda acotada a la profundidad n.

Búsqueda heurística

En inglés, best-first search.

Los algoritmos anteriores hacen una búsqueda ciega y exhaustiva, lo que presenta serios
problemas en espacios de estado grandes. Esto se puede mejorar expandiendo primero
los estados que tienen más expectativas de encontrarse en el camino a la solución, lo
que implica utilizar una función heurística que permita darle una mayor prioridad a esos
estados.

El conjunto open se maneja en este caso como una cola de prioridad ordenada según
una función heurística que aporta un conocimiento adicional sobre el problema
abordado. Esta función puede ser, por ejemplo, una estimación del largo del camino que
queda por recorrer para llegar al estado objetivo.

procedure Búsqueda_heurística {

open [estado_inicial]

closed {}
while (open no está vacía) {
remover el primer estado X de la lista open
if (X es un estado objetivo) return camino hasta X
else {
generar el conjunto de sucesores del estado X
foreach (Y en sucesores) {
if (Y no está en open ni en closed) {
asignar a Y un valor heurístico
agregar Y en la lista open
}
elsif (Y está en open) {
if (el nuevo camino a Y es más corto)
actualizar el camino almacenado en open
}
elsif (Y está en closed) {
if (el nuevo camino a Y es más corto) {
remover el estado Y del conjunto closed
agregar el estado Y en la lista open
}
}
}
agregar el estado X al conjunto closed
reordenar la lista open según valores heurísticos
}
}
return fracaso
}

Además de utilizar una cola de prioridad, este algoritmo se diferencia por actualizar los
caminos almacenados en la lista open cada vez que se encuentra un camino más corto,
lo que mejora la probabilidad de encontrar el camino óptimo. El camino se almacena en
cada estado como un puntero al padre.

Cuando se llega a un estado en closed por un camino más corto, habría que transmitir
esta información a todos sus sucesores. Sin embargo, algunos de estos sucesores pueden
haber sido generados o posteriormente actualizados por otro camino que hasta el
momento parecía más corto, por lo cual estarían desvinculados del ancestro que se está
considerando. Administrar este problema sería muy engorroso, entonces se opta por
repetir la búsqueda.

Se puede obtener una versión simplificada de esta búsqueda heurística eliminando toda
la información histórica contenida en open y closed. En cada paso se generan los
sucesores del estado actual y sólo se conserva al mejor de ellos para el paso siguiente.
El algoritmo se detiene cuando ninguno de los sucesores tiene una mejor evaluación que
el estado actual (sino entraría en un ciclo infinito). Esta estrategia se llama algoritmo del
gradiente (hill climbing en inglés). Funciona adecuadamente cuando no hay óptimos
locales.
REFERENCIAS BIBLIOGRAFICAS

Users.dcc.uchile.cl. (2019). Apuntes de Inteligencia Artificial. [Página Web]


Recuperado de: https://users.dcc.uchile.cl/~abassi/Cursos/IA/Apuntes/c5.html

You might also like