¡Recomienda este blog!

domingo, 1 de julio de 2012

Comecocos - Búsqueda en juegos con adversario y Optimización Combinatoria mediante metaheurística de búsqueda local.

Índice:


1. Introducción al contexto de la práctica. 2

2. Breve descripción de la estructura de la memoria. 3

3. Estudio del algoritmo Hill Climbing. 4
    3.1.  Objetivo. 4
    3.2.  Descripción del algoritmo expuesto. 4
    3.3.  Ventajas e inconvenientes detectados. 5
    3.4.  Pruebas y resultados. 6

4. Algoritmo de búsqueda local ILS. 7
    4.1. Objetivo. 7
    4.2. Solución al problema propuesto. 7
    4.3. Ventajas e inconvenientes detectados. 8
    4.4. Pseudocódigo. 8
    4.5. Pruebas y resultados. 10

5. Algoritmo de búsqueda local VNS. 11
    5.1. Objetivo. 11
    5.2. Solución al problema propuesto. 11
    5.3. Ventajas e inconvenientes detectados. 12
    5.4. Funcionamiento del Algoritmo y Pseudocódigo. 12
    5.5. Pruebas y resultados. 14

6. Algoritmo MiniMax. 16
    6.1. Objetivo. 16
    6.2. Solución al problema propuesto y heurística elegida. 16
    6.3. Ventajas e inconvenientes detectados. 17
    6.4. Funcionamiento de Algoritmo y Pseudocódigo. 17
    6.5. Pruebas y resultados. 20

7. Conclusión.

1.    Introducción al contexto de la práctica.

Como breve introducción, se resaltan unas breves pinceladas sobre el trabajo realizado.

En primer lugar, se ha analizado y estudiado el algoritmo Hill Climbing que viene implementado en la práctica, con lo que hemos obtenido una serie de conclusiones.

Tras este estudio, se ha desarrollado e implementado dos técnicas metaheurísticas, como son el algoritmo de búsqueda local VNS (búsqueda en entornos variables) e  un algoritmo ILS (búsqueda local iterada).

También se han implementado una seriede evaluadores, para probar partidas con distintas configuraciones. Para ello hemos modificado el número y tipo de fantasmas,  la cantidad de vidas que dispone el Pacman, y el número de niveles máximos que acotan la duración de la partida, de tal forma que se nos facilita considerablemente la realización de pruebas para probar las implementaciones realizadas.

Estos algoritmos serán aplicados y utilizados para optimizar la partida de un PacMan, de forma que se realizarán multitud de simulaciones de juegos para conseguirlo.

También se ha implementado un jugador basado en el algoritmo MiniMax (Búsqueda con adversario), que implementa la clase ParameterizedPacmanPlayer, de manera que se le podrán pasar unos parámetros iniciales, para ser utilizados a la hora de realizar la evaluación en las hojas del árbol de búsqueda.

Por último se habla de las diferencias entre ambos algoritmos de búsqueda local implementados y obtenemos nuestra conclusión de la práctica.


2.    Breve descripción de la estructura de la memoria.

A continuación se detalla la estructura que seguirá la presente memoria, para facilitar en la medida de lo posible su comprensión, en cada apartado aparecerá de forma aproximada el siguiente guión:

· Objetivo: Se comenta brevemente los que se quiere conseguir, y cuál es el algoritmo a desarrollar.
· Solución al problema propuesto: Es decir, cómo ha sido resuelto el problema desde un punto de vista conceptual y sin entrar en detalles de implementación.
· Ventajas e inconvenientes detectados: Antes y después del proceso de implementación.
· Funcionamiento del algoritmo y Pseudocódigo: Detalles sobre la implementación del algoritmo.
· Pruebas y resultados: Testeo del funcionamiento del algoritmo con el mayor detalle posible.

Además,  en la descripción de los algoritmos se pretenderá utilizar una notación y un nivel de detalle que  faciliten la comprensión de los mismos.

Así mismo, se denota la posibilidad de prescindir de aquellos puntos que no aporten nada al desarrollo de la memoria.


3.    Estudio del algoritmo Hill Climbing.

       3.1 Objetivos.

