• Nenhum resultado encontrado

Sob vários pontos de vista os algoritmos Meméticos podem ser considerados uma forma híbrida de algoritmos Genéticos. Um algoritmo Genético híbrido é um AG clássico que utiliza algum método de busca local (Whitley, 1994). A maneira mais comum de implementar esses algoritmos utiliza um algoritmo simples de busca local para imprimir melhorias em termos de adequação à população inicial e aos indivíduos resultantes de operações de recombinação. Nesse contexto, a busca local pode ser vista como um tipo de “aprendizagem” que ocorre durante o tempo de vida de um indivíduo.

De uma forma geral, os algoritmos Meméticos possuem melhor performance que os algoritmos genéticos clássicos. Goldberg e Voessner (1999) apresentam uma análise teórica sobre a economia que ocorre quando uma hibridização eficaz é realizada em um AG. Essa aprendizagem, no entanto, não é gratuita. As principais vantagens dos algoritmos Meméticos são: a diversificação, devido à população, crossover e mutação, e a intensificação devido às buscas locais.

Duas abordagens utilizando a heurística Memético são propostas neste trabalho. A primeira abordagem é descrita no Quadro 4 e a segunda no Quadro 5. No algoritmo

Memetico1 a construção da solução inicial é realizada através do procedimento

GerarSolN( ), gera-se 20 possíveis soluções para a primeira linha, de acordo com os limites de alocação dos blocos desta linha. Todas essas 20 possibilidades são testadas, e a que possuir a menor função objetivo é escolhida. Esse procedimento é feito para a segunda linha e assim por diante. Metade dos indivíduos são gerados respeitando-se a viabilidade das linhas e a outra metade a viabilidade das colunas. O tamanho da população (tamPop) foi definido igual a 700. O critério de parada foi ajustado em 1000 gerações. A taxa de cruzamento foi fixado em 50% e a taxa de mutação igual a 10%. Os afinamentos desses parâmetros são exibidos na Seção 7.1.2.

Algoritmo Memetico1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

para i de 1 até tamPop faça

S ← GerarSolN() inserir s na população P fim_para

iter ← 1000

Enquanto (iter > 0) faça

para i de 1 até quantCruz faça S1 ← SortearIndividuo (P) S2 ← SortearIndividuo (P) F ← cruzamento(S1 ,S2) F ← buscaLocal(F) inseir F na populacao P fim_para

para i de 1 até quantMut faça

S ← SortearIndividuo(P) S ← Mutacao(S) S ← buscaLocal(S) inserir S na população P fim_para iter  iter - 1 Fim_enquanto

Quadro 4 – Pseudo-código do algoritmo Memetico1

A seleção dos pais para o cruzamento pode ser realizada de duas formas: aleatoriamente ou através do método da roleta. Os dois métodos foram analisados e a seleção aleatória dos pais foi escolhida (Capítulo 7). Caso o primeiro pai sorteado seja viabilizado em linha, o segundo também deverá ser. Foram testados três métodos de cruzamento. No primeiro método de cruzamento (cruzCorte), supondo-se que os pais tenham sido gerados respeitando a viabilidades das linhas, sorteiam-se duas posições do pai1, e o filho receberá as linhas entre essas posições sorteadas do pai1 e as demais linhas do pai2. A Figura 32 exemplifica como esse cruzamento ocorre: duas posições são sorteadas, 2 e 4, o filho (Figura 32 c) recebe as linhas 1 e 5 do pai2 (Figura 32 b) e as linhas 2, 3 e 4 do pai1 (Figura 32 a).

No segundo método de cruzamento (cruzFO) a primeira linha do filho recebe aleatoriamente a primeira linha do pai1 ou pai2, a partir da segunda linha, testa-se no filho a segunda linha do pai1 e do pai2, escolhendo-se a linha que provocar um menor aumento na função objetivo do filho.

No terceiro método de cruzamento (cruzAle) o filho recebe aleatoriamente as linhas do pai1 ou do pai2. Na Seção 7.1.2 são exibidos os testes para decidir que tipo de cruzamento é mais favorável para o algoritmo em questão. O método de cruzamento selecionado foi o cruzCorte.

Figura 32 – CruzCorte: (a) pai1; (b) pai2; (c) Filho resultante do cruzamento do pai1 com o pai2 Após o cruzamento, é realizada uma busca local no filho (linha 11 - Quadro 4), e o mesmo é inserido na população (linha 12 - Quadro 4) no local do pai com maior função objetivo. O procedimento da busca local é realizado 300 vezes. Um indivíduo é sorteado aleatoriamente para sofrer a mutação.

O procedimento mutação – linha 16 (Quadro 4) – modifica uma linha ou coluna da solução corrente, escolhida aleatoriamente. Sorteia-se uma linha (ou coluna) aleatoriamente e a posição inicial de cada bloco é sorteada respeitando-se os limites lógicos do bloco. São sorteadas aleatoriamente cinco linhas (ou colunas) para sofrer a mutação. O objetivo desse procedimento é diversificar as soluções exploradas pelo algoritmo. Após a mutação é realizada a busca local (Seção 6.3), e esse procedimento é executado 300 vezes. A análise de parâmetros e os resultados do Memetico1 são apresentados no Capítulo 7.

