|
TProcura
Biblioteca em C++ para testes paramΓ©tricos de algoritmos, e coleΓ§Γ£o de algoritmos de procura e otimizaΓ§Γ£o
|
ExecuΓ§Γ£o de exemplo com base no problema do Aspirador.
No Visual Studio, selecione o projeto TProcuraConstrutiva, e execute. No Linux na pasta .../TProcura/Construtiva/Teste$ execute make seguido de ./bin/Release/TProcuraConstrutiva
Pode acompanhar o teste executando as aΓ§Γ΅es localmente.
Nota: ao executar no terminal, os parΓ’metros, indicadores e outros elementos, aparecem com realce de cor para facilitar a leitura.
ββ Teste TProcuraConstrutiva βββ
β 1 - Aspirador β
β 2 - Puzzle 8 β
β 3 - 8 Damas β
β 4 - PartiΓ§Γ£o β
ββββββββββββββββββββββββββββββββ
OpΓ§Γ£o: 1
Selecione o problema do Aspirador: 1.
A versΓ£o deste problema foi generalizada no cΓ³digo para poderem existir N salas, umas ao lado das outras, e nΓ£o apenas 2 como no manual, sendo em tudo o resto igual.
Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): NADA | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 4 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): ignorar | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β [*] * . * ββ β° Menu ββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββ β 1 π InstΓ’ncia β 2 π Explorar β 3 β ParΓ’metros β 4 β SoluΓ§Γ£o β β 5 β Indicadores β 6 βΊ Executar β 7 π οΈ ConfiguraΓ§Γ΅es β 8 π§ͺ Teste β βββββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββ OpΓ§Γ£o:
Esta Γ© a informaΓ§Γ£o apresentada no teste manual. Na zona superior aparece o nome do problema, seguido dos parΓ’metros e valores atuais. Podemos ver que o primeiro parΓ’metro Γ© o ALGORITMO, e estΓ‘ selecionado por omissΓ£o a Largura Primeiro. Em termos de NIVEL_DEBUG estΓ‘ selecionado o valor NADA, ou seja, nΓ£o Γ© mostrada informaΓ§Γ£o de debug. Seguem-se outros parΓ’metros, os quais alguns serΓ£o apresentados ao longo desta execuΓ§Γ£o. Os nomes dos parΓ’metros e valores, sΓ£o os mesmos utilizados no cΓ³digo, e por esse motivo nΓ£o Γ© utilizada acentuaΓ§Γ£o.
Temos o estado atual apΓ³s a caixa dos parΓ’metros, que tem uma visualizaΓ§Γ£o dependente do problema.
ApΓ³s o estado temos o menu, com as opΓ§Γ΅es de inicializar numa nova instΓ’ncia, explorar o espaΓ§o de estados, editar os parΓ’metros atuais, ver a soluΓ§Γ£o atual, escolher os indicadores a calcular apΓ³s execuΓ§Γ£o, executar o algoritmo selecionado com os parΓ’metros atuais, editar configuraΓ§Γ΅es e executar um teste empΓrico com as configuraΓ§Γ΅es atuais.
Tanto os parΓ’metros como o menu, repetem-se em cada interaΓ§Γ£o. Para evitar repetiΓ§Γ£o na documentaΓ§Γ£o, o output Γ© cortado sempre que nΓ£o existam ambiguidades.
Escreva os seguintes nΓΊmeros separados por Enter: 1; 2
Temos hipΓ³tese aqui de alterar o prefixo da instΓ’ncia, ΓΊtil para situaΓ§Γ΅es em que se lΓͺ os dados da instΓ’ncia de um ficheiro. Neste problema as instΓ’ncias sΓ£o geradas aleatoriamente, e nΓ£o lidas de ficheiros, pelo que escolhemos apenas o ID da instΓ’ncia.
TΓnhamos inicialmente uma instΓ’ncia com 4 salas, estando o aspirador na terceira sala, estando as duas primeiras sujas:
OpΓ§Γ£o: 1 ββ π InstΓ’ncia βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β ID atual: 4 Intervalo: [2β50] β Prefixo atual: 'instancia_' βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Novo ID (ENTER mantΓ©m) ou novo prefixo (texto): 2 Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): NADA | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 4 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): ignorar | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ * [*] ββ β° Menu ββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββ β 1 π InstΓ’ncia β 2 π Explorar β 3 β ParΓ’metros β 4 β SoluΓ§Γ£o β β 5 β Indicadores β 6 βΊ Executar β 7 π οΈ ConfiguraΓ§Γ΅es β 8 π§ͺ Teste β βββββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββ OpΓ§Γ£o:
Agora temos uma instΓ’ncia com 2 salas, estando ambas sujas, e o aspirador estΓ‘ na segunda: A representaΓ§Γ£o do estado Γ© algo que Γ© implementado na sub-classe (neste caso em CAspirador::Debug()), de modo a se poder visualizar o estado em que estamos. Ao chamar Inicializar() podemos trocar o ID da instΓ’ncia. Para este problema o ID Γ© utilizado para definir a dimensΓ£o da instΓ’ncia, e assim podemos escolher em ter uma instΓ’ncia maior ou menor. A sujidade das casas Γ© gerada aleatoriamente. No entanto a semente aleatΓ³ria Γ© um parΓ’metro (P3(SEMENTE): 1), sendo sempre a mesma caso nΓ£o se altere, garantindo assim que podemos obter a mesma instΓ’ncia mais tarde.
A partir do estado atual, introduza: 2; 1; 2.
OpΓ§Γ£o: 2 ββ€β π° g:0 π― h:3 β 1|2 βββ β * [*] β ββ β‘ ββββ esq asp π Sucessor [1-2, aΓ§Γ£o(Γ΅es), exe]: 1 ββ β βββββββββββββββ β AΓ§Γ£o executada. βββββββββββββββββββββ ββ€β π° g:0 π― h:3 β 2|4 βββ β [*] * β ββ β‘ ββββ dir asp π Sucessor [1-2, aΓ§Γ£o(Γ΅es), exe]: 2 ββ β βββββββββββββββ β AΓ§Γ£o executada. βββββββββββββββββββββ ββ€β π° g:0 π― h:2 β 3|6 βββ β [.] * β ββ β‘ ββββ dir asp π Sucessor [1-2, aΓ§Γ£o(Γ΅es), exe]:
Podemos ver que o estado atual tem dois sucessores, o aspirador pode ir para a sala da esquerda, ou aspirar a sala atual. Escolhemos o primeiro estado, e depois escolhemos o segundo, aspirar. Os sucessores sΓ£o visualizados pelas suas aΓ§Γ΅es, existindo trΓͺs possΓveis aΓ§Γ΅es: esq, dir, asp. Para indicar o nΓΊmero do sucessor, Γ© preciso ver, jΓ‘ que o nΓΊmero 1 Γ© para a primeira aΓ§Γ£o vΓ‘lida, na lista de sucessores. No entanto, as aΓ§Γ΅es sΓ£o unΓvocas. Podemos indicar vΓ‘rias aΓ§Γ΅es de uma sΓ³ vez.
Neste momento estamos na sala da esquerda, com a sala limpa, mas a sala da direita estΓ‘ suja. Complete os movimentos necessΓ‘rios para limpar ambas as salas, e saia da exploraΓ§Γ£o dos sucessores. Utilize desta vez o nome das aΓ§Γ΅es e nΓ£o nΓΊmero, introduzindo duas aΓ§Γ΅es de uma vez. Introduza: dir asp; ENTER. Note que "dir asp" podem ser introduzidas de uma vez.
π Sucessor [1-2, aΓ§Γ£o(Γ΅es), exe]: dir asp ββ β ββββββββββββββββ β Executadas 2 aΓ§Γ΅es. ββββββββββββββββββββββ ββ€β π° g:0 β 6|12 βββ β . [.] β ββ β‘ ββββ esq asp π Sucessor [1-2, aΓ§Γ£o(Γ΅es), exe]: β΅ Aspirador ... β . [.] ββ β° Menu ββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββ β 1 π InstΓ’ncia β 2 π Explorar β 3 β ParΓ’metros β 4 β SoluΓ§Γ£o β β 5 β Indicadores β 6 βΊ Executar β 7 π οΈ ConfiguraΓ§Γ΅es β 8 π§ͺ Teste β βββββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββ OpΓ§Γ£o:
Ao receber as duas aΓ§Γ΅es, estas foram executadas e indicado o nΓΊmero de aΓ§Γ΅es executados com sucesso. Se fosse uma soluΓ§Γ£o completa, todas as aΓ§Γ΅es atΓ© ao estado final, esta operaΓ§Γ£o seria uma verificaΓ§Γ£o da soluΓ§Γ£o. Caso exista alguma aΓ§Γ£o invΓ‘lida, a aΓ§Γ£o Γ© rejeitada e o estado atual fica na primeira aΓ§Γ£o invΓ‘lida. Assim, Γ© possΓvel verificar ou identificar erros em soluΓ§Γ΅es obtidas por mΓ©todos externos, sendo apresentada a evidΓͺncia de falha.
Para um problema novo, Γ© sempre importante que explore os sucessores, nomeadamente procure resolver instΓ’ncias pequenas no modo manual. Tem duas vantagens: identifica bugs que tenha na sua implementaΓ§Γ£o; ganha entendimento sobre o problema em questΓ£o, que lhe poderΓ‘ levar a identificar optimizaΓ§Γ΅es que de outra forma lhe passariam desapercebidas.
O resultado da resoluΓ§Γ£o manual da aΓ§Γ£o anterior, Γ© visualizar apenas o ΓΊltimo estado. No entanto houve um caminho, que ficou guardado. Introduza: 4.
OpΓ§Γ£o: 4 ββ β SoluΓ§Γ£o ββ β * [*] (π° g:0) β‘ β esq β asp β dir β asp β . [.] (π° g:4) π― Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): NADA | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 4 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): ignorar | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β . [.] ... OpΓ§Γ£o:
Neste problema uma soluΓ§Γ£o Γ© um conjunto de aΓ§Γ΅es, o caminho desde o estado inicial atΓ© ao estado final. Γ mostrado esse caminho visualizando as aΓ§Γ΅es a partir do estado inicial. Foram 4 movimentos, mas houve um desperdΓcio. No primeiro movimento, poderΓamos ter logo aspirado. Em outros problemas, a soluΓ§Γ£o pode ser apenas o estado final. Notar ainda na letra g, seguida de um nΓΊmero. Esta letra representa o custo g(n) no manual, e sempre que ocorra significa o custo desde o estado inicial atΓ© esse estado. Neste problema o custo nΓ£o foi definido, pelo que Γ© adoptado o valor de 1 unidade por cada movimento.
A visualizaΓ§Γ£o de aΓ§Γ΅es Γ© mais curta e simples, mas podemos ver todos os estados tambΓ©m. Para isso Γ© preciso alterar o parΓ’metro P6(VER_ACOES).
Vamos editar o parΓ’metro P6(VER_ACOES). Introduza: 3
OpΓ§Γ£o: 3 ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro (1 a 7) β P2(NIVEL_DEBUG): NADA (0 a 4) β P3(SEMENTE): 1 (1 a 1000000) β P4(LIMITE_TEMPO): 10 (1 a 3600) β P5(LIMITE_ITERACOES): 0 (0 a 1000000000) β P6(VER_ACOES): 4 (1 a 100) β P7(LIMITE): 0 (-1 a 1000000) β P8(ESTADOS_REPETIDOS): ignorar (1 a 3) β P11(BARALHAR_SUCESSORES): 0 (0 a 1) βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ParΓ’metro:
Podemos ver todos os parΓ’metros e valores mΓnimos e mΓ‘ximos.
Podemos tambΓ©m editar qualquer parΓ’metro, como Γ© o caso, o parΓ’metro 6, tem o valor 4, e pretendemos colocar a 1. Caso seja definido no problema novos parΓ’metros, ficariam aqui tambΓ©m expostos ao utilizador para ediΓ§Γ£o. Introduza: 6; 1; ENTER; 4.
ParΓ’metro: 6 ββ β P6(VER_ACOES) βββββββββββββββββββββββββββββββββββββββββββββββββββ β Mostra estado a cada K aΓ§Γ΅es. Se 1 mostra sempre estados e nunca aΓ§Γ΅es. β Intervalo: 1 a 100 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ VER_ACOES (atual 4): 1 ... OpΓ§Γ£o: 4 ββ β SoluΓ§Γ£o ββ β * [*] (π° g:0) β‘ β [*] * (π° g:1) β‘ β [.] * (π° g:2) β‘ β . [*] (π° g:3) β‘ β . [.] (π° g:4) π― Aspirador ... β . [.] ... OpΓ§Γ£o:
Vemos agora a soluΓ§Γ£o, o caminho com todos os estados intermΓ©dios do estado inicial atΓ© ao estado final.
Coloque na instΓ’ncia inicial, nΓΊmero 2, com nΓvel de debug mΓ‘ximo: 1; 2; 3; 2; 4; ENTER; 6.
A opΓ§Γ£o 1 jΓ‘ sabemos, inicia uma instΓ’ncia, neste caso 2. A opΓ§Γ£o 4 vamos alterar neste caso o parΓ’metro nΓvel de debug. HΓ‘ vΓ‘rios nΓveis de debug, sendo o 4 o valor que mostra a informaΓ§Γ£o mais completa, embora extensa.
... ParΓ’metro: 2 ββ β P2(NIVEL_DEBUG) βββββββββββββββββββββββββββββββββββββββββββββββββ β NΓvel de debug, de reduzido a completo. β 0: NADA β 1: ATIVIDADE β 2: PASSOS β 3: DETALHE β 4: COMPLETO βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ NIVEL_DEBUG (atual 0): 4 ... * [*] ... OpΓ§Γ£o: 6
A opΓ§Γ£o 6 executa o algoritmo selecionado, que Γ© a Largura Primeiro.
OpΓ§Γ£o:
ββ€β βΊ ExecuΓ§Γ£o iniciada βββ
ββ ββ€β π° g:0 βββ { }
β * [*]
β ββ ββ€β π 1 π° g:1 β 1|2 βββ esq
β β [*] *
β ββ ββ€β π 2 π° g:1 β 1|2 βββ asp
β * [.]
ββ ββ€β π 1 π° g:1 β 1|2 βββ { π 2 }
β [*] *
β ββ ββ€β π 3 π° g:2 β 2|4 βββ dir
β β * [*]
β ββ ββ€β π 4 π° g:2 β 2|4 βββ asp
β [.] *
ββ ββ€β π 2 π° g:1 β 2|4 βββ { π 3 π 4 }
β * [.]
β ββ ββ€β π 5 π° g:2 β 3|6 βββ esq
β β [*] .
β ββ ββ€β π 6 π° g:2 β 3|6 βββ asp
β * [.]
ββ ββ€β π 3 π° g:2 β 3|6 βββ { π 4 π 5 π 6 }
β * [*]
β ββ ββ€β π 7 π° g:3 β 4|8 βββ esq
β β [*] *
β ββ ββ€β π 8 π° g:3 β 4|8 βββ asp
β * [.]
ββ ββ€β π 4 π° g:2 β 4|8 βββ { π 5 π 6 π 7 π 8 }
β [.] *
β ββ ββ€β π 9 π° g:3 β 5|10 βββ dir
β β . [*]
β ββ ββ€β π 10 π° g:3 β 5|10 βββ asp
β [.] *
ββ ββ€β π 5 π° g:2 β 5|10 βββ { π 6 π 7 π 8 π 9 π 10 }
β [*] .
β ββ ββ€β π 11 π° g:3 β 6|12 βββ dir
β β * [.]
β ββ ββ€β π 12 π° g:3 β 6|12 βββ asp
β [.] .
β π― SoluΓ§Γ£o encontrada! π° g:3
β [.] .
ββ ParΓ’metros β P1=1 P2=4 P3=1 P4=10 P5=0 P6=1 P7=0 P8=1 P11=0
ββ§β π ExecuΓ§Γ£o terminada β± βββ
Aspirador
ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): COMPLETO | P3(SEMENTE): 1
β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 1 | P7(LIMITE): 0
β P8(ESTADOS_REPETIDOS): ignorar | P11(BARALHAR_SUCESSORES): 0
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[.] .
ββ β Indicadores βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β I1(IND_CUSTO): 3 | I2(Tempo(ms)): 0 | I3(IteraΓ§Γ΅es): 0 | I4(IND_EXPANSOES): 6 |
β I5(IND_GERACOES): 12 | I6(IND_LOWER_BOUND): 0
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ β° Menu ββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββ
β 1 π InstΓ’ncia β 2 π Explorar β 3 β ParΓ’metros β 4 β SoluΓ§Γ£o β
β 5 β Indicadores β 6 βΊ Executar β 7 π οΈ ConfiguraΓ§Γ΅es β 8 π§ͺ Teste β
βββββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββ
OpΓ§Γ£o:
Verificar que o nΓΊmero de expansΓ΅es Γ© 6 e geraΓ§Γ΅es Γ© 12. O resultado da procura Γ© 3, sendo recolhido pelo I1(IND_CUSTO). Significa que a procura encontrou uma soluΓ§Γ£o de comprimento 3. Notar que o I3(IteraΓ§Γ΅es) e I6(IND_LOWER_BOUND) ficaram a 0, jΓ‘ que nΓ£o sΓ£o atualizados neste algoritmo.
No caso de nΓ£o ter os resultados iguais, confirme se todos os parΓ’metros estΓ£o iguais.
Podemos ver a soluΓ§Γ£o, tendo ficado guardada, tal como na resoluΓ§Γ£o manual. Introduza: 4.
OpΓ§Γ£o: 4
ββ β SoluΓ§Γ£o ββ
* [*] (π° g:0) β‘
* [.] (π° g:1) β‘
[*] . (π° g:2) β‘
[.] . (π° g:3) π―
...
[.] .
...
OpΓ§Γ£o:
Verifique que tem apenas 3 movimentos, ao contrΓ‘rio dos 4 obtidos na resoluΓ§Γ£o manual.
A Γ‘rvore da procura em largura nΓ£o Γ© desenhada na visualizaΓ§Γ£o textual, apenas na procura em profundidade.
Nesta procura o que podemos ver Γ© cada estado expandido e respetivos sucessores gerados. Cada estado irΓ‘ aparecer pela primeira vez quando Γ© gerado, e uma segunda vez quando Γ© expandido.
Existe uma etiqueta em cada estado que permite confirmar que cada estado gerado serΓ‘ expandido uma sΓ³ vez. Γ tambΓ©m mostrada a lista dos estados gerados nΓ£o expandidos em cada passo. O estado expandido Γ© sempre o primeiro dessa lista, que consta na iteraΓ§Γ£o anterior.
Na procura em largura expandimos sempre o estado gerado hΓ‘ mais tempo.
Temos no entanto o mesmo estado inicial a ser gerado. De facto, o primeiro sucessor na segunda expansΓ£o, o estado 3, Γ© o estado inicial que Γ© gerado novamente.
Podemos lidar com estados repetidos de duas formas:
Altere a opΓ§Γ£o para remover os repetidos com base nos ascendentes, e o debug para nΓvel 3: 1; 2; 3; 8; 2; 2; 3; ENTER; 6.
... OpΓ§Γ£o: 6 ββ€β βΊ ExecuΓ§Γ£o iniciada βββ ββ ββ€β π° g:0 βββ { } β * [*] ββ ββ€β π 1 π° g:1 β 1|2 βββ { π 2 } β [*] * ββ ββ€β π 2 π° g:1 β 2|3 βββ { π 3 } β * [.] ββ ββ€β π 3 π° g:2 β 3|4 βββ { π 4 } β [.] * ββ ββ€β π 4 π° g:2 β 4|5 βββ { π 5 } β [*] . β π― SoluΓ§Γ£o encontrada! π° g:3 β [.] . ββ ParΓ’metros β P1=1 P2=3 P3=1 P4=10 P5=0 P6=1 P7=0 P8=2 P11=0 ββ§β π ExecuΓ§Γ£o terminada β± βββ Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): DETALHE | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 1 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): ascendentes | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ [.] . ββ β Indicadores βββββββββββββββββββββββββββββββββββββββββββββββββββββ β I1(IND_CUSTO): 3 | I2(Tempo(ms)): 0 | I3(IteraΓ§Γ΅es): 0 | I4(IND_EXPANSOES): 5 | β I5(IND_GERACOES): 6 | I6(IND_LOWER_BOUND): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ... OpΓ§Γ£o:
A interaΓ§Γ£o de troca de parΓ’metro nΓ£o Γ© mais mostrada para nΓ£o saturar o texto.
Podemos ver o nΓvel de debug a 3. Tem apenas os estados expandidos, mas nΓ£o vemos os estados gerados. Vemos no entanto a lista dos estados gerados nΓ£o expandidos, confirmando que Γ© claramente menor. Podemos tambΓ©m confirmar que o estado inicial nΓ£o foi um dos gerados, caso contrΓ‘rio seria expandido na 4ΒΊ ou 5ΒΊ expansΓ£o.
Alterar a opΓ§Γ£o para remover os repetidos com base nos gerados, e alterar o debug para nΓvel 2: 1; 2; 3; 8; 3; 2; 2; ENTER; 6.
... OpΓ§Γ£o: 6 ββ€β βΊ ExecuΓ§Γ£o iniciada βββ ββ ββ€β π° g:0 βββ { } ββ ββ€β π 1 π° g:1 β 1|2 βββ { π 2 } ββ ββ€β π 2 π° g:1 β 2|3 βββ { π 3 } ββ ββ€β π 3 π° g:2 β 3|4 βββ { π 4 } ββ ββ€β π 4 π° g:2 β 4|5 βββ { π 5 } β π― SoluΓ§Γ£o encontrada! π° g:3 β [.] . ββ ParΓ’metros β P1=1 P2=2 P3=1 P4=10 P5=0 P6=1 P7=0 P8=3 P11=0 ββ§β π ExecuΓ§Γ£o terminada β± 9ms βββ Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): PASSOS | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 1 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): gerados | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ [.] . ββ β Indicadores βββββββββββββββββββββββββββββββββββββββββββββββββββββ β I1(IND_CUSTO): 3 | I2(Tempo(ms)): 9 | I3(IteraΓ§Γ΅es): 0 | I4(IND_EXPANSOES): 5 | β I5(IND_GERACOES): 6 | I6(IND_LOWER_BOUND): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ... OpΓ§Γ£o:
Podemos ver que o estado jΓ‘ nΓ£o Γ© mostrado. Em cada expansΓ£o Γ© mostrado o custo (g) seguido de dois nΓΊmeros: expansΓ΅es e geraΓ§Γ΅es realizadas atΓ© ao momento. A lista com os estados gerados nΓ£o expandidos, Γ© ainda visualizada no final. No caso deste problema o estado Γ© visualizado numa sΓ³ linha, mas em outros problemas estes dois nΓveis de debug podem fazer diferenΓ§a. Notar que nΓ£o houve alteraΓ§Γ£o no nΓΊmero de expansΓ΅es e geraΓ§Γ΅es, muito embora a tΓ©cnica para lidar com os estados repetidos seja distinta.
Γ importante observar a procura em instΓ’ncias pequenas, para poder observar ineficiΓͺncias, como os estados repetidos, ou mesmo bugs.
O nΓvel de debug 1 insere um # por cada 1000 expansΓ΅es, de modo a dar alguma noΓ§Γ£o de como vai a procura, e o nΓvel 0 nΓ£o dΓ‘ qualquer informaΓ§Γ£o.
Repor a opΓ§Γ£o de ignorar os repetidos, colocar o debug no nΓvel 1, e procurar resolver uma instΓ’ncia maior: 1; 10; 3; 8; 1; 2; 1; ENTER; 6.
Pode haver um problema de memΓ³ria. A instΓ’ncia Γ© demasiado grande, e sem remover repetidos, rapidamente gera demasiados estados:
... * * . * * [*] * . . . ... OpΓ§Γ£o: 6 ββ€β βΊ ExecuΓ§Γ£o iniciada βββ#######...####### β π― SoluΓ§Γ£o encontrada! π° g:13 β [.] . . . . . . . . . ββ ParΓ’metros β P1=1 P2=1 P3=1 P4=10 P5=0 P6=1 P7=0 P8=1 P11=0 ββ§β π ExecuΓ§Γ£o terminada β± 626ms βββ Aspirador ββ β ParΓ’metros ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β P1(ALGORITMO): Largura Primeiro | P2(NIVEL_DEBUG): ATIVIDADE | P3(SEMENTE): 1 β P4(LIMITE_TEMPO): 10 | P5(LIMITE_ITERACOES): 0 | P6(VER_ACOES): 1 | P7(LIMITE): 0 β P8(ESTADOS_REPETIDOS): ignorar | P11(BARALHAR_SUCESSORES): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ [.] . . . . . . . . . ββ β Indicadores βββββββββββββββββββββββββββββββββββββββββββββββββββββ β I1(IND_CUSTO): 13 | I2(Tempo(ms)): 626 | I3(IteraΓ§Γ΅es): 0 | I4(IND_EXPANSOES): 516031 | β I5(IND_GERACOES): 1513017 | I6(IND_LOWER_BOUND): 0 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ... OpΓ§Γ£o:
SΓ£o demasiados estados gerados, 1,5 milhΓ΅es, em 0.4 segundos. HΓ‘ um # que Γ© colocado no output a cada 1000 expansΓ΅es. Se desconfiamos que com tanto estado, dificilmente a soluΓ§Γ£o pode ser Γ³ptima, podemos ver a soluΓ§Γ£o. Introduza: 4
OpΓ§Γ£o: 4
ββ β SoluΓ§Γ£o ββ
* * . * * [*] * . . . (π° g:0) β‘
* * . * * * [*] . . . (π° g:1) β‘
* * . * * * [.] . . . (π° g:2) β‘
* * . * * [*] . . . . (π° g:3) β‘
* * . * * [.] . . . . (π° g:4) β‘
* * . * [*] . . . . . (π° g:5) β‘
* * . * [.] . . . . . (π° g:6) β‘
* * . [*] . . . . . . (π° g:7) β‘
* * . [.] . . . . . . (π° g:8) β‘
* * [.] . . . . . . . (π° g:9) β‘
* [*] . . . . . . . . (π° g:10) β‘
* [.] . . . . . . . . (π° g:11) β‘
[*] . . . . . . . . . (π° g:12) β‘
[.] . . . . . . . . . (π° g:13) π―
NΓ£o houve desperdΓcio visivel nesta soluΓ§Γ£o. O algoritmo procura em largura garante-nos que esta soluΓ§Γ£o Γ© Γ³tima, dado que o custo de cada aΓ§Γ£o Γ© unitΓ‘rio.
Para lidar com o problema de memΓ³ria, podΓamos limitar a procura em largura com o parΓ’metro limite, fixando a 100 ou 1000 estados, mas perdendo a optimalidade.
A melhor soluΓ§Γ£o para lidar com este problema Γ© eliminar estados repetidos, idealmente todos os gerados. Mas se mesmo assim a procura em largura resultar num problema de memΓ³ria, a utilizaΓ§Γ£o de um limite, poderΓ‘ ser uma opΓ§Γ£o, mantendo-se apenas um determinado nΓΊmero limitado de estados gerados nΓ£o expandidos. Esta abordagem perde a optimalidade, e tambΓ©m a garantia de construir um caminho do estado inicial ao final, o que poderΓ‘ nΓ£o ser problemΓ‘tico em alguns problemas.
Com a procura em largura, atΓ© que tamanho consegue obter a soluΓ§Γ£o Γ³tima do aspirador?
Depende das condiΓ§Γ΅es de execuΓ§Γ£o, vamos colocar na resposta o VPL com a 512MB. Consegue resolver com P8(Repetidos)=gerados, atΓ© Γ instΓ’ncia 19, existindo problema de memΓ³ria na instΓ’ncia 20. Num computador pessoal pode variar, e o limite de tempo pode ocorrer antes do problema de memΓ³ria. Limitando a 1000 e mantendo os replicados gerados, a procura em largura consegue resolver atΓ© Γ instΓ’ncia 50, a maior considerada no cΓ³digo. A utilizaΓ§Γ£o do limite nΓ£o permite garantir a otimalidade da soluΓ§Γ£o A utilizaΓ§Γ£o de repetidos com base nos ascendentes, permite tambΓ©m resolver o problema de memΓ³ria, mas ganha-se o problema de tempo, sendo uma soluΓ§Γ£o viΓ‘vel atΓ© Γ instΓ’ncia 44, mantendo o tempo limite em 10 segundos.