Tras analizar el código del algoritmo y ejecutarlo varias veces,  se puede observar que se trata de un algoritmo simple de búsqueda local, más en concreto se trata de una Búsqueda por escalada o ascensión de colinas. Para una mejor comprensión de este, en los siguientes apartados se tratará de realizar una descripción lo más detallada posible de este.

       3.2 Descripción del algoritmo.

Para ir desglosando poco a poco el problema expuesto, se comenzará a detallar el espacio de configuraciones usado en el algoritmo a estudiar. En esta ocasión, se dispone de un espacio de configuraciones formado por un vector c, con un tamaño fijo de 22 elementos. Donde cada posición representa un peso asociado a un parámetro del comecocos, como por ejemplo:

C = (p1, p2, p3,……, p22)

Donde cada peso tendrá un valor de entre 0.0 y 5.0, y en cada posición se hace correspondencia a un aspecto importante en el desarrollo del juego. Como por ejemplo, a los puntos que quedan en la pantalla, a la distancia existente entre el Pacman y los fantasmas, etc.

Se ha de mencionar, que la función de evaluación usada determina la puntuación que se obtiene con la configuración de pesos que se está valorando. Para así, posteriormente determinar cuál es la mejor configuración posible.

A continuación, se detallarán las partes importantes, que desde nuestro criterio tiene el algoritmo.
De forma general, es sencillo ver que el este dispone de tres partes importantes. Primeramente se genera un vecino x, de forma aleatoria, ofreciendo así una posible solución al problema propuesto.

Tras esto, y basándonos en esta primera configuración, comenzará a obtener nuevas soluciones, con nuevos individuos de la vecindad. En este punto se destaca, que para ello, se realiza una operación sencilla, que consiste en recorrer uno a uno los elementos del vector C,  para así añadirles 1 si es mayor que 0, o restarles 1 si es mayor que cinco. En el siguiente ejemplo se puede observar de forma más clara.

[1.0,2.0,0.0,3.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…]
[0.0,1.0,0.0,3.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…] [0.0,3.0,0.0,3.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…] [0.0,2.0,1.0,3.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…] [0.0,2.0,0.0,2.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…]
[0.0,2.0,0.0,4.0,1.0,1.0,4.0,5.0,0.0,1.0,4.0…]
[0.0,2.0,0.0,3.0,0.0,1.0,4.0,5.0,0.0,1.0,4.0…]

Por último, vemos que se determina la mejor solución como aquella que consigue mejor puntuación, y que si en alguna iteración no se encuentra una solución que mejora la última encontrada hasta el momento. Se termina la ejecución del algoritmo.

       3.3 Ventajas e Inconvenientes detectados.

Los principales problemas que se encuentran en este algoritmo son, como en todo algoritmo de búsqueda local, que es muy propenso a acabar en un óptimo local, una cresta o una meseta.

Debido a que no se ha realizado ninguna mejora sobre este algoritmo (como ILS, o la que hemos implementado VNS), es especialmente dependiente de la solución que se escoja como inicial.

Si bien, es cierto que siempre encentra una solución posible al problema, aunque esta no sea del todo óptima.

        3.4 Pruebas y Resultados.



Hill Climbing
Evaluador

Puntuación
Tiempo (s)
Nº Evaluaciones
Evaluator1
Ejecución 1
19719
211
113
Ejecución 2
19559
143
75
Ejecución 3
19134
86
76
Valor Medio
19470
146
88
Evaluator2
Ejecución 1
751
27
67
Ejecución 2
860
28
69
Ejecución 3
2453
30
70
Valor Medio
1354
28
68
Evaluator3
Ejecución 1
1303
65
149
Ejecución 2
1019
31
72
Ejecución 3
981
34
77
Valor Medio
1101
43
99

4.    Algoritmo de búsqueda local ILS.

        4.1 Objetivos.

Como objetivo principal en este apartado, se propone realizar la implementación de una búsqueda local, basado en Búsqueda Local Iterativa o ILS.

Posteriormente, se realizarán una serie de pruebas para determinar como de bueno o malo es el algoritmo desarrollado, y que ayude a posteriores comparaciones con otros algoritmos similares.

        4.2 Solución al problema propuesto.

