Você está na página 1de 46

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA

FLUMINENSE CAMPUS CAMPOS-CENTRO


BACHARELADO EM SISTEMAS DE INFORMAÇÃO

Caio Fernandes Medina e Patrícia Marins Franco

UM ESTUDO DE MÉTODOS DE SELEÇÃO EM ALGORITMOS


GENÉTICOS COM CHAVES ALEATÓRIAS TENDENCIOSAS
APLICADOS AO PROBLEMA DA MOCHILA BINÁRIA

CAMPOS DOS GOYTACAZES


2018
CAIO FERNANDES MEDINA E PATRÍCIA MARINS FRANCO

UM ESTUDO DE MÉTODOS DE SELEÇÃO EM ALGORITMOS


GENÉTICOS COM CHAVES ALEATÓRIAS TENDENCIOSAS
APLICADOS AO PROBLEMA DA MOCHILA BINÁRIA

Trabalho de Conclusão de Curso


apresentado ao Instituto Federal
Fluminense campus Campos-Centro
como requisito parcial para conclusão do
Curso de Bacharelado em Sistemas de
Informação.

Orientador: Prof. Philippe Leal Freire dos


Santos

CAMPOS DOS GOYTACAZES


2018
CAIO FERNANDES MEDINA E PATRÍCIA MARINS FRANCO

UM ESTUDO DE MÉTODOS DE SELEÇÃO EM ALGORITMOS


GENÉTICOS COM CHAVES ALEATÓRIAS TENDENCIOSAS
APLICADOS AO PROBLEMA DA MOCHILA BINÁRIA

Trabalho de Conclusão de Curso


apresentado ao Instituto Federal
Fluminense campus Campos-Centro
como requisito parcial para conclusão do
Curso de Bacharelado em Sistemas de
Informação.

Aprovada em 14 de Setembro de 2018.

BANCA EXAMINADORA:

____________________________________________
Prof. D.Sc. Philippe Leal Freire dos Santos (orientador)
Instituto Federal Fluminense

____________________________________________
Prof. D.Sc. Mark Douglas de Azevedo Jacyntho
Instituto Federal Fluminense

____________________________________________
Prof. M.Sc. Rogério de Avellar Campos Cordeiro
Instituto Federal Fluminense
Dedicamos este trabalho aos nossos
familiares e amigos que de forma direta ou
indireta nos ajudaram a vencer as etapas
deste desafio.
AGRADECIMENTOS

Primeiramente queremos agradecer a Deus, por ter nos concedido saúde e


força, Sem Ele nada disso seria possível. Também somos gratos ao Senhor por ter
nos dado paz e tranquilizado nossos espíritos nos momentos mais difíceis da nossa
trajetória acadêmica até então.
Aos nossos familiares pela paciência, incentivo e compreensão.
Somos gratos a todos os professores que contribuíram com a nossa trajetória
acadêmica, especialmente ao Professor Philippe Leal, responsável pela orientação
do nosso projeto. Obrigado por esclarecer tantas dúvidas e ser tão atencioso e
paciente. Manifestamos aqui nossa gratidão eterna por compartilhar sua sabedoria,
tempo e experiência.
Agradecemos ao Instituto Federal Fluminense, por nos proporcionar um
ambiente criativo e amigável para os estudos. Somos gratos a cada membro do
corpo docente, à direção e à administração dessa instituição de ensino.
“Que os vossos esforços desafiem as
impossibilidades, lembrai-vos de que as
grandes coisas do homem foram
conquistadas do que parecia impossível.”
(Charles Chaplin)
RESUMO

O Problema da Mochila (Knapsack Problem, em inglês) é uma classe de


problemas estudada em áreas como otimização combinatória, análise de algoritmos
e inteligência computacional. É considerado complexo para algoritmos
convencionais, sendo resultados ótimos impraticáveis em tempo computacional
n
aceitável. Trata-se de um problema da ordem 2 , onde n representa o número de
itens a serem tratados. Neste trabalho serão apresentadas heurísticas baseadas nos
Algoritmos Genéticos com Chaves Aleatórias Tendenciosas (BRKGA) com o intuito
de solucionar o Problema da Mochila Binária (PMB), tendo como foco investigar,
dentre os métodos de seleção Roleta, Torneio e o padrão do BRKGA, aquele que
apresenta os melhores resultados para o problema. Nos experimentos
computacionais foram utilizadas instâncias do PMB a fim de avaliar o desempenho
dos algoritmos propostos.

Palavras-chave: Algoritmos Genéticos, Problema da Mochila, Heurísticas,


Metaheurísticas, Métodos de Seleção.
ABSTRACT

The Knapsack Problem is a class of problem are study in area like:


Combinatorial Optimization, Algorithm Analysis and Computational Intelligence. It is
considered complex for conventional algorithms, being impractical great results in
acceptable computational time. It is a problem of order 2n, where n represents the
number of items to be treated. In this monograph we will be presents heuristics
based in Biased Random Key Genetic Algorithms (BRKGA) with propose to solve the
Knapsack Problem (PMB), taking focus to investigate, among selection methods
Roulette, Tournament and the simple BRKGA, the one who presents the best results
of the problem. In the computational experiments was used instances of PMB in
order to evaluated the performance of propose algorithm.

Keywords: Genetic Algorithms, Knapsack Problem, Decoder, Heuristics,


Metaheuristics. Selection Methods.
LISTA DE FIGURAS

Figura 1: Fluxograma de um Algoritmo Genético. .................................................................. 9


Figura 2: Processo de evolução da população no RKGA (Extraída de Santos, 2018).......... 11
Figura 3: Exemplo de cruzamento uniforme parametrizado. ................................................ 12
Figura 4: Fluxograma de um BRKGA (Extraída de Gonçalves e Resende (2011)). ............. 13
LISTAS DE TABELA
Tabela 1: Valores dos parâmetros utilizados para ajuste e os melhores valores obtidos para
as heurísticas BRKGA, BRKGA-Roleta, BRKGA-Torneio. ................................................... 19
Tabela 2: Valores obtidos pela heurística BRKGA. .............................................................. 20
Tabela 3: Valores obtidos pela heurística BRKGA-Roleta. ................................................... 21
Tabela 4: Valores obtidos pela heurística BRKGA-Torneio. ................................................. 21
Tabela 5: Comparativo da performace das heurísticas BRKGA, BRKGA-Roleta e
BRKGA-Torneio. .................................................................................................................. 22
SUMÁRIO
I. INTRODUÇÃO ................................................................................................................................ 1
II. O PROBLEMA DA MOCHILA ........................................................................................................ 3
2.1. INTRODUÇÃO ................................................................................................................. 3
2.2. FORMULAÇÃO ............................................................................................................... 3
2.3. VARIAÇÕES DO PROBLEMA DA MOCHILA ........................................................................ 4
2.3.1. O Problema da Mochila Binária ............................................................................... 4
2.3.2. O Problema da Mochila Restrito .............................................................................. 5
2.3.3 O Problema da Soma de Subconjuntos .................................................................. 5
2.3.4 O Problema do Troco ................................................................................................ 6
2.3.5 O Problema da Mochila Quadrático ........................................................................ 6
2.3.6 O Problema de Múltiplas Mochila 0-1 ..................................................................... 6
2.3.7 O Problema de Designação Generalizada .............................................................. 6
2.3.8 O Problema Bin-Packing .......................................................................................... 7
2.3.9 O Problema da Mochila Compartimentada ............................................................. 7
III. ALGORITMOS GENÉTICOS COM CHAVES ALEATÓRIAS TENDENCIOSAS .......................... 8
3.1. BRKGA APLICADO AO PROBLEMA DA MOCHILA BINÁRIA............................................. 14
3.1.1. Decodificador .......................................................................................................... 14
3.1.2. Métodos de Seleção ................................................................................................ 15
3.1.2.1. Método de Seleção Roleta ................................................................................ 16
3.1.2.2. Método de Seleção Torneio.............................................................................. 16
IV. EXPERIMENTOS COMPUTACIONAIS ........................................................................................ 18
5.1 AJUSTES DE PARÂMETROS .......................................................................................... 19
5.2 ANÁLISE DE QUALIDADE DAS SOLUÇÕES ...................................................................... 20
V. CONCLUSÃO E TRABALHOS FUTUROS .................................................................................. 23
REFERÊNCIAS BIBLIOGRÁFICAS..................................................................................................... 24
ANEXO I: DECODIFICADOR ............................................................................................................... 27
ANEXO II: MÉTODO DE SELEÇÃO ROLETA .................................................................................... 29
ANEXO III: MÉTODO DE SELEÇÃO TORNEIO .................................................................................. 33
I. Introdução