A segunda abordagem do Memético (Memetico2) para solucionar o Nonograma é descrita no Quadro 5. Para esta abordagem metade dos indivíduos são gerados respeitando-se a viabilidade das linhas e a outra metade a viabilidade das colunas. Os indivíduos são gerados através do procedimento GerarSolN( ). O tamanho da população (tamPop) foi definido igual a 700 indivíduos. O critério de parada foi ajustado em 1000 gerações. A taxa de cruzamento foi fixado em 50% e a taxa de mutação em 10%.

Algoritmo Memetico2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

para i de 1 até tamPop faça

S ← GerarSolN() inserir S na população P fim_para

iter ← 1000

Enquanto (iter > 0) faça

para i de 1 até quantCruz faça S1 ← SortearIndividuo (P)

S2 ← SortearIndividuo (P)

F1← cruzamento(S1 ,S2)

Se F1= S1 ou F1= S2 faça

para i de 1 até quantInt faça F1← AlteraPixel(F1)

fim_para fim_se

F1← buscaLocal(F1)

F2← AlteraRowCol(F1)

inseir F1 e/ou F2 na populacao P

fim_para

para i de 1 até quantMut faça

S ← SortearIndividuo(P)

para i de 1 até 5 faça

S ← Mutacao(S) fim_para S ← buscaLocal(S) inserir S na população P fim_para iter ←iter - 1 Fim_enquanto

Quadro 5 – Pseudo-código do algoritmo Memetico2

Para realizar o cruzamento, dois indivíduos (pais) são sorteados aleatoriamente. O método de cruzamento selecionado foi o cruzCorte (Capítulo 7). Caso se verifique que o filho gerado é igual a um dos pais, o procedimento AlteraPixel( ) é realizado. Nesse procedimento, escolhe-se a linha (ou coluna) com maior conflito – aplica-se o cálculo da função objetivo para cada linha (ou coluna), caso nessa linha (ou coluna) haja mais pixels pretos do que as restrições, blocos são deslocados para diminuir a quantidade de pixels pretos desta linha (ou coluna). O procedimento AlteraPixel( ) é repetido 10 vezes (nPixel).

Após o procedimento AlteraPixel( ) é realizada uma busca local (Seção 5.3) no filho (linha 14 - Quadro 5). Após a buscalocal( ), é realizado o procedimento AlteraRowCol( ). Caso o indivíduo tenha sido criado respeitando-se as viabilidades das linhas, o procedimento AlteraRowCol( ) só ocorrerá se a quantidade de colunas que não estiverem respeitando as restrições for menor ou igual a 10% do número de colunas, ou seja, em um puzzle de tamanho 20 X 20, se apenas 2 colunas não estiverem respeitando

as restrições das mesmas, o procedimento é realizado. Nesse procedimento, caso o puzzle tenha sido gerado respeitando as viabilidades das linhas, o mesmo será alterado para respeitar as viabilidades das colunas. Tal procedimento ajuda a sair de ótimos locais. A partir dos indivíduos S1 , S2 , F1 e F2 mantém-se na população os dois indivíduos com menor função objetivo (linha 18 - Quadro 5).

O procedimento de mutação – linha 23 (Quadro 5) – modifica uma linha ou coluna da solução corrente, escolhida aleatoriamente. Sorteia-se uma linha (ou coluna) aleatoriamente e a posição inicial de cada bloco é sorteada respeitando-se os limites lógicos do bloco. Esse procedimento é repetido 5 vezes. O objetivo desse procedimento é diversificar as soluções exploradas pelo algoritmo. Após a mutação, a busca local é realizada durante 300 iterações. Os resultados do Memetico2 são apresentados no Capítulo 7.

7 Experimentos Computacionais

O U-teste é um teste não-paramétrico que avalia se duas amostras de observações independentes advêm da mesma distribuição. Este é um dos testes de hipótese mais conhecidos. A hipótese nula do Mann-Whitney é que as duas amostras foram obtidas da mesma população (Monteiro, 2009).

Como resultado do teste de Mann-Whitney, obtém-se p-valores. O nível de significância adotado é de 5% (0,05). Assim, se um algoritmo apresentar p-valor menor ou igual a 0,05, o resultado é favorável a esse algoritmo.

Neste Capítulo será exposto o estudo dos parâmetros, os resultados e as comparações das heurísticas propostas para solucionar o Nonograma. Na Seção 7.1 é exposto o estudo dos parâmetros, a Seção 7.2 exibe os resultados das heurísticas e finalmente na Seção 7.3 é realizada a comparação das heurísticas propostas.

Todos os experimentos foram realizados em uma máquina com processador Intel Core i7-2600K 3,40 GHz e 4Gb de RAM. O sistema operacional usado foi o Ubuntu 12.04.01 LTS e a codificação foi feita utilizando-se a linguagem C++.

Documentos relacionados