Para llevar a cabo la resolución del problema propuesto, tomamos la decisión de que el espacio de configuraciones a usar será exactamente el mismo que fue detallado en el punto 3.2 de la presente memoria.

Una vez establecido esto, se detalla que el algoritmo funciona exactamente igual que el anterior pero con algunos matices o variaciones. 

Para ello se establece que cuando el algoritmo de ascensión de colinas no encuentre una solución mejor, no acabará la ejecución, si no que basándonos en la mejor solución encontrada hasta el momento, se realizará una perturbación en esta, y continuaremos iterando hasta volver a tener una solución que no mejora la anterior y volvamos a perturbar, haciendo esto hasta 3 veces en la ejecución del algoritmo.

La perturbación llevada a cabo, consiste en generar una nueva vecindad recorriendo uno a uno los pesos de la solución x, y estableciendo un número calculado de forma aleatoria entre 0.0 y 5.0 para todos aquellos pesos con posiciones pares.

Además, se establecerá la misma operación para todos los pesos impares con un índice en el vector de pesos mayor que 10.

Con esto, vemos que como antes el algoritmo tiene 3 partes importantes, añadiendo en esta ocasión, la generación de una nueva vecindad con la forma antes descrita, y el reinicio a partir de esta tras caer en un óptimo local.

        4.3 Ventajas e Inconvenientes detectados.

La ventaja principal que se observa en este tipo de algoritmos es que evitamos mediante perturbaciones caer en un óptimo local. Así mismo vemos que, por lo general, se obtienen mejores puntuaciones que con el algoritmo detallado en el punto anterior.

Por el contrario, el tiempo de ejecución y el coste computacional aumenta sustancialmente en este tipo de algoritmos.

        4.4 Pseudocódigo.

En este apartado, se describe el pseudocódigo desarrollado para adoptar la solución propuesta anteriormente. Se ha de destacar, que solo se expondrá el código relacionado exclusivamente con la implementación del algoritmo ILS, y por tanto, solo mostraremos el código que ha sido desarrollado por nosotros, obviando así el código que venía desarrollado en el algoritmo Hill Climbing.

La resolución del problema se desarrolla principalmente en la función “run ()”, donde se seleccionará y devolverá la configuración de pesos más apropiada. A continuación se describe esta función:

funcion double[] run() {

    double[] currentSolucion = Calculamos la configuración inicial;

    double bestScore = Calculamos La puntuacion de(currentSolucion)

    Mostramos ambas cosas: Solucion + score.
     
… Todo esto es igual que para el Algoritmo de Ascención de Colinas.

Mientras ( tenga una solución mejor ) hacer

  …Hill Climing.

If ( No tenemos una solución mejor && no se ha perturbado 3 veces)
       
Perturbamos a partir de la mejor solución hasta ahora, con la función à generateNuevaVecindad(mejorSolucion).
 
  Calculamos su score.

  Mostramos todo: Solución + Score.

Establecemos esta solución, como la encontrada, y continuamos con la ejecución como si estuviéramos en Hill Climbing.
   
    Fin_si
      Fin_mientras
           
      Mostramos la solución Final, y su score.

Retornamos la solución Final.
}

Función generateNuevaVecindad(mejorSolucion){

    NuevaSolucion[] = mejorSolucion[];

    Para( i =0; i < Numero de pesos; i++) hacer

      If ( i es par ) entonces

            NuevaSolucion[i] = ramdom entre 0.0 y 5.0;
      Fin_si

      If ( i es impar y es mayor que 10 )
NuevaSolucion[i] = ramdom entre 0.0 y 5.0;
      Fin_si
     

    Fin_para

    Retornamos NuevaSolucion;
}

        4.5 Pruebas y Resultados.

Se han realizado tres ejecuciones por cada evaluador, usado examplePacmanPlayer,  de manera que los resultados que analizaremos serán los correspondientes a la media de estas.

Los resultados que hemos obtenido se resumen en la siguiente tabla:

ILS
Evaluador

Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
Ejecución 1
20119
313
252
Ejecución 2
19079
351
293
Ejecución 3
20163
314
192
Valor Medio
19787
326
246
4 fantasmas tipo Stalking
Ejecución 1
1068
91
227
Ejecución 2
2449
99
221
Ejecución 3
2459
113
224
Valor Medio
1992
101
226
2 Stalking y 2 Dave
Ejecución 1
4399
126
296
Ejecución 2
1796
71
183
Ejecución 3
2360
102
230
Valor Medio
2852
100
236



   5.    Algoritmo de búsqueda local VNS.


        5.1 Objetivos.

En el siguiente apartado se especifica paso a paso como se ha llevado a cabo la implementación del algoritmo de búsqueda local VNS, para solucionar los problemas encontrados en el algoritmo del punto anterior, tal y como se expone en el enunciado de la práctica.

        5.2 Solución al problema propuesto.

Para llevar a cabo la resolución de este problema, seguiremos tomando el mismo espacio de configuraciones que en los dos puntos anteriores.

Quedando fijado lo anterior, diremos que el algoritmo de búsqueda local VNS, tiene un funcionamiento idéntico a los anteriores, a excepción de que cuando este no encuentra una solución que mejore a la actual, que en este caso aumentaríamos la amplitud de la vecindad y continuaríamos buscando hasta encontrar una solución mejor. En caso de encontrarla, la siguiente iteración se realizara con la amplitud de vecindad que teníamos inicialmente, pero si no encontramos una solución mejor, volveríamos a ampliar la vecindad.

En este algoritmo, solo ampliaremos la vecindad dos veces consecutivas, en caso de que no se obtenga una mejora de la solución, se devolverá la mejor solución obtenida en la ejecución.

Cada ampliación de vecindad, nos generara un número de vecinos que casi duplicará a los de la iteración anterior.

La forma de realizar los cambios en los individuos para conseguir nuevos vecinos consistirá en cambiar los dígitos de forma lineal, sumando o restando una unidad a las componentes, de forma que en una vecindad de nivel uno, se cambiaran cada uno de los dígitos del individuo. Si la vecindad es de nivel dos, se cambiarán los dígitos 0 y 1, después 1 y 2, después 2 y 3, y así sucesivamente. Para la vecindad de nivel tres también se realizarían así (0, 1 y 2, después 1,2 y 3, etc).

Con este sistema, se intentara obtener mejores soluciones que con los algoritmos anteriormente descritos, debido a que evitaremos quedarnos con una solución que meramente sea un  óptimo local.

        5.3 Ventajas e Inconvenientes detectados.

La principal ventaja es la de que este algoritmo intenta no terminar en óptimos locales ampliando la búsqueda a partir de una solución (la que tengamos en ese momento) prometedora. A pesar de esta mejora, también es cierto que los costes, sobre todo en tiempo, aumentan considerablemente, ya que al aumentar la vecindad, el número se individuos prácticamente se duplica.

Otro detalle que también hemos de remarcar es que, aunque el algoritmo encuentre el óptimo global del espacio de búsqueda en su primera iteración, éste no se dará cuenta hasta que explore la vecindad de nivel tres.

        5.4 Funcionamiento del Algoritmo y Pseudocódigo.

El funcionamiento de este algoritmo es básicamente el que hemos visto en clase.

El algoritmo comienza su ejecución en la función run () generando aleatoriamente gracias a la función generateInitialSolution() de un individuo, tras esto se evalúa dicho individuo.

Con la solución inicial, nos introducimos en el bucle principal del algoritmo con la generación de la vecindad. De esto se encarga el método generateNeighbourhood(), que, de forma recursiva generará  las vecindades, cambiando uno o más dígitos del individuo, sumando o restando una unidad. Se cambiarán uno o más dígitos dependiendo de la población requerida, de forma que se cambiarán un digito para población de nivel uno, dos dígitos para la de nivel dos, y tres dígitos para la de nivel tres.

El algoritmo parará en el momento en el que llegue a tener una solución que no ha sido capaz de mejorar después de explorar su vecindad hasta nivel tres. En este momento, el algoritmo parará y devolverá la solución encontrada. 