Os problemas pertencentes à classe NP-Completo são os que não se


conhece algoritmos determinísticos eficientes que os resolvam. De acordo com
Benfica (2004), essa classe envolve os problemas de maior dificuldade entre todos
os problemas de NP. Existem diversos problemas NP-Completo, como o Problema
de Satisfatibilidade Booleana, o Problema de Coloração de Grafos, o Problema do
Ciclo Hamiltoniano, entre outros.
O Problema da Mochila também é classificado como NP-Completo (MOR,
2007), tendo um alto nível de processamento de acordo com a quantidade de itens a
serem alocados na mochila. Neste problema, há itens distintos com pesos e valores
(ganhos) associados a cada um. O objetivo é alocar tais itens na mochila a fim de
maximizar o ganho da alocação, respeitando a capacidade de peso da mochila. A
mochila pode representar, por exemplo, um caminhão, navio ou container a ser
carregado. Na literatura existem variações para o Problema da Mochila, sendo o
Problema da Mochila Binária a variação tratada neste trabalho.
Atualmente, para solucionar esse tipo de problema pode ser feito o uso de
metaheurísticas, que são métodos de solução que coordenam procedimentos de
busca local com estratégias de mais alto nível (GLOVER; KOCHENBERGER, 2006).
Alguns exemplos de metaheurísticas são: Busca Tabu (ARMENTANO; RONCONI,
2000), Simulated Annealing (VAN LAARHOVEN; AARTS, 1987), GRASP
(MARQUES-SILVA; SAKALLAH, 1999), Algoritmos Genéticos, entre outras.
Segundo Vianna e Souza (2006), os Algoritmos Genéticos (AG) pertencem a
uma classe de algoritmos de pesquisa probabilística e de otimização chamada
Algoritmos Evolucionários, que simulam processos naturais, aplicando-os à solução
de problemas reais. Eles combinam a sobrevivência entre os melhores indivíduos
com uma forma estruturada de troca de informação genética entre eles para formar
uma estrutura heurística de busca. Os AGs possuem uma série de fases (população
inicial, função objetivo, seleção, cruzamento, mutação e critério de parada) e cada
uma pode ser modelada de diversas maneiras.
Com a intenção de evitar a produção de filhos inviáveis a partir de pais viáveis
no processo de cruzamento em um AG, Bean (1994) propôs uma nova forma de
representar os alelos de um indivíduo ao utilizar números reais, introduzindo os

1
Algoritmos Genéticos com Chaves Aleatórias (Random Key Genetic Algorithms –
RKGA, em inglês). A partir da estrutura estabelecida pelo RKGA, Ericsson et al.
(2002) propuseram uma alteração na escolha de um dos dois indivíduos que serão
submetidos ao processo de cruzamento, dando origem aos Algoritmos Genéticos
com Chaves Aleatórias Tendenciosas (em inglês, Biased Random Key Genetic
Algorithms – BRKGA).
Assim, o presente trabalho tem o objetivo de propor heurísticas baseadas nos
Algoritmos Genéticos com Chaves Aleatórias Tendenciosas para solucionar o
Problema da Mochila Binária (PMB), tendo como foco investigar, dentre os métodos
de seleção Roleta, Torneio e o padrão do BRKGA, aquele que apresenta as
melhores soluções para o problema, baseando-se em medidas de qualidade.
Este trabalho está organizado em cinco capítulos. O Capítulo II apresenta o
Problema da Mochila e algumas de suas variações, dentre elas o Problema da
Mochila Binária. As heurísticas propostas baseadas na metaheurística BRKGA a fim
de solucionar o PMB são descritas no Capítulo III. O Capitulo IV apresenta os
experimentos computacionais realizados, bem como os resultados obtidos. Por fim,
as conclusões e sugestões para trabalhos futuros são apresentadas no Capitulo V.

2
II. O Problema da Mochila

2.1. Introdução

O Problema da Mochila (PM) (Knapsack Problem, em inglês) é um dos mais


estudados nas áreas de Programação Discreta, Otimização Combinatória e
Inteligência Artificial (FINCATTI, 2010). Seu objetivo é alocar itens em uma mochila,
respeitando sua capacidade, de modo a maximizar o ganho total desta alocação,
considerando que cada item possui um peso e um valor (ganho) associado. Na
modelagem de uma situação real, a mochila pode representar, por exemplo, um
caminhão, navio ou container a ser carregado.
O PM pertence à classe de problemas NP-Completo (MOR, 2007), para os
quais não se conhece um algoritmo determinístico polinomial que os solucionem.

2.2. Formulação

Considerando uma mochila de capacidade C e n itens, onde o peso Pi e o

ganho Vi são dados, i = 1,...,n, deseja-se escolher a quantidade de cada item que
será alocado na mochila, de modo que a sua capacidade não seja ultrapassada e o
ganho total seja máximo. Assim, pode-se definir um modelo matemático para o
problema por:
Variável de Decisão:
- : quantidade de itens do tipo i selecionados, i = 1,...,n.

Modelagem Matemática:

(2.1)

sujeito a:

(2.2)

(2.3)

3
A função objetivo (2.1) maximiza a soma dos ganhos dos itens alocados. A
restrição (2.2) impõe que o peso total dos itens alocados não ultrapasse a
capacidade da mochila, enquanto a restrição (2.3) indica que a variável tem que
ser inteira não-negativa.

2.3. Variações do Problema da Mochila

Existem problemas que podem ser considerados variações do Problema da


Mochila. Nesta seção serão apresentados os seguintes: o Problema da Mochila
Binária, também conhecida como Problema da Mochila 0-1 (Binary KP ou Zero-One
Knapsack Problem ou 0-1 KP, em inglês), o Problema da Mochila Restrito, o
Problema da Soma de Subconjuntos, o Problema do Troco, o Problema da Mochila
Quadrático, o Problema de Múltiplas Mochilas 0-1, o Problema de Designação
Generalizada, o Problema do Bin-Packing e o Problema da Mochila
Compartimentada.

2.3.1. O Problema da Mochila Binária

O Problema da Mochila Binária (PMB) é, talvez, o mais importante Problema


da Mochila e um dos mais estudados problemas de Programação Discreta
(PISINGER, 1997). A razão para tal interesse está basicamente ligada a três fatores:
pode ser visto como um dos mais simples problemas de Programação Linear Inteira;
aparece como um subproblema em muitos outros problemas mais complexos; pode
representar uma gama muito grande de situações práticas.
No PMB tem-se a situação em que um único exemplar de cada item pode ser
selecionado. Portanto, a cada novo item, são acrescentadas novas possibilidades de
solução devido à sua complexidade exponencial , no qual n é o número de itens a
serem avaliados.
Assim, considerando uma mochila de capacidade C e um conjunto de n itens,

onde o peso Pi e o ganho Vi de cada item i são dados, i = 1,...,n, deseja-se


selecionar quais itens serão alocados na mochila, sem ultrapassar a sua capacidade
e de modo que o ganho total seja máximo. Com isso, uma formulação matemática
para o PMB pode ser definido como:

4
Variável de Decisão:
- : 1 se o item i for selecionado e caso contrário, i = 1,...,n.

Modelagem Matemática:

(2.4)

sujeito a:

(2.5)

(2.6)

A função objetivo (2.4) maximiza a soma dos ganhos dos itens alocados. A
restrição (2.5) impõe que o peso total dos itens alocados não ultrapasse a
capacidade da mochila, enquanto a restrição (2.6) indica a integralidade da variável
.

