• Nenhum resultado encontrado

5 ALGORITMO GENÉTICO EVOLUCIONÁRIO ESPECIALIZADO:

5.5 IMPLEMENTAÇÃO COMPUTACIONAL DO AGE

5.5.1 Detalhes da implementação computacional

A implementação computacional do AGE também foi realizada utilizando-se a linguagem C por meio da ferramenta de desenvolimento Open Source DevC++, compilador GCC 4.8.1. Os resultados computacionais foram obtidos utilizando um computador com CPU Intel Core i3-M380 @2.53 GHz, com o Sistema Operacional Microsoft Windows 7 Professional (32 bits). Os métodos utilizados estão apresentados a seguir, alguns, reaproveitados do BRKGA, principalmente no que concerne à Estratégia de Carregamento de Lai e Chan [20], dentro do Decodificador Procedimento

de Carregamento de Resende e Gonçalves [12]:

1. GetTickCount(): Realiza a contagem de tempo que o Algoritmo AGE utiliza para apresentar a proposta de solução final, com respectiva fitness.

2. AlimentarValores(): Método aproveitado da implementação do BRKGA (Subseção 4.3.3), no qual definem-se os parâmetros de entrada do algoritmo, e criam-se uma estrutura inicial para cada contêiner, contendo uma lista de EMS, uma variável booleana para indicar se o contêiner já foi aberto e uma variável que atualiza o volume utilizado dentro do contêiner. O método também inicializa as matrizes auxiliares que serão utilizadas no Processo DP: EmsReaproveitados, EmsSobrepostos, EmsUtilizados. Todo contêiner inicializa contendo um EMS útil de tamanho máximo, que é o próprio contêiner. E cada cromossomo possui n contêiners disponíveis para efetuar o carregamento.

3. GerarPopulacaoInicial(): Gera a população inicial utilizando duas estratégias (valores aleatórios e Heurística HFPI, respectivamente), armazenando os valores em uma matriz nomeada Apopde p = αn + 1 linhas e 3n colunas. As linhas da matriz são os cromossomos, e os valores de cada linha são os genes de cada cromossomo das subsequências 1a-S, 2a-S e 3a-2a-S. A primeira estratégia gera a primeira metade de cromossomos da população

126 inicial, cromossomo 1 a 𝑝

2, de maneira puramente aleatória e tal como definido na Subseção 5.2.2. A segunda estratégia privilegia o carregamento de caixas maiores, utilizando a Heurística HFPI (Subseção 5.3.1). Uma linha a mais é adicionada e preenchida inicialmente apenas com valores iguais a zero, sendo posteriormente utilizada para armazenar os dados do cromossomo descendente mutante.

4. CarregarCaixa(): Método aproveitado da implementação do BRKGA, verifica qual o primeiro contêiner aberto, para cada cromossomo. Em seguida, verifica qual o primeiro EMS útil de cada contêiner aberto em que seja possível carregar a caixa atual i, descrita na matriz Apop, que é então atualizada a cada iteração. Esse método será repetido para todas as caixas e para todos os cromossomos.

5. VerificarSobreposicao(): Verifica se a caixa carregada sobrepõe EMS úteis dentro do contêiner utilizado e de acordo com o pseudocódigo 5.4. Se verdadeiro, o EMS sobreposto será subtraído da parcela da caixa sobreposta pelo Processo DP dentro do método CalcularEMSsobrepostos (abaixo). Caso contrário, o EMS não sobreposto, será armazenado na matriz auxiliar EMSReaproveitados.

6. CalcularEMSsobrepostos(): Calcula o processo DP para os EMS que foram sobrepostos pela caixa atual carregada de acordo com o pseudocódigo 5.4, não incluindo o próprio EMS selecionado para realizar o carregamento. Os EMS gerados são armazenados na matriz EMSsobrepostos.

7. TestarEMSsobrepostos(): Verifica cinco testes de eliminação de EMS (quatro destes aproveitados da implementação do BRKGA), em todas as listas de EMS de cada contêiner que foram sobrepostos pela caixa atual. É um teste prévio, visando à diminuição da lista final de EMS do método calcularEMS.

