¡Esta es una revisión vieja del documento!
Es un algoritmo que se basa en tratar la evolución de estados de un problema como si de un grafo se tratase. Los nodos de este grafo son los posibles estados del problema, y estos pueden representar cualquier cosa, desde una coordenada 2d hasta la posición de las piezas de un puzle.
Los nodos se unen por aristas, estas corresponden a los cambios que hay que hacer para cambiar de un estado a otro. De un nodo salen tantas aristas como cambios inmediatos pueden hacerse.
A cada nodo del árbol se le asigna un coste, este coste corresponde a lo cerca que está un estado del estado final, es decir, la solución. La forma de calcular el coste es distinta para cada problema y a la vez importante para su resolución. Cuando el estado final es desconocido o complejo de calcular podemos indicar que el coste del nodo corresponde a la dificultad que plantea tomarlo, por ejemplo, en una carrera un terreno plano tendrá menos costo que una subida.
Para llevar a cabo el algoritmo A* necesitaremos…
Partiendo de un estado que será el denominado “estado actual”…
Como ejemplo al estudio del A* haremos un seguimiento del algoritmo en la resolución de un puzzle de 8 fichas, un 3×3.
Se seguirá el siguiente diagrama que parte de un posible estado (1) e intenta llegar a un objetivo (4) utilizando el A*. Aunque para cada problema el cálculo del parámetro h es distinto y en él radica la calidad de la solución, en este se ha utilizado la Distancia Manhattan (aunque se podría haber utilizado cualquier otra). La forma concreta de cálculo ha sido:
Siendo el número de piezas mal colocadas en cada iteración, con esto conseguimos dar más puntuación a aquel estado que tiene más fichas mal colocadas. La i, por lo tanto sería el número de pieza.
El hill-climbing (también llamado rather descent si su función evalua el coste en vez de la calidad, aunque también podríamos convertir el valor de coste a negativo) intenta, sobre una solución ya existente del problema qué cambios hay que hacer hasta conseguir una solución mejor.
Representa la búsqueda que realiza como si fuese un escalador que, en medio de una densa niebla, busca la cima de un monte pero este no sabe cual es, ya que un monte puede tener varios picos y el escalador puede creer que un pico es la cima debido a la niebla.
El algoritmo consiste en un bucle que busca incrementar la calidad de una situación. Empieza con una solución inicial (generada aleatoriamente) y de forma iterativa va haciendo pequeños cambios hasta llegar a la mejor solución que pueda encontrar, entonces usa dicha solución como solución inicial y así continúa. Por lo tanto no depende de un árbol de búsqueda (nodos), es por eso que el problema le ha de permitir evaluar dichos nodos (o estados) de forma independiente. Cuando los estados a los cuales se puede acceder desde el estado actual tienen un valor equivalente el siguiente que se evaluará se seleccionará aleatoriamente. En este algoritmo se distinguen los siguientes conceptos:
Realmente el algoritmo lo que hace es iniciar en una solución aleatoria y busca una mejor y próxima solución hasta encontrar una que no pueda mejorar. Puede restringirse el número de iteraciones en las que permitiremos en las que no se haga un avance, así si hay un máximo restricción de iteraciones permitidas un reinicio aleatorio puede llegar a encontrar la solución óptima. El éxito depende de la diversidad de estados “picos”, si sólo existen pocas máximas locales un reinicio aleatorio encontrará una solución óptima bastante rápido, pero por desgracia los problemas reales tienen una superficie parecida a la de un puercoespín, muchas máximas locales. Aún así, y debido a esto, es fácil encontrar rápidamente una buena solución a pesar de que esta no sea la óptima.
function Hill-Climbing (problema) retorna una posible solución
entrada:
problema
utiliza:
currentNode
nextNode
ejecución:
currentNode = getInitialState (problem)
loop do
nextNode = currentNode.getSuccessors().getNodeWithMaximumValue()
if (nextNode.value < currentNode.value)
return current
currentNode = nextNode
end loop
Es un hill climbing pero que permite la bajada. El hill climbing tiene el el inconveniente que puede quedarse atascado en una máxima local, pero si, al contrario de esto, realizasemos un movimiento puramente aleatorio sería extremadamente ineficiente a pesar de que podría alcanzar el problema óptimo en algún momento. En metalurgia “annealing” es el proceso para calentar metales y vídrios, moldearlos y luego enfriarlos. Simulated annealing consiste en eso, en subir y bajar la temperatura o, en el caso de un hill climbing, la colina.
función SimulatedAnnealing (problema, organización) retorna un estado solución
entrada:
problema
organización, asigna la relación tiempo\temperatura
ejecución:
current = getInitialState (problem)
for t = 1 hasta infinito hacer:
T = organización (t)
if T = 0:
return current
next = current.getRandomSuccessors()
∧E = next.Value - current.Value
if ∧E > 0:
current = next
else if isProbable(∧E, T)
current = next
El loop interno es similar al del hill climbing, pero en vez de escoger el mejor movimiento escoge uno aleatorio, si dicho movimiento mejora la situación será siempre aceptado pero si no a cada paso que se haga será, por probabilidad, más difícil que se siga. Es decir, la mala calidad de la solución hace que la temperatura (T) baje y, por lo tanto, la cantidad de evaluación (∧E) menor.