2.3.2. O Problema da Mochila Restrito

Alguns problemas podem apresentar condições adicionais, como por


exemplo, a limitação da quantidade de itens a serem selecionados. Neste caso, o
problema passa a ser chamado de Problema da Mochila Restrito ou Limitado.

2.3.3 O Problema da Soma de Subconjuntos

O Problema da Soma de Subconjuntos consiste em selecionar um


subconjunto de itens cuja soma total dos pesos dos itens escolhidos se aproxime ao
máximo de C, sem excedê-lo. Este problema é um caso particular do Problema da

Mochila Binária, onde Vi = Pi, para i = 1,...,n, sendo também conhecido como o
Problema da Mochila de Valor Independente.

5
2.3.4 O Problema do Troco

O Problema do Troco geralmente aparece na literatura como um problema de


minimização. O mesmo consiste em selecionar um número de itens de cada tipo i

(i = 1,...,n), tal que o peso total seja C e o número total de itens selecionados seja
mínimo.
O problema é chamado Problema do Troco, pois pode ser interpretado como
o problema de um caixa (supermercado, banco, etc.), que deve devolver uma
determinada quantia C, usando, para isto, um número mínimo de moedas de valores

específicos Pi (i = 1,...,n). Neste caso, para cada valor, um número ilimitado de


moedas está disponível, sendo importante notar que a condição de igualdade
imposta pode fazer com que inexista uma solução para o problema.

2.3.5 O Problema da Mochila Quadrático

O Problema da Mochila Quadrático é um dos mais estudados (MARQUES,


2000) problemas na área de Problemas da Mochila Não-Lineares (PMNL). Um
PMNL, em geral, é o Problema da Mochila com função objetivo não-linear ou que
envolve restrições não-lineares.

2.3.6 O Problema de Múltiplas Mochila 0-1

O Problema de Múltiplas Mochilas 0-1 consiste em carregar um conjunto de m

mochilas (m ≤ n) cujas capacidades são dadas por Cj, j = 1,...,m. O mesmo consiste
em selecionar subconjuntos disjuntos de itens, tal que o valor de utilidade destes
itens seja máximo e cada subconjunto possa ser associado a uma mochila diferente,
cuja capacidade não seja menor que o peso total dos itens no subconjunto.

2.3.7 O Problema de Designação Generalizada

O Problema de Designação Generalizada pode ser descrito usando a


terminologia aplicada para os Problemas da Mochila. O problema consiste em

6
associar cada item a exatamente uma mochila, visando maximizar o ganho real total,
sem associar a nenhuma mochila um peso total que ultrapasse sua capacidade.

2.3.8 O Problema Bin-Packing

O Problema Bin-Packing pode ser descrito usando a terminologia do


Problema da Mochila, sendo Pi o peso do item i, i = 1,...,n, e C a capacidade de
cada bin (caixa). Assim, associa-se cada item a uma caixa, tal que o peso total dos
itens em cada caixa não exceda C e o número de caixas usadas seja mínimo.

2.3.9 O Problema da Mochila Compartimentada

O Problema da Mochila Compartimentada consiste em determinar as


capacidades adequadas de cada compartimento e como estes devem ser
carregados, de modo que o valor de utilidade total (soma dos valores de utilidade de
todos os itens selecionados) seja máximo, descontando-se os custos dos
compartimentos, os quais dependem dos agrupamentos com que foram
preenchidos.

Apresentadas algumas variações do Problema da Mochila, a intenção neste


trabalho é tratar o Problema da Mochila Binária. Para isto foram propostas
heurísticas baseadas na metaheurística BRKGA, onde cada uma utiliza um método
distinto de seleção de indivíduos para cruzamento. Os componentes dessas
heurísticas são descritos no capítulo seguinte.

7
III. Algoritmos Genéticos com Chaves Aleatórias
Tendenciosas

O conceito de otimização está bem identificado como um mecanismo de


análise de decisões complexas, com o simples objetivo de quantificar seu
desempenho e medir a qualidade das decisões. A intenção é encontrar a melhor
solução, respeitando restrições impostas de acordo com os parâmetros de cada
problema.
A formulação para um problema real de otimização geralmente não passa de
uma boa aproximação e se tratando de problemas complexos, nem sempre os
métodos de procura encontram realmente a melhor solução. Itens como
conhecimento teórico e experiência em modelagem são requeridos para capturar os
elementos essenciais do problema. Satisfeitos esses quesitos, a otimização é
considerada como ferramenta fundamental para análise de problemas reais.
Existem métodos variados e cada um deles é mais adequado a uma
determinada classe de problemas. Um procedimento para otimização, verificando-
se, principalmente, a característica de atingir mais vezes a solução global por
número de execuções, é um fator de medida da potencialidade dos algoritmos e,
entre os métodos mais eficazes, encontram-se os metaheurísticas.
Metaheurísticas são procedimentos de alto nível que coordenam heurísticas
simples, por exemplo, buscas locais (GLOVER; KOCHENBERGER, 2006). Em geral,
metaheurísticas encontram soluções de melhor qualidade quando comparadas com
aquelas encontradas, de forma isolada, por heurísticas simples (GONÇALVES;
RESENDE, 2011).
Os Algoritmos Genéticos são exemplos de metaheurísticas, sendo algoritmos
de busca baseados nos mecanismos de seleção natural e genética (LINDEN, 2006).
Eles combinam a sobrevivência entre os melhores indivíduos com uma forma
estruturada de troca de informação genética entre eles para formar uma estruturada
heurística de busca. Por sua grande capacidade de alteração e adaptação,
tornaram-se uma técnica muito usada em diversas áreas de otimização (OLIVEIRA,
2015).
Um AG possui um conjunto de indivíduos (ou cromossomos), onde cada um
representa uma solução do problema e é composto por um determinado número de
8
genes. Este conjunto forma uma população P que evolui ao longo de um certo
número de gerações. A cada geração uma nova população é criada, utilizando os
operadores genéticos de cruzamento e mutação. No cruzamento, os indivíduos da
população corrente, selecionados pelo método de seleção, são combinados para
produzir novos indivíduos para a próxima geração. O operador de mutação altera
aleatoriamente um ou mais genes, a fim de diversificar a nova população e evitar
que o processo de evolução fique estagnado com ótimos locais. O algoritmo é
repetido até que um critério de parada seja alcançado. A qualidade (ou aptidão) de
cada indivíduo é dada pelo seu fitness, cujo valor é resultado da aplicação de uma
função de avaliação sobre ele.
Basicamente, um AG gera uma população de indivíduos (soluções) para o
problema, para depois ser iniciado o processo de evolução. As etapas de um AG
são apresentadas na Figura 1, sendo descritas a seguir:

Figura 1: Fluxograma de um Algoritmo Genético.

Avaliação: avalia-se a aptidão das soluções (indivíduos da população), sendo


feita uma análise para que se estabeleça quão bem elas resolvem o problema
proposto;

9
Seleção: indivíduos são selecionados para a reprodução (cruzamento). A
probabilidade de uma dada solução i ser selecionada é proporcional à sua aptidão;
Cruzamento: características das soluções escolhidas são recombinadas,
gerando novos indivíduos;
Mutação: características dos indivíduos resultantes do processo de
reprodução são alteradas, acrescentando assim variedade à população;
Atualização: os indivíduos criados nesta geração são inseridos na população;
Finalização: analisa se as condições de encerramento da evolução foram
atingidas, retornando para a etapa de avaliação em caso negativo e encerrando a
execução em caso positivo.

Com a intenção de evitar a produção de filhos inviáveis a partir de pais viáveis


