Un hachage est un nombre qui remplace une phase. Il y a un hachage dans node_hash. Il est utilisé dans le but de relier les informations de situation et de nœud et de traiter diverses choses.
Un total de nombres UCT_HASH_SIZE à partir de 0. 4096 dans le livre. Convertissez la valeur de hachage en index avec hash_to_index () et utilisez la valeur de hachage en association avec l'index. La raison pour laquelle la largeur de 4096 est utilisée au lieu d'utiliser la valeur de hachage telle quelle est parce que la taille du hachage est de 64 bits, ce qui est inutilement grand.
node_hash node_hash est un tableau. Chaque élément est une instance de la classe NodeHashEntry et chaque élément possède des informations de hachage, de rotation, d'effort et d'indicateur. Lors de la création, créez d'abord une instance de la classe NodeHash avec self.xxx = NodeHash (). Un tableau node_hash existe en tant que membre dans cette instance appelé xxx.
Dans le livre, xxx est nommé node_hash, qui est le même nom que le tableau à l'intérieur. Soyez prudent car cela peut prêter à confusion.
Si vous extrayez uniquement le contour, ce sera comme ça.
UCT_HASH_SIZE = 4 #Doit être de 2 à la nième puissance. 4096 dans le livre. Il a été fixé à 4 pour l'explication.
class NodeHashEntry:
def __init__(self):
self.hash = 1 #Valeur de hachage Zobrist. C'est vraiment 0. Il a été mis à 1 pour l'explication.
self.color = 2 #Tour. C'est vraiment 0. Il a été réglé sur 2 pour l'explication.
# self.moves = 0 #Omis pour simplifier l'explication.
# self.flag = False #Omis pour simplifier l'explication.
class NodeHash:
def __init__(self):
self.node_hash = [NodeHashEntry() for _ in range(UCT_HASH_SIZE)]
Je vais essayer différentes choses pour comprendre la structure. Tout d'abord, créez une instance a de la classe NodeHash et imprimez-la.
a = NodeHash()
print(a)
Répondre
<__main__.NodeHash object at 0x0000015BDBB54948>
Cette classe a un tableau de noms de variables appelé node_hash, et dans ce cas UCT_HASH_SIZE = 4, donc le nombre d'éléments dans ce tableau est 4. node_hash = [objet NodeHashEntry, objet NodeHashEntry, Objet NodeHashEntry, objet NodeHashEntry].
affiche le tableau node_hash d'un
print(a.node_hash)
Répondre
[<__main__.NodeHashEntry object at 0x0000015BE2B7FD88>,
<__main__.NodeHashEntry object at 0x0000015BE4E13E48>,
<__main__.NodeHashEntry object at 0x0000015BE67F0108>,
<__main__.NodeHashEntry object at 0x0000015BE65B5F08>]
Ces quatre objets ont des variables appelées hachage et couleur, respectivement.
Imprimer le hachage et la couleur de 4 objets
for i in range(4):
print(a.node_hash[i].hash, a.node_hash[i].color)
Répondre
1 2
1 2
1 2
1 2
uct_node uct_node est un tableau. Chaque élément est une instance de la classe UctNode, et chaque élément a le nombre de visites sur le nœud, le taux de réussite total, le nombre de nœuds enfants, le déplacement du nœud enfant, l'index du nœud enfant, le nombre de visites sur le nœud enfant et le taux de réussite du nœud enfant. Il contient des informations sur les totaux, les taux de victoire prévus pour les réseaux politiques, les taux de victoire prévus pour les réseaux de valeur et les indicateurs évalués. Lors de la génération, self.uct_node = [UctNode () for _ in range (UCT_HASH_SIZE)].
search_empty_index() Une méthode pour rechercher les index inutilisés. Les arguments sont le hachage, la rotation et l'effort.
Ce qu'il fait, c'est générer un index à partir du hachage et vérifier si l'élément à cet index dans le tableau node_hash est inutilisé. S'il n'est pas utilisé, le hachage, la rotation et l'effort de l'argument sont affectés à l'élément, et un indicateur indiquant que l'élément est utilisé est défini. S'il a été utilisé, ajoutez 1 à l'index et faites de même jusqu'à ce qu'il contourne tous les index. S'il n'y a pas d'index inutilisé après un tour, UCT_HASH_SIZE est renvoyé.
Par exemple, si UCT_HASH_SIZE = 4096 et qu'il y a un index inutilisé, le hachage, la rotation et le nombre de mouvements sont affectés au premier élément de hit parmi les 4096 éléments de node_hash [0] à node_hash [4095], et un indicateur est défini pour se terminer. S'il n'y a pas d'index inutilisé, la valeur de 4096 est renvoyée et le processus se termine.
find_same_hash_index() Une méthode pour trouver l'index correspondant à la situation. Les arguments sont le hachage, la rotation et l'effort.
Ce qu'il fait, c'est générer un index à partir du hachage et vérifier si l'élément à cet index dans le tableau node_hash est inutilisé. Renvoie UCT_HASH_SIZE s'il n'est pas utilisé. Si le hachage, la rotation et l'effort de l'élément correspondent à l'argument utilisé, l'index est renvoyé. Faites de même jusqu'à ce que vous parcouriez tous les index tout en ajoutant 1 à l'index. S'il n'y a aucun index qui correspond à l'argument après un tour, UCT_HASH_SIZE est renvoyé.
Par exemple, si UCT_HASH_SIZE = 4096 et qu'un élément correspond au hachage, à la rotation et à l'effort de l'argument, l'index de cet élément (qui est l'un des 4096 de 0 à 4095) est renvoyé et le processus se termine. S'il n'y a pas d'élément correspondant, la valeur de 4096 est renvoyée et le processus se termine.
Search_empty_index () et find_same_hash_index () sont dans la même instance que le tableau node_hash. Par conséquent, lors de son utilisation, utilisez self. Instance name.search_empty_index (). Notez que le nom de l'instance est node_hash dans le livre, et qu'il semble être déroutant avec le même nom que node_hash dans le tableau de membres.
Recommended Posts