28 static const char* nomesAlgoritmos[] = {
"MiniMax",
"MiniMax alfa/beta" };
33 parametro[
algoritmo] = {
"Algoritmo",2,1,2,
"Seleção do algoritmo de procura adversa base.", nomesAlgoritmos };
40 parametro.Add({
"Ordenar",2,0,2,
"0 não ordena sucessores, 1 ordena por heurística, 2 usa o melhor valor de procuras anteriores.",NULL });
41 parametro.Add({
"PodaHeuristica",0,0,1000,
"0 não existe poda, caso contrário é o número máximo de sucessores a considerar (tem de se ordenar sucessores).",NULL });
42 parametro.Add({
"PodaCega",0,0,10000,
"Igual a PodaHeuristica, mas é efetuado de forma aleátoria, sem calcular a heurística. Utilizar um valor sempre maior que Poda. ",NULL });
54 if (nivel == 1 ||
Parar()) {
66 if (sucessores.
Count() == 0)
72 int resultado = 0, melhor = -1;
74 for (
int i = 0; i < sucessores.
Count(); i++) {
80 valorConhecido.
nivel >= nivel)
82 valor = valorConhecido.
valor;
87 valorConhecido = { valor, nivel,
exato };
92 if (i == 0 || (
minimizar ? resultado > valor : resultado < valor)) {
97 printf(
"(%d)", resultado);
142 delete sucessores[id];
143 sucessores[id] = sucessores.
Last();
160 manterSuc.
Add(sucessores[
id[i]]);
162 delete sucessores[
id[i]];
163 sucessores = manterSuc;
165 for (
int i = 0; i < sucessores.
Count(); i++)
171 for (
int i = 0; i < sucessores.
Count(); i++)
177 int resultado = 0, resOK = 0, nivel = 0;
185 if (!
Parar() || nivel == 0) {
194 printf(
"\n%d: %s (%d)", nivel,
Acao(solOK), resultado);
211 int pontos = 0, peso = 1;
220 if (maxAmeaca > qMin.
Count())
221 peso <<= (maxAmeaca - qMin.
Count());
222 for (
int i = qMin.
Count() - 1, peso = 1; i >= 0; i--) {
223 pontos -= qMin[i] * peso;
228 if (maxAmeaca > qMax.
Count())
229 peso <<= (maxAmeaca - qMin.
Count());
230 for (
int i = qMax.
Count() - 1, peso = 1; i >= 0; i--) {
231 pontos += qMax[i] * peso;
236 return infinito * (2 / (1 + exp(-0.01 * pontos)) - 1);
263 printf(
" %d", resultado);
275 if (nivel == 1 ||
Parar()) {
285 if (sucessores.
Count() == 0)
291 int resultado = 0, melhor = -1;
292 for (
int i = 0; i < sucessores.
Count(); i++) {
298 Utilizavel(valorConhecido, nivel, alfa, beta))
300 valor = valorConhecido.
valor;
304 valor = ((
TProcuraAdversa*)sucessores[
id[i]])->MiniMaxAlfaBeta(nivel - 1, alfa, beta);
305 valorConhecido = { valor, nivel,
exato };
308 else if (valor >= beta)
314 if (i == 0 || (
minimizar ? resultado > valor : resultado < valor)) {
320 printf(
"(%d)", resultado);
324 if (i < sucessores.
Count() - 1) {
340 return valor.
nivel >= nivel &&
359 printf(
" alfa(%d)",alfa);
376 printf(
" beta(%d)",beta);
425 if (brancas != pretas) {
426 printf(
"\nMatch %d vs %d:", brancas + 1, pretas + 1);
428 int resultado = -1, njogada=0;
429 clock_t inicioCorrida;
437 inicioCorrida = clock();
440 tempoTotal[njogada % 2 == 0 ? brancas : pretas] += clock() - inicioCorrida;
444 if (mostrarSolucoes) {
448 (njogada % 2 == 0 ?
"Brancas" :
"Pretas"),
449 (njogada / 2) + 1, strAcao);
451 printf(
" f:%d ", resultado);
454 printf(
" %s", strAcao);
464 if (resultado != 0) {
467 inverter = (njogada % 2 == 0) &&
minimizar ||
470 torneio[brancas][pretas] += (resultado < 0 ? -1 : 1) * (inverter ? -1:1);
471 printf(
" Vitória %s", (inverter ? resultado < 0 : resultado > 0) ?
"Branca" :
"Preta");
479 printf(
"\nTempos: ");
480 for (
int i = 0; i < tempoTotal.
Count(); i++)
481 printf(
"%.3fs ", 1.0 * tempoTotal[i] / CLOCKS_PER_SEC);
498 printf(
" HT: reutilização %.2f vezes ", taxa);
521 unsigned int original =
Hash();
539 if (operacao ==
ler) {
@ podaHeuristica
permite cortar sucessores, mas calcula a heurística a todos, de modo a mantendo os melhores
@ podaCega
corta os sucessores, mesmo sem calcular a heurística, por ordem aleatória
@ ordenarSucessores
opção de ordenar sucessores por heurística, ou por último valor registado
@ upperbound
o valor foi afetado por um corte de alfa (ou seja, ele é no máximo esse valor, mas pode ser menor).
@ exato
o valor foi calculado sem cortes, ou seja, não sofreu influência de alfa ou beta;
@ lowerbound
o valor foi afetado por um corte de beta (ou seja, ele é pelo menos esse valor, mas pode ser maior);
@ limite
Valor dependente do algoritmo. Exemplo: Profundidade limitada.
@ estadosRepetidos
Forma de lidar com estados repetidos (ignorá-los, ascendentes, gerados).
@ verAcoes
Mostra estado a cada K ações. Se 1, mostra sempre estados e nunca ações.
@ seed
Semente aleatória para inicializar a sequência de números pseudo-aleatórios.
@ nivelDebug
Nível de debug, de reduzido a completo.
@ baralharSuc
Baralhar os sucessores ao expandir.
@ algoritmo
Algoritmo base a executar.
@ gerados
estados são comparados com todos os gerados, e se forem repetidos são removidos
@ ignorados
ignorados os estados gerados repetidos
#define TAMANHO_HASHTABLE
Representa um estado no espaço de estados.
int NoFolha(bool nivel)
fim da procura, por corte de nível (ou não haver sucessores), retornar heurística
int MaiorAmeaca(TVector< int > &qMin, TVector< int > &qMax, int maxAmeaca)
Utilitário para calculo de uma heurística standard em jogos simples.
void OrdenarSucessores(TVector< TNo > &sucessores, TVector< int > &id, int nivel)
int MiniMax(int nivel=4)
retorna o valor do estado actual, apos procura de profundidade nivel
static bool completo
controlo para indicar se a procura foi realizada de forma completa (c.c. foi cortada)
bool minimizar
o jogador actual deve minimizar o custo (ou maximizar caso tenha o valor falso)
int Heuristica(void)
chamar após calcular a heurística (grava o valor, dependendo da parametrização)
int MetodoIterativo(int alfaBeta)
iteração, aumentando o nível progressivamente
bool CorteAlfaBeta(int valor, int &alfa, int &beta)
verifica se há um corte alfa/beta, atualizando alfa e beta
bool ValorEstado(TValorEstado &valor, int operacao)
ler ou gravar o melhor valor conhecido
bool ExisteHeuritica(void)
void ResetParametros()
Método para inicializar os parâmetros (redefinir se forem adicionados parâmetros específicos)
void SubstituirHT(int indice)
static int reutilizadoAvaliacao
bool Utilizavel(TValorEstado &valor, int nivel, int alfa, int beta)
ver se o valor obtido é utilizável no contexto atual
static int infinito
valor de infinito (vitoria/derrota), omissao 1000
static int nivelOK
profundidade máxima no método iterativo
int MiniMaxAlfaBeta(int nivel=4, int alfa=-infinito, int beta=+infinito)
retorna o valor do estado actual, apos procura de profundidade nivel. Idêntico a MiniMax
static TValorEstado valorHT[TAMANHO_HASHTABLE]
void TesteEmpirico(int inicio=-1, int fim=-1, bool mostrarSolucoes=true)
Executa testes empíricos, em todas as configurações guardadas, nas instâncias selecionadas.
int ExecutaAlgoritmo()
Executa o algoritmo com os parametros atuais.
Representa um estado no espaço de estados.
void DebugCorte(int sucessores=-1, bool duplo=false)
void MostrarTorneio(TVector< TVector< int > > &torneio, bool jogo=false)
void ConfiguracaoAtual(TVector< int > ¶metros, int operacao)
static uint64_t elementosHT[TAMANHO_HASHTABLE][OBJETO_HASHTABLE]
void CalcularHeuristicas(TVector< TNo > &sucessores, TVector< int > *id=NULL, bool sortLB=false)
int Dominio(int &variavel, int min=INT_MIN, int max=INT_MAX)
void NovaLinha(bool tudo=true)
static void LibertarVector(TVector< TNo > &vector, int excepto=-1, int maiorQue=-1)
virtual void SubstituirHT(int indice)
void MostrarConfiguracoes(int detalhe, int atual=-1)
void DebugExpansao(int sucessor, int sucessores, bool duplo=false)
void LimparEstatisticas(clock_t &inicio)
void DebugIteracao(int iteracao)
static uint64_t estadoCodHT[OBJETO_HASHTABLE]
static unsigned int rand(int seq=0)
static void srand(unsigned int seed, int seq=0)
void Reset(Item const &i)
virtual void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
virtual bool SolucaoCompleta(void)
Verifica se o estado actual é objectivo (é uma solução completa)
virtual void SolucaoVazia(void)
Coloca o objecto no estado inicial da procura.
virtual void Copiar(TNo objecto)
Fica com uma cópia do objecto.
virtual bool Parar(void)
Verifica se a procura deve ser interrompida.
virtual int Heuristica(void)
Função para calcular quanto falta para o final, o valor da heurística.
virtual void Debug(void)
Mostra o estado no ecrã, para debug.
virtual void ResetParametros()
Inicializa os parametros.
virtual const char * Acao(TNo sucessor)
Retorna a ação (movimento, passo, jogada, lance, etc.) que gerou o sucessor.
int heuristica
Estimativa para o custo até um estado objetivo, se disponível.
int custo
Custo total acumulado desde o estado inicial.
static int lowerBound
Valor mínimo que a solução pode apresentar, obtido pela procura.
static int tamanhoCodificado
Número de inteiros de 64 bits utilizados para codificar um objeto (≤ OBJETO_HASHTABLE).
static TVector< TVector< int > > configuracoes
Conjuntos de configurações para teste empírico.
static TVector< TParametro > parametro
Parâmetros a serem utilizados na configuração atual.
static TVector< unsigned char > ramo
static TNo solucao
Estado objetivo encontrado, retornado pela procura (deve ser libertado).
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().
int valor
valor do parametro
int max
valor máximo que o parametro pode tomar
int min
valor mínimo que o parametro pode tomar
registo do valor de um estado, em procuras anteriores