no processo de cruzamento em um AG, Bean (1994) propôs uma nova forma de
representar um indivíduo, introduzindo os RKGA (Random Key Genetic Algorithms,
em inglês).
Em um RKGA, os indivíduos são representados por um vetor de números
reais no intervalo contínuo [0,1). Cada elemento (denominado alelo, sendo o valor
de um gene) do vetor é chamado de chave aleatória, que é gerada randomicamente
na população inicial. Assim, uma população de P vetores de chaves aleatórias evolui
aplicando, como os AGs, o princípio darwiniano da sobrevivência do mais adaptado,
onde os indivíduos mais aptos de uma população são os mais propensos a
encontrar um parceiro e repassar seu material genético para as gerações futuras.
Um algoritmo determinístico chamado decodificador mapeia um vetor de chaves
aleatórias numa solução do problema de otimização. Ou seja, este algoritmo
transforma um indivíduo em uma solução do problema tratado, sendo o custo desta
solução utilizado como valor de aptidão.
Segundo Santos (2018), em um RKGA, os P indivíduos da população inicial

são gerados de forma aleatória. A população corrente k é dividida em um pequeno

grupo de Pe indivíduos elite, que possuem os melhores valores de fitness, e o

restante em Pne indivíduos não-elite. Com o propósito de evoluir a população, todos


os indivíduos elite são copiados sem qualquer modificação para a população da
geração k+1, onde também é introduzido um pequeno número de Pm mutantes, que

10
são indivíduos gerados do mesmo modo que aqueles da população inicial e com
finalidade idêntica ao operador de mutação presente nos AGs. Os demais indivíduos
são gerados pelo cruzamento de outros dois, que são selecionados aleatoriamente
de toda a população corrente (elite e não-elite). A Figura 2 ilustra esse processo de
evolução da população.

Figura 2: Processo de evolução da população no RKGA (Extraída de


Santos, 2018).

A partir dessa estrutura estabelecida pelo RKGA, Ericsson et al. (2002)


propuseram uma alteração na escolha de um dos dois indivíduos que serão
submetidos ao cruzamento, dando origem aos Algoritmos Genéticos com Chaves
Aleatórias Tendenciosas (Biased Random Key Genetic Algorithms – BRKGA, em
inglês). Assim, a diferença entre o BRKGA e o RKGA está na forma em que os pais
são selecionados para cruzamento e como é implementado. Ambos os algoritmos
selecionam os pais aleatoriamente e com reposição. Porém, enquanto no RKGA os
pais são escolhidos da população inteira, no BRKGA um dos pais é sempre
escolhido do conjunto elite, enquanto o outro é escolhido do conjunto não-elite. Essa
diferença entre eles faz com que o BRKGA apresente resultados melhores que o
RKGA (RESENDE et al., 2010).
Ambos os algoritmos utilizam o método Uniforme Parametrizado de Spears e
De Jong (1991) para a operação de cruzamento. Esse método utiliza uma

11
probabilidade do descendente herdar o alelo do indivíduo elite e de herdar
do indivíduo não-elite.
A Figura 3 demonstra o processo de cruzamento de um indivíduo elite com
outro não-elite. O número de genes (n) é igual a 5 e o valor de é igual a 0,7. Então,
um número real é gerado aleatoriamente no intervalo [0,1). Caso o valor gerado seja
menor do que a 0,7, o descendente herda o alelo do indivíduo elite. Caso contrário,
ele herda o alelo do indivíduo não-elite. Neste exemplo, o descendente herdou o
alelo do indivíduo elite do primeiro, terceiro e quinto genes.

Figura 3: Exemplo de cruzamento uniforme parametrizado.

No BRKGA, o único componente dependente do problema é o processo de


decodificação, onde o decodificador produz uma solução a partir de um vetor de
chaves aleatórias (indivíduo), calculando a adequação dessa solução. Ao descrever
um BRKGA de acordo com um problema específico de otimização combinatória é
primordial mostrar como esses vetores são decodificados para soluções viáveis do
problema. A Figura 4 apresenta o fluxograma de um BRKGA, destacando os
componentes que dependem e aquele que não depende do problema.

12
Figura 4: Fluxograma de um BRKGA (Extraída de Gonçalves e Resende (2011)).
Para problemas de otimização mais complexos, como o Problema da Mochila,
e que exigem uma solução em tempo hábil, a heurística BRKGA vem sendo utilizada
em várias áreas, por sua confiabilidade e geração de bons resultados.
Para exemplificar, no trabalho de Brito et al. (2017), o BRKGA foi utilizado
para solucionar o Problema de Agrupamento com Soma Mínima. Neste problema,
devem-se alocar os n objetos de uma base de dados em k grupos, de forma que o
somatório das distâncias entre todos os pares de objetos, dentro de cada um dos
grupos, seja mínimo.
Em Rizzi et al. (2017), os autores aplicaram o BRKGA ao Problema de
Alocação Tática de Berços, que consiste em alocar navios nos berços de atracação
e definir o perfil de guindastes que serão utilizados para carregamento e
descarregamento das cargas. O objetivo é minimizar o custo de serviço em transferir
as cargas entre os navios atracados e otimizar a utilização dos guindastes
disponíveis para as tarefas.
Outra aplicação pode ser encontrada em Cavalheiro e Filho (2017), que
abordaram o Problema de Distribuição de Energia Elétrica. O trabalho estuda
alternativas de encontrar as melhores configurações de redes de distribuição
utilizando o BRKGA com a inclusão de uma busca local. Os estudos de casos
indicam que a inserção da busca local no processo evolutivo pode trazer benefícios
na qualidade das soluções encontradas.
Como demonstrado, o BRKGA tem sido utilizado em diversas aplicabilidades
práticas, juntamente com outros métodos, como Programação Dinâmica (DIAS,
13
2010), Algoritmos Gulosos (ROCHA; DORINI, 2004), Branch-and-Bound
(NARENDRA; FUKUNAGA, 1977), entre outros.
Na seção seguinte serão apresentados o decodificador e os métodos de
seleção empregados nas heurísticas baseadas nos Algoritmos Genéticos com
Chaves Aleatórias Tendenciosas (BRKGA) propostas neste trabalho a fim de
solucionar o Problema da Mochila Binária (PMB).

3.1. BRKGA Aplicado ao Problema da Mochila Binária

Foi visto anteriormente que há diversas variações para o Problema da


Mochila, todas computacionalmente complexas, e que as metaheurísticas podem ser
utilizadas para resolver problemas deste tipo.
Como neste trabalho é abordada a variação binária do Problema da Mochila e
propostas heurísticas para solucioná-la baseadas na metaheurística BRKGA, o
decodificador, que é único componente desta que depende do problema abordado,
deve ser descrito. Além disso, como o foco é investigar outros métodos de seleção
de indivíduos para cruzamento diferentes do método padrão do BRKGA, tais
métodos também devem sem especificados. Assim, nas seções seguintes, serão
apresentados o decodificador utilizado por todas as heurísticas propostas e os
métodos de seleção Roleta e Torneio.

3.1.1. Decodificador

Como é possível ver no Anexo I deste trabalho, um decodificador (decoder,


em inglês) é um algoritmo determinístico que utiliza um vetor de chaves aleatórias
(indivíduo) como entrada, tendo como saída o valor de fitness deste indivíduo
(BRANDÃO et al., 2015). Na abordagem empregada neste trabalho, os indivíduos
possuem n chaves aleatórias, cada uma associada a um dos n itens, sendo os
indivíduos mais aptos àqueles que apresentam o maior valor de fitness, que é a
soma dos ganhos dos itens alocados na mochila.

14
Algoritmo 1: Decodificador
Entrada: Indivíduo I.
Saída: Valor de fitness do indivíduo I.
1 Ordene os itens It pelas suas chaves aleatórias:
2
3
4 para e faça
5 se então
6
7
8 fim se
9 fim para
10

O Algoritmo 1 apresenta o pseudocódigo do decodificador proposto. Na linha


1 os itens são ordenados de maneira não-descrescente pelas suas chaves
aleatórias correspondentes. A mochila é inicializada na linha 2 e o peso total alocado
na linha 3. O laço das linhas 4 9 aloca os itens na mochila. Na linha 5 o peso do
item analisado juntamente com o peso total até então alocado são comparados com
a capacidade da mochila. Caso seja possível inserir o item, o mesmo é alocado na
mochila na linha 6, sendo o peso total atualizado na linha 7. Finalizada a alocação
de todos os itens possíveis, o valor de fitness do indivíduo é calculado na linha 10.

