Reescrevi esta resposta para tentar abordar alguns comentários em uma versão anterior.
Suponho que você leu a definição da Wikipedia para completude NP, que realmente não se concentra nos jogos. Vou diluir um pouco o significado exato da NP-completude e da teoria dos jogos e explicar a essência de um jogo NP-Complete.
Vamos considerar um jogo para 2 jogadores com movimentos alternativos, de forma mais restritiva, isso é essencialmente sobre jogos combinatórios . Basicamente, um jogo em que você tem alguns movimentos que podem ser feitos e você deve escolher um deles. Você gostaria de jogar "perfeitamente", o que significa que nunca faria uma jogada "ruim". Então, dos movimentos permitidos que você deseja selecionar o melhor. (É claro que seu oponente tem o mesmo objetivo ...)
Observe que o jogo perfeito não significa que você sempre vencerá. As regras do jogo podem ser tais que o primeiro ou o segundo jogador ganhem. Além disso, alguns jogos como o Tic-Tac-Toe devem terminar empatados. Portanto, o que significa "jogo perfeito" nesta discussão é:
(1) Você nunca estará em uma posição vencedora e depois perderá o jogo porque fez um movimento "ruim"
(2) Você nunca perderá a oportunidade de obter para a posição vencedora, se surgir essa oportunidade.
Dado o estado atual do jogo, você gostaria de poder usar um "algoritmo eficiente" para calcular a melhor jogada. Por outro lado, note que um algoritmo que precisa pesquisar por toda a árvore do jogo é um "algoritmo ineficiente".
Agora vamos definir "eficiência" um pouco mais formal. Vou simplificar um pouco, mas a essência está correta. Considere o número de cálculos, , que devem ser feitos para escolher a próxima jogada, que a média de cada jogada tem possibilidades (o fator de ramificação ) e que existem jogadas no jogo. A noção também é de que cada cálculo leva o mesmo tempo para que o esforço possa ser traduzido em complexidade de tempo , , em vez de cálculos brutos.B n TCBnT
- Um "algoritmo eficiente" terá: que é um "número inteiro pequeno" e ah são alguns números reais. Assim, o algoritmo eficiente é executado em tempo polinomial, pois é uma expressão polinomial.
αT∝aBa+bBα−1+cBα−2+...+hB0
α
- Um "algoritmo ineficiente" terá:
e esse algoritmo é executado em tempo exponencial (isto é, tempo não polinominal). O ponto aqui é que, à medida que aumenta, ocorre uma explosão combinatória.
nT∝aBn
n
Agora, o ponto importante é que é impossível ter um algoritmo eficiente, o tempo polinomial, que joga perfeitamente para um jogo que NP completa. Para jogar perfeitamente, um problema NP-completo deve, por definição, ser resolvido por um algoritmo ineficiente que é executado em tempo não polinomial.
Observe que o tempo de execução é sobre o número intrínseco de cálculos, não o tempo de resposta percebido pelo ser humano. Para um jogo pequeno como o Tic-Tac-Toe, o computador pode executar todos os movimentos futuros possíveis e ainda responder rapidamente como percebido por um humano.
Para Nim , é possível criar um algoritmo de tempo polinomial. Em qualquer ponto do jogo, o algoritmo pode calcular qual jogador tem uma jogada vencedora e qual deve ser essa jogada.
Por outro lado, vamos jogar o jogo Qubic . (Você está tentando fazer uma linha de 4 em uma grade 3D. Portanto, é essencialmente jogo da velha em uma grade 4x4x4.) Qubic é NP-completo, portanto, não há algoritmo de tempo polinomial para calcular o próximo movimento perfeito. A única maneira de saber se você tem uma jogada vencedora é tentar todas as jogadas possíveis de ambos os jogadores para verificar se uma jogada em particular é vencedora ou, pelo menos, não perdedora.
Na verdade, toda a árvore de jogos do Qubic é pequena o suficiente para que possa ser codificada em um programa de computador que possa ser reproduzido perfeitamente. O que significa codificação é que toda a árvore do jogo foi explorada e todos os movimentos foram trabalhados com antecedência. Portanto, o programa pode essencialmente fazer uma chamada rápida ao banco de dados usando o estado atual da placa e recuperar a melhor jogada para esse estado da placa sem precisar fazer a pesquisa em árvore toda vez que uma mudança for feita. Este é realmente um "truque" para nossos propósitos aqui.
Agora vamos discutir xadrez para discutir a função de avaliação, ignorando alguns dos outros recursos dos programas de xadrez. O xadrez ainda é um jogo não resolvido . Não se sabe se o primeiro ou o segundo jogador deve ganhar. Não é possível ter nenhuma posição no conselho e prever com certeza quem vencerá. De fato, o xadrez tem uma árvore de jogo tão grande que é impossível pesquisar a árvore inteira. Você precisaria de computadores não apenas 10 ou 100 vezes mais rápidos, mas bilhões de bilhões de tempo mais rápidos do que qualquer computador atual. (Existe a esperança de que a computação quântica possa atravessar esse nó górdio.)
Pense na função de avaliação do xadrez como dando a cada próximo passo possível a probabilidade de ser o melhor. O que um programa de xadrez faz é combinar o futuro com a função de avaliação. Assim, o programa analisa todos os movimentos futuros possíveis até chegar a um ponto em que uma pontuação "boa" possa ser atribuída à posição do conselho. O computador avalia todos os caminhos possíveis pela árvore dessa maneira e escolhe o caminho com a melhor pontuação. Como a busca nunca chegou ao fim do jogo por todos os caminhos que estão sendo avaliados, todos os programas de xadrez acabam usando uma função de avaliação imperfeita. (Se você estiver próximo do final do jogo, o computador poderá analisar todas as possíveis jogadas futuras.) Isso significa que pode ser possível vencer o programa mesmo que ele tenha uma posição vencedora em algum momento.