Si consigo que dos motores jueguen uno contra el otro con los mismos colores, ¿el mismo juego resultará siempre? Si no, ¿de dónde viene la aleatoriedad en el juego del motor? (Descuidando el libro de apertura, donde si no me equivoco, el libro puede decirle al motor que elija entre dos movimientos al azar, ya que son igualmente buenos).
Supongo que hay aleatoriedad porque en el partido Alphazero vs. Stockfish, no tuvimos el mismo juego muchas veces seguidas. Sin embargo, no entiendo por qué. Presumiblemente, la única forma de hacer esto es hacer que el motor juegue un movimiento inferior en algunas ocasiones, que suena como seppuku.
Respuestas:
En cuanto al partido AlphaZero vs Stockfish, esta pregunta ya ha sido cubierta aquí por SmallChess .
Dejando a un lado AlphaZero (que emplea una rutina especializada Monte Carlo 1 en su exploración de las líneas de juego), que se hace que no sea determinista por construcción, para los motores de ajedrez basados en heurística habituales, como Stockfish y otros (aunque hay otros motores que tienen rutinas basadas en MC, AFAIK Rybka solía tener esa característica), la fuente de aleatoriedad generalmente es solo una consecuencia de aspectos técnicos en la implementación, en lugar de la aleatoriedad intencional introducida algorítmicamente en la toma de decisiones del motor. Hablando de manera abstracta, una de las razones es el hecho de que los motores no están funcionando de manera puramente secuencial (ejecutando una tarea tras otra). En cambio, para hacer que los motores sean más eficientes, realizan búsquedas paralelas en varias ramas del árbol de posibles movimientos. Lo hacen a través de lo que se llama subprocesamiento múltiple (o procesamiento, pero eso es un poco diferente). Por lo tanto, múltiples hilos de las CPU son concurrentesejecutar operaciones para buscar en el árbol (y almacenar en caché las evaluaciones de las posiciones visitadas), así que imagine que a cada hilo se le asigna un subárbol. El problema con este tipo de implementación es que la ejecución general de los subprocesos se vuelve altamente dependiente de todo tipo de condiciones (tiempos de espera, intercambios de RAM, ...), por lo que al final se puede elegir una variación principal sin haber permitido todos los demás hilos para terminar su búsqueda.
De hecho, esto sucede a menudo porque el motor está configurado para tomar una decisión en un período de tiempo determinado, por lo que la gestión del tiempo altera el comportamiento. También puede revertir esta declaración diciendo: conocer el algoritmo e implementar rutinas de subprocesos deterministas no son suficientes para predecir de manera confiable el estado del programa después de cualquier tiempo t. Por supuesto, si uno siempre permite que todos los hilos terminen su búsqueda, y no ha habido problemas de concurrencia durante esa ejecución (por ejemplo, un hilo que intenta acceder a un cierto caché que no es accesible), entonces el comportamiento será completamente reproducible dado que todo lo demás es igual 2 .
1 : Junto con el hecho de que a través del entrenamiento adicional (por ejemplo, el auto-juego) su red neuronal sigue evolucionando (parámetros reajustados), o si lo desea, su función de evaluación no tiene una definición constante y fija (a diferencia de los motores basados en heurística )
2 : Incluso entonces, como dijiste, en el nivel inicial, con un libro inicial, a veces el motor toma decisiones aleatorias intencionales sobre qué variación elegir. Del mismo modo, fuera de la fase de apertura, puede haber momentos en los que múltiples variaciones tienen evaluaciones casi iguales (dentro de la resolución elegida para el Eval), luego, según el diseño, puede terminar eligiendo uno al azar. Finalmente, a nivel de la configuración del motor, también debe tener cuidado, por ejemplo, la profundidad de búsqueda y los tiempos de reflexión elegidos para cada motor (y si pueden calcular aún más durante los tiempos de reflexión del otro).
fuente
Gracias a @Phonon que cubre mis respuestas anteriores en detalles. Me gustaría agregar un punto más: control de tiempo .
El único control de tiempo determinista es por número de nodos , pero esto es poco común. El control de tiempo mucho más común: el número fijo de segundos o el tiempo de juego generalmente no son deterministas.
Probemos un ejemplo. Ejecute stockfish en su terminal. Tipo:
Este comando le indica al motor que haga un movimiento después de 20 segundos. Mis resultados:
El movimiento fue 1.Cf3. Luego, maté a mi Stockfish, comencé uno nuevo. De nuevo, 20 segundos. Tengo:
¡Es 1.d4! Misma posición, ¡ambos 20 segundos de búsqueda!
¿Lo ves? Ambos 20 segundos para el movimiento, pero debido a la fluctuación en el sistema operativo Linux, mi segunda ejecución tuvo una búsqueda más profunda (26185280> 24325860).
Tenga en cuenta que este pequeño experimento ni siquiera fue multiproceso (número de subprocesos = 1). Multithreading haría las cosas aún más no deterministas.
Stockfish recibió un minuto por jugada en el partido Google AlphaZero. El número de hilos era 64. Las decisiones de Stockfish en el partido no podrían ser deterministas.
fuente