3.1.2. Métodos de Seleção

O processo de seleção está agregado à forma de escolha de indivíduos da


população que participarão do processo evolutivo, para a geração de descendentes,
por meio do cruzamento, que farão parte da população na geração seguinte.
Há vários métodos para selecionar um indivíduo. Segundo Linden (2006), o
método utilizado na seleção pode induzir consideravelmente o resultado final, pois
dependendo do método empregado, pode-se acelerar ou retardar o acontecimento
da convergência genética. A seleção por Roleta, Torneio, Amostragem Estocástica
Uniforme, Local, Ranking e Truncada (LINDEN, 2006) são exemplos de métodos de

15
seleção comumente empregados. Os métodos utilizados neste trabalho são
descritos a seguir.

3.1.2.1. Método de Seleção Roleta

No método de seleção Roleta, a chance de seleção de um indivíduo é


totalmente proporcional ao seu valor de fitness. A probabilidade do mesmo ser
selecionado é dada pela razão entre o seu valor de fitness e a soma dos fitness de
todos os indivíduos da população. A roleta tende a escolher o indivíduo que possui
maior valor de fitness, pois o mesmo é representado por uma fatia maior da roleta.
Como pode ser visto no Anexo II deste trabalho, para que seja possível obter
o número de indivíduos necessários para a execução do processo de cruzamento, a
roleta é girada quantas vezes for preciso.

3.1.2.2. Método de Seleção Torneio

Como o próprio nome diz, o método de seleção Torneio traduz-se em


selecionar vários indivíduos da população e fazer com que eles entrem em disputa
direta pelo direito de ser pai (LINDEN, 2006).
Conforme é possível verificar no Anexo III, existe neste método um
parâmetro, denominado tamanho do torneio (k), que é definido pela quantidade de
indivíduos que serão selecionados aleatoriamente da população para a competição.
Neste trabalho, o valor de k ficou definido como decisão de projeto ser igual a 4.
Inicialmente é feito o sorteio aleatório dos quatro indivíduos que irão competir. Após
isto, o indivíduo que apresentar melhor valor de fitness vence o torneio e é escolhido
para ser um dos pais no processo de cruzamento. Este processo de competição é
realizado tanto na população elite quanto na não-elite para a definição dos dois
indivíduos que serão submetidos ao procedimento de cruzamento.
A diferença entre esse método e o de seleção Roleta é que no Torneio não há
qualquer favorecimento para os melhores indivíduos. Este método possui uma
desvantagem em relação ao indivíduo de pior valor de fitness. A única chance deste
ser selecionado para participar da competição acontece se no torneio em que ele
participar, só existir o mesmo como único competidor.

16
Apresentados os componentes das heurísticas propostas, as mesmas foram
nomeadas de acordo com o método de seleção empregado, sendo importante
ressaltar que todas elas utilizaram o mesmo decodificador. A heurística que utilizou
o método de seleção padrão dos BRKGAs, que é a seleção aleatória de um
indivíduo elite e de outro não-elite, foi intitulada simplesmente de BRKGA. A que
empregou o método de seleção Roleta foi chamada de BRKGA-Roleta, sendo
intitulada BRKGA-Torneio a que fez uso do método Torneio. Os experimentos
computacionais com tais heurísticas sobre um conjunto de instâncias do PMB, a fim
de avaliá-las na resolução do problema, são descritos no próximo capítulo.

17
IV. Experimentos Computacionais

Os testes computacionais apresentados neste capítulo têm por objetivo


ajustar os parâmetros das heurísticas BRKGA, BRKGA-Roleta e BRKGA-Torneio
propostas, bem como posteriormente avaliar a qualidade das soluções produzidas
por elas na resolução do PMB.
Para isso foram utilizadas instâncias geradas por um software desenvolvido
por Pisinger (1994, 1997, 2003), que trabalha com parâmetros n, R, S, i e t, onde n

representa a quantidade de itens que podem fazer parte da mochila, R a faixa de

coeficientes, S o número de instâncias, i o índice da instância e t o tipo de critério

utilizado. A quantidade de itens n assumiu os valores 50, 100, 200, 1000, 2000,
5000, 10000. Considerou-se também, segundo Pisinger (2003), a faixa de
coeficientes igual 1000, o número de instâncias igual a 1, o índice da instância
também igual a 1 e o tipo de critério Weakly Correlated Instances (Instâncias
Fracamente Correlatas), onde o peso ( ) de cada item é escolhido randomicamente
em [1,R] e o ganho ( ) em [ – R/10, + R/10], sendo maior ou igual a 1. Para

cada valor assumido por n, uma instância foi gerada e um valor para a capacidade
da mochila foi calculado a partir da seguinte fórmula:

onde:
C: capacidade da mochila;
i: índice da instância;
S: número de instâncias;
n: quantidade de itens;
j: índice do item;
: peso do item j.

A biblioteca brkgaAPI (TOSO; RESENDE, 2015), que é um framework na


linguagem C++ para o desenvolvimento de BRKGAs, foi utilizada para a
implementação das heurísticas propostas, sendo compiladas com g++ versão 5.4.0.
18
Os testes foram executados em um notebook Samsung com processador Intel®
Core i7-3630QM de 2.4 GHz, memória RAM de 6 GB e sistema operacional Linux
Ubuntu 18.04.1.

5.1 Ajustes de Parâmetros

Foram realizados teste de ajustes para definir qual seria a melhor combinação
de valores para os seguintes parâmetros: tamanho da população (P), porcentagem

da população elite (Pe), porcentagem da população mutante (Pm) e a probabilidade


( ) do descendente herdar um alelo do indivíduo elite. Os valores testados para
estes parâmetros foram baseados naqueles recomendados por Gonçalves e
Resende (2011).
Os ajustes foram feitos com uma instância de 1000 itens, executando cada
heurística uma única vez para cada combinação, analisando o valor da função
objetivo para determinar quais os melhores valores de parâmetros a serem
utilizados. Assim, a combinação de parâmetros, para cada heurística, que retornou o
maior valor de função objetivo, foi a escolhida para os testes de qualidade. Como
critério de parada, cada heurística utilizou o número máximo de gerações igual a
1000.
A Tabela 1 apresenta na segunda coluna os valores utilizados para cada
parâmetro e nas colunas seguintes os melhores valores obtidos para as heurísticas
BRKGA, BRKGA-Roleta e BRKGA-Torneio, respectivamente.

Parâmetro Valor BRKGA BRKGA-Roleta BRKGA-Torneio


P 100, 200 100 100 100
Pe 0,20xP, 0,25xP 0,25xP 0,25xP 0,20xP
Pm 0,10xP, 0,20xP 0,10xP 0,10xP 0,10xP
ρ 0,70, 0,80 0,80 0,80 0,80
Tabela 1: Valores dos parâmetros utilizados para ajuste e os melhores valores
obtidos para as heurísticas BRKGA, BRKGA-Roleta, BRKGA-Torneio.

19
5.2 Análise de Qualidade das Soluções

Foram utilizadas seis instâncias para os testes de qualidade, com números de


itens igual a 50, 100, 200, 2000, 5000 e 10000. Cada algoritmo foi executado dez
vezes para cada instância, variando-se a semente de números aleatórios de zero até
nove, utilizando a melhor combinação de parâmetros determinada na etapa de
ajuste. Como critério de parada, novamente foi utilizado o número máximo de
gerações igual a 1000.
As Tabelas 2, 3 e 4 mostram os resultados obtidos pelo BRKGA, BRKGA-
Roleta e BRKGA-Torneio, respectivamente. Estas tabelas informam, para cada
instância, o valor da melhor solução conhecida ao longo de todos os experimentos
realizados (entre todas as heurísticas), o menor valor de solução alcançado, a média
dos valores das soluções obtidas e o melhor (maior) valor de solução atingido,
sendo estes últimos três valores para as 10 execuções independentes da heurística.
As colunas seguintes indicam o desvio relativo médio percentual entre o valor da
solução obtida e o valor da melhor solução conhecida, bem como o tempo médio
(em segundos) de execução do algoritmo. Os valores destacados em negrito
indicam que a heurística atingiu o melhor valor conhecido.