8. CalcularEMS(): Método aproveitado da implementação do BRKGA, calcula o Processo DP apenas no EMS em que a caixa i foi carregada. São gerados seis EMS que são armazenados na lista de EMS do contêiner utilizado. Nesta mesma lista, também são incluídos os EMS contidos nas matrizes EMSsobrepostos e EMSreaproveitados.

9. TestarEMS(): Verifica os cinco testes de eliminação de EMS, na lista de EMS do contêiner utilizado, quatro destes, aproveitados da implementação do BRKGA.

10. OrdenarEMS(): Ordena a lista de EMS do contêiner utilizado, segundo as heurísticas BBL e BLB dentro do Processo DP, e a partir da decodificação da subsequência 2a-S.

127 11. CalcularFitness(): Método aproveitado da implementação do BRKGA, calcula o

volume não utilizado de todos os contêiners abertos, finalizando com o cálculo do valor da fitness final.

12. OrdenarPopulacaoInicial(): Promove a ordenação das p primeiras linhas da matriz Apop (desconsiderando a última linha que é destinada aos valores do cromossomo mutante) de acordo com a ordem crescente das fitness associadas a cada linha (cromossomo).

13. GerarPais(): Seleciona aleatoriamente quatro linhas distintas da matriz Apop. Após, compara a fitness associada às duas primeiras linhas da matriz, e a que possuir menor valor será o primeiro cromossomo pai selecionado. Compara, na sequência, as fitness associadas às duas últimas linhas selecionadas aleatoriamente, computando a linha com menor valor

de fitness como sendo o segundo cromossomo pai escolhido a gerar um descendente.

14. RecombinacaoPMX(): Gera um número aleatório k1 até a metade da sequência 1a-S, e um segundo número aleatório k2 que pode variar desde k1 até 50% do tamanho de 1a-S. Em seguida, realiza a Recombinação PMX entre as linhas selecionadas pelo método GerarPais(), segundo a lógica descrita em 5.3.2. Analogamente ao que acontece com a recombinação das subsequências 1a-S dos dois cromossomos pais, executa-se também para os genes associados das subsequências 2a-S e 3a-S.

15. MutacaoFilho(): Gera aleatoriamente dois valores que possuam uma distância de t% entre si, porcentagem esta que é definida como um parâmetro de entrada para o algoritmo AGE. Depois, o algoritmo permuta as caixas da subsequência 1a-S, e os respectivos valores associados nas subsequências 2a-S e 3a-S, armazenando os dados na última linha da matriz Apop, definindo esta como o cromossomo filho mutante da iteração i.

16. CriarCarregamentoMutante(): Realiza a execução do Algoritmo AGE apenas para a última linha da matriz Apop, utilizando desde o método 4, CarregarCaixa, até o método 10, ordenarEMS.

17. VerificarFitnessMutante(): Calcula-se a fitness apenas para a última linha da matriz Apop (cromossomo mutante) através do método 11, calcularFitness(). Realiza-se também a execução do método 12, ordenarPopulacaoInicial(), mas considerando todas as linhas da matriz Apop, incluindo a linha que inclui o mutante descendente (que pode ou não estar incluído na atualização da população, dentro das p primeiras melhores linhas).

128

2

2 do algoritmo.

19. Main(): É o método principal do programa que descreve toda a lógica do AGE-E. Unindo todas as informações, apresenta a melhor solução encontrada a partir da sequência de métodos: GetTickCount(), AlimentarValores(), GerarPopulacaoInicial(), CarregarCaixa(), CalcularFitness(), OrdenarPopulacaoInicial(), GerarPais(), RecombinacaoPMX(), MutacaoFilho(), CriarCarregamentoMutante(), CarregarCaixa() (mesmo método aplicado, dessa vez, ao cromossomo filho mutante), CalcularFitness() (novamente, aplicado ao descendente mutante), VerificarFitnessMutante(), OrdenarPopulacaoInicial(), ListarFitness() e ListarMelhorCarregamento(), apresenta a melhor solução encontrada.