Definición de una Poda Alpha Beta Queda claro que el arbol empieza a crecer, y en un juego de ajedrez el nivel de expertez del juego se mide por que tantas jugadas adelante vel el minimax, normalmente de va desde 1 ply hasta 6 plys completos. por esto es necesario podar un tanto el arbol, para esto se tiene varios métodos entre ellos la poda Alfaa Beta y la poda de Crash Cut PODA Alfa Beta Asumiendo que un jugador Alfa tiene que maximizar lo que el otro jugador Beta tiene que minimizar, podemos almacenar la información que van obteniendo los dos y retroalimentarla. Veamos esto en un ejemplo, en el algoritmo basico de MINIMAX a dos niveles se tiene que 1. Abrir el arbol o 1.1 Todas mis jugadas o 1.2 Todas sus jugadas 2. Aplicar la evaluación en todos sus hijos 3. Minimizar por nodo en sus jugadas ( beta ) 4. Maximizar en todo mis jugadas 5. Seleccionar la mejor ( alpha ) Asi por ejemplo vemos la apliacación en la figura Sin embargo el numero de tiradas puede crecer, con la poda alfa beta podemos eliminar con el conocimiento que se va procesando si dejamos hasta el final la evaluación de los nodos, veamos la figura siguiente: En la figura observamos que una vez que minizo el primer nodo el valor beta = 3 indica al jugador alfa que cuando menos ya podra obtener un valor >=3 por lo que no tiene caso evaluar jugadas menores a 3 para el nodo siguiente, asi vemos que cuando el jugador beta minimiza el segundo nodo, se nota que una vez encontrado el valor 1 como su trabajo es minimizar el nodo que subira sera unicamente<=1 y por ende el jugador alpha no va a usarlo, por lo que en algoritmo minimax resulta posible no evaluar las jugadas marcadas con x, con el correspondiente ahorro de tiempo ( el ahorro se puede dar en tres modos : la creacion de la jugadas, el recorrido del arbol y la evaluación ) . Sin embargo para el caso del tercer nodo el jugador beta tendra despues de encontrar el tablero con valor 8 tiene que continuar evaluado, ya que 8 es mayor 3 y el jugador alfa si lo tomaria, por lo que el beta debe buscar una tirada menor, la cual encuentra con la jugada de valor 2. Quedando el algoritmo como sigue: 1. Abrir la siguiente jugada mia generando un nodo para el con alfa = valor pequeño o 1.1 Si ya no hay mas jugadas : me voy a 4. 2. Abrir la siguiente jugada de él con beta = valor grande o 2.1 Si ya no hay mas jugadas y Si beta > alfa : alfa = beta y salto al paso 1 3. Evaluo su jugada o 3.1. Si la jugada de él es mayor que beta me salto al paso 1 o 3.2. Si la jugada de él es menor que beta : beta = evaluacion y me salto al paso 2 4. Tomo la jugada que me dio el último alfa y termino Este ahorro permite generar mas hijos en jugadas posteriores para esto es necesario modificar el algoritmo para hacerlo recursivo, lo que se logra con modificar el paso 3 0. numtiradas = profundidad 1. Abrir la siguiente jugada mia generando un nodo para el con alfa = valor pequeño o 1.1 Si ya no hay mas jugadas : me voy a 4. 2. Abrir la siguiente jugada de él con beta = valor grande ; o 2.1 Si ya no hay mas jugadas y Si beta > alfa : alfa = beta y salto al paso 1 3 Evaluación o 3.1.1 Si numerotiradas = profundidad : Evaluo la jugada o 3.1.2 Si numerotiradas < produndidad : numerotiradas = numerotiradas + 1 ;voy( recursivamente ) a paso 1 o 3.2.1 Si la jugada de él es mayor que beta me salto al paso 1 o 3.2.2 Si la jugada de él es menor que beta : beta = evaluacion y me salto al paso 2 4. Tomo como valor la jugada que me dio el último alpha y regreso a quien me llamo ( recursivamente ) Pseudo Código para una poda Alfa Beta en Minimax import java.awt.*; import java.applet.Applet; public class alfabeta extends Applet // Inicializa variables int[] TIRADA = new TIRADA[2] // TIRADA[1] es el tablero TIRADA[2] es el valor del tablero int[] POSIBLE = new POSIBLE[2] ; int[] MinTirada = new MinTirada[2] ; int[] MaxTirada = new MaxTirada[2] ; int Jugada, numtir, procrece ; // variables que defiene el numero de tablero y la profundidad deseada // Procedimiento maximizacion y minimizacion recursivamente public void init() { numtir = profundidad ; Juego = "en Proceso"; Jugada = 0; tiro= 0; while (Juego <> "en Proceso") { procrece = 1; TIRADA = Maximiza(Jugada, alfa, beta, procrece); Grafica(TIRADA[1]); Jugada = TIRADA[1] ; Juego = EvaluaTerminacion(TIRADA); } ; }; // Procedimiento para la Maximizacion int Maximiza(Jugada,alfa,beta,procrece) { alfa = -infinito; for ( j= 1; j <= Njugadas ; j=j+1 ) { MaxTirada[1] = SiguienteTab(j,Jugada); POSIBLE = Minimiza(MaxTirada[1],alfa,beta,procrece); if ( beta > alfa ) alfa = beta; if alfa >= POSIBLE[2] then TIRADA = POSIBLE }; return TIRADA ; } // Procedimiento para la Minimizacion int Minimiza(Jugada,alfa,beta,procrece) { procrece = procrece +1; Poda = "enproceso" ; beta = + infinito ; for ( j = 1; j <= Njugadas AND poda = "enproceso" ; j=j+1 ) { MinTirada[1] = SiguienteTab(j, Jugada); if ( procrece = numtir ) POSIBLEMIN[2] = Evalua(MinTirada[1]) else POSIBLEMIN = Maximiza(MinTirada[1], alfa, beta, procrece); } if ( MinTirada[2] <= beta ) { TIRADA = POSIBLEMIN ; beta = MinTirada[2] ; if (beta <= alfa) Poda = "hecha" ; } } Return TIRADA } // Procedimiento para la Evaluacion int Evalua(Jugada) // Procedimiento para la Graficacion int Grafica(Jugada) // Procedimiento para la determinacion de la siguiente jugada int SiguienteTab(j, Jugada) } // end class Alfabeta Este ahorro permite generar mas hijos hacia adelante sin un crecimiento exponencial como se muestra en la gráfica La Figura muestra adicionalmente una poda denomida de corte agresivo, la cual tiene como objetivo eliminar completamente de la evaluacion toda una zona de un arbol en caso de que se considere que dicha zona contiene una jugada que de antemando se perdibe mala, aunque al final se pudiera ganar por esa ruta, este es el caso para el caso del ajedrez, de decidir no evaluar tableros que asuma la perdida de una pieza clave como la reina, que aunque resulte factible, el programa no quiere considerarlas. A esta poda se le denomina Corte agresivo o Crash Cut. El pseudocódigo para dicha poda se ve reflejado en el metodo de maximizacion // Procedimiento para la Maximizacion int Maximiza(Jugada,alfa,beta,procrece) { alfa = -infinito; for ( j= 1; j <= Njugadas ; j=j+1 ) { MaxTirada[1] = SiguienteTab(j,Jugada); If (NotCut(MaxTirada[1]) // la funcion NotCut regresa verdad si no hay un corte agresivo en la jugada considerada { POSIBLE = Minimiza(MaxTirada[1],alfa,beta,procrece); if ( beta > alfa ) alfa = beta; if alfa >= POSIBLE[2] then TIRADA = POSIBLE } }; return TIRADA ; }