Comment fonctionne l'algorithme NegaScout?


8

Concernant l'élagage Alpha-Beta, NegaScout affirme qu'il peut accélérer le processus en définissant [Alpha, Beta] sur [Alpha, Alpha-1].

Je ne comprends pas tout le processus de NegaScout.

Comment ça marche? Quel est son mécanisme de récupération lorsque sa supposition a échoué?


1
Veuillez fournir des liens vers vos références et formuler une question plus ciblée.
Raphael

1
La notion principale derrière NegaScout est clairement expliquée dans le lien que vous avez fourni: en utilisant une fenêtre nulle (où α et β sont les mêmes, au lieu de β=α-1comme vous le dites), on peut vérifier si l'enfant le plus à gauche de chaque profondeur repose ou non sur la variation principale . Si tel est le cas, la recherche est terminée. Sinon, les algorithmes procèdent comme un algorithme de recherche minimax ordinaire avec élagage alpha-bêta. Notez que NegaScout développe à nouveau tous les nœuds qui se trouvent dans la branche gauche de l'algorithme de recherche. En outre, il est basé sur Negamax au lieu de Minimax.
Carlos Linares López

Qu'est-ce que cette phrase signifie «on peut vérifier si l'enfant le plus à gauche de chaque profondeur se trouve sur la variation principale ou non». ? Y a-t-il un exemple? Merci ~
sam

@ CarlosLinaresLópez, si vous souhaitez développer votre commentaire en une réponse, nous pourrions nettoyer cette réponse
Merbs

Réponses:


6

Désolé pour la réponse tardive ( 4 ans !)

NegaScout est un algorithme très simple. Pour comprendre, nous devons réviser l' approfondissement itératif .

L'approfondissement itératif est une technique utilisée par un moteur d'échecs pour rechercher la profondeur i, puis i + 1, puis i + 2, etc. Ceci est un exemple de programmation dynamique. À chaque itération, nous avons notre meilleure estimation de ce que serait le meilleur coup. La plupart des moteurs d'échecs garderaient ce mouvement dans une table de hachage.

Imaginez que nous sommes maintenant à l'itération i + 1, et nous avons le meilleur coup de la dernière itération i. Maintenant, nous avons 5 nœuds à rechercher, devons-nous faire?

Si nous supposons que nous avons fait un travail raisonnablement bon lors de notre dernière itération, le meilleur mouvement de la dernière itération (que nous obtenons de la table de hachage) devrait également être le meilleur mouvement pour l'itération en cours.

Si notre hypothèse est correcte, nous devrions pouvoir gagner du temps en recherchant chaque mouvement autre que le meilleur mouvement (les quatre mouvements ne figurant pas dans la table de hachage) avec a null window. Une fenêtre nulle est quelque chose comme:

score := -pvs(child, depth-1, -α-1, -α, -color)

Remarque -α-1et . Ce sont les valeurs alpha et bêta que nous donnerons à la prochaine récursivité. Comme la largeur de la fenêtre n'est que de 1, la recherche échouera toujours:

  • S'il échoue en dessous de α, le mouvement est pire que ce que nous avons déjà, nous pouvons donc l'ignorer
  • S'il échoue au-dessus de β, le coup est trop bon pour être joué, on peut donc l'ignorer
  • Sinon, nous devons faire une nouvelle recherche correctement

Bien sûr, nous rechercherons toujours le meilleur coup (celui que nous obtenons de la table de hachage) avec une fenêtre alpha et bêta appropriée. Nous devons le faire parce que nous devons connaître exactement la valeur du nœud, nous ne pouvons pas simplement l'ignorer.

Tout ce que j'ai dit est implémenté dans le pseudocode suivant. Le pseudocode spécifie child is not first childmais c'est un moyen de vérifier si le mouvement est également le meilleur mouvement de l'itération précédente. La table de hachage est l'implémentation la plus courante.

# 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 α
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.