Esta es una pregunta de seguimiento a Aleatoriedad en Engine Play . La respuesta de SmallChess indica que, en un caso, Stockfish buscó un número determinado de nodos después de 20 años, y un número diferente en los otros 20 años, por lo tanto, hay aleatoriedad.
La pregunta: si cada nodo es una posición determinada, ¿cómo decide Stockfish qué nodo buscar primero? Tomemos, por ejemplo, la primera media capa. Las blancas tienen 20 primeros movimientos posibles, por lo que hay 20 nodos. Exijo que Stockfish juegue un movimiento después de buscar cinco nodos. ¿Significa esto que Stockfish podría haber evaluado solo 1. a4, 1. a3, 1. b4, 1. b3 y 1. c3 antes de que tenga que hacer un movimiento? Sin embargo, una búsqueda sistemática como esta significaría que Stockfish no ha evaluado los primeros movimientos más comunes.
Me imagino que, más adelante en el juego, habría un salto masivo en el número de nodos por media capa. Eso significaría que Stockfish a veces decide hacer un movimiento a pesar de que no ha terminado de evaluar cada nodo en la mitad de la capa. ¿Cómo sabría que ha buscado en los nodos más prometedores?
Respuestas:
http://rebel13.nl/rebel13/ideas.html explica esto bien.
La idea básica es ordenar los movimientos en función de lo que el programa piensa que es el mejor movimiento sin buscar. Este puntaje generalmente se basa en la movilidad, el valor de la pieza cuadrada, el control central, la historia, el potencial de ataque, las capturas y otros elementos que el programador considera importantes. Así como los humanos basan sus movimientos de candidatos basados en la intuición y la historia, la computadora busca primero el movimiento de mayor puntuación.
Si la computadora está limitada a solo cinco nodos, entonces sí, la computadora solo buscará los cinco movimientos de mayor puntuación. Este factor de límite de tiempo podría causar que la computadora pierda un compañero en uno si se calificó mal. El primer método para corregir esto fue establecer cajas de seguridad. Esto interrumpiría una búsqueda si la posición empeorara notablemente o mejorara significativamente. La esperanza era permitir más tiempo para buscar más variaciones que pudieran usar mejor el tiempo. Otros algoritmos de búsqueda, la profundización iterativa, han mejorado la gestión del tiempo, ya que tienen una longitud más corta antes de que promulguen una prueba de fallas.
fuente
Este problema es bastante similar a algunos problemas de codificación. Stockfish ya tiene múltiples conjuntos de movimientos precalculados. Representa el estado del tablero de ajedrez usando múltiples bitboards, que luego usa para evaluar las posiciones del tablero usando una representación categórica (cheques, tempos, jaque mate) y estadística (valores de pieza). Casi de inmediato, utiliza un algoritmo de búsqueda alfa-beta avanzado. Para no analizar la misma posición varias veces, se utiliza una tabla de transposición. Esto es esencialmente memorización aplicada a la función de búsqueda, que es fundamental en muchos problemas de programación de teoría de grafos. Por lo tanto, en realidad usa un algoritmo bastante simple. Aquí hay algunas investigaciones realizadas antes:
Paso 1. Inicializar nodo
Paso 2. Verifique la búsqueda abortada y el sorteo inmediato. Haga cumplir el límite de nodo aquí. (Esto solo funciona con 1 hilo de búsqueda, a partir de Stockfish 2.3.1.)
Paso 3. Reducir la poda a distancia. Incluso si nos apareamos en el siguiente movimiento, nuestra puntuación sería, en el mejor de los casos, mate_in (textsrightarrowtextply + 1textssrightarrowtextply + 1, pero si alfa ya es más grande porque se encontró una pareja más corta hacia arriba en el árbol, entonces no hay necesidad de buscar más, nunca vencer al alfa actual La misma lógica pero con signos invertidos se aplica también en la condición opuesta de ser apareado en lugar de dar mate, en este caso devolver un puntaje de falla alta.
Paso 4. Búsqueda de tabla de transposición. No queremos que el puntaje de una búsqueda parcial sobrescriba una búsqueda completa anterior. Utilizamos una tecla de posición diferente en caso de un movimiento excluido.
Paso 5. Evalúe la posición estáticamente y actualice las estadísticas de ganancia de los padres
Paso 6. Razoring (se omite en los nodos PV)
Paso 7. Poda de movimiento nulo estático (se omite en los nodos PV). Apostamos a que el oponente no tiene un movimiento que reducirá el puntaje en más de futility_margin (profundidad) si hacemos un movimiento nulo.
Paso 8. Búsqueda de movimiento nulo con búsqueda de verificación
Paso 9. ProbCut. Si tenemos una captura muy buena y una búsqueda reducida devuelve un valor muy superior a beta, podemos (casi) podar con seguridad el movimiento anterior.
Paso 10. Profundización iterativa interna.
Paso 11. Recorre los movimientos. Recorra todos los movimientos pseudolegales hasta que no queden movimientos o se produzca un corte beta
Paso 12. Extiende los controles y también los movimientos peligrosos.
Paso 13. Poda inútil.
Paso 14. Haz el movimiento
Paso 15. Búsqueda de profundidad reducida (LMR). Si el movimiento falla alto, se volverá a buscar a toda profundidad.
Paso 16. Búsqueda de profundidad completa, cuando se omite LMR o falla alto.
Paso 17. Deshacer movimiento
Paso 18. Verifica si hay un nuevo mejor movimiento
Paso 19. Verifique la división
Paso 20. Verifique el mate y el estancamiento
Paso 21. Actualizar tablas. Actualizar la entrada de la tabla de transposición, los asesinos y el historial
Intentaré explicar de qué está hablando la investigación del profesor. Stockfish crea un árbol de búsqueda del movimiento legal. Luego, comienza a evaluar si cada movimiento es bueno o malo, y qué tan bueno o malo es, ejecutando primero un campo de búsqueda superficial y luego usando los valores de corte alfa / beta resultantes como valores iniciales para una búsqueda más profunda. Stockfish también da prioridad a las piezas. Por ejemplo, los caballeros tendrían prioridad en el centro, por lo que si un caballero y un alfil se bifurcan en el centro, moverá al caballero, a menos que haya otras ganancias significativas al mover al alfil. Si bien esto puede parecer complicado, esta ejecución es aproximadamente logarítmica (número de movimientos posibles), por lo que aún es bastante rápida.
fuente