TProcura
Biblioteca em C++ para testes paramétricos de algoritmos, e coleção de algoritmos de procura e otimização
Loading...
Searching...
No Matches
TProcura.cpp
Go to the documentation of this file.
1#include "TProcura.h"
2#include <stdio.h>
3#include <time.h>
4#include <string.h>
5#include <ctype.h>
6
7#define BUFFER_SIZE 1024
8
9// Resultado retornado pelo algoritmo na última execução.
11// tempo consumido na última execução.
12int TProcura::tempo = 0;
13// numero de iterações, conforme definido no algoritmo
15
16// deadline da corrida atual
17clock_t TProcura::instanteFinal = 0;
18// flag de problemas de memória esgotada
19bool TProcura::memoriaEsgotada = false;
20// ID da instância atual (problemas com várias instâncias, a utilizar em SolucaoVazia())
21TParametro TProcura::instancia = { NULL,1,1,1, NULL, NULL };
22// nome do ficheiro de uma instância (utilizar como prefixo, concatenando com ID da instância)
23char TProcura::ficheiroInstancia[256] = "instancia_";
24
25// adicionar parâmetros específicos, se necessário
27// adicionar indicadores conforme a necessidade
29// lista por ordem dos indicadores a utilizar
31
32
33// conjuntos de valores de parâmetros, para teste
35
36
38{
39 static const char* nomesAlgoritmos[] = {
40 "Algoritmo base" };
41 static const char* nomesDebug[] = {
42 "nada",
43 "atividade",
44 "passos",
45 "detalhe",
46 "completo" };
47
48 // definir indicadores base
50 indicador.Add({ "Resultado","Resultado do algoritmo, interpretado conforme o algoritmo (sucesso/insucesso, custo, qualidade, valor, etc.).", 0 });
51 indicador.Add({ "Tempo(ms)","Tempo em milisegundos da execução (medida de esforço computacional).", 1 });
52 indicador.Add({ "Iterações","Iterações do algoritmo, intrepretadas conforme o algoritmo (medida de esforço independente do hardware).", 2 });
53 for (int i = 0; i < indicador.Count(); i++) // ativar todos os indicadores
54 indAtivo.Add(i);
55
56 // definir parametros base
58 // algoritmos
59 parametro.Add({ "Algoritmo",1,1,1,"Algoritmo base a executar.", nomesAlgoritmos });
60 // nivel de debug
61 parametro.Add({ "Debug",0,0,4,"Nível de debug, de reduzido a completo.",nomesDebug });
62 // seed
63 parametro.Add({ "Seed",1,1,1000000, "Semente aleatória para inicializar a sequência de números pseudo-aleatórios.",NULL });
64 // limite tempo
65 parametro.Add({ "Tempo",10,1,3600, "Limnite de tempo em segundos. ",NULL });
66 // máximo de iterações
67 parametro.Add({ "Iterações",0,0,1000000000, "Limite de número de iterações (0 não há limite). ",NULL });
68
69 // colocar as configurações vazias (podem ser inicializadas se existirem configurações de omissão)
71}
72
73// retorna o valor do indicador[id]
75 switch (id) {
76 case indResultado:
77 return resultado;
78 case indTempo:
79 return tempo;
80 case indIteracoes:
81 return iteracoes;
82 }
83 return 0;
84}
85
86// Escrever informacao de debug sobre o objecto atual
88{
90 printf("\nTProcura::Debug() método não redefinido.");
91}
92
93// Chamar antes de iniciar uma procura
101
102// Metodo para teste manual do objecto (chamadas aos algoritmos, construcao de uma solucao manual)
103// Este metodo destina-se a testes preliminares, e deve ser redefinido apenas se forem definidos novos algoritmos
104void TProcura::TesteManual(const char* nome)
105{
106 int selecao;
111 Inicializar();
113 while (true) {
114 printf("\n%s", nome);
116 Debug();
118 printf("\n\
119____________________________________________________________________\n\
120| 1 - Inicializar | 2 - Explorar | 3 - Parâmetros | 4 - Solução |\n\
121| 5 - Indicadores | 6 - Executar | 7 - Configurações | 8 - Teste |");
122 if ((selecao = NovoValor("\nOpção: ")) == NAO_LIDO)
123 return;
124 switch (Dominio(selecao, 0, 9)) {
125 case 0: return;
127 case 2: Explorar(); break;
128 case 3: EditarParametros(); break;
129 case 4: MostrarSolucao(); break;
130 case 5: if (EditarIndicadores())
131 resultados.Count(0);
132 break;
133 case 6:
134 // executar um algoritmo
140 break;
141 case 7: EditarConfiguracoes(); break;
142 case 8: {
144 char* ficheiro = NovoTexto("Ficheiro (nada para mostrar no ecrã):");
145 int mostrarSol = NovoValor("Mostrar soluções? ");
147 break;
148 }
149 case 9: return;
150 default: printf("\nOpção não definida."); break;
151 }
152 }
153}
154
156 int nElementos = (idParametros == NULL ? parametro.Count() : idParametros->Count());
157 printf("\n ");
158 for (int i = 0; i < nElementos; i++) {
159 int parID = (idParametros == NULL ? i : (*idParametros)[i]);
160 // identificação do parâmetro
161 if (detalhe == 0 || parametro[parID].nome == NULL)
162 printf("P%d=", parID + 1);
163 else
164 printf("P%d(%s): ", parID + 1, parametro[parID].nome);
165 // valor do parâmetro
166 if (detalhe == 0 || parametro[parID].nomeValores == NULL)
167 printf("%d", Parametro(parID));
168 else
169 printf("%s", parametro[parID].nomeValores[Parametro(parID) - parametro[parID].min]);
170 // mostrar intervalo permitido
171 if (detalhe > 1)
172 printf(" (%d a %d)", parametro[parID].min, parametro[parID].max);
173 // separador/mudança de linha
174 if (i < nElementos - 1) {
175 if (detalhe > 1 || (i + 1) % (detalhe == 0 ? 10 : 5) == 0)
176 printf("\n ");
177 else if (detalhe > 0)
178 printf(" | ");
179 else
180 printf(" ");
181 }
182 }
183}
184
186 int opcao = 0;
187 bool editado = false;
188 while (true) {
190 if ((opcao = NovoValor("\nAlterar indicador: ")) == NAO_LIDO || opcao == 0)
191 return editado;
192 opcao = Dominio(opcao, 1, indicador.Count());
193 if (indicador[opcao - 1].indice >= 0) {
194 for (int i = 0; i < indicador.Count(); i++)
195 if (i != opcao - 1 && indicador[i].indice > indicador[opcao - 1].indice)
196 indicador[i].indice--;
197 indicador[opcao - 1].indice = -1;
198 indAtivo.Remove(opcao - 1);
199 }
200 else {
201 indicador[opcao - 1].indice = 0;
202 for (int i = 0; i < indicador.Count(); i++)
203 if (i != opcao - 1 && indicador[i].indice >= indicador[opcao - 1].indice)
204 indicador[opcao - 1].indice = indicador[i].indice + 1;
205 indAtivo.Add(opcao - 1); // coloca no fim
206 }
207 // invalidar resultados atuais
208 editado = true;
209 }
210 return editado;
211}
212
214 int opcao = 0, valor;
215 while (true) {
217 if ((opcao = NovoValor("\nParametro:")) == NAO_LIDO || opcao == 0)
218 return;
219 opcao = Dominio(opcao, 1, parametro.Count());
220 // mostrar descrição se existir
221 if (parametro[opcao - 1].descricao != NULL)
222 printf("\n%s", parametro[opcao - 1].descricao);
223 // mostrar textos dos valores possíveis, caso existam
224 if (parametro[opcao - 1].nomeValores != NULL)
225 for (int i = parametro[opcao - 1].min; i <= parametro[opcao - 1].max; i++)
226 printf("\n%d: %s", i,
227 parametro[opcao - 1].nomeValores[i - parametro[opcao - 1].min]);
228
229 // valor atual
230 if (parametro[opcao - 1].nome != NULL)
231 printf("\n%s (atual %d): ", parametro[opcao - 1].nome, Parametro(opcao - 1));
232 else
233 printf("\nP%d (atual %d): ", opcao, Parametro(opcao - 1));
234 // solicitar valor
235 valor = NovoValor("");
236 if (valor != NAO_LIDO || valor == 0)
237 parametro[opcao - 1].valor = Dominio(
238 valor,
239 parametro[opcao - 1].min,
240 parametro[opcao - 1].max);
241 }
242}
243
245{
246 int id = -1;
247 // procurar pela configuração
248 for (int i = 0; i < configuracoes.Count() && id < 0; i++)
249 if (configuracoes[i].Equal(parametros))
250 id = i;
251 if (id < 0) {
254 return configuracoes.Count() - 1;
255 }
256 return id;
257}
258
259
260// gravar (ou ler) a configuração atual
261void TProcura::ConfiguracaoAtual(TVector<int>& parametros, int operacao) {
262 if (operacao == gravar) {
263 for (int i = 0; i < parametro.Count() && i < parametros.Count(); i++)
264 parametro[i].valor = parametros[i];
265 }
266 else if (operacao == ler) {
267 parametros.Count(0);
268 for (int i = 0; i < parametro.Count(); i++)
269 parametros.Add(Parametro(i));
270 }
271}
272
273void TProcura::InserirRegisto(TVector<TResultado>& resultados, int inst, int conf)
274{
275 resultados.Add({ inst, conf });
276 for (auto ind : indAtivo)
278 // adicionar no final a solução codificada em inteíros
279 resultados.Last().valor += CodificarSolucao();
280}
281
282int TProcura::Registo(TResultado& resultado, int id)
283{
284 if (id >= 0 && id < indicador.Count() && indicador[id].indice >= 0)
285 return resultado.valor[indicador[id].indice];
286 return 0;
287}
288
289void TProcura::Registo(TResultado& resultado, int id, int valor)
290{
291 if (id >= 0 && id < indicador.Count() && indicador[id].indice >= 0)
292 resultado.valor[indicador[id].indice] = valor;
293}
294
295// Sintaxe de <lista> (apenas inteiros, sem espaços):
296// A ou A,B,C - único valor ou enumeração
297// A:B ou A:B:C - intervalo A a B, ou com passo C
300 char* pt;
301
302 if (!str || *str == '\0')
303 return lista;
304
305 // separar por vírgulas
306 if (pt = strchr(str, ',')) {
307 *pt = 0;
309 do {
310 str = pt + 1;
311 if (pt = strchr(str, ','))
312 *pt = 0;
314 } while (pt);
315 }
316 else {
317 // procurar por : (intervalo)
318 if (pt = strchr(str, ':')) {
319 char* pt2;
320 *pt = 0;
321 int A = atoi(str);
322 int C = 1;
323 A = atoi(str);
324 if (pt2 = strchr(pt + 1, ':')) { // A:B:C
325 *pt2 = 0;
326 if ((C = atoi(pt2 + 1)) <= 0)
327 C = 1;
328 } // c.c. A:B
329 int B = atoi(pt + 1);
330 if (A > B) { // ordem não interessa
331 int aux = A;
332 A = B;
333 B = aux;
334 }
335 for (int i = A; i <= B; i += C)
336 lista.Add(i);
337 }
338 else // inteiro apenas
339 lista.Add(atoi(str));
340 }
341 lista.BeASet();
342 return lista;
343}
344
346{
348 char str[BUFFER_SIZE];
349 printf("\nSintaxe (apenas inteiros, sem espaços):\n\
350 A ou A,B,C - único valor ou enumeração\n\
351 A:B ou A:B:C - intervalo A a B, ou com passo C\n\
352Introduza IDs das instâncias (de %d a %d): ", instancia.min, instancia.max);
354 if (strlen(str) > 1)
355 return ExtraiLista(str);
356 instancias.Add(instancia.valor); // colocar apenas a instância atual
357 return instancias;
358}
359
360
362 TVector<int> atual; // parâmetros atuais
363 int id = -1, auxID;
364 char* str;
365
366 ConfiguracaoAtual(atual, ler);
367
368 id = NovaConfiguracao(atual);
369
370 do {
372
373 str = NovoTexto("\nSintaxe comando:\n\
374 id / -id - Seleciona configuração como atual ou apaga 'id'\n\
375 Pk=<conj.> - Varia Pk na configuração atual (gera N configurações)\n\
376 Pk=<conj.> x Pw=<conj.> - produto externo de Pk e Pw (gera NxM configurações)\n\
377Sintaxe de <conj.> (apenas inteiros, sem espaços):\n\
378 A ou A,B,C - único valor ou enumeração\n\
379 A:B ou A:B:C - intervalo A a B, ou com passo C\n\
380Comando: ");
381 if (strlen(str) <= 1)
382 break;
383
384 if ((auxID = atoi(str)) != 0) {
385 id = auxID;
387 if (id < 0) {
388 id++;
390 }
391 else if (id > 0) {
392 id--;
393 atual = configuracoes[id];
394 }
395 }
396 else {
398 configuracoes[id] = atual; // alterar atual se necessário
400 }
401 } while (true);
403}
404
406 char* pt;
409
410 // processar todos os itens a iniciar em P, obtendo informação entre quais existe x
411 pt = strtok(str, " \n\t\r");
412 while (pt) {
413 if (*pt == 'P') {
414 char* pt2;
415 int param;
416 if (pt2 = strchr(pt + 1, '=')) {
417 *pt2 = 0;
418 param = atoi(pt + 1);
419 if (param > 0 && param <= parametro.Count()) {
420 valores.Count(valores.Count() + 1);
421 valores.Last().Count(0);
422 valores.Last().Add(param); // primeiro valor é ID do parâmetro
423 valores.Last() += ExtraiLista(pt2 + 1); // valores para o parâmetro tomar
424 if (valores.Last().Count() == 2) {
425 // apenas um elemento, altera a configuração atual
426 // (se fosse para alternar, colocava o valor base masi o valor a alternar)
427 int valor = valores.Last().Last();
428 if (valor >= parametro[param - 1].min &&
429 valor <= parametro[param - 1].max)
430 base[param - 1] = valor;
431 }
432 if (valores.Last().Count() <= 2)
433 valores.Count(valores.Count() - 1);
434 }
435 }
436 }
437 else if (*pt == 'x') {
438 valores.Count(valores.Count() + 1);
439 valores.Last().Add(0); // produto externo
440 }
441 pt = strtok(NULL, " \n\t\r");
442 }
443 // inserir configurações de acordo com o pretendido (produto externo, ou apenas à configuração base)
444 produto.Count(0);
445 for (int i = 0; i < valores.Count(); i++)
446 if (valores[i].First() > 0) { // c.c. é o operador produto externo
447 if (i == valores.Count() - 1 || valores[i + 1].First() != 0) { // não há outro produto externo, colocar na configuração atual
448 produto.Add(i);
450 produto.Count(0);
451 }
452 else
453 produto.Add(i);
454 }
455}
456
458{
459 // inserir os valores do último elemento de forma recursiva
460 int idLista = produto.Pop();
463 int param = lista.First();
464
465 for (int i = 1; i < lista.Count(); i++)
466 if (lista[i] >= parametro[param - 1].min &&
467 lista[i] <= parametro[param - 1].max)
468 {
469 base[param - 1] = lista[i];
470 if (produto.Count() == 0)
472 else
474 }
475 base = backup;
476 produto.Push(idLista);
477}
478
481 // identificar parametros comuns e distintos entre as parametrizações
482 for (int i = 0; i < configuracoes.First().Count(); i++) {
483 bool igual = true;
484 for (int j = 1; j < configuracoes.Count() && igual; j++)
486 if (igual)
487 comum.Add(i);
488 else
489 distinto.Add(i);
490 }
491 // mostra parametros comuns, evitando repetição em cada configuração
492 printf("\nParâmetros comuns:");
494
495 // visualizar configurações atuais, assinalando a atualmente escolhida
496 printf("\n- Configurações geradas (total: %d) -", configuracoes.Count());
497 for (int i = 0; i < configuracoes.Count(); i++) {
500 printf(" [%d]", i + 1);
501 if (i == atual)
502 printf(" --- atual");
503 }
504}
505
506
507// utilizar para executar testes empíricos, utilizando todas as instãncias,
508// com o último algoritmo executado e configurações existentes
509void TProcura::TesteEmpirico(TVector<int> instancias, bool mostrarSolucoes, char* ficheiro) {
510 TVector<TResultado> resultados; // guarda as soluções obtidas
511 TVector<int> atual;
513 for (auto item : instancias)
515 item = -1;
516 instancias.Remove(-1);
517 ConfiguracaoAtual(atual, ler);
518 if (configuracoes.Count() == 0) {
519 // não foram feitas configurações, utilizar a atual
521 configuracoes.Last() = atual;
522 }
523 // percorrer todas as instâncias
524 for (int configuracao = 0; configuracao < configuracoes.Count(); configuracao++) {
525 ConfiguracaoAtual(configuracoes[configuracao], gravar);
527 for (auto inst : instancias) {
528 instancia.valor = inst;
531 // carregar instância
532 Inicializar();
533 // executar um algoritmo
534 printf("\nInstância %d: ", instancia.valor);
540
541 if (resultado >= 0) {
542 if (mostrarSolucoes)
544 }
545 else {
546 if (Parar())
547 printf("Não resolvido. ");
548 if (TempoExcedido())
549 printf("Tempo excedido. ");
550 if (memoriaEsgotada)
551 printf("Memória esgotada. ");
552 if (resultado < 0 && !Parar())
553 printf("Instância Impossível! (se algoritmo completo) ");
554 else // não resolvido, cancelar resultados
555 resultados.Last().valor.First() = -2;
556 }
557 printf("DONE.");
558 }
559 }
560 if (ficheiro == NULL || strlen(ficheiro) <= 1)
562 else {
563 char* pt = strtok(ficheiro, " \n\t\r");
564 char str[BUFFER_SIZE];
565 strcpy(str, pt);
566 strcat(str, ".csv");
567 FILE* f = fopen(str, "wt");
568 if (f != NULL) {
569 // escrever BOM UTF-8
570 const unsigned char bom[] = { 0xEF,0xBB,0xBF };
571 fwrite(bom, 1, sizeof(bom), f);
572 fprintf(f, "sep=;\n");
574 printf("\nFicheiro %s gravado.", str);
575 fclose(f);
576 }
577 else
578 printf("\nErro ao gravar ficheiro %s.", str);
579 }
580
584 Inicializar();
585}
586
587// processa os argumentos da função main
588void TProcura::main(int argc, char* argv[], const char* nome) {
589 if (argc <= 1) {
590 TesteManual(nome);
591 }
592 else {
594 bool mostrarSolucoes = false;
595 char fichResultados[256];
597 strcpy(fichResultados, "resultados");
598
599 if (strcmp(argv[1], "-h") == 0) {
601 return;
602 }
603
605
606 // 1:10 --- conjunto de instâncias (idêntico ao interativo)
608 if (instancias.Count() == 0) {
610 return;
611 }
612
613 // opcionais:
614 // -R resultados --- ficheiro de resultados em CSV (adicionada extensão .csv)
615 // -F instancia_ --- prefixo dos ficheiros de instâncias
616 // -I 2,1,3 --- indicadores selecionados por ordem
617 // -P P1=1:3 x P2=0:2 --- formatação de parâmetros (idêntico ao interativo)
618 for (int i = 2; i < argc; i++) {
619 if (strcmp(argv[i], "-R") == 0 && i + 1 < argc) {
621 }
622 else if (strcmp(argv[i], "-F") == 0 && i + 1 < argc) {
624 }
625 else if (strcmp(argv[i], "-S") == 0) {
626 mostrarSolucoes = true;
627 }
628 else if (strcmp(argv[i], "-I") == 0 && i + 1 < argc) {
629 char* pt = strtok(argv[i + 1], ",");
630 indAtivo.Count(0);
631 while (pt) {
632 indAtivo.Add(atoi(pt) - 1);
633 indicador[indAtivo.Last()].indice = indAtivo.Count() - 1;
634 pt = strtok(NULL, ",");
635 }
636 }
637 else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) {
639 // o resto é para concatenar e enviar
641 while (++i < argc) {
642 strcat(argParametros, " ");
644 }
648 break;
649 }
650 }
653 }
654}
655
656void TProcura::AjudaUtilizacao(const char* programa) {
657 printf(
658 "Uso: %s <instâncias> [opções]\n"
659 " <instâncias> Conjunto de IDs: A | A,B,C | A:B[:C]\n"
660 "Opções:\n"
661 " -R <ficheiro> Nome do CSV de resultados (omissão: resultados.csv)\n"
662 " -F <prefixo> Prefixo dos ficheiros de instância (omissão: instancia_)\n"
663 " -I <ind> Lista de indicadores (e.g. 2,1,3)\n"
664 " -S Mostrar soluções durante a execução\n"
665 " -h Esta ajuda\n"
666 " -P <expr> Parâmetros (e.g. P1=1:3 x P2=0:2) - último campo\n"
667 "Exemplo: %s 1:5 -R out -F fich_ -I 3,1,4,2 -P P1=1:5 x P6=1,2 \n"
668 " Executar sem argumentos entra em modo interativo, para explorar todos os parametros e indicadores\n",
670 );
672 printf("\nLista de parâmetros:");
674 printf("\n\nLista de indicadores:");
676}
677
678
679void TProcura::RelatorioCSV(TVector<TResultado>& resultados, FILE* f) {
680 // cabeçalho: instância, parametros, indicadores
681 // TODO: poder-se selecionar parametros a mostrar
682 fprintf(f, "Instância;");
683 for (int i = 0; i < parametro.Count(); i++)
684 fprintf(f, "P%d(%s);", i + 1, parametro[i].nome);
685 for (auto item : indAtivo)
686 fprintf(f, "I%d(%s);", item + 1, indicador[item].nome);
687 fprintf(f, "\n");
688
689 for (auto res : resultados) {
690 fprintf(f, "%d;", res.instancia);
691 for (int j = 0; j < parametro.Count(); j++)
692 if (parametro[j].nomeValores == NULL)
693 fprintf(f, "%d;", configuracoes[res.configuracao][j]);
694 else
695 fprintf(f, "%d:%s;",
696 configuracoes[res.configuracao][j],
697 parametro[j].nomeValores[configuracoes[res.configuracao][j] - parametro[j].min]);
698 for (auto ind : indAtivo)
699 fprintf(f, "%d;", Registo(res, ind));
700 fprintf(f, "\n");
701 }
702}
703
704
705void TProcura::MostraRelatorio(TVector<TResultado>& resultados, bool ultimo)
706{
707 if (ultimo) {
708 if (resultados.Count() > 0) {
709 int elementos = 0;
710 for (auto ind : indAtivo) {
711 if (elementos > 0)
712 printf(" | ");
713 if (elementos % 5 == 0)
714 printf("\n");
715 printf("I%d(%s): %d", ind + 1, indicador[ind].nome, Registo(resultados.Last(), ind));
716 elementos++;
717 }
718 }
719 return;
720 }
721
722 TVector<TResultado> total; // totais por cada configuração
724 for (int i = 0; i < total.Count(); i++) {
725 total[i].instancia = total[i].configuracao = 0;
726 total[i].valor.Count(indicador.Count());
727 total[i].valor.Reset(0);
728 }
729
730 // mostrar os resultados dos indicadores escolhidos
731 printf("\n ID |conf|");
732 for (auto ind : indAtivo)
733 printf("%10s|", indicador[ind].nome);
734
735 printf("\n----|----|");
736 for (auto ind : indAtivo)
737 printf("----------|");
738
739 for (auto res : resultados) {
740 if (Registo(res, indResultado) >= -1)
741 total[res.configuracao].instancia++;
742 printf("\n%3d |%3d |", res.instancia, res.configuracao + 1);
743
744 for (auto ind : indAtivo)
745 printf(" %8d |", Registo(res, ind));
746
747 for (auto ind : indAtivo)
748 Registo(total[res.configuracao], ind,
749 Registo(total[res.configuracao], ind) +
750 Registo(res, ind));
751 }
752 printf("\n----|----|");
753 for (auto ind : indAtivo)
754 printf("----------|");
755 printf("resolvidas");
756 // tabela com os totais por configuração
757 for (int i = 0; i < total.Count(); i++) {
758 printf("\nTotal%3d |", i + 1);
759
760 for (auto ind : indAtivo)
761 printf(" %8d |", Registo(total[i], ind));
762
763 printf(" %d", total[i].instancia);
764 }
765 // mostrar torneio entre configurações
768 printf("\n");
769}
770
772 TVector<TVector<int>> torneio; // pares de configurações: 1 melhor, 0 igual -1 pior
774 for (int i = 0; i < torneio.Count(); i++) {
775 torneio[i].Count(configuracoes.Count());
776 torneio[i].Reset(0);
777 }
778 // registar resultados mediante o melhor resultado
779 for (int i = 0; i < configuracoes.Count(); i++) {
781 for (int j = 0; j < configuracoes.Count(); j++)
782 if (i != j) {
784 // resultados sempre por mesma ordem de instância
785 for (int k = 0; k < configuracaoI.Count() && k < configuracaoJ.Count(); k++)
787 }
788 }
790}
791
793{
794 printf("\n");
795 for (int i = 0; i < indicador.Count(); i++) {
796 printf("\nI%d(%s): ", i + 1, indicador[i].nome);
797 if (indicador[i].indice < 0)
798 printf("inativo ");
799 else
800 printf("%dº lugar ", indicador[i].indice + 1);
801 printf("(%s)", indicador[i].descricao);
802 }
803}
804
805
807{
809 pontos.Count(torneio.Count());
810 pontos.Reset(0);
811 // registar resultados mediante o melhor resultado
812 for (int i = 0; i < torneio.Count(); i++)
813 for (int j = 0; j < torneio.Count(); j++)
814 if (i != j) {
815 pontos[i] += torneio[i][j];
816 if (jogo) // contar pontos perdidos de pretas
817 pontos[j] -= torneio[i][j];
818 }
819
820 // mostrar tabela do torneio
821 printf("\nTorneio (#instâncias melhores):");
822 BarraTorneio(true);
823 for (int i = 0; i < pontos.Count(); i++) {
824 printf("\n%2d", i + 1);
825 for (int j = 0; j < pontos.Count(); j++)
826 if (i == j)
827 printf(" |");
828 else
829 printf("%3d |", torneio[i][j]);
830 // no final colocar os pontos totais
831 printf("%3d", pontos[i]);
832 BarraTorneio(false);
833 }
834}
835
838 for (auto res : resultados)
839 if (res.configuracao == configuracao)
841 return extracao;
842}
843
844
845void TProcura::BarraTorneio(bool nomes) {
846 // barra inical/final: |----|----|----|
847 printf("\n |");
848 for (int i = 0; i < configuracoes.Count(); i++)
849 if (nomes)
850 printf("-%02d-|", i + 1);
851 else
852 printf("----|");
853}
854
855
857 // se não resolvido por ambos, retornar igualdade (assumir código -1 para impossível, -2 para não resolvido, menor é melhor)
859 return 0;
860 // se igual no custo e o tempo menor que 100, retornar igualdade
863 return 0;
864 // primeiro custo (ou não resolvido, -2)
865 if ((Registo(base, indResultado) == -2 &&
869 return -1;
870 if ((Registo(base, indResultado) > -2 &&
872 (Registo(base, indResultado) > 0 &&
874 return 1;
875 // agora o tempo
876 return Registo(base, indTempo) < Registo(alternativa, indTempo) ? 1 : -1;
877}
878
879void TProcura::ExecucaoTerminada(clock_t inicio)
880{
881 tempo = (int)(1000.0 * (clock() - inicio) / CLOCKS_PER_SEC);
882 if (TempoExcedido())
883 printf(" Tempo excedido.");
884 else if (memoriaEsgotada)
885 printf(" Memória esgotada.");
886}
887
888// MostrarSolucao: definir para visualizar a solução
890 TVector<int> solucao = CodificarSolucao();
891 printf("\nSolução: ");
892 for (auto& x : solucao)
893 printf("%d ", x);
894 printf(".");
895}
896
897
898int TProcura::NovoValor(const char* prompt) {
899 char str[BUFFER_SIZE];
900 printf("%s", prompt);
902 if (strlen(str) > 1)
903 return atoi(str);
904 return NAO_LIDO;
905}
906
907// ler uma string
908char* TProcura::NovoTexto(const char* prompt) {
909 static char str[BUFFER_SIZE];
910 printf("%s", prompt);
912 return str;
913}
914
915
917 if (instancia.max != instancia.min) {
918 int resultado;
919 char* texto;
920 printf("\nID atual: %d Intervalo: [%d–%d] ",
922 printf("Prefixo atual: '%s' ", ficheiroInstancia);
923 printf("\nNovo ID (ENTER mantém) ou novo prefixo (texto): ");
924
925 texto = NovoTexto("");
927 if (resultado != 0 || strlen(texto) <= 1) {
930 }
931 else if (strlen(texto) < 256) {
932 char* pt = strtok(texto, " \n\t\r");
934 }
935 }
936 else
938}
939
940
941int TProcura::Dominio(int& variavel, int min, int max) {
942 if (variavel < min)
943 variavel = min;
944 if (variavel > max)
945 variavel = max;
946 return variavel;
947}
#define BUFFER_SIZE
@ ler
Definition TProcura.h:75
@ gravar
Definition TProcura.h:75
@ indResultado
resultado do algoritmo
Definition TProcura.h:17
@ indIteracoes
número de iterações consumidas
Definition TProcura.h:19
@ indTempo
tempo em milisegundos consumidos
Definition TProcura.h:18
#define NAO_LIDO
Definition TProcura.h:13
@ detalhe
Debug detalhada sobre estados e decisões.
Definition TProcura.h:66
@ nada
Sem informações de debug.
Definition TProcura.h:63
@ seed
Semente aleatória para inicializar a sequência de números pseudo-aleatórios.
Definition TProcura.h:44
@ nivelDebug
Nível de debug, de reduzido a completo.
Definition TProcura.h:43
@ limiteTempo
Tempo limite em segundos.
Definition TProcura.h:45
virtual void MostrarSolucao()
definir para visualizar a solução
Definition TProcura.cpp:889
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
Definition TProcura.h:467
virtual int ExecutaAlgoritmo()
Executa o algoritmo com os parametros atuais.
Definition TProcura.h:193
static int Dominio(int &variavel, int min=INT_MIN, int max=INT_MAX)
Limita o domínio de um parâmetro inteiro.
Definition TProcura.cpp:941
static char * NovoTexto(const char *prompt)
Definition TProcura.cpp:908
virtual void Inicializar(void)
Coloca o objecto no estado inicial da procura.
Definition TProcura.h:182
static TVector< TVector< int > > configuracoes
Conjuntos de configurações para teste empírico.
Definition TProcura.h:457
static int resultado
Resultado retornado pelo algoritmo na última execução.
Definition TProcura.h:459
void BarraTorneio(bool nomes)
Mostra a barra de progresso ou nomes do torneio.
Definition TProcura.cpp:845
void MostrarTorneio(TVector< TVector< int > > &torneio, bool jogo=false)
Mostra os resultados do torneio.
Definition TProcura.cpp:806
void MostrarConfiguracoes(int detalhe, int atual=-1)
Mostra as configurações disponíveis.
Definition TProcura.cpp:479
virtual int Indicador(int id)
Retorna um indicador, após a execução do algoritmo.
Definition TProcura.cpp:74
TVector< TResultado > ExtrairConfiguracao(TVector< TResultado > &resultados, int configuracao)
Extrai resultados de uma determinada configuração.
Definition TProcura.cpp:836
static int tempo
tempo consumido na última execução.
Definition TProcura.h:461
static int iteracoes
Número total de iterações realizadas na última execução.
Definition TProcura.h:463
virtual void TesteManual(const char *nome)
Inicializa a interação com o utilizador.
Definition TProcura.cpp:104
static char ficheiroInstancia[256]
nome do ficheiro de uma instância - editado pelo utilizador (utilizar como prefixo, concatenando com ID...
Definition TProcura.h:448
int NovaConfiguracao(TVector< int > &parametros)
Adiciona uma nova configuração se ainda não existir.
Definition TProcura.cpp:244
void InserirConfiguracoes(char *str, TVector< int > &base)
Insere configurações a partir de uma string.
Definition TProcura.cpp:405
TVector< int > SolicitaInstancias()
Solicita ao utilizador uma lista de instâncias.
Definition TProcura.cpp:345
virtual void ResetParametros()
Inicializa os parametros, indicadores e instâncias.
Definition TProcura.cpp:37
void MostraParametros(int detalhe=1, TVector< int > *idParametros=NULL)
Mostra os parâmetros atuais.
Definition TProcura.cpp:155
virtual bool Parar(void)
Verifica se a procura deve ser interrompida.
Definition TProcura.h:336
virtual void ExecucaoTerminada(clock_t inicio)
Chamar após a execução do algoritmo. Grava o tempo consumido.
Definition TProcura.cpp:879
void MostraRelatorio(TVector< TResultado > &resultados, bool ultimo=false)
Mostra um relatório dos resultados.
Definition TProcura.cpp:705
bool EditarIndicadores()
Permite ao utilizador editar os indicadores a utilizar.
Definition TProcura.cpp:185
TVector< int > ExtraiLista(char *str)
Extrai uma lista de inteiros a partir de uma string.
Definition TProcura.cpp:298
virtual TVector< int > CodificarSolucao()
retorna um vetor de inteiros com a codifciação da solução (esta codificação será adicionada aos indicadores,...
Definition TProcura.h:438
virtual void Debug(void)
Mostra o estado no ecrã, para debug.
Definition TProcura.cpp:87
static int NovoValor(const char *prompt)
Definition TProcura.cpp:898
void MostraIndicadores()
Mostra os indicadores definidos.
Definition TProcura.cpp:792
static TVector< TIndicador > indicador
Indicadores que podem ser calculados após a execução, quer com informação da instãncia, quer com resultado da ...
Definition TProcura.h:454
virtual void main(int argc, char *argv[], const char *nome)
Inicializa a interação com o utilizador.
Definition TProcura.cpp:588
static clock_t instanteFinal
Instante final (deadline) da corrida atual.
Definition TProcura.h:465
void EditarParametros()
Permite ao utilizador editar os parâmetros.
Definition TProcura.cpp:213
int Registo(TResultado &resultado, int id)
Procura um registo com determinado id.
Definition TProcura.cpp:282
int MelhorResultado(TResultado base, TResultado alternativa)
Compara dois resultados para determinar o melhor.
Definition TProcura.cpp:856
virtual void Explorar()
definir para explorar manualmente os dados (não definido em TProcura, apenas em TProcuraConstrutiva)
Definition TProcura.h:434
void RelatorioCSV(TVector< TResultado > &resultados, FILE *f)
Gera um relatório CSV com os resultados.
Definition TProcura.cpp:679
void CalculaTorneio(TVector< TResultado > &resultados)
Calcula o torneio entre várias configurações.
Definition TProcura.cpp:771
void ConfiguracaoAtual(TVector< int > &parametros, int operacao)
Grava ou lê a configuração atual.
Definition TProcura.cpp:261
static TVector< int > indAtivo
Definition TProcura.h:455
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().
Definition TProcura.h:21
void InserirRegisto(TVector< TResultado > &resultados, int inst, int conf)
Insere um novo registo de resultados.
Definition TProcura.cpp:273
virtual void LimparEstatisticas(clock_t &inicio)
Chapar antes da execução do algoritmo. Limpa valores estatísticos, e fixa o instante limite de tempo para...
Definition TProcura.cpp:94
static TVector< TParametro > parametro
Parâmetros a serem utilizados na configuração atual.
Definition TProcura.h:451
void AjudaUtilizacao(const char *programa)
Mostra ajuda de utilização do programa.
Definition TProcura.cpp:656
void EditarConfiguracoes()
Permite ao utilizador editar as configurações.
Definition TProcura.cpp:361
void SolicitaInstancia()
Solicita ao utilizador o ID da instância a utilizar, permitindo alterar também o prefixo do ficheiro.
Definition TProcura.cpp:916
int Parametro(int id)
Definition TProcura.h:479
bool TempoExcedido()
Definition TProcura.h:469
virtual void TesteEmpirico(TVector< int > instancias, bool mostrarSolucoes=true, char *ficheiro=NULL)
Executa testes empíricos, em todas as configurações guardadas, nas instâncias selecionadas.
Definition TProcura.cpp:509
Item & First()
Definition TVector.h:154
TVector< Item > & Remove(Item const &i)
Remove todas as ocorrências de um dado elemento.
Definition TVector.h:707
TVector< Item > & Add(Item a)
Definition TVector.h:115
Item & Last()
Definition TVector.h:157
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
Definition TVector.h:759
int Count() const
Definition TVector.h:160
void srand(unsigned int seed, int seq)
Inicializa a semente da geração pseudo-aleatória.
Definition TRand.cpp:34
Estrutura para registo de um parâmetro.
Definition TProcura.h:110
int valor
valor do parametro
Definition TProcura.h:114
int max
valor máximo que o parametro pode tomar
Definition TProcura.h:118
int min
valor mínimo que o parametro pode tomar
Definition TProcura.h:116