6.2 M´odulo de Busca
6.2.3 Tabela de Transposi¸c˜ao
6.2.3.3 Colis˜ oes Conflitos de Endere¸cos para Estados do Tabuleiro do Jogo
A TT do D-MA-Draughts trata dois tipos de erros identificados por Zobrist [73]. O primeiro tipo de erro, chamado erro tipo 1, ocorre quando dois estados distintos do tabuleiro do jogo de damas s˜ao mapeados na mesma chave hash. Caso o erro n˜ao seja detectado, pode acontecer de predi¸c˜oes incorretas serem retornadas pela rotina de busca ao consultar a TT.
Para controlar os erros tipo 1, s˜ao usadas as duas chaves hash da estrutura ENTRY : hashvalue e checksum. Estas chaves s˜ao geradas utilizando n´umeros aleat´orios independentes. Se dois estados diferentes do tabuleiro produzirem a mesma chave hash, hashvalue, ´e improv´avel que produzam, tamb´em, o mesmo valor para checksum. A segunda chave hash n˜ao precisa ser, necessariamente, do mesmo tamanho da primeira. Por´em, quanto maior o n´umero de bits presentes nas chaves hash, menor a probabilidade de ocorrˆencia dos erros tipo 1. A primeira chave, hashvalue, cont´em 64 bits e a segunda, checksum, possui 32 bits.
O erro tipo 2 ocorre em virtude dos recursos finitos de mem´oria existentes, quando dois estados distintos do tabuleiro, apesar de serem mapeados em chaves hash diferentes, s˜ao direcionados para o mesmo endere¸co na TT. Para resolver este problema, o D-MA-Draughts utiliza dois esquemas de substitui¸c˜ao, um chamado Deep e outro chamado New. Esses esquemas foram escolhidos entre os sete estudados por Breuker em [74], [75]. A escolha desses dois esquemas foi feita baseada no jogador Chinook [25], [4]. O Chinook utiliza uma TT de dois n´ıveis em que cada entrada da
6.2. M´odulo de Busca 91 tabela (endere¸co) pode conter informa¸c˜oes relativas a at´e 2 estados do tabuleiro (um estado em cada n´ıvel). Experimentos no Chinook mostram que tal estrutura para a TT reduz o tamanho da ´
arvore de busca em at´e 10% [72].
Caso um endere¸co da TT armazene informa¸c˜oes sobre o mesmo estado do tabuleiro S0 em seus
dois n´ıveis, isso indica que as informa¸c˜oes sobre S0 do primeiro n´ıvel teriam sido obtidas a partir
de uma busca mais profunda que aquela a partir da qual foram obtidas as informa¸c˜oes sobre S0
armazenadas no segundo n´ıvel. Caso um endere¸co da TT armazene em seus dois n´ıveis informa¸c˜oes sobre dois estados distintos do tabuleiro, isso indica que o segundo n´ıvel foi utilizado para resolver um problema de colis˜ao. Em termos pr´aticos, o primeiro n´ıvel armazena os dados de maior precis˜ao enquanto o segundo, age como um “cache” temporal.
Assim sendo, a tabela TTABLE cont´em 2 vetores e1 e e2, do tipo ENTRY, representando os 2 n´ıveis da TT, e cada esquema de substitui¸c˜ao est´a associado a um dos dois vetores de TTABLE, como mostrado abaixo:
• Deep: o esquema de substitui¸c˜ao Deep armazena no primeiro vetor de TTABLE (ENTRY * e1 ) o estado com a mais profunda sub-´arvore, ou seja, se em uma posi¸c˜ao da TT j´a houver armazenado um estado igual ao estado corrente a ser armazenado, ser´a mantido na TT o estado com maior profundidade. O conceito por tr´as desse esquema ´e que uma sub-´arvore mais profunda, normalmente, cont´em mais n´os do que uma sub-´arvore mais rasa, e tal fato faz com que o algoritmo de busca economize um tempo maior quando ´e poupado de pesquisar uma sub-´arvore mais profunda;
• New : o esquema de substitui¸c˜ao New substitui o conte´udo de uma posi¸c˜ao na tabela quando uma colis˜ao ocorre. Tal conceito ´e baseado na observa¸c˜ao de que a maioria das transposi¸c˜oes ocorrem localmente, ou seja, dentro de pequenas sub-´arvores da ´arvore de busca global. O segundo vetor da TT TTABLE (ENTRY * e2 ) utiliza esse esquema de substitui¸c˜ao.
Foi poss´ıvel constatar que, utilizando os dois esquemas de substitui¸c˜ao (deep e new ), os erros tipo 2 foram totalmente controlados no D-MA-Draughts [18].
A seguir ´e apresentada a estrutura da TT bem como o modo como os esquemas deep e new s˜ao usados para resolver colis˜oes.
6.2.3.4 Estrutura TTABLE - Manipula¸c˜ao de Dados na Tabela de Transposi¸c˜ao com Tratamento de Colis˜oes
A TT utilizada pelo D-MA-Draughts ´e uma estrutura do tipo TTABLE composta por dois vetores, (e1 e e2 com elementos do tipo ENTRY ). Al´em disso, existe um m´etodo para armazenar novas entradas e um m´etodo para ler as entradas j´a existentes na tabela.
Pseudoc´odigo 15 Estrutura de TTABLE class TTABLE{ int tableSize; ENTRY* e1; ENTRY* e2; StoreEntry (...); GetEntry (...); }
O campo tableSize define o espa¸co alocado na TT para manipula¸c˜ao de registros do tipo ENTRY na mem´oria. ´E importante notar que TTABLE utiliza tanta mem´oria quanto houver dispon´ıvel e, claro, quanto mais mem´oria, melhor o desempenho da TT.
Cada par de vetor e1e e2´e formado por elementos do tipo ENTRY e disponibiliza, em mem´oria, os
dados relevantes de at´e dois estados do tabuleiro do jogo de damas. Tais dados s˜ao obtidos durante o procedimento de busca e os detalhes de como s˜ao armazenados e recuperados s˜ao definidos pelos m´etodos StoreEntry(...) e GetEntry(...) apresentados nas express˜oes 6.1 e 6.2, respectivamente.
StoreEntry(newEntry); (6.1)
O m´etodo StoreEntry(newEntry), apresentado na express˜ao 6.1, representa o m´etodo de armaze- namento de informa¸c˜oes sobre um dado estado do tabuleiro na TT. Para tanto, o m´etodo recebe um elemento newEntry do tipo ENTRY e tenta armazen´a-lo em TTABLE. O m´etodo localiza o endere¸co E1 em TTABLE associado ao parˆametro hashvalue de newEntry. Considerando o
endere¸co E1, trˆes situa¸c˜oes podem ocorrer:
1. E1 encontra-se vazio: devido `a inexistˆencia de informa¸c˜ao gravada no endere¸co E1, basta
armazenar newEntry no primeiro vetor e1 do endere¸co E1;
2. E1 possui o mesmo elemento passado como parˆametro: o endere¸co E1 j´a possui informa¸c˜ao
e o valor da primeira chave do primeiro vetor e1 de E1´e exatamente igual ao valor hashvalue
de newEntry. Assim, caso a profundidade de busca do elemento newEntry seja maior que a profundidade de busca do elemento e1 presente em E1, transfere-se o elemento presente
no vetor e1 para a mesma posi¸c˜ao no vetor e2 e sobrescreve-se a informa¸c˜ao presente em e1
com a informa¸c˜ao de newEntry. Caso a profundidade de busca do elemento newEntry seja menor, mant´em-se a informa¸c˜ao presente em e1 e perdem-se as informa¸c˜oes de newEntry;
3. E1 possui elemento diferente: o endere¸co E1 j´a possui informa¸c˜ao e o valor da primeira
chave do primeiro vetor e1 de E1 ´e diferente do valor hashvalue de newEntry. Nesse caso,
StoreEntry resolve a colis˜ao mantendo a informa¸c˜ao de e1 e gravando o valor de newEntry
em e2 independentemente do conte´udo do segundo vetor e2;
6.2. M´odulo de Busca 93 O m´etodo GetEntry(...) da express˜ao 6.2 visa recuperar informa¸c˜oes sobre um dado estado do tabuleiro eventualmente armazenado na TT. Para tanto, ele recebe 4 parˆametros de entrada associados ao estado: n representa o pr´oprio estado; hashvalue representa a primeira chave hash associada ao estado; checksum representa a segunda chave hash associada ao estado; e pdepth especifica a profundidade m´ınima de busca desejada (que coincide com a profundidade corrente de busca).
A partir da´ı, GetEntry localiza o endere¸co E1 associado ao parˆametro hashvalue na TT e verifica
se existe algum elemento do tipo ENTRY gravado no primeiro vetor e1 de E1. Caso exista, verifica
se a primeira chave hash associada ao elemento de e1´e igual a hashvalue. Caso afirmativo, verifica
se a segunda chave hash associada ao elemento de e1 ´e igual a checksum. Caso positivo, verifica
se a profundidade de busca associada ao elemento de e1 ´e maior ou igual a pdepth. Caso isso
tamb´em se confirme, o m´etodo GetEntry ter´a obtido sucesso em sua busca e ter´a encontrado, em TTABLE, as informa¸c˜oes desejadas para o tabuleiro n. Assim, o algoritmo de busca pode utilizar os dados armazenados em mem´oria ao inv´es de continuar expandido a ´arvore de busca do jogo. Caso n˜ao se tenha obtido ˆexito com o primeiro vetor e1, o mesmo processo ´e realizado, novamente,
para o segundo vetor e2 de E1.
Em resumo, havendo uma TT como a TTABLE, sempre que um determinado estado do tabuleiro for apresentado ao algoritmo de busca, ele verificar´a, primeiro, a TT para ver se aquele estado do tabuleiro j´a foi analisado. Caso afirmativo e o conjunto de restri¸c˜oes (apresentado na se¸c˜ao 6.2.3.6) tamb´em seja satisfeito, a informa¸c˜ao armazenada na mem´oria ser´a utilizada diretamente. Caso contr´ario, a ´arvore do jogo ser´a expandida pela rotina de busca e uma nova entrada ser´a gravada na TT.
6.2.3.5 Armazenamento dos Estados do Tabuleiro na Tabela de Transposi¸c˜ao a par-