Tempo
Melhor Menor Valor Maior Desvio
Instância Médio
Valor Valor Médio Valor Médio (%)
(s)
50 12867 12643 12742,60 12783 9,62 0,001
100 27659 27193 27412,50 27542 8,87 0,001
200 51151 50648 50874,80 51151 5,35 0,002
2000 592910 589110 590509,80 592910 4,01 0,020
5000 1260010 1257620 1258294,00 1259510 1,30 0,054
10000 2516590 2512100 2513399,00 2514680 1,20 0,115
Tabela 2: Valores obtidos pela heurística BRKGA.

20
Tempo
Melhor Menor Valor Maior Desvio
Instância Médio
Valor Valor Médio Valor Médio (%)
(s)
50 12867 12683 12755,40 12859 8,63 0,001
100 27659 27253 27418,60 27547 8,65 0,001
200 51151 50750 50889,10 51128 5,09 0,002
2000 592910 589710 590580,00 591210 3,88 0,021
5000 1260010 1257410 1258338,00 1259230 1,27 0,055
10000 2516590 2512200 2513530,00 2514890 1,17 0,112
Tabela 3: Valores obtidos pela heurística BRKGA-Roleta.

Tempo
Melhor Menor Valor Maior Desvio
Instância Médio
Valor Valor Médio Valor Médio (%)
(s)
50 12867 12716 12801,90 12867 5,01 0,001
100 27659 27385 27508,70 27659 5,37 0,001
200 51151 50779 50935,00 51112 4,15 0,002
2000 592910 590002 590829,00 592610 3,46 0,021
5000 1260010 1258360 1258993,00 1260010 0,77 0,057
10000 2516590 2513180 2514708,00 2516590 0,70 0,114
Tabela 4: Valores obtidos pela heurística BRKGA-Torneio.

Na Tabela 5 pode-se identificar valores que mostram a performance de cada


heurística. Para isto, foram empregadas medidas de qualidade aplicadas em Ribeiro
et al. (2002), Resende et al. (2010), Pessoa et al. (2013), Brandão et al. (2015),
Santos (2018), entre outros:
 Best: valor da melhor solução obtida para uma determinada instância,
considerando todas as execuções até então realizadas.
 Sum Best: número de execuções para as quais o valor de Best foi
alcançado por uma determinada heurística. Quanto maior o valor de Sum Best,
melhor é a performance do algoritmo.
 #Best: número de instâncias para as quais o valor de Best foi alcançado
por uma determinada heurística. Quanto maior o valor de #Best, melhor é a
performance do algoritmo.
 Dev: desvio relativo entre Best e o valor da solução obtida em uma
execução de uma determinada instância por uma dada heurística. Quanto menor o

21
valor de Dev, melhor é a performance do algoritmo. Pode-se verificar um modelo
matemático para encontrar o valor de Dev por:

 Avg Dev: valor médio de Dev sobre todas as instâncias e execuções de


uma dada heurística. Quanto menor o valor de Avg Dev, melhor é a performance do
algoritmo.
 Tempo: corresponde à soma, sobre todas as instâncias, do tempo médio
de execução de um algoritmo em um determinado experimento.

Analisando os resultados da Tabela 5 pode ser verificado que, dentre as


heurísticas BRKGA, BRKGA-Roleta e BRKGA-Torneio, a que mostrou melhores
resultados foi a BRKGA com método de seleção Torneio. A mesma apresentou o
menor valor de desvio médio, indicando que ela obteve resultados, em média, 3,24%
abaixo dos melhores valores conhecidos. Além disso, ela atingiu os maiores valores
para as medidas Sum Best e #Best. A heurística BRKGA-Roleta foi a que obteve o
menor tempo médio entre todas as heurísticas propostas.

BRKGA BRKGA-Roleta BRKGA-Torneio


Avg Dev (%) 5,06 4,78 3,24
Sum Best 2 0 4
#Best 2 0 4
Tempo (s) 0,193 0,192 0,196
Tabela 5: Comparativo da performace das heurísticas BRKGA,
BRKGA-Roleta e BRKGA-Torneio.

22
V. Conclusão e Trabalhos Futuros

Como pôde ser visto, até o momento não foi encontrado nenhum algoritmo
determinístico de tempo polinomial que resolva problemas pertencentes à classe
NP-Completo, sendo uma boa alternativa para resolvê-los o uso de metaheurísticas.
Neste trabalho a metaheurística abordada foram os Algoritmos Genéticos com
Chaves Aleatórias Tendenciosas (BRKGA). Desse modo, foram implementados o
decodificador, com a finalidade de traduzir o Problema da Mochila Binária (PMB)
para o BRKGA, e os métodos de seleção Roleta e Torneio, gerando três heurísticas
baseadas na metaheurística BRKGA: BRKGA com o método de seleção padrão
(BRKGA), BRKGA com seleção Roleta (BRKGA-Roleta) e BRKGA com seleção
Torneio (BRKGA-Torneio). Assim, o intuito foi comparar estas heurísticas avaliando
a performance de cada uma na resolução do PMB a partir de medidas de qualidade.
Após a realização dos experimentos computacionais, foi realizada a
comparação dos algoritmos propostos, sendo observado que o BRKGA-Torneio foi o
que apresentou os melhores valores para as medidas utilizadas. Realizando uma
análise criteriosa, pode-se perceber que este método de seleção teria sido
considerada uma má escolha devido ao seu funcionamento, que possibilita que
indivíduos representando soluções não tão boas sejam escolhidos com a mesma
probabilidade dos bons indivíduos, já que a escolha é feita de forma aleatória.
Porém, este método de seleção possui uma característica que provavelmente
foi relevante para o seu bom desempenho, que é gerar diversidade na população,
elevando a cobertura do espaço de busca do problema.
Como trabalhos futuros podem ser aplicados outros métodos de seleção,
conforme foi mostrado no Capítulo 2, com a heurística BRKGA para fazer uma
comparação das suas performances e serem analisadas suas medidas,
possibilitando uma melhor avaliação de tais métodos.
Outra proposta seria aumentar o número de gerações juntamente com o
tamanho da população. Este aumento pode proporcionar uma melhora no valor de
solução, pois cresce o número de tentativas de se obter indivíduos mais bem
adaptados, embora também resulte no aumento do tempo de execução.

23
REFERÊNCIAS BIBLIOGRÁFICAS

Bean, James C. Genetic algorithms and random keys for sequencing and
optimization. ORSA Journal on Computing, v. 6, n. 2, p. 154-160, 1994.

Benfica, Alex T. Problema da Mochila aplicado ao Sistema de Memória Virtual.


15f. Projeto de Pesquisa (Ciência da Computação) – Instituto de Ciências Exatas,
Universidade Federal de Minas Gerais, Belo Horizonte, 2004.

Brito, José A.; Fadel, Augusto C.; Semaan, Gustavo S.; Brito, Luciana R. Algoritmo
Genético de Chaves Aleatórias Viciadas Aplicado ao Problema de
Agrupamento com soma mínima. Blumenau. XLIX Simpósio Brasileiro de
Pesquisa Operacional, 2017.

Brandão, Julliany S.; Noronha, Thiago F.; Resende, Mauricio G. C.; Ribeiro, Celso C.
A biased random‐key genetic algorithm for single‐round divisible load
scheduling. International Transactions in Operational Research, v. 22, n. 5, p. 823-
839, 2015.

Cavalheiro, Ellen M. B.; Filho, Christiano L. Otimização de Redes de Distribuição


de Energia Elétrica por BRKGA. Blumenau. XLIX Simpósio Brasileiro de Pesquisa
Operacional, 2017.

Dias, Bruno Henriques. Programação Dinâmica Estocástica e Algoritmo de


Fechos Convexos no Planejamento da Operação de Sistemas Hidrotérmicos.
Tese de Doutorado. Tese de Doutorado, PUC-Rio, Rio de Janeiro, 2010.

Ericsson, M.; Resende, Mauricio G. C.; Pardalos, Panos .M. A genetic algorithm for
the weight setting problem in OSPF routing. Journal of Combinatorial
Optimization, v. 6, n. 3, p. 299-333, 2002.

Fincatti, Camilla. Problema da Mochila. Universidade Presbiteriana Mackenzie, São


Paulo, Brasil, 2010.

Gonçalves, José F; Resende, Mauricio G. C. Biased random-key genetic


algorithms for combinatorial optimization. Journal of Heuristics, v. 17, n. 5, p.
487-525, 2011.

Glover, Fred W.; Kochenberger, Gary A. (Ed.). Handbook of Metaheuristics.


Springer Science & Business Media, 2006.

Linden, Ricardo. Algoritmos Genéticos: Uma importante ferramenta da


Inteligência Computacional. Rio de Janeiro: Brasport, 2006. 348 p.

Marques, Fabiano do P. O problema da mochila compartimentada.Tese de


Doutorado. Universidade de São Paulo, Brasil, 2000.

24
Marques-Silva, João P.; Sakallah, Karem A. GRASP: A search algorithm for
propositional satisfiability. IEEE Transactions on Computers, v. 48, n. 5, p. 506-
521, 1999.

Mor, Stéfano D. K. Emprego da Técnica de Workstealing: Estudo de Caso com o


Problema da Mochila e MPI. 114 f. Projeto de Diplomação (Bacharelado em
Ciência da Computação) - Universidade Federal do Rio Grande do Sul, Porto Alegre,
2007.

Narendra, Patrenahalli M. ; Fukunaga, Keinosuke. A branch and bound algorithm


for feature subset selection. IEEE Transactions on computers, n. 9, p. 917-922,
1977.

Oliveira, Thiago H. F. Abordagem híbrida para o problema de atribuição de


localidades a anéis em redes SONET/SDH. Dissertação de Mestrado –
UERN/UFERSA, 2015.

Pisinger, D. Core Problems in Knapsack Algorithms. Technical Report 94-26,


DIKU, University of Copenhagen, Denmark, 1994.

Pisinger,D.; Martello. S; Toth, P. New Trends in Exact Algorithms for the 0-1
Knapsack Problem. Technical Report 97-10, DIKU, University of Copenhagen,
Denmark,1997.

Pisinger,D. Where Are the Hard Knapsack Problems?. Technical Report 03-08,
DIKU, University of Copenhagen, Denmark, 2003.

Pessoa, Luciana S.; Resende, Mauricio G. C; Ribeiro, Celso C. A hybrid


Lagrangean heuristic with GRASP and path-relinking for set k-covering.
Computers & Operations Research, v. 40, n. 12, p. 3132-3146, 2013.

Resende, Mauricio G. C.; Martí, R.; Gallego, M.; Duarte, A. GRASP and path
relinking for the max–min diversity problem. Computers & Operations Research,
v. 37, n. 3, p. 498-508, 2010.

Ribeiro, Celso C.; Uchoa, Eduardo; Werneck, Renato F. A hybrid GRASP with
perturbations for the Steiner problem in graphs. INFORMS Journal on
Computing, v. 14, n. 3, p. 228-246, 2002.

Rizzi, Mateus M.; Pomari, Carlos Z.; Oliveira, Rudinei M.; Chaves, Antonio A.;
Lorena, Luiz A. N. Metaheurística híbrida aplicada ao problema de alocação
tática de berços. Blumenau. XLIX Simpósio Brasileiro de Pesquisa Operacional,
2017.

Rocha, Anderson; Dorini, Leyza B. Algoritmos gulosos: definições e


aplicações. Campinas, SP, p. 42, 2004.

25
Santos, Philippe L. F. Heurísticas para o Problema da Partição Cromática de
Custo Mínimo. 110 f. Tese (Doutorado em Computação) - Instituto de Computação,
Universidade Federal Fluminense, Niterói, 2018.

Spears, William; de Jong, Kenneth. On the virtues of parameterized uniform


crossover. In Belew, R. e Booker, L., editors, Proceedings of the Fourth
International Conference on Genetic Algorithms, pages 230-236, San Mateo, 1991.

Toso Rodrigo F.; Resende, Mauricio G. C. A c++ application programming


interface for biased random-key genetic algorithms. Optimization Methods &
Software, 30:81_93, 2015.

Toscani, Laira V.; Veloso, Paulo. A. S. Complexidade de Algoritmos: análise,


projeto e métodos. Porto Alegre: Sagra Luzzato, 2005.

Van Laarhoven, Peter J.M.; Aarts, Emile H.L. Simulated annealing. In: Simulated
annealing: Theory and applications. Springer, Dordrecht, 1987. p. 7-15.

Vianna, Dalessandro. S.; Souza, Fábio. D. Um modelo de Implementação para o


Desenvolvimento de Algoritmos Genéticos. Relatório Técnico. Universidade
Candido Mendes - Campos. Submetido à Revista Produção On Line, (2006).
Armentano, Vinícius A.; Ronconi, Débora P. Minimização do tempo total de atraso
no problema de flowshop com buffer zero através de busca tabu. Gestão &
Produção, 2000.

26
ANEXO I: Decodificador

/*
* SampleDecoder.cpp
*
*Criado em: Agosto, 2018
*Autor: Caio & Patricia
*/

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <sys/time.h>
#include "SampleDecoder.h"
#include "VetorGanhoPeso.h"

SampleDecoder::SampleDecoder() { }

SampleDecoder::~SampleDecoder() { }

double SampleDecoder::decode(const std::vector< double >&


chromosome) const {

//Struct with the pair: Item and Random Keys


typedef std::pair< double, double > RandomKeyItem;

std::vector<RandomKeyItem> VetorItemRK(chromosome.size());

unsigned pesoAlocado = 0, ganhoAlocado = 0, item;

std::vector<unsigned> ItemAlocado(chromosome.size());

for(int i = 0; i <chromosome.size();i++)
{
VetorItemRK[i].first = chromosome[i]; // first é a
chave aleatória
VetorItemRK[i].second = i; // second é a posição do
item
ItemAlocado[i] = 0; // vetor que informa se o item foi
alocado "1" ou não "0"
}

// ordena as chaves em ordem crescente


std::sort(VetorItemRK.begin(),VetorItemRK.end());

27
// Verifica se o item pode ser alocado na mochila e calcula o
valor de todos os itens
for (int i; (i < chromosome.size()) && (pesoAlocado <
sizeknapsack);i++){
item = VetorItemRK[i].second;

if (pesoAlocado + VetorGanhoPeso[item].second
<= sizeknapsack)
{

pesoAlocado =
VetorGanhoPeso[item].second + pesoAlocado;
ganhoAlocado =
VetorGanhoPeso[item].first + ganhoAlocado;
ItemAlocado[i] = 1;

// sample fitness is the first allele


return ganhoAlocado; // return ganhoTotalAlocado;
}

28
ANEXO II: Método de Seleção Roleta

/*-----------------------Método de Seleção - ROLETA----------------*/

double selecionadoElite, selecionadoNaoElite, somaElite,


somaNaoElite;
double sorteioElite, sorteioNaoElite, identElite, identNaoElite;
unsigned y = 0;

/*-----------------------Criando Vetores----------------------------*/

typedef std::pair< double, double > PerctFitness;


std::vector<PerctFitness> vtPerctFitness(p);

typedef std::pair< double, double > Elite;


std::vector<Elite> vtElite(p);

typedef std::pair< double, double > NaoElite;


std::vector<NaoElite> vtNaoElite(p);

typedef std::pair< double, double > Selecionados;


std::vector<Selecionados> vtSelecionados(2);

/*-------------------Inserindo valores de Fitness-------------------*/

for ( y = 0; y < p; ++y)


{
vtPerctFitness[y].first = y; // insere na matriz
vtPerctFitness as posições
vtPerctFitness[y].second = curr.fitness[y].first; //
insere na matriz vtPerctFitness os fitness
//somaFitness = somaFitness + vtPerctFitness[i].second;
// soma os fitness

/*----------------Vetor Elite - Inserindo valores-------------------*/

/*Pegando valores de Elite do vetor PerctFiness e inserindo


valores no vetor Elite */

for (y=0; y < pe; y++){

vtElite[y].first = y;
vtElite[y].second = vtPerctFitness[y].second;
somaElite = somaElite + vtElite[y].second;
}

/* Ordenando o vetor Elite em forma crescente*/

29
std::sort(vtElite.rbegin(), vtElite.rend());

/*Imprimindo valores do Vetor Elite */


/*
for (y=0; y < pe; y++){

std::cout << "\n\nVetor Elite: " << vtElite[y].second;

}
*/
/*Inserir porcetagem Vetor População Elite*/

for (y = 0; y < pe; ++y){

vtElite[y].second = (vtElite[y].second)/somaElite;

}
/*
for (y=0; y < pe; y++){

std::cout << "\n\nPorcentagem Vetor Elite: " <<


vtElite[y].second;

}
*/
/*--------------------Vetor Não Elite - Inserindo valores------------*/

/*Pegando valores de Não Elite do vetor PerctFiness e inserindo


valores no vetor Não Elite */

for (y= pe; y < p; y++){

vtNaoElite[y].first = pe; //Insere no vetor a posição


vtNaoElite[y].second = vtPerctFitness[y].second;
somaNaoElite = somaNaoElite + vtNaoElite[y].second;
}

/* Ordenando o vetor Não Elite em forma crescente*/

std::sort(vtNaoElite.begin(), vtNaoElite.end());

/*Imprimindo valores do Vetor Não Elite*/


/*
for (y= pe; y < p; y++){

std::cout << "\n\nVetor Não Elite ANTES: " <<


vtNaoElite[y].second;

}
*/
/*Inserir porcetagem Vetor População Não Elite*/

for (y = pe; y < p; ++y){


30
vtNaoElite[y].second =
(vtNaoElite[y].second)/somaNaoElite;

/*
for (y = pe; y < p; y++){

std::cout << "\n\nVetor Não Elite Depois: " <<


vtNaoElite[y].second;

}
*/

while(i < p - pm) {

/*-------------------------GIRA A ROLETA NO ELITE--------------------*/

identElite = 0;

selecionadoElite = vtElite[identElite].second;

/* Sorteia um numero entre 0 e 1 com casas decimais */

sorteioElite = refRNG.rand();

//std::cout << "\n\n SORTEIO ELITE: " << sorteioElite;

/* Verifica se o valor da roleta é maior que o selecionado */

while(selecionadoElite < sorteioElite)


{
identElite++;

selecionadoElite=selecionadoElite+vtElite[identElite].second;

//std::cout << "\n\nPai Elite selecionado: " <<


vtElite[identElite].second;

/*---------------------GIRA A ROLETA NO NÃO ELITE--------------------*/

identNaoElite = pe;

selecionadoNaoElite = vtNaoElite[identNaoElite].second;

/* Sorteia um numero entre 0 e 1 com casas decimais */

sorteioNaoElite = refRNG.rand();

31
//std::cout << "\n\n SORTEIO NÃO ELITE: " << sorteioNaoElite;

/* Verifica se o valor da roleta é maior que o selecionado */

while(selecionadoNaoElite < sorteioNaoElite)


{

identNaoElite++;
selecionadoNaoElite = selecionadoNaoElite +
vtNaoElite[identNaoElite].second;

//std::cout << "\n\nPai Nao Elite selecionado: " <<


vtNaoElite[identNaoElite].second;

32
ANEXO III: Método de Seleção Torneio

/*--------------------Método de Seleção - TORNEIO -------------------*/

float sorteioElite, sorteioNaoElite, fitnessElite,


fitnessNaoElite, selecionadoElite, selecionadoNaoElite;
int y = 0,k = 4, posicaoNaoElite, auxiliarElite,
auxiliarNaoElite;

/*-----------------------Criando Vetores-----------------------------*/

typedef std::pair< double, double > NewFitness;


std::vector<NewFitness> vtNewFitness(p);

typedef std::pair< double, double > Sorteio;


std::vector<Sorteio> vtSorteio(p);

typedef std::pair< double, double > Elite;


std::vector<Elite> vtElite(p);

typedef std::pair< double, double > NaoElite;


std::vector<NaoElite> vtNaoElite(p);

/*----------------Inserindo valores de Fitness-----------------------*/

for (int i = 0; i < p; ++i)


{
vtNewFitness[i].first = i; // insere na matriz
vtPerctFitness as posições
vtNewFitness[i].second = curr.fitness[i].first; // insere
na matriz vtPerctFitness os fitness

/*------------Imprimindo a matriz toda com posição e fitness---------*/


/*
for (i = 0; i < p; ++i)
{
std::cout << "\nPosicao: " <<
vtNewFitness[i].first ;
std::cout << "\nFitness: " <<
vtNewFitness[i].second;
}
*/
/*------------------Vetor Elite - Inserindo valores------------------*/

/*Pegando valores de Elite do vetor PerctFiness e inserindo


valores no vetor Elite */

for (y=0; y < pe; y++){

33
vtElite[y].first = y;
vtElite[y].second = vtNewFitness[y].second;

/*Imprimindo valores do Vetor Elite */


/*
for (y=0; y < pe; y++){

std::cout << "\n\nVetor Elite: " << vtElite[y].second;

}
*/

/*-----------------Vetor Não Elite - Inserindo valores---------------*/

for (y= pe; y < p; y++){

vtNaoElite[y].first = y; //Insere no vetor a posição


vtNaoElite[y].second = vtNewFitness[y].second;

/*Imprimindo valores do Vetor Não Elite*/

/*
for (y= pe; y < p; y++){

std::cout << "\n\nVetor Não Elite: " <<


vtNaoElite[y].second;

*/

// 3. We'll mate 'p - pe - pm' pairs; initially, i = pe, so we


need to iterate until i < p - pm:

while(i < p - pm)


{

/*------------------------Armazena pai Elite------------------------*/

auxiliarElite = pe;
//std::cout << "\n\n\n\n\nAuxiliar Elite: " <<
auxiliarElite;
for (y = 0; y < k; y++)
{

sorteioElite = rand( ) % pe;


//std::cout << "\n\n\nSorteados Elite: " <<
sorteioElite;

34
/*Compara os itens Elite*/

if (sorteioElite < auxiliarElite)


{
auxiliarElite = sorteioElite;
}
//std::cout << "\n\n\n\n\nAuxiliar Elite: " <<
auxiliarElite;
}

selecionadoElite = vtElite[auxiliarElite].second;

//std::cout << "\n\nSelecionado Elite: " <<


selecionadoElite;

/*----------------------Armazena pai Não Elite-----------------------*/

auxiliarNaoElite = p - pe;
//std::cout << "\n\n\n\n\nAuxiliar Não Elite: " <<
auxiliarNaoElite;
for (y = pe; y < pe + k ; y++)
{

sorteioNaoElite = rand( ) % (p - pe) + pe;

//std::cout << "\n\n\nSorteados Não Elite: " <<


sorteioNaoElite;

/*Compara os itens Não Elite*/

if (sorteioNaoElite < auxiliarNaoElite)


{
auxiliarNaoElite = sorteioNaoElite;
}
//std::cout << "\n\nAuxiliar Não Elite: " <<
auxiliarNaoElite;
}

posicaoNaoElite = pe + auxiliarNaoElite;
//std::cout << "\n\nPosição não Elite: " <<
posicaoNaoElite;

selecionadoNaoElite =
vtNaoElite[posicaoNaoElite].second;

//std::cout << "\n\nSelecionado Não Elite: " <<


selecionadoNaoElite;

/*-------------------------------------------------------------------*/

35

Você também pode gostar