Reescribí esta respuesta para tratar de abordar algunos comentarios en una versión anterior.
Supongo que has leído la definición de Wikipedia para completar NP que realmente no se centra en los juegos. Voy a diluir un poco el significado exacto de NP-completitud y teoría del juego y explicaré la esencia de un juego NP-Complete.
Consideremos un juego de 2 jugadores con movimientos alternativos, más restrictivamente se trata esencialmente de juegos combinatorios . Básicamente, un juego en el que tienes algunos movimientos que puedes hacer y debes elegir uno de ellos. Te gustaría jugar "perfectamente", lo que significa que nunca harías un movimiento "malo". Entonces, de los movimientos permitidos, te gustaría seleccionar el mejor. (Por supuesto, tu oponente tiene el mismo objetivo ...)
Tenga en cuenta que el juego perfecto no significa que siempre ganará. Las reglas del juego pueden ser tales que gane el primer o el segundo jugador. También algunos juegos como Tic-Tac-Toe deberían terminar en empate. Por lo tanto, lo que significa "juego perfecto" en esta discusión es:
(1) Que nunca estarás en una posición ganadora y luego perderás el juego porque hiciste un movimiento "malo"
(2) Nunca perderás la oportunidad de obtener en la posición ganadora si surge esa oportunidad.
Dado el estado actual del juego, lo que le gustaría es poder usar un "algoritmo eficiente" para calcular el mejor movimiento. Por otro lado, observemos que un algoritmo que tiene que buscar en todo el árbol del juego es un "algoritmo ineficiente".
Ahora definamos "eficiencia" un poco más formalmente. Voy a simplificar esto un poco, pero la esencia es correcta. Considere la cantidad de cálculos, , que se deben hacer para elegir el próximo movimiento, que el promedio de cada movimiento tiene posibilidades (el factor de ramificación ) y que quedan movimientos en el juego. La noción también es que cada cálculo lleva el mismo tiempo para que el esfuerzo pueda traducirse en complejidad de tiempo , , en lugar de cálculos brutos.B n TCBnT
- Un "algoritmo eficiente" tendrá: donde es un "entero pequeño" y ah son algunos números reales. Por lo tanto, el algoritmo eficiente se ejecuta en tiempo polinómico, ya que esta es una expresión polinómica.
αT∝aBa+bBα−1+cBα−2+...+hB0
α
- Un "algoritmo ineficiente" tendrá:
y este algoritmo se ejecuta en tiempo exponencial (es decir, tiempo no polinominal). El punto aquí es que a medida que crece, se produce una explosión combinatoria.
nT∝aBn
n
Ahora, el punto importante es que es imposible tener un algoritmo eficiente, el tiempo polinómico, que funcione perfectamente para un juego que completa NP. Para jugar perfectamente, un problema NP-completo debe, por definición, resolverse mediante un algoritmo ineficiente que se ejecuta en tiempo no polinómico.
Tenga en cuenta que el tiempo de ejecución se trata del número intrínseco de cálculos, no del tiempo de respuesta percibido por un humano. Para un juego pequeño como Tic-Tac-Toe, la computadora podría jugar todos los movimientos futuros posibles y aún responder rápidamente como lo percibe un humano.
Para Nim es posible crear un algoritmo de tiempo polinómico. En cualquier momento del juego, el algoritmo puede calcular qué jugador tiene un movimiento ganador y cuál debería ser ese movimiento.
Por otro lado, tomemos el juego de Qubic . (Estás tratando de hacer una línea de 4 en una cuadrícula 3D. Por lo tanto, es esencialmente tic-tac-toe en una cuadrícula de 4x4x4.) Qubic tiene NP completo, por lo que no hay un algoritmo de tiempo polinómico para calcular el siguiente movimiento perfecto. La única forma de saber si actualmente tiene un movimiento ganador es probar todos los movimientos posibles de ambos jugadores para verificar que un movimiento en particular sea un ganador, o al menos no un perdedor.
A decir verdad, todo el árbol del juego para Qubic es lo suficientemente pequeño como para que pueda codificarse en un programa informático que pueda jugar perfectamente. Lo que significa la codificación es que se ha explorado todo el árbol del juego y todos los movimientos se han resuelto de antemano. Entonces, el programa esencialmente puede hacer una llamada rápida a la base de datos usando el estado actual del tablero y recuperar el mejor movimiento para ese estado del tablero sin tener que hacer la búsqueda de árbol cada vez que se haga un movimiento. Esto es realmente un "truco" para nuestros propósitos aquí.
Ahora analicemos el ajedrez para analizar la función de evaluación ignorando algunas de las otras características de los programas de juego de ajedrez. El ajedrez sigue siendo un juego sin resolver . Se desconoce si el primer o segundo jugador debe ganar. No es posible obtener una posición en el tablero y predecir con certeza quién ganará. De hecho, el ajedrez tiene un árbol de juego tan grande que es imposible buscar en todo el árbol de juego. Necesitaría computadoras que no sean solo 10 o 100 veces más rápidas, sino miles de millones de veces más rápidas que cualquier computadora actual. (Existe la esperanza de que la computación cuántica pueda cortar este nudo gordiano).
Piense en la función de evaluación de ajedrez como si le diera a cada posible próximo movimiento una probabilidad de ser el mejor movimiento. Lo que hace un programa de ajedrez es combinar look aheads con la función de evaluación. Por lo tanto, el programa analiza todos los movimientos futuros posibles hasta que llega a un punto en el que se puede dar un "buen" puntaje a la posición del tablero. La computadora evalúa todas las rutas posibles a través del árbol de esta manera y luego elige la ruta con la mejor puntuación. Como la búsqueda nunca llegó al final del juego para todos los caminos que se evalúan, todos los programas de ajedrez finalmente utilizan una función de evaluación imperfecta. (Si está cerca del final del juego, entonces la computadora podría mirar todos los movimientos futuros posibles). Eso significa que podría ser posible vencer al programa incluso si el programa tenía una posición ganadora en algún momento.