La resolución del problema se desarrolla principalmente en la función “run ()”, donde se seleccionará y devolverá la configuración de pesos más apropiada. A continuación se describe esta función:

funciondouble[] run() {

double[] currentSolucion = Calculamos la configuración inicial;
int vecindad = 1;

doublebestScore = Calculamos La puntuacion de(currentSolucion)

    Mostramos ambas cosas: Solucion + score.
     
… Todo esto es igual que para el Algoritmo de Ascensión de Colinas.

Mientras ( vecindad sea menor o igual que tres) hacer

  …Hill Climing.

Si( No tenemos una solución mejor)
 
Obtenemos la nueva vecindad a partir de la mejor solución que tengamos hasta ahora, con la función àgeneraVecinos(mejorSolucion,vecindad,0).
 
  Calculamos su score.

  Mostramos todo: Solución + Score.

Establecemos esta solución, como la encontrada, y continuamos con la ejecución como si estuviéramos en Hill Climbing.

Aumentamos la variable vecindad.

Fin_si
      Fin_mientras
           
      Mostramos la solución Final, y su score.

Retornamos la solución Final.
}

Función generaVecinos(mejorSolucion,vecindad,i){

ArrayList<double[]> vecindad= new ArrayList<double[]>();

        Si (vecindad es distinto de 0)

            Si (La posición i de mejorSolucion es mayor que 0)

                double[] NewSolution1 = mejorSolucion

                Restamos uno a la componente i del vector NewSolution1

Añadimos el vecino al vector vecindad y llamamos a la        función generaVecinos(NewSolution1,vecindad-1,i+1)

            Fin_si

            Si (La posición i de mejorSolucion es menor que 5) {

                double[] NewSolution2 = mejorSolucion

                Sumamos uno a la componente i del vector NewSolution1

Añadimos el vecino al vector vecindad y llamamos a la        función generaVecinos(NewSolution1,vecindad-1,i+1)

            Fin_si

       
      Sino

            Añades al vector vecindad mejorSolucion
     
      Fin_si

    Retornamos vecindad.

}

        5.5 Pruebas y Resultados.

Con este algoritmo hemos realizado una serie de pruebas con distintos evaluadores. Estos evaluadores simularán partidas con 4 fantasmas tipo Basic, otro con 4 tipos Stalking, y otro con 2 Stalking y 2 Dave. Además existirá una limitación de diez niveles y el número de vidas del PacMan en cada uno de ellos será tres.

Se han realizado tres ejecuciones por cada evaluador, usado examplePacmanPlayer,  de manera que los resultados que analizaremos serán los correspondientes a la media de estas.

Los resultados que hemos obtenido se resumen en la siguiente tabla:

VNS
Evaluador

Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
Ejecución 1
20519
4011
503
Ejecución 2
20489
2921
275
Ejecución 3
20539
2726
386
Valor Medio
20516
3219
388
4 fantasmas tipo Stalking
Ejecución 1
2447
1339
329
Ejecución 2
2447
1117
264
Ejecución 3
2435
1126
266
Valor Medio
2443
1194
286
2 Stalking y 2 Dave
Ejecución 1
2444
139
202
Ejecución 2
4351
219
280
Ejecución 3
2377
108
172
Valor Medio
3057
155
218

Se puede observar que según la media, el número de puntos obtenido es bajo, ya que cuando introducimos fantasmas distintos a los Basic, el jugador ExamplePacManPlayer no juega correctamente y el PacMan es cogido por los fantasmas rápidamente.
                     

6.    Algoritmo MiniMax.


        6.1 Objetivos.

El objetivo principal en este apartado es desarrollar un agente de búsqueda basado en un algoritmo Minimax, para llevar a cabo la resolución de los puntos 4.3 y 4.4 de la práctica objeto de esta memoria.

        6.2 Solución al problema propuesto y Heurística elegida.

A continuación se detalla, de forma puramente teórica, como se ha realizado la resolución del problema. En primer lugar se ha de mencionar que al tratarse de una Búsqueda con adversarios, primero se ha de identificar a estos. Con lo que, decidimos que el Pacman sea el jugador identificado como Max, y el fantasma más cercano a este será el jugador Min.

De esta forma, nuestro problema se reduce a determinar de entre los movimientos legales de los que dispone Pacman, cuál será el más apropiado para él, para posteriormente movernos en esa dirección.

Como heurística, establecerá que Max realice el movimiento que le aporta la mayor cantidad de score posible, siendo este determinado por su aporte y establecido en una configuración de pesos. Esta será de la siguiente forma:

Pesos = {3, // Puntos en pantalla
         0, // Manhattan punto más cercano
         0, // Manhattan fantasma más cercano
         5, // Media Manhattan puntos
         2, // Media Manhattan fantasmas
         1, // Penalización por cabeceo

De forma contraria, Min escogerá el movimiento que haga que Pacman tenga menos score, pues esto es lo mejor para él.

Además, se realizan pruebas con el mismo algoritmo, pero con la configuración de pesos dada inicialmente, es decir 22 pesos, y como se puede ver en las pruebas posteriores, por lo general funciona bastante peor que con la configuración que proponemos.

Con esto, básicamente se trata de realizar un recorrido en profundidad por todos los estados, y escoger la mejor opción basándonos en los scores expuesto en las hojas de este árbol.

        6.3 Ventajas e Inconvenientes detectados.

Las ventajas de este algoritmo, frente a un MiniMax sin parámetros, no son demasiadas, ya que no varía la funcionalidad del algoritmo en ambos casos.

Pero de esta manera, podemos realizar ejecuciones con algoritmos de optimización combinatoria, y obtener el mejor valor de los parámetros, evaluando los puntos que va obteniendo el PacMan en sus reiteradas ejecuciones.

Por otra parte, el valor de estos parámetros está muy restringido, ya que solo se toman valores de 0 a 5, y por tanto, no podemos probar gran parte de combinaciones posibles, que pudiesen dar mejores resultados en la ejecución del MiniMax.

        6.4 Funcionamiento del Algoritmo y Pseudocódigo.

El funcionamiento interno del propio algoritmo es el siguiente: la función chooseMove(game) elegirá el movimiento que mejor puntuación tenga. Esta puntuación resultará tras generar los posibles movimientos del agente PacMan en ese estado y llamando a la función Max(state,int).

Una vez en la función Max, según el valor de la profundidad: si es cero, calculará y devolverá el valor del estado, según la función evaluateState(state) que a continuación comentaremos; y si es mayor que cero, listará los posibles movimientos del PacMan en ese estado, y tras esto llamará a la función Min(state,int) con una profundidad reducida en uno. La función Max en este caso devolverá el valor máximo de los que haya obtenido.

Cuando el algoritmo entre en la función Min realizará lo mismo que en Max, pero calculando los movimientos de los fantasmas (en vez del movimiento del PacMan) y devolverá el valor mínimo de entre los que ha obtenido.

      De esta forma, el funcionamiento general consistirá en escoger el máximo valor de los estados cuando “mueve” el PacMan, y el valor mínimo de los estados en los que “se mueven” los fantasmas. Así obtendremos el movimiento que más nos convenga en función de que los fantasmas estén más lejos.

El pseudocódigo de las funciones Min y Max, sería el siguiente:
Ambas funciones tendrán como entradas el estado siguiente y la profundidad, y devolverán la puntuación correspondiente.

Max(State n, int prof){

      double puntuación, inicializado a menos infinito.

      Si( La profundidad es mayor que 0)
         
Si hemos ganado devolvemos 10000

            Sino si hemos perdido devolvemos -10000

                  Sino

                  Obtenemos movimientos legales del estado n pasado

                  Mientras (queden movimientos legales por simular)

                        Obtenemos el estado siguiente
                       
                        Llamamos a la función Min(nextState,prof-1)

Si la puntuación actual es menor que la devuelta por min, se actualiza la puntuación actual con el valor máximo.

Fin_si
                       
                  Fin_mientras

                  Fin_si

            Fin_si

      Si (profundidad es 0)

Llamamos a evaluateState con el estado actual, y lo que nos devuelva lo guardamos en puntuación.

      Fin_si

            Devolvemos puntuación.

}


Max(State n, int prof){

      double puntuación, inicializado a más infinito.

      Si( La profundidad es mayor que 0)
         
Si hemos ganado devolvemos 10000

            Sino si hemos perdido devolvemos -10000

                  Sino

                  Obtenemos movimientos legales del estado n pasado

                  Mientras (queden movimientos legales por simular)

                        Obtenemos el estado siguiente
                       
                        Llamamos a la función Max(nextState,prof-1)

Si la puntuación actual es mayor que la devuelta por Max, se actualiza la puntuación actual con el valor mínimo.

Fin_si
                       
                  Fin_mientras

                  Fin_si

            Fin_si

      Si (profundidad es 0)

Llamamos a evaluateState con el estado actual, y lo que nos devuelva lo guardamos en puntuación.

      Fin_si

            Devolvemos puntuación.

}
  
Las funciones chooseMove y evaluateState, son similares a las del examplePacmanPlayer. 

        6.5 Pruebas y Resultados.

MiniMax con ILS
Evaluador

Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
Profundidad 3
17859
84
87
Profundidad 5
19559
327
79
Profundidad 7
17973
1351
60
Valor Medio
18464
587
75
4 fantasmas tipo Stalking
Profundidad 3
1611
33
65
Profundidad 5
881
62
75
Profundidad 7
778
149
66
Valor Medio
1090
81
67
2 Stalking y 2 Dave
Profundidad 3
1428
40
99
Profundidad 5
1422
84
86
Profundidad 7
779
78
74
Valor Medio
1210
67
86

MiniMax con ILS, profundidad 3 y 22 componentes
Evaluador
Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
1175
1072
267
4 fantasmas tipo Stalking
2447
1339
329
2 Stalking y 2 Dave
1773
260
250

MiniMax con VNS
Evaluador

Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
Profundidad 3
17189
286
137
Profundidad 5
16580
685
126
Profundidad 7
18159
4853
126
Valor Medio
17309
1941
112
4 fantasmas tipo Stalking
Profundidad 3
746
34
58
Profundidad 5
436
31
38
Profundidad 7
1337
475
80
Valor Medio
840
180
59
2 Stalking y 2 Dave
Profundidad 3
1417
56
98
Profundidad 5
1270
94
76
Profundidad 7
834
112
29
Valor Medio
1174
87
68

MiniMax con VNS, profundidad 3 y 22 componentes
Evaluador
Puntuación
Tiempo (s)
Nº Evaluaciones
4 fantasmas tipo Basic
7124
2909
704
4 fantasmas tipo Stalking
20494
1189
671
2 Stalking y 2 Dave
4448
762
495

   7.    Conclusión.


Tras el desarrollo de esta práctica se puede concretar que por lo general, si un algoritmo basado en Búsqueda por escalada es más eficiente, requerirá un mayor coste computacional.

Como podemos ver en los resultados obtenidos en las diferentes pruebas realizadas a cada tipo de algoritmo de búsqueda local (Hill Climbing, ILS y VNS), se observa que por lo general, el algoritmo Hill Climbing es el que menos puntuaciones obtiene como media, mientras que VNS obtiene muy buenas puntuaciones. 

A la postre, vemos que VNS requerirá más tiempo de ejecución, y realizará un mayor número de evaluaciones. Estos resultados se pueden observar gráficamente en las siguientes gráficas comparativas.




Tras esto, podemos deducir que el algoritmo que más se ajusta con respecto a prestaciones, tiempo de ejecución y número de iteraciones es ILS, ya que es un término medio entre los tres.

Con respecto a MiniMax, observamos que tiene un mejor rendimiento cuando se usan la opción de ser parametrizado. Además vemos que funciona mejor con 6 parámetros que con 22. Suponemos que es debido a un tiempo computacional mayor con el de 22.

1 comentarios:

edufissure dijo...

Muy bien explicado pero creo que hay un error en pseudocodigo de minimax, Dentro de max deberia llamar a la duncion min, y no otra vez a la max. Vamos eso lo entiendo al menos.

Publicar un comentario