TProcuraAdversa
Algoritmos de procura adversa
Loading...
Searching...
No Matches
TProcuraConstrutiva.h
Go to the documentation of this file.
1#pragma once
2
3#define _CRT_SECURE_NO_WARNINGS
4
5#include "TVector.h"
6#include <stdint.h>
7#include <time.h>
8#include <limits.h>
9
10// número de elementos na hashtable com perdas
11#define TAMANHO_HASHTABLE 1000000
12// tamanho máximo de um objecto, em unidades de 64 bits
13#define OBJETO_HASHTABLE 5
14// código para número não lido (não deve ser utilizado num parâmetro)
15#define NAO_LIDO -1000000
16
18
25
60
61
79
99
114
120enum EOperacao { gravar = 0, ler };
121
144typedef struct SParametro {
146 const char* nome;
148 int valor;
150 int min;
152 int max;
154 const char* descricao;
157 const char** nomeValores;
159
160
172
193{
194public:
196 virtual ~TProcuraConstrutiva(void) {}
197
208 int custo;
211
// Fim do grupo VariaveisEstado
213
214
248 virtual TNo Duplicar(void) = 0;
249
276 virtual void Copiar(TNo objecto) { }
277
307 virtual void SolucaoVazia(void) { custo = 0; }
308
346 virtual void Sucessores(TVector<TNo>& sucessores);
347
370 virtual bool SolucaoCompleta(void) { return false; }
371
412 virtual void TesteManual(const char* nome);
413
// Fim do grupo RedefinicaoMandatoria
415
452 virtual const char* Acao(TNo sucessor) { return "ação inválida"; }
453
493 virtual void Codifica(uint64_t estado[OBJETO_HASHTABLE]);
494
533 virtual int Heuristica(void);
534
569 virtual void Debug(void);
570
616 virtual void ResetParametros();
617
618
// Fim do grupo RedefinicaoSugerida
620
639 virtual bool Acao(const char* acao);
640
660 virtual bool Parar(void) {
662 }
663
682 virtual bool Distinto(TNo estado) { return true; }
683
713 virtual void MostrarSolucao(void) { MostrarCaminho(); }
714
726 virtual int ExecutaAlgoritmo();
727
747 virtual void TesteEmpirico(int inicio = -1, int fim = -1, bool mostrarSolucoes = true);
748
// Fim do grupo RedefinicaoOpcional
750
751
776 int LarguraPrimeiro(int limite = 0);
777
778
792 int CustoUniforme(int limite = 0);
793
807 int ProfundidadePrimeiro(int nivel = 0);
808
// Fim do grupo ProcurasCegas
810
830 int MelhorPrimeiro(int nivel = 0);
831
853 int AStar(int limite = 0);
854
872 int IDAStar(int upperBound = 0);
873
891 int BranchAndBound(int upperBound = 0);
892
// Fim do grupo ProcurasInformadas
894
903 static TParametro instancia;
910 static int geracoes;
912 static int expansoes;
914 static int avaliacoes;
918 static bool memoriaEsgotada;
920 static TNo solucao;
922 static int lowerBound;
925
929 static int espacosRamo;
931 static clock_t instanteFinal;
932
// Fim do grupo VariaveisGlobais
934
935 // LimparEstatisticas: Chamar antes da corrida
936 void LimparEstatisticas(clock_t &inicio);
937 // FinalizarCorrida: Chamar após a corrida
938 void FinalizarCorrida(clock_t inicio);
939
940 int LowerBound() { return custo + parametro[pesoAStar].valor * heuristica / 100; } // f(n) = g(n) + W h(n)
941 static void LibertarVector(TVector<TNo>& vector, int excepto = -1, int maiorQue = -1);
942
943 // Chamar sempre que se quer uma nova linha com a árvore em baixo
944 void NovaLinha(bool tudo = true);
945
946 // ler um número, ou retorna NAO_LIDO
947 static int NovoValor(const char* prompt);
948
949protected:
950
951 // Métodos para visualizar a procura
952
953 // Método para ser chamado antes de analisar cada sucessor
954 void DebugExpansao(int sucessor, int sucessores, bool duplo = false);
955 // Método para ser chamado quando não há sucessores ou há um corte de profundidade
956 void DebugCorte(int sucessores = -1, bool duplo = false);
957 // Encontrou uma solução
958 void DebugSolucao(bool continuar = false);
959 // Informação de debug na chamada ao método recursivo
960 void DebugChamada(void);
961 // Passo no algoritmo em largura
962 void DebugPasso(void);
963 // Mostrar sucessores
964 void DebugSucessores(TVector<TNo>& sucessores);
965 // uma nova iteração de um algoritmo iterativo
966 void DebugIteracao(int iteracao);
967 // informação geral sobre o estado
968 void DebugEstado(int id = -1, int pai = -1);
969 void DebugRamo(char ramo, char folha);
970
971 // metodos internos
972 int ObjetivoAlcancado(int item, TVector<TNo>& lista);
973 int ObjetivoAlcancado(TNo estado, bool completa = true);
974 int SolucaoEncontrada(bool continuar = false);
975 void CalculaCaminho(bool completa = true); // coloca o caminho desde o estado objetivo
976 void VerificaLimites(int limite, int porProcessar, TVector<TNo>& sucessores);
977 void CalcularHeuristicas(TVector<TNo>& sucessores, TVector<int>* id = NULL, bool sortLB = false);
978 int SolucaoParcial(int i, TVector<TNo>& sucessores);
979 void ExplorarSucessores(bool jogo=false);
980 void EditarParametros();
981 void EditarConfiguracoes();
982 void MostrarConfiguracoes(int detalhe, int atual = -1);
983 void SolicitaInstancia();
984 bool TempoExcedido() { return instanteFinal < clock(); }
986 return parametro[limiteGeracoes].valor > 0 && parametro[limiteGeracoes].valor < geracoes;
987 }
989 return parametro[limiteExpansoes].valor > 0 && parametro[limiteExpansoes].valor < expansoes;
990 }
992 return parametro[limiteAvaliacoes].valor > 0 && parametro[limiteAvaliacoes].valor < avaliacoes;
993 }
994 void MostrarCaminho();
995 void MostraParametros(int detalhe = 1, TVector<int>* idParametros = NULL);
996 void MostraRelatorio(TVector<TResultado>& resultados);
997 int Dominio(int& variavel, int min = INT_MIN, int max = INT_MAX);
998 void ConfiguracaoAtual(TVector<int>& parametros, int operacao); // gravar (ou ler) a configuração atual
999 int MelhorResultado(TResultado base, TResultado alternativa);
1000 void CalculaTorneio(TVector<TResultado>& resultados);
1001 void MostrarTorneio(TVector<TVector<int>>& torneio, bool jogo=false);
1002 void BarraTorneio(bool nomes);
1003 void ExtrairConfiguracao(TVector<TResultado>& resultados, TVector<TResultado>& extracao, int configuracao);
1004
1005 // variáveis da hashtable com perdas, se existir uma colisão, substitui
1006 static uint64_t elementosHT[TAMANHO_HASHTABLE][OBJETO_HASHTABLE]; // hashtable
1007 static int custoHT[TAMANHO_HASHTABLE]; // hashtable / custo do estado que foi gerado
1008 static uint64_t estadoCodHT[OBJETO_HASHTABLE]; // elemento codificado
1009 static int colocadosHT; // número de elementos colocados na HT
1010 unsigned int Hash(); // retorna um valor hash do estado atual, após codificado
1011 void LimparHT();
1012 // caso o estado não exista, retorna falso e insere para que não seja gerado novamente
1013 // caso exista um elemento, mas gerado com um custo mais alto, considerar que não existe ainda
1014 // se existe retorna true
1015 bool ExisteHT();
1016 virtual void SubstituirHT(int indice);
1017};
1018
1019// estrutura para índice a fazer a função de lista (em vetor), de modo a reduzir custos de inserção ordenada
1020// utilizado em CListaNo
1021typedef struct SIndice {
1022 TNo estado; // elemento na lista
1023 int prox; // próximo elemento da lista, pela ordem mantida (de custo)
1024 int proxDistinto; // próximo elemento da lista com custo distinto
1026
1027// classe para manter lista ordenada de estados (CustoUniforme e AStar)
1029private:
1030 int limite; // tamanho da lista, se !=0 --- tamanho vai até ao dobro, após o qual é limpa para metade dos elementos
1031 TVector<TIndice> indice; // índice com a estrutura de lista
1032 TVector<int> livre; // índices da lista apagados, que estão livres e podem ser utilizados
1033 bool completa; // se verdade, nunca foi limpa, pelo que a lista é completa
1034public:
1035 CListaNo(int limite = 0) :
1036 limite(limite),
1037 indice(2*limite),
1038 livre(limite),
1039 completa(true),
1040 atual(0) {}
1041 ~CListaNo();
1042
1043 // elemento a ser processado
1044 // (anteriores a este, excepto o primeiro, podem ser apagados, quando há falta de espaço)
1045 int atual;
1046
1047 bool Completa() { return completa; }
1048
1049 // retorna o valor de um elemento
1050 int Valor(int i) {
1051 TNo estado;
1052 if ((estado = Estado(i)) != NULL)
1053 return estado->LowerBound();
1054 return INT_MAX;
1055 }
1056
1057 // retorna o próximo elemento, ou -1 se não há mais
1058 int Proximo(int i = -1) {
1059 if (i < 0)
1060 return indice[atual].prox;
1061 if(i>=0 && i<indice.Count())
1062 return indice[i].prox;
1063 return -1;
1064 }
1065 // este passo é crítico para poder inserir rapido numa lista ordenada com muitos elementos iguais
1066 int ProximoDistinto(int i = -1) {
1067 if (i < 0)
1068 return indice[atual].proxDistinto;
1069 if (i >= 0 && i < indice.Count())
1070 return indice[i].proxDistinto;
1071 return -1;
1072 }
1073 // retorna o estado deste elemento
1074 TNo Estado(int i = -1) {
1075 if (i < 0)
1076 return indice[atual].estado;
1077 if (i >= 0 && i < indice.Count())
1078 return indice[i].estado;
1079 return NULL;
1080 }
1081
1082 int Inserir(TNo elemento, int id = 0); // insere por ordem de LB, retorna o primeiro elemento com o mesmo valor
1083 void Inserir(TVector<TNo>& elementos); // inserir todos os elementos por ordem (não alterar atual)
1084
1085private:
1086 int NovoElemento(TNo elemento); // retorna o índice onde foi inserido
1087 void LibertarLista();
1088 void LibertarSeguinte(int id);
1089
1090};
EOperacao
Define o sentido da operação de entrada/saída de dados.
EParametrosConstrutiva
Identifica um parâmetro específico no código.
@ limite
Valor dependente do algoritmo. Exemplo: Profundidade limitada.
@ ruidoHeur
Ruído a adicionar à heurística para testes de robustez.
@ pesoAStar
Peso aplicado à heuristica, na soma com o custo para calculo do lower bound.
@ estadosRepetidos
Forma de lidar com estados repetidos (ignorá-los, ascendentes, gerados).
@ limiteAvaliacoes
Número máximo de avaliações (0 significa sem limite).
@ verAcoes
Mostra estado a cada K ações. Se 1, mostra sempre estados e nunca ações.
@ parametrosConstrutivas
Marcador para permitir a extensão do enum em subclasses.
@ seed
Semente aleatória para inicializar a sequência de números pseudo-aleatórios.
@ nivelDebug
Nível de debug, de reduzido a completo.
@ limiteTempo
Tempo limite em segundos.
@ limiteGeracoes
Número máximo de gerações (0 significa sem limite).
@ baralharSuc
Baralhar os sucessores ao expandir.
@ limiteExpansoes
Número máximo de expansões (0 significa sem limite).
@ algoritmo
Algoritmo base a executar.
struct SResultado TResultado
TProcuraConstrutiva * TNo
Representa um nó na árvore de busca, apontando para um estado.
EEstadosRepetidos
Enumerado com os valores possíveis do parametro estadosRepetidos.
@ ascendentes
estados são comparados com ascendentes, e se forem repetidos são removidos
@ gerados
estados são comparados com todos os gerados, e se forem repetidos são removidos
@ ignorados
ignorados os estados gerados repetidos
EAlgoritmo
Algoritmos disponíveis para procura construtiva.
@ melhorPrimeiro
Executa a procura melhor primeiro, algoritmo informado.
@ custoUniforme
Executa a procura por custo uniforme, algoritmo cego.
@ larguraPrimeiro
Executa a procura em largura primeiro, algoritmo cego.
@ aStar
Executa a procura A*, algoritmo informado.
@ idAStar
Executa a procura IDA*, algoritmo informado.
@ profundidadePrimeiro
Executa a procura em profundidade primeiro, algoritmo cego.
@ branchAndBound
Executa o algoritmo Branch-and-Bound, um algoritmo informado.
#define TAMANHO_HASHTABLE
ENivelDebug
Níveis de detalhamento para debug.
@ detalhe
Debug detalhada sobre estados e decisões.
@ atividade
Apenas eventos principais.
@ completo
Mostra toda a execução detalhadamente.
@ passos
Exibe passos intermediários.
@ nada
Sem informações de debug.
struct SParametro TParametro
Estrutura para registo de um parâmetro.
struct SIndice TIndice
#define OBJETO_HASHTABLE
TNo Estado(int i=-1)
CListaNo(int limite=0)
int Inserir(TNo elemento, int id=0)
int ProximoDistinto(int i=-1)
int Proximo(int i=-1)
Representa um estado no espaço de estados.
void DebugCorte(int sucessores=-1, bool duplo=false)
void DebugSucessores(TVector< TNo > &sucessores)
void MostrarTorneio(TVector< TVector< int > > &torneio, bool jogo=false)
void DebugRamo(char ramo, char folha)
int SolucaoEncontrada(bool continuar=false)
void DebugEstado(int id=-1, int pai=-1)
void DebugSolucao(bool continuar=false)
static int NovoValor(const char *prompt)
void ConfiguracaoAtual(TVector< int > &parametros, int operacao)
void CalculaTorneio(TVector< TResultado > &resultados)
static uint64_t elementosHT[TAMANHO_HASHTABLE][OBJETO_HASHTABLE]
void CalcularHeuristicas(TVector< TNo > &sucessores, TVector< int > *id=NULL, bool sortLB=false)
int SolucaoParcial(int i, TVector< TNo > &sucessores)
int Dominio(int &variavel, int min=INT_MIN, int max=INT_MAX)
void NovaLinha(bool tudo=true)
int ObjetivoAlcancado(int item, TVector< TNo > &lista)
int MelhorResultado(TResultado base, TResultado alternativa)
static void LibertarVector(TVector< TNo > &vector, int excepto=-1, int maiorQue=-1)
virtual void SubstituirHT(int indice)
void MostrarConfiguracoes(int detalhe, int atual=-1)
virtual ~TProcuraConstrutiva(void)
void CalculaCaminho(bool completa=true)
void ExplorarSucessores(bool jogo=false)
void MostraRelatorio(TVector< TResultado > &resultados)
void DebugExpansao(int sucessor, int sucessores, bool duplo=false)
void ExtrairConfiguracao(TVector< TResultado > &resultados, TVector< TResultado > &extracao, int configuracao)
void LimparEstatisticas(clock_t &inicio)
void DebugIteracao(int iteracao)
void VerificaLimites(int limite, int porProcessar, TVector< TNo > &sucessores)
void FinalizarCorrida(clock_t inicio)
static int custoHT[TAMANHO_HASHTABLE]
void MostraParametros(int detalhe=1, TVector< int > *idParametros=NULL)
static uint64_t estadoCodHT[OBJETO_HASHTABLE]
int Count()
Definition TVector.h:70
int CustoUniforme(int limite=0)
Executa a procura por custo uniforme, algoritmo cego.
int ProfundidadePrimeiro(int nivel=0)
Executa a procura em profundidade primeiro, algoritmo cego.
int LarguraPrimeiro(int limite=0)
Executa a procura em largura primeiro, algoritmo cego.
int AStar(int limite=0)
Executa a procura A*, algoritmo informado.
int IDAStar(int upperBound=0)
Executa a procura IDA*, algoritmo informado.
int MelhorPrimeiro(int nivel=0)
Executa a procura melhor primeiro, algoritmo informado.
int BranchAndBound(int upperBound=0)
Executa o algoritmo Branch-and-Bound, um algoritmo informado.
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 TesteManual(const char *nome)
Inicializa a interação com o utilizador.
virtual void Copiar(TNo objecto)
Fica com uma cópia do objecto.
virtual TNo Duplicar(void)=0
Cria um objecto que é uma cópia deste.
virtual bool Distinto(TNo estado)
Verifica se o estado actual distinto do fornecido.
virtual void MostrarSolucao(void)
Mostrar solução, seja um caminho ou o próprio estado.
virtual 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.
virtual int ExecutaAlgoritmo()
Executa o algoritmo com os parametros atuais.
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 Codifica(uint64_t estado[OBJETO_HASHTABLE])
Codifica o estado para um vetor de inteiros de 64 bits.
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.
TNo pai
Ponteiro para o estado pai, na árvore de procura.
static int expansoes
Número total de expansões realizadas na procura.
static int lowerBound
Valor mínimo que a solução pode apresentar, obtido pela procura.
static int avaliacoes
Número total de avaliações realizadas na procura.
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
static int tamanhoCodificado
Número de inteiros de 64 bits utilizados para codificar um objeto (≤ OBJETO_HASHTABLE).
static int geracoes
Número total de gerações realizadas na procura.
static TVector< TNo > caminho
Solução retornada pela procura (os estados devem ser libertados).
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().
Estrutura para registo de um parâmetro.
const char * descricao
descrição do parametro, opcional
int valor
valor do parametro
const char * nome
nome do parametro, opcional mas aconselhado nos parâmetros específicos
int max
valor máximo que o parametro pode tomar
const char ** nomeValores
Nome associado a cada valor do parâmetro, útil para variáveis categóricas.
int min
valor mínimo que o parametro pode tomar