Desculpe pela resposta tardia ( 4 anos !)
O NegaScout é um algoritmo muito simples. Para entender, devemos revisar o aprofundamento iterativo .
O aprofundamento iterativo é uma técnica para um mecanismo de xadrez procurar profundidade i, depois i + 1, depois i + 2 etc. Este é um exemplo de programação dinâmica. Durante cada iteração, temos o nosso melhor palpite sobre qual seria a melhor jogada. A maioria dos mecanismos de xadrez manteria esse movimento em uma tabela de hash.
Imagine que agora estamos na iteração i + 1 e temos a melhor jogada da última iteração i. Agora, temos 5 nós para pesquisar, devemos fazer?
Se assumirmos que fizemos um trabalho razoavelmente bom durante nossa última iteração, a melhor jogada da última iteração (que obtemos da tabela de hash) também deve ser a melhor jogada para a iteração atual.
Se nossa suposição estiver correta, poderemos economizar tempo pesquisando cada movimento que não seja o melhor (os quatro movimentos que não estão na tabela de hash) com a null window
. Uma janela nula é algo como:
score := -pvs(child, depth-1, -α-1, -α, -color)
Nota -α-1
e -α
. Eles são os valores alfa e beta que daremos à próxima recursão. Como a largura da janela é apenas 1, a pesquisa sempre falha:
- Se falhar abaixo de α, a movimentação é pior do que já temos, para que possamos ignorá-la
- Se falhar acima de β, a jogada é boa demais para jogar, para que possamos ignorá-la
- Caso contrário, precisamos fazer uma nova pesquisa corretamente
Obviamente, ainda procuraremos a melhor jogada (a que obtemos da tabela de hash) com uma janela alfa e beta adequada. Precisamos fazer isso porque precisamos saber exatamente o valor do nó, não podemos simplesmente ignorá-lo.
Tudo o que eu disse é implementado no pseudocódigo a seguir. O pseudocódigo especifica, child is not first child
mas essa é uma maneira de verificar se a movimentação também é a melhor movimentação na iteração anterior. A tabela de hash é a implementação mais comum.
# Negasort is also termed Principal Variation Search - hence - pvs
function pvs(node, depth, α, β, color)
if node is a terminal node or depth = 0
return color x the heuristic value of node
for each child of node
if child is not the first child
# search with a null window
score := -pvs(child, depth - 1, -α - 1, -α, -color)
# if it failed high, do a full re-search
if α < score < β
score := -pvs(child, depth - 1, -β, -score, -color)
else
score := -pvs(child, depth - 1, -β, -α, -color)
α := max(α, score)
# beta cut-off
if α >= β
break
return α