52 {
"ALGORITMO", 1, 1, 1,
"Algoritmo base a executar.", {
"Algoritmo base"} },
53 {
"NIVEL_DEBUG", 0, 0, 4,
"Nível de debug, de reduzido a completo.",
54 {
"NADA",
"ATIVIDADE",
"PASSOS",
"DETALHE",
"COMPLETO" } },
55 {
"SEMENTE", 1, 1, 1000000000,
"Semente aleatória para inicializar a sequência de números pseudo-aleatórios." },
56 {
"LIMITE_TEMPO", 10, 1, 3600,
"Limite de tempo em segundos. " },
57 {
"LIMITE_ITERACOES", 0, 0, 1000000000,
"Limite de número de iterações (0 não há limite). " }
62 {
"Resultado",
"Resultado do algoritmo, interpretado conforme o algoritmo (sucesso/insucesso, custo, qualidade, valor, etc.).",
IND_RESULTADO },
63 {
"Tempo(ms)",
"Tempo em milissegundos da execução (medida de esforço computacional).",
IND_TEMPO },
64 {
"Iterações",
"Iterações do algoritmo, interpretadas conforme o algoritmo (medida de esforço independente do hardware).",
IND_ITERACOES }
88 Debug(
ATIVIDADE,
false,
"\nTProcura::Debug() método não redefinido.");
111 printf(
"\n%s", *nome);
116 "┌─ %-2sMenu ─────────┬────────────────┬─────────────────────┬──────────────┐\n"
119 "└───────────────────┴────────────────┴─────────────────────┴──────────────┘",
120 Icon(EIcon::MENU), Icon(EIcon::INST), Icon(EIcon::EXP), Icon(EIcon::PARAM),
121 Icon(EIcon::SOL), Icon(EIcon::IND), Icon(EIcon::EXEC), Icon(EIcon::CONF),
136 printf(
"\n═╤═ %-2s Execução iniciada ═══", Icon(EIcon::EXEC));
143 printf(
"\n═╧═ %-2s Execução terminada %-2s %s ═══",
144 Icon(EIcon::FIM), Icon(EIcon::TEMPO),
154 default:
Mensagem(Icon(EIcon::IMP),
"Opção não definida.");
break;
181 if (
tokens.Count() < 3 || indice < 0)
189 "\n ├─ %-2sSoluções:%d %-2sInstâncias: %d.",
190 Icon(EIcon::SUCESSO),
solucoes.Count(),
211 "\n ├─ %-2s:%d %-2s %-2s %-2s %-2s %d",
212 Icon(EIcon::INST), inst,
213 Icon(EIcon::SUCESSO),
214 Icon(EIcon::VALOR), Icon(EIcon::IMP),
215 Icon(EIcon::TEMPO),
tempo);
224 "\n ├─ %-2s:%d %-2s %-2s %d",
225 Icon(EIcon::INST), inst,
227 Icon(EIcon::TEMPO),
tempo);
249 "\n ├─ %-2s:%d %-2s %-2s %d %-2s %d",
250 Icon(EIcon::INST), inst,
251 Icon(EIcon::SUCESSO),
253 Icon(EIcon::TEMPO),
tempo);
261 "\n ├─ %-2s:%d %-2s %-2s %d",
262 Icon(EIcon::INST), inst,
264 Icon(EIcon::TEMPO),
tempo);
299 if (
res.valor[0] > 0 &&
res.valor[1] == 0) {
301 if (
res.valor[2] >= 0)
303 if (
res.valor[3] >= 0)
308 if (
res.valor[1] > 0) {
316 "\n ├─ %-2sVálidas:%d %-2sInstâncias: %d.",
321 "\n ├─ %-2sMelhor:%d %-2sPior: %d.",
326 "\n ├─ %-2sTempo(ms):%d.",
348 "\n ├─ %-2s %.1f%% (%-2s %.1f%% %-2s %.1f%% %-2s %.1f%%)",
355 "\n ├─ %-2s %.1f%% (%-2s %.1f%% %-2s %.1f%%)",
369 for (
int i = 0;
i <
titulo.Count();
i++) {
370 unsigned int len = (
unsigned int)(
408 printf(
"│ %s", *
titulo[
i]);
break;
410 if (
i == 0) { printf(
"\n%*s└",
identacao,
"");
break; }
431 bool aberta,
int identacao,
const char* icon)
439 unsigned int len = (
unsigned int)(
477 printf(
"─ %s ─", *
titulo);
530 float f = (2 *
l - 1);
531 float c = (1 - (
f < 0 ? -
f :
f)) *
s;
533 float h60 =
h / 60.0f;
539 if (
h < 60) {
r =
c;
g =
x;
b = 0; }
540 else if (
h < 120) {
r =
x;
g =
c;
b = 0; }
541 else if (
h < 180) {
r = 0;
g =
c;
b =
x; }
542 else if (
h < 240) {
r = 0;
g =
x;
b =
c; }
543 else if (
h < 300) {
r =
x;
g = 0;
b =
c; }
544 else {
r =
c;
g = 0;
b =
x; }
546 printf(
"\x1b[%d;2;%d;%d;%dm", (
fundo ? 48 : 38),
547 (
int)((
r +
m) * 255), (
int)((
g +
m) * 255), (
int)((
b +
m) * 255));
570 for (
int i = 0;
i < nElementos;
i++) {
606 col += printf(
"%*s", (30 -
col),
"");
617 col += printf(
"%*s", (40 -
col),
"");
626 if (
i < nElementos - 1) {
637 col += printf(
" | ");
675 int opcao = 0, valor;
682 printf(
"\nParâmetro inativo.");
702 printf(
"Intervalo: %d a %d",
715 if (valor !=
NAO_LIDO || valor == 0)
829 " id / -id " COR_LEVE "- Seleciona configuração como atual ou apaga 'id'" COR_RESET,
830 " Pk = <conj.> " COR_LEVE "- Varia Pk na configuração atual (gera N configs)" COR_RESET,
831 " Pk = <conj.> x Pw = <conj.> " COR_LEVE "- produto externo (gera NxM configs)" COR_RESET,
869 if (
token[0] ==
'P') {
871 auto par =
token.tok(
"=");
872 if (par.Count() == 2) {
879 if (
valores.Last().Count() == 2) {
882 int valor =
valores.Last().Last();
887 if (
valores.Last().Count() <= 2)
892 else if (
token[0] ==
'x') {
920 for (
int i = 1;
i <
lista.Count();
i++)
952 printf(
"\n═╪═ Configurações ═══");
955 str.
printf(
"%-2s [%d]", Icon(EIcon::PARAM),
i + 1);
966 printf(
"\n═╧═══════════════════");
976 for (
int i = 0;
i <= 2;
i++)
984 printf(
"#%d",
valores.Count());
999 printf(
"\n\n═╤═ Instâncias ═══");
1004 printf(
"\n═╤═ %-2s Início do Teste (%-2s%d) ═══",
1005 Icon(EIcon::TESTE), Icon(EIcon::PROCESSO),
mpiID);
1012 printf(
"\n═╧═ %-2s Fim do Teste (%-2s%d %-2s%s) ═══",
1013 Icon(EIcon::FIM), Icon(EIcon::PROCESSO),
mpiID, Icon(EIcon::TEMPO),
1037 "\n ├─ %-2sTarefas:%d %-2sInstâncias: %d %-2sConfigurações: %d %-2sProcessos: %d.",
1041 Icon(EIcon::PROCESSO),
mpiCount) &&
1054 "\n ├─ %-2s%-15s %-2s%-5d %-2s%-5d %-2s%-5d %-2s%-5d",
1057 Icon(EIcon::INST), inst,
1058 Icon(EIcon::CONF), configuracao + 1,
1059 Icon(EIcon::PROCESSO),
mpiCount) &&
1086 "\n ├─ %-2s Ficheiro %s.csv gravado.\n"
1087 " │ %-2s Tempo real: %s",
1105 int dados[3] = { 0, 0, 0 };
1136 tarefas += { inst, configuracao };
1139 Debug(
ATIVIDADE,
false,
"\n ├─ %-2sTarefas:%d %-2sInstâncias: %d %-2sConfigurações: %d %-2sProcessos: %d.",
1140 Icon(EIcon::TAREFA),
tarefas.Count(),
1143 Icon(EIcon::PROCESSO),
trabalhador.Count() + 1) &&
1182 "\n ├─ %-2s%-15s %-2s%-5d %-2s%-5d %-2s%-5d %-2s%-5d %-2s ",
1185 Icon(EIcon::INST),
resultados.Last().instancia,
1186 Icon(EIcon::CONF),
resultados.Last().configuracao,
1190 printf(
"%" PRId64 " ", ind);
1223 "\n ├─ %-2s Ficheiro %s.csv gravado.\n"
1224 " │ %-2s Tempo real: %s",
1233 Debug(
ATIVIDADE,
false,
"\n │ %-2s Utilização:\n │ - Total: %.1f%%\n │ - Gestor: %.1f%%\n │ - Trabalhadores: %.1f%% ",
1244 int dados[3] = { 0, 0, 0 };
1317 mpiID == 0 &&
Debug(
COMPLETO,
false,
"%-2s%-2s", Icon(EIcon::SUCESSO), Icon(EIcon::IMP));
1324 printf(
"%-2s ", Icon(EIcon::IND));
1326 printf(
"%" PRId64 " ", ind);
1366 for (
int i = 2;
i <
argc;
i++) {
1453 "Uso: %s <instâncias> [opções]\n"
1454 " <instâncias> Conjunto de IDs: A | A,B,C | A:B[:C]\n"
1456 " -R <ficheiro> Nome do CSV de resultados (omissão: resultados.csv)\n"
1457 " -S solucoes [custoMin,custoMax,tempoMin,tempoMax [<ids>]]\n"
1458 " caso exista ficheiro de soluções, pretende-se apenas validação\n"
1459 " pode-se dar referências de custo min/max e tempo min/max para indicador de desempenho\n"
1460 " <ids> - identificação das instâncias impossíveis\n"
1461 " -F <prefixo> Prefixo para leitura da instância por ficheiro (omissão: vazio)\n"
1462 " -FG <prefixo> Prefixo para gravação da instância em ficheiro (omissão: vazio)\n"
1463 " -M <modo> Modo MPI: 0 = divisão estática, 1 = gestor-trabalhador\n"
1464 " -G <0/1> Gravar solução (sequência de ações): 0 = não grava, 1 = grava\n"
1465 " -I <ind> Lista de indicadores (e.g. 2,1,3)\n"
1467 " -P <expr> Parâmetros (e.g. P1=1:3 x P2=0:2) - valores para cada parâmetro, distintos dos por omissão\n"
1468 "Exemplo: %s 1:5 -R out -F fich_ -I 3,1,4,2 -P P1=1:5 x P6=1,2 \n"
1469 " Executar sem argumentos entra em modo interativo, para explorar todos os parâmetros e indicadores\n",
1493 linhas.Last().printf(
"Solução");
1497 linhas.Last().printf(
"Válidas;Inválidas;Melhor;Pior;Tempo(ms)");
1509 linhas.Last().printf(
"%d:%s;",
1516 if (!
res.solucao.Empty()) {
1517 for (
auto&
acao :
res.solucao)
1548 col += printf(
" | ");
1563 for (
int i = 0;
i <
total.Count();
i++) {
1586 total[
res.configuracao].instancia++;
1588 str[0].printf(
"%d",
res.instancia);
1589 str[1].printf(
"%d",
res.configuracao + 1);
1604 for (
int i = 0;
i <
total.Count();
i++) {
1607 str.
printf(
"%-2s Total %-2s%d", Icon(EIcon::TAXA), Icon(EIcon::CONF),
i + 1);
1656 printf(
"%-2sinativo ", Icon(EIcon::NSEL));
1658 printf(
"%-2s%dº lugar ", Icon(EIcon::SEL),
indicador[
i].indice + 1);
1681 printf(
"\n%-2s Torneio (#instâncias melhores):", Icon(EIcon::TORNEIO));
1683 for (
int i = 0;
i <
pontos.Count();
i++) {
1684 printf(
"\n%2d",
i + 1);
1685 for (
int j = 0;
j <
pontos.Count();
j++)
1699 if (
res.configuracao == configuracao)
1710 printf(
"-%02d-|",
i + 1);
1742 Mensagem(Icon(EIcon::INSUC),
" Tempo excedido");
1744 Mensagem(Icon(EIcon::INSUC),
" Memória esgotada");
1750 printf(
"\nSolução: ");
1751 for (
auto&
x : solucao)
1797 texto =
NovoTexto(
"\nNovo ID (ENTER mantém) ou novo prefixo (texto): ");
1804 else if (
texto.Count() < 256)
1838 TString prefixo,
int modoCor,
bool duplaColuna)
1842 printf(
"\n%s%-4s ", *
prefixo, *tipo);
1843 for (
int i = 0;
i < 10 &&
i <
tabela.Count();
i++)
1844 printf(
"%4d ",
i + 1);
1845 printf(
"\n%s────┼", *
prefixo);
1846 for (
int i = 0;
i < 10 &&
i <
tabela.Count();
i++)
1848 for (
int i = 0;
i <
tabela.Count();
i++) {
1883 for (
int j = 1;
j <
linhas.Count();
j++)
1936 Mensagem(Icon(EIcon::INSUC),
" Erro ao executar o comando.");
1939 else if (
error != 0) {
1940 Mensagem(Icon(EIcon::INSUC),
" O comando retornou um código de erro: %d",
error);
constexpr int BUFFER_SIZE
constexpr int BUFFER_SIZE
constexpr int RES_INVALIDO
@ IND_TEMPO
tempo em milissegundos consumidos
@ IND_ITERACOES
número de iterações consumidas
@ IND_RESULTADO
resultado do algoritmo (>=0 custo da solução, -1 impossível, -2 não resolvido)
constexpr int COR_LEVE_TAM
constexpr int RES_NAO_RESOLVIDO
ENivelDebug
Níveis de detalhamento para debug.
@ ATIVIDADE
Apenas eventos principais.
@ COMPLETO
Mostra toda a execução detalhadamente.
@ NADA
Sem informações de debug.
@ DETALHE
Debug detalhada sobre estados e decisões.
constexpr int RES_IMPOSSIVEL
@ CONT_TESTE
Tempo total do teste (todas as execuções)
@ CONT_REPORTE
Tempo entre mensagens durante o teste.
@ CONT_ALGORITMO
Tempo da execução do algoritmo por instância.
@ NIVEL_DEBUG
Nível de debug, de reduzido a completo.
@ LIMITE_TEMPO
Tempo limite em segundos.
ECaixaParte
Define as partes de uma caixa de texto para exibição formatada.
TVector< int > _TV(const char *str)
TVector< int64_t > indValores
void ResetParametros()
Reset parâmetros, assumindo variáveis da classe definidas.
int ExecutaAlgoritmo()
Executa o algoritmo e extrai os indicadores.
int64_t Indicador(int id)
retorna indicadores após execução
TVector< TString > indPrefixo
TVector< TIndicador > ind
TVector< TString > parPrefixo
TVector< TParametro > par
virtual void MostrarSolucao()
definir para visualizar a solução
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
static void MostraCaixa(TVector< TString > titulo, ECaixaParte parte, TVector< int > largura, bool aberta=true, int identacao=0)
virtual void Debug(bool completo=true)
Mostra o estado no ecrã, para debug.
int Parametro(int id) const
virtual int ExecutaAlgoritmo()
Executa o algoritmo com os parametros atuais.
static int Dominio(int &variavel, int min=INT_MIN, int max=INT_MAX)
Limita o domínio de um parâmetro inteiro.
virtual void RelatorioValidacao(TVector< TResultado > resultados, TVector< int > referencias)
static int modoMPI
Modo MPI.
virtual void Inicializar(void)
Coloca o objecto no estado inicial da procura.
static TVector< TVector< int > > configuracoes
Conjuntos de configurações para teste empírico.
static int resultado
Resultado retornado pelo algoritmo na última execução.
void BarraTorneio(bool nomes)
Mostra a barra de progresso ou nomes do torneio.
void ExecutaTarefa(TVector< TResultado > &resultados, int inst, int conf)
Executa uma tarefa num teste empírico.
void AjudaUtilizacao(TString programa)
Mostra ajuda de utilização do programa.
void MostrarTorneio(TVector< TVector< int > > &torneio, bool jogo=false)
Mostra os resultados do torneio.
static TString ficheiroInstancia
prefixo do nome ficheiro de uma instância - editado pelo utilizador Caso não seja nulo,...
static int mpiID
MPI - rank do processo.
void MostrarConfiguracoes(int detalhe, int atual=-1)
Mostra as configurações disponíveis.
void MostraParametros(int detalhe=1, TVector< int > *idParametros=NULL, TString titulo="")
Mostra os parâmetros atuais.
virtual int64_t Indicador(int id)
Retorna um indicador, após a execução do algoritmo.
virtual TVector< TString > Solucao()
retorna uma solução no formato do TResultado, para ser gravada em ficheiro de soluções,...
static TString NovoTexto(TString prompt)
static int gravarSolucao
Gravar solução CSV (todas as ações)
static TString ficheiroGravar
prefixo do nome do ficheiro para gravar a instância para ficheiro (terá sido gerada)
TVector< TResultado > ExtrairConfiguracao(TVector< TResultado > &resultados, int configuracao)
Extrai resultados de uma determinada configuração.
virtual void Gravar(void)
void TesteInicio(TVector< int > &instancias, TVector< int > &configAtual)
arranque de teste, auxiliar aos Testes Empíricos
static int iteracoes
Número total de iterações realizadas na última execução.
static void FinalizaMPI()
Finaliza o ambiente MPI, se aplicável.
virtual void TesteValidacao(TVector< int > instancias, TVector< int > impossiveis, TVector< int > referencias, TString fichSolucoes, TString fichResultados="")
Executa testes de validação, executando cada solução na instância respetiva, e verificando a sua vali...
int NovaConfiguracao(TVector< int > ¶metros)
Adiciona uma nova configuração se ainda não existir.
TVector< int > SolicitaInstancias()
Solicita ao utilizador uma lista de instâncias.
virtual void ResetParametros()
Inicializa os parâmetros, indicadores e instâncias.
virtual void TesteEmpiricoTrabalhador(TVector< int > instancias, TString ficheiro="")
Teste empírico com modo mestre-escravo (este é o escravo)
virtual bool Parar(void)
Verifica se a procura deve ser interrompida.
bool JuntarCSV(TString ficheiro)
Juntar ficheiros CSV gerados por diferentes processos MPI em um único ficheiro.
static int NovoValor(TString prompt)
bool ParametroAtivo(int id, TVector< int > *valores=NULL) const
virtual void TesteManual(TString nome)
Inicializa a interação com o utilizador.
static TString MostraTempo(double segundos)
Mostra tempo num formato humano.
virtual void ExecucaoTerminada()
Chamar após a execução do algoritmo. Grava o tempo consumido.
virtual void main(int argc, char *argv[], TString nome)
Inicializa a interação com o utilizador.
void MostraRelatorio(TVector< TResultado > &resultados, bool ultimo=false)
Mostra um relatório dos resultados.
bool EditarIndicadores()
Permite ao utilizador editar os indicadores a utilizar.
static int mpiCount
MPI - número de processos.
static void InicializaMPI(int argc, char *argv[])
Inicializa o ambiente MPI, se aplicável.
void MostraIndicadores()
Mostra os indicadores definidos.
static void Mensagem(TString titulo, const char *fmt,...)
static TVector< TIndicador > indicador
Indicadores que podem ser calculados após a execução, quer com informação da instãncia,...
virtual void TesteEmpiricoGestor(TVector< int > instancias, TString ficheiro="")
Teste empírico com modo mestre-escravo (este é o mestre)
void DebugTabela(ENivelDebug nivel, TVector< int >tabela, TString tipo="", TString prefixo="", int modoCor=0, bool duplaColuna=false)
Mostra uma tabela de inteiros, 10 elementos por linha, apenas se o nível de debug for igual ou superi...
bool RelatorioCSV(TVector< TResultado > &resultados, TString ficheiro, bool parametros=true)
Gera um relatório CSV com os resultados.
virtual bool Validar(TVector< TString > solucao)
Verifica a validade de uma solução para a instância atual.
static clock_t instanteFinal
Instante final (deadline) da corrida atual.
void EditarParametros()
Permite ao utilizador editar os parâmetros.
void InserirConfiguracoes(TString str, TVector< int > &base)
Insere configurações a partir de uma string.
int MelhorResultado(TResultado base, TResultado alternativa)
Compara dois resultados para determinar o melhor.
virtual void Explorar()
definir para explorar manualmente os dados (não definido em TProcura, apenas em TProcuraConstrutiva)
static void DebugHSL(float h=-1, float s=1.0, float l=0.2, bool fundo=true)
Muda a cor (fundo/letra) com HSL.
void CalculaTorneio(TVector< TResultado > &resultados)
Calcula o torneio entre várias configurações.
void ConfiguracaoAtual(TVector< int > ¶metros, int operacao)
Grava ou lê a configuração atual.
static TVector< int > indAtivo
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().
virtual TVector< int64_t > CodificarSolucao()
retorna um vetor de inteiros com a codificação da solução (esta codificação será adicionada aos indic...
static double Cronometro(enum ECronometro id=CONT_ALGORITMO, bool inicializar=false)
retorna o tempo em segundos desde que o cronómetro foi inicializado
void InserirRegisto(TVector< TResultado > &resultados, int inst, int conf)
Insere um novo registo de resultados.
virtual void TesteEmpirico(TVector< int > instancias, TString ficheiro="")
Executa testes empíricos, em todas as configurações guardadas, nas instâncias selecionadas.
static TVector< TParametro > parametro
Parâmetros a serem utilizados na configuração atual.
void EditarConfiguracoes()
Permite ao utilizador editar as configurações.
int64_t Registo(TResultado &resultado, int id)
Procura um registo com determinado id.
virtual void LimparEstatisticas()
Chamar antes da execução do algoritmo. Limpa valores estatísticos, e fixa o instante limite de tempo ...
void SolicitaInstancia()
Solicita ao utilizador o ID da instância a utilizar, permitindo alterar também o prefixo do ficheiro.
static double tempo
tempo consumido na última execução.
static void MostraConjunto(TVector< int > valores, const char *etiqueta)
TVector< TString > tok(const char *delim=" \t\n\r") const
TString & printf(const char *fmt,...)
TVector< TString > readLines()
TString & writeLines(const TVector< TString > &lines, bool append=false)
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
Item * Data()
Acesso direto.
virtual bool Empty() const
int ContaUTF8(const char *str)
Estrutura para registo de um parâmetro.
int valor
valor do parâmetro
int max
valor máximo que o parâmetro pode tomar
int min
valor mínimo que o parÂmetro pode tomar