Ein Hash ist eine Zahl, die eine Phase ersetzt. In node_hash befindet sich ein Hash. Es wird verwendet, um die Situations- und Knoteninformationen zu verknüpfen und verschiedene Dinge zu verarbeiten.
Insgesamt UCT_HASH_SIZE-Nummern ab 0. 4096 im Buch. Konvertieren Sie den Hashwert mit hash_to_index () in einen Index und verwenden Sie den Hashwert in Verbindung mit dem Index. Der Grund, warum die Breite des Hashs auf 4096 festgelegt wird, anstatt ihn als Index zu verwenden, liegt darin, dass die Größe des Hashs 64 Bit beträgt, was nutzlos groß ist.
node_hash node_hash ist ein Array. Jedes Element ist eine Instanz der NodeHashEntry-Klasse, und jedes Element verfügt über Hash-, Turn-, Effort- und Flag-Informationen. Erstellen Sie beim Erstellen zunächst eine Instanz der NodeHash-Klasse mit self.xxx = NodeHash (). In dieser Instanz existiert ein node_hash-Array als Mitglied mit dem Namen xxx.
In diesem Buch heißt xxx node_hash und hat denselben Namen wie das darin enthaltene Array. Seien Sie vorsichtig, da es verwirrend erscheint.
Wenn Sie nur den Umriss extrahieren, sieht es so aus.
UCT_HASH_SIZE = 4 #Muss 2 zur n-ten Potenz sein. 4096 im Buch. Zur Erklärung wurde es auf 4 gesetzt.
class NodeHashEntry:
def __init__(self):
self.hash = 1 #Zobrist-Hashwert. Es ist wirklich 0. Zur Erklärung wurde es auf 1 gesetzt.
self.color = 2 #Wende. Es ist wirklich 0. Zur Erklärung wurde es auf 2 gesetzt.
# self.moves = 0 #Zur Vereinfachung der Erklärung weggelassen.
# self.flag = False #Zur Vereinfachung der Erklärung weggelassen.
class NodeHash:
def __init__(self):
self.node_hash = [NodeHashEntry() for _ in range(UCT_HASH_SIZE)]
Ich werde verschiedene Dinge versuchen, um die Struktur zu verstehen. Erstellen Sie zunächst eine Instanz der Klasse NodeHash und drucken Sie sie aus.
a = NodeHash()
print(a)
Antworten
<__main__.NodeHash object at 0x0000015BDBB54948>
Diese Klasse verfügt über ein Array von Variablennamen mit dem Namen node_hash. In diesem Fall ist UCT_HASH_SIZE = 4, sodass die Anzahl der Elemente in diesem Array 4 beträgt. node_hash = [NodeHashEntry-Objekt, NodeHashEntry-Objekt, NodeHashEntry-Objekt, NodeHashEntry-Objekt].
print node_hash Array von a
print(a.node_hash)
Antworten
[<__main__.NodeHashEntry object at 0x0000015BE2B7FD88>,
<__main__.NodeHashEntry object at 0x0000015BE4E13E48>,
<__main__.NodeHashEntry object at 0x0000015BE67F0108>,
<__main__.NodeHashEntry object at 0x0000015BE65B5F08>]
Diese vier Objekte haben Variablen, die als Hash bzw. Farbe bezeichnet werden.
Drucken Sie Hash und Farbe von 4 Objekten
for i in range(4):
print(a.node_hash[i].hash, a.node_hash[i].color)
Antworten
1 2
1 2
1 2
1 2
uct_node uct_node ist ein Array. Jedes Element ist eine Instanz der UctNode-Klasse, und jedes Element hat die Anzahl der Besuche auf dem Knoten, die Gesamtgewinnrate, die Anzahl der untergeordneten Knoten, die Verschiebung des untergeordneten Knotens, den Index des untergeordneten Knotens, die Anzahl der Besuche auf dem untergeordneten Knoten und die Gewinnrate des untergeordneten Knotens. Es enthält Informationen zu Gesamtsummen, prognostizierten Gewinnraten für Richtliniennetzwerke, prognostizierten Gewinnraten für Wertnetzwerke und ausgewerteten Flags. Beim Generieren ist self.uct_node = [UctNode () für _ in range (UCT_HASH_SIZE)].
search_empty_index() Eine Methode zum Suchen nach nicht verwendeten Indizes. Die Argumente sind Hash, Turn und Anstrengung.
Es generiert einen Index aus dem Hash und prüft, ob das Element an diesem Index im Array node_hash nicht verwendet wird. Wenn es nicht verwendet wird, werden dem Element Hash, Turn und Aufwand des Arguments zugewiesen, und ein Flag, das angibt, dass das Element verwendet wird, wird gesetzt. Wenn es verwendet wurde, fügen Sie dem Index 1 hinzu und machen Sie dasselbe, bis alle Indizes umgangen sind. Wenn nach einer Runde kein unbenutzter Index vorhanden ist, wird UCT_HASH_SIZE zurückgegeben.
Wenn beispielsweise UCT_HASH_SIZE = 4096 ist und ein nicht verwendeter Index vorhanden ist, werden dem ersten Trefferelement unter den 4096 Elementen von node_hash [0] bis node_hash [4095] Hash, Turn und Anzahl der Züge zugewiesen, und ein Flag wird auf Ende gesetzt. Wenn kein nicht verwendeter Index vorhanden ist, wird der Wert 4096 zurückgegeben und der Prozess beendet.
find_same_hash_index() Eine Methode, um den der Situation entsprechenden Index zu finden. Die Argumente sind Hash, Turn und Anstrengung.
Es generiert einen Index aus dem Hash und prüft, ob das Element an diesem Index im Array node_hash nicht verwendet wird. Gibt UCT_HASH_SIZE zurück, wenn es nicht verwendet wird. Wenn der Hash, die Drehung und der Aufwand des Elements während der Verwendung mit dem Argument übereinstimmen, wird der Index zurückgegeben. Machen Sie dasselbe, bis Sie alle Indizes umgangen haben, während Sie dem Index 1 hinzufügen. Wenn nach einer Runde kein Index vorhanden ist, der mit dem Argument übereinstimmt, wird UCT_HASH_SIZE zurückgegeben.
Wenn beispielsweise UCT_HASH_SIZE = 4096 ist und ein Element vorhanden ist, das dem Hash, der Wendung und dem Aufwand des Arguments entspricht, wird der Index dieses Elements (der einer von 4096 von 0 bis 4095 ist) zurückgegeben und der Prozess beendet. Wenn kein übereinstimmendes Element vorhanden ist, wird der Wert 4096 zurückgegeben und der Prozess beendet.
Sowohl search_empty_index () als auch find_same_hash_index () befinden sich in derselben Instanz wie das Array node_hash. Verwenden Sie daher bei Verwendung self. Instance name.search_empty_index (). Beachten Sie, dass der Instanzname in diesem Buch node_hash lautet und mit demselben Namen wie node_hash im Member-Array zu verwechseln scheint.
Recommended Posts