Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do...

90
SERVIÇO PÚBLICO FEDERAL MINISTÉRIO DA EDUCAÇÃO INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DO PARÁ TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS GASTÃO JOSE MACEDO CLAUDE WESLEY LOUZEIRO MOTA APLICAÇÃO DA TÉCNICA MAPREDUCE NA MODELAGEM DE ALGORITMOS GENÉTICOS PARA O “PROBLEMA DO CAIXEIRO VIAJANTE” BELÉM 2014

Transcript of Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do...

Page 1: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

SERVIÇO PÚBLICO FEDERAL

MINISTÉRIO DA EDUCAÇÃO INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DO PARÁ

TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

GASTÃO JOSE MACEDO CLAUDE WESLEY LOUZEIRO MOTA

APLICAÇÃO DA TÉCNICA MAPREDUCE NA MODELAGEM

DE ALGORITMOS GENÉTICOS PARA O “PROBLEMA DO CAIXEIRO VIAJANTE”

BELÉM

2014

Page 2: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

1

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

TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

GASTÃO JOSE MACEDO CLAUDE WESLEY LOUZEIRO MOTA

APLICAÇÃO DA TÉCNICA MAPREDUCE NA MODELAGEM

DE ALGORITMOS GENÉTICOS PARA O “PROBLEMA DO

CAIXEIRO VIAJANTE”

.

Trabalho Acadêmico de Conclusão de Curso apresentado ao Colegiado

Específico de TADS do Instituto Federal de Educação, Ciência e Tecnologia do Pará – IFPA, como requisito para a

obtenção do Grau em Tecnologia em Análise e Desenvolvimento de Sistemas,

sob a orientação do Prof. Ms. Claudio Roberto de Lima Martins.

BELÉM 2014

Page 3: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

2

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

TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

GASTÃO JOSE MACEDO CLAUDE WESLEY LOUZEIRO MOTA

APLICAÇÃO DA TÉCNICA MAPREDUCE NA MODELAGEM DE ALGORITMOS GENÉTICOS PARA O “PROBLEMA DO CAIXEIRO

VIAJANTE” Data Defesa: ___ /___/___

Conceito:______________

Banca Examinadora

.

_______________________________________

Profº. Orientador: Msc. Claudio Roberto de Lima Martins – IFPA

_______________________________________ Profº. Msc. Fabrício Medeiros Alho – IFPA

_______________________________________

Profº. Msc. Márcio Góes do Nascimento – IFPA

BELÉM 2014

Page 4: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

3

RESUMO

Os problemas que envolvem processamento de grandes conjuntos de

dados, tem como solução o uso do modelo do processamento paralelo e distribuído,

que se adapta a qualquer volume e nível de processamento. Esse é o caso do

MapReduce, uma técnica que abstrai os detalhes de paralelização do algoritmo de

execução para o processamento de grandes conjuntos de dados, tornando-se

adequado na aplicação dos Algoritmos Genéticos (AG), técnicas de otimização

aplicadas em domínios como inteligência artificial, otimização numérica e

combinatória. Neste trabalho é demonstrada a aplicação da técnica MapReduce na

modelagem do Algoritmo Genético para resolver o Problema do Caixeiro Viajante,

um problema que tenta determinar a menor rota para percorrer uma série de cidades

(visitando cada uma pelo menos uma vez). É realizado um levantamento das

técnicas, conceitos e modelos, e com base nisso é proposto uma nova modelagem

do Algoritmo Genético para o MapReduce na tecnologia Apache Hadoop. A proposta

é fundamentada nas melhores características apresentadas por outros modelos,

melhorando o seu desempenho e simplificando o seu desenvolvimento. A avaliação

é baseada na simulação da aplicação e no desempenho do modelo sobre a variação

do tamanho dos dados de processamento. Os resultados demonstram que o

modelo proposto é eficiente no processamento de grande quantidade de dados, pois

comprova-se que o aumento do tamanho dos dados iniciais da aplicação tende a

encontrar as melhores soluções.

PALAVRAS-CHAVE: MapReduce; Hadoop; Algoritmos Genéticos; Problema do

Caixeiro Viajante.

Page 5: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

4

ABSTRACT

The problems involving processing of large data sets, has as solution model

of parallel and distributed processing, which adapts to any volume and level of

processing. This is the case of MapReduce, a technique that abstracts the details of

parallelization of the execution algorithm for processing of large data sets, making it

suitable in the application of Genetic Algorithms (GA) optimization techniques applied

in fields such as artificial intelligence, numerical optimization, and Combinatorics. In

this work is demonstrated the application of MapReduce technique on modeling the

genetic algorithm to solve the Travelling Salesman Problem, a problem that attempts

to determine the shortest route to traverse a series of cities (visiting each one at least

once). Is performed a survey of techniques, concepts and models, and on this basis

it is proposed a new modeling of Genetic Algorithm for the MapReduce in the Apache

Hadoop technology. The proposal is grounded on the best features presented by

other models, improving performance and simplifying its development. The

evaluation is based on simulations of application and performance of the model on

the variation of the size of the data processing. The results demonstrate that the

proposed model is efficient in processing large amounts of data, because it proves

that the increase in the size of the initial data from the application tends to find the

best solutions.

KEY-WORDS: MapReduce, Hadoop, Genetic Algorithm, Traveling Salesman

Problem

Page 6: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

5

LISTA DE ILUSTRAÇÕES

1 Figura 2.1: Ilustração das funções de ordem-superior map e fold, e

seu funcionamento.

15

2 Figura 2.2: Vista simplificada do funcionamento de um trabalho

MapReduce.

17

3 Figura 2.3: Fluxo de uma operação do modelo MapReduce. 18

4 Figura 3.2. Shuffle e Sort em MapReduce. 32

5 Figura 4.1. Detalhe do indivíduo AG. 38

6 Figura 4.2: Grafo completo no plano Euclidiano. 42

7 Figura 4.3: Codificação da “Representação Matricial”. 45

8 Figura 4.4: Codificação “sequencial”: a) Sequência Ordenada; b)

Notação do Ciclo.

45

9 Figura 4.5: Funcionamento do operador PMX. 47

10 Figura 4.6: Funcionamento do operador CX. 48

11 Figura 4.7: Funcionamento do operador OX. 49

12 Figura 5.1: Mapa das cidades do PCVS no plano euclidiano. 55

13 Figura 5.2: Exemplo do cálculo da distância entre as cidades. 56

14 Figura 5.3: Funcionamento do processamento MapReduce para o

Algoritmo Genético no modelo Dupla Geração.

59

15 Figura 5.4: Fluxo lógico de dados do processo MapReduce para o AG. 61

16 Figura 5.5: Código Map do Algoritmo Genético MapReduce. 63

17 Figura 5.6: Código Reduce do Algoritmo Genético MapReduce. 64

18 Figura 5.7: Diagrama de classe do PCV-AG para o MapReduce. 65

19 Figura 5.8: Código simplificado da classe Indivíduo. 66

20 Figura 5.9: Código simplificado da classe CaixeiroViajanteMapper. 66

21 Figura 5.10: Código simplificado da classe CaixeiroViajanteReducer. 67

22 Figura 5.11: Código simplificado da classe OperacaoGenetica. 68

23 Figura 5.12: Mapa do conjunto de 20 cidades no plano euclidiano. 70

24 Figura 5.13: Tendência gerada pelo aumento de escala da população. 72

25 Figura 5.14: Melhor e pior indivíduo encontrado entre os melhores. 73

Page 7: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

6

SUMARIO

1 INTRODUÇÃO ........................................................................................................................ 8

1.1 OBJETIVO ......................................................................................................................... 11

1.1.1 Objetivo Geral.................................................................................................................. 11

1.1.2 Objetivo Especifico .......................................................................................................... 11

1.2 METODOLOGIA ................................................................................................................. 11

1.3 ESTRUTURA DO TEXTO .................................................................................................. 12

2 MODELO MAPREDUCE....................................................................................................... 13

2.1 INTRODUÇÃO.................................................................................................................... 13

2.2 MAPREDUCE ..................................................................................................................... 16

2.2.1 Funcionamento ................................................................................................................ 18

2.3 FRAMEWORK DE EXECUÇÃO MAPREDUCE ................................................................ 20

2.4 IMPLEMENTAÇÃO ............................................................................................................ 21

2.4.1 Google MapReduce......................................................................................................... 21

2.4.2 Apache Hadoop ............................................................................................................... 22

2.4.3 Twister ............................................................................................................................. 22

2.4.4 Phoenix ............................................................................................................................ 23

2.4.5 Mars ................................................................................................................................. 23

2.4.6 CELL MapReduce ........................................................................................................... 24

2.4.7 MRPGA............................................................................................................................ 24

2.5 CONCLUSÃO ..................................................................................................................... 24

3 HADOOP ............................................................................................................................... 25

3.1 INTRODUÇÃO.................................................................................................................... 25

3.1.1 Componentes .................................................................................................................. 25

3.1.2 Modo de Execução .......................................................................................................... 26

3.2 HDFS .................................................................................................................................. 27

3.3 FRAMEWORK MAPREDUCE............................................................................................ 28

3.3.1 Execução do Trabalho .................................................................................................... 29

3.3.2 Partitioners e Combiners ................................................................................................. 30

3.3.3 Shuffle e Sort ................................................................................................................... 31

3.3.4 Aplicações ....................................................................................................................... 33

3.4 CONCLUSÃO ..................................................................................................................... 35

4 AG & PCV.............................................................................................................................. 36

4.1 ALGORITMOS GENÉTICOS ............................................................................................. 36

Page 8: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

7

4.1.1 Indivíduos e a População ................................................................................................ 37

4.1.2 Inicialização ..................................................................................................................... 39

4.1.3 Processo de Avaliação e Seleção................................................................................... 39

4.1.4 Processo de Cruzamento e Mutação .............................................................................. 40

4.1.5 Processo de Atualização e Finalização .......................................................................... 41

4.2 PROBLEMA DO CAIXEIRO VIAJANTE ............................................................................ 41

4.2.1 Codificação ...................................................................................................................... 44

4.2.2 Aptidão ............................................................................................................................. 46

4.2.3 Operadores de cruzamento............................................................................................. 46

4.2.4 Operadores de mutação.................................................................................................. 49

4.3 CONCLUSÃO ..................................................................................................................... 50

5 IMPLEMENTAÇÃO ............................................................................................................... 51

5.1 TRABALHOS RELACIONADOS ........................................................................................ 51

5.2 MODELO AG EM MAPREDUCE ....................................................................................... 52

5.3 MODELAGEM DO PROBLEMA ........................................................................................ 54

5.3.1 Modelagem do Algoritmo Genético ................................................................................. 56

5.3.2 Modelagem do MapReduce ............................................................................................ 58

5.4 IMPLEMENTAÇÃO ............................................................................................................ 61

5.4.1 Algoritmo.......................................................................................................................... 61

5.4.2 Implementação em Java ................................................................................................. 65

5.5 TESTES E AVALIAÇÃO DE RESULTADOS..................................................................... 69

5.5.1 Ambiente operacional e cenário de execução ................................................................ 69

5.5.2 Simulações e resultados obtidos .................................................................................... 71

5.5.3 Desempenho da Modelagem Dupla Geração ................................................................ 73

5.6 CONSIDERAÇÕES FINAIS ............................................................................................... 74

CONCLUSÃO........................................................................................................................... 78

REFERÊNCIAS BIBLIOGRÁFICAS ....................................................................................... 81

ANEXO A.................................................................................................................................. 84

Page 9: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

8

1 INTRODUÇÃO

Vivemos na era dos dados. Não é fácil medir o volume total de dados

armazenados eletronicamente, mas uma estimativa da IDC (EMC, 2014) colocou o

tamanho do "universo digital" em ordem do zetabytes, fenômeno chamado de Big

Data (aqui denominado com BigData). Há uma grande quantidade de dados, a

maioria dos dados está contida nas maiores propriedades da web, ou instituições

científicas ou financeiras. A New York Stock Exchange, Facebook, Ancestry.com, O

Large Hadron Collider (LHC), trabalha ou armazena dados que vai de terabytes a

petabytes (WHITE, 2010).

Atualmente há vários exemplos de aplicações sobre o BigData. Por exemplo,

a análise dos dados sobre o comportamento do usuário web recuperados de

sistemas de vendas na web e redes sociais. O registro do comportamento gera uma

quantidade de dados que muitas organizações simplesmente não conseguem lidar

com o volume, levando ao descarte desses dados depois de algum tempo. Isto

representa perda de oportunidades. Conhecer o comportamento dos usuários

permite melhores decisões de negócios e uma vantagem competitiva no mercado.

Em termos gerais, isso é conhecido como inteligência de negócios, que abrange

uma ampla variedade de tecnologias, incluindo data warehousing, data mining e

analytics (LIN & DYER, 2010).

O BigData é um conceito definido para um conjunto de dados extremamente

grande, gerado pelo crescimento do poder computacional e do surgimento de novas

fontes geradoras de informação, tornando-se um desafio na área de Tecnologia da

Informação. O BigData deve tratar de pelo menos três propriedades: volume,

velocidade, variedade. O volume está associado ao sistema de armazenamento que

extrapola os valores tradicionais a ser armazenado. A velocidade está relacionado

ao processamento e à rapidez no acesso aos dados. A variedade diz respeito à

diversidade do formato e da estrutura de armazenamento dos dados de origem.

Portanto a solução para o BigData deve possuir a característica de

escalabilidade para suprir todas as sua propriedades. Soluções convencionais, como

banco de dados relacional, não conseguem atender questões que envolvem o

Volume e a Velocidade, pois o poder de processamento, de capacidade e

Page 10: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

9

armazenamento é melhor resolvido no modelo do processamento paralelo e

distribuído, como o presentes em grid computacional, tornado assim adaptável a

qualquer volume em nível de processamento.

Mas, empregar o paradigma de paralelização da computação, com

distribuição dos dados, não é trivial. Aspectos envolvidos com a paralelização,

tolerância a falhas, distribuição de dados e balanceamento de carga devem ser

levados em conta pelo desenvolvedor de aplicações (DEAN & GHEMAWAT, 2008).

O programador tem que pensar nas falhas da implementação, na reprogramação e

substituição de máquinas defeituosas, coordenar os processos da computação

distribuída em larga escala, saber se um processo remoto falhou ou não, enfim, um

grande desafio a superar.

Como solução para esses problemas e desafios, foi proposto o modelo

MapReduce de programação, para ser executado em um grid computacional. Como

a solução para o BigData está relacionada com escalabilidade, MapReduce extrai a

dificuldade de programação do grid computacional, provendo suporte às

propriedades do BigData. A velocidade é resolvida com as escalabilidade do

processamento do MapReduce, baseado em cada processador dos nós que fazem

parte do grid; se houver necessidade de aumentar a velocidade de resposta, basta

aumenta o número de máquinas no arranjo do grid. O Volume é resolvido com a

escalabilidade do sistema de armazenamento distribuído do MapReduce; para mais

volume, mais máquinas podem ser adicionadas para a utilização do disco rígido em

cada nó, sem prejudicar o sistema, tornado-se bem flexível. A Variedade é resolvida

com a utilização de Banco de Dados com tecnologias específicas para o modelo,

como o NoSQL, que fornece suporte a estrutura "chave/valor", um esquema

altamente escalavel para a manipulação de grandes bases de dados em formatos

diversos.

MapReduce é um modelo de programação baseado em duas funções

chamadas map e reduce, inspiradas em linguagens funcionais. Esse modelo

estabelece uma abstração que permite construir aplicações com operações simples,

escondendo os detalhes da paralelização. Em resumo, tais funções uti lizam um

conjunto de pares chave/valor para entrada e saída dos dados. O modelo

MapReduce divide o processamento em duas etapas. Na primeira o Map, mapeia e

Page 11: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

10

distribui os dados em diversos nós de processamento e armazenamento; na

segunda etapa, o Reduce, que agrega e processa os resultados principais, para

gerar um resultado final. O poder computacional da técnica MapReduce pode ser

aplicado em vários campos, como o agrupamento de dados, aprendizado de

máquina e visão computacional. Um desses casos são os Algoritmos Genéticos na

qual tende a encontra valores de alta aptidão com o aumento na escala do número

de indivíduos da população, porém esse aumento levaria um alto custo de

processamento, tornado a técnica MapReduce ideal.

Os Algoritmos Genéticos são aplicados em vários domínios, tais como, no

campo da inteligência artificial, otimização numérica e combinatória, engenharia,

química, biologia e etc. Os Algoritmos Genéticos mais simples necessitam de uma

grande população para encontrar uma boa solução, essa grande quantidade de

dados podem afetar o desempenho da máquina, pois dependendo do problema

exigiria grande quantidade de memória e de processamento, tornando impossível

para uma só máquina. Sendo os Algoritmos Genéticos um algoritmo de natureza

paralela ele pode ser processado em várias máquinas, porém isso demandaria que

o algoritmo implementasse todas as rotinas necessárias para a paralelização em

ambiente distribuído, tornado-o mais complexo. O MapReduce é uma técnica para

abstrair os detalhes de paralelização do algoritmo de execução, tornando adequado

para a necessidade dos Algoritmos Genéticos podendo escalar grande quantidade

de indivíduos e reduzir o tempo de execução.

O Algoritmo Genético é uma técnica de otimização utilizada como um

método de busca, podendo ser aplicada em situações que o número valores ou

combinações para resolver um determinado problema são muito alto como é caso

Problema do Caixeiro Viajante (PCV), em que o número de combinações de

caminhos aumenta exponencialmente em função do número de cidades. O PCV é

um problema de otimização NP-difícil, que consiste em encontrar o menor caminho

para um caixeiro viajante que visita várias cidades apenas uma vez, e tem diferentes

aplicações, como problema de roteamento de veículos e a otimização das tarefas de

máquinas industriais.

No trabalho de Verma et al.(2009), foi proposto uma forma de modelar as

iterações dos algoritmos genéticos, porém essa modelagem tem um alto custo de

Page 12: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

11

desempenho quando implementada na técnica MapReduce, pois essa técnica não

suporta eficientemente aplicações iterativas. Para resolver esse problema de

desempenho, foi desenvolvida novas formas de modelar os Algoritmos Genéticos

para a técnica MapReduce, com objetivo de minimizar o custo de desempenho.

1.1 OBJETIVO

1.1.1 Objetivo Geral

O objetivo deste trabalho é demonstrar o uso da técnica MapReduce na

modelagem de algoritmos genéticos. Para isso, será demonstrado a implementação

de uma aplicação que busque a otimização para a melhor solução ao problema

conhecido por "caixeiro viajante".

1.1.2 Objetivo Especifico

Pesquisar conceitos, técnicas e ferramentas para o desenvolvimento de

aplicações distribuídas para processamento paralelo e massivo de dados.

Apresentar o modelo MapReduce de programação. Demonstrar uma implementação

MapReduce para armazenamento, manipulação e análise de dados. Apresentar o

Algoritmo Genético e seu processo de funcionamento. Apresentar o conceito do

Problema do Caixeiro Viajante e os métodos dos Algoritmos Genéticos específicos

para esse problema. Demonstrar as formas de modelar os Algoritmos Genéticos e

sua implementação para Framework Hadoop. Avaliar os resultados do modelo e da

aplicação uti lizada para resolver o Problema do Caixeiro Viajante.

1.2 METODOLOGIA

Neste trabalho foi feita uma pesquisa bibliográfica de documentos relevantes

sobre a tecnologia do BigData, do modelo de programação MapReduce, do

Framework Hadoop, sobre o Algoritmos Genético e, especialmente, ao problema

do "Caixeiro Viajante".

Page 13: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

12

Depois do levantamento da técnica e conceitos, foi desenvolvida uma

modelagem para implementar o algoritmo genético no MapReduce, para resolver o

problema do "caixeiro viajante".

Foi realizada uma avaliação dos resultados obtidos na simulação da

aplicação quanto a melhor solução otimizada, considerando o tamanho da

população do AG, isto é, uma análise sobre a variação da quantidade de dados que

servem de parâmetros para busca da melhor solução.

1.3 ESTRUTURA DO TEXTO

O trabalho está organizado da seguinte forma. No capítulo 2 apresenta o

modelo de programação MapReduce, seus conceitos, características,

funcionamento e implementações. No capítulo 3 é apresentada a implementação

MapReduce, o Apache Hadoop, sua estrutura, características e componentes, em

especial o HDFS e o framwork Hadoop MapReduce. No capítulo 4, apresenta-se a

técnica do Algoritmo Genético e o Problema do Caixeiro Viajante. No capítulo 5 é

apresentada a modelagem do Algoritmo Genético no modelo de programação

MapReduce para o Problema do Caixeiro Viajante, além de sua implementação no

Apache Hadoop, e relatados os resultados obtidos na simulação do algoritmo e as

considerações finais.

Page 14: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

13

2 MODELO MAPREDUCE

O modelo de programação MapReduce é utilizado para o processamento de

grandes conjuntos de dados. É baseado no ambiente computacional paralelo e

distribuído, provendo escalabilidade e simplificação para o desenvolvimento das

aplicações para o BigData. Embora MapReduce proporcione facilidades no

processamento do BigData, as aplicações devem se projetadas como é proposto no

modelo de programação funcional, exigindo um estudo mais detalhado sobre o

domínio da aplicação, verificando-se se ela se adéqua ao modelo MapReduce.

Este capítulo apresenta a técnica MapReduce. Na seção 2.1 é apresentada

uma visão geral do modelo. Na seção 2.2, o modelo MapReduce é definido em

termos de seu funcionamento. Na seção 2.3 apresentamos as características de

execução do MapReduce. Na seção 2.4 apresentamos as implementações do

MapReduce disponíveis no mercado. Finalizamos com a conclusão do capítulo na

seção 2.5.

2.1 INTRODUÇÃO

O MapReduce foi originalmente desenvolvido pela Google no início dos anos

2000, no qual se buscava aperfeiçoar o serviço de busca de páginas Web,

almejando criar uma melhor técnica para processar e analisar regularmente o

imenso conjunto de dados da Web (GOLDMAN et al., 2012, p. 3). Para o

processamento de grande quantidade de dados, há necessidade que o

processamento seja distribuído entre centenas ou milhares de máquinas,

configuração que permite diminuir o tempo desse processamento. As questões de

como paralelizar a computação, distribuir os dados, e identificar as falhas, dificultam

a computação simples, levando o programador a lidar com grande quantidade de

código complexo (DEAN & GHEMAWAT, 2008, p. 1).

Com o objetivo de resolver esta complexidade, Jeffrey Dean e Sanjay

Ghemawat, dois engenheiros da Google, desenvolveram a tecnologia MapReduce

inspirada nas funções map e reduce presentes na linguagem de programação Lisp e

em muitas outras linguagens funcionais. Essa nova abstração permitiu a execução

Page 15: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

14

de algoritmos mais simples, escondendo os detalhes da paralelização, tolerância a

falhas, distribuição de dados e balanceamento de carga em uma biblioteca criada

para essa finalidade (DEAN & GHEMAWAT, 2008, p. 1). Deste modo, possibilitou

otimizar a indexação e catalogação dos dados sobre as páginas Web e suas

ligações.

O MapReduce permite dividir um grande problema em vários pedaços e

distribuí-los em diversos computadores. Essa técnica deixou o sistema de busca do

Google mais rápido mesmo sendo executado em computadores convencionais e

menos confiáveis, diminuindo assim os custos ligados à infraestrutura (GOLDMAN et

al., 2012, p. 3).

MapReduce tem suas raízes em programação funcional. Uma característica

chave de linguagens funcionais é o conceito de funções de ordem-superior (higher-

order), ou funções que podem aceitar outras funções como argumentos. Duas

funções comuns de ordem superior são map e fold. Por exemplo, dada uma lista

conforme vista na Figura 2.1, a função superior map utiliza a função f, que recebe

como parâmetros todos os elementos da lista. A lista resultante da função map é

utilizada pela função superior fold, que combina os valores da lista através da função

g. A função g usa um valor inicial e o primeiro item da lista, o resultado é

armazenado em uma variável intermediária. Na segunda execução, g utiliza a

variável intermediária e o próximo item da lista. Este processo se repete até que

todos os itens da lista tenham sido processados, retornando no final o valor da

variável intermediária (LIN & DYER, 2010, p. 20).

Podemos ver map como uma forma concisa para representar a

transformação de um conjunto de dados, como definido pela função f. Na mesma

linha, podemos ver fold como uma operação de agregação, como definido pela

função g. Uma observação imediata é que a aplicação de f para cada item em uma

lista pode ser paralelizado de uma maneira simples, uma vez que cada aplicação

funcional acontece isoladamente. Em um cluster de máquinas, estas operações

podem ser distribuídas em diferentes máquinas. A operação de fold, por outro lado,

tem mais restrições quanto à localidade dos dados, pois os elementos da lista

devem ser reunidos para serem aplicados na função g. No entanto, muitas

aplicações não exigem que a função g seja aplicada a todos os elementos da lista.

Page 16: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

15

Na medida em que elementos na lista posam ser divididos em grupos, a função fold

também pode prosseguir em paralelo. Resumidamente, descrevemos a técnica

MapReduce, em que suas fases Map e Reduce correspondam aproximadamente às

operação map e fold da programação funcional (LIN & DYER, 2010, p. 20).

Figura 2.1: Ilustração das funções de ordem-superior map e fold, e seu

funcionamento (Adaptado de: LIN & DYER, 2010, p. 20).

Visto de um ângulo diferente, MapReduce pode ser aplicado como uma

receita genérica para processamento de grandes conjuntos de dados, organizado

em duas fases que correspondem às duas funções do MapReduce. No primeiro

estágio, uma computação é aplicada paralelamente sobre todos os registros de

entrada de um conjunto de dados, produzindo uma saída intermediária que é então

agregada por uma computação na segunda fase (LIN & DYER, 2010, p. 21).

O par chave/valor é a estrutura básica de dados no MapReduce. Os

algoritmos devem levar um conjunto de pares chave/valor de entrada e produzir um

conjunto de pares chave/valor de saída. O usuário da biblioteca do MapReduce

modela o algoritmo como duas funções Map e Reduce. O Map leva um par de

entradas e produz um conjunto de pares chave/valor intermediários, que em seguida

são agrupados de acordo com a chave e passa para a função de Reduce. A função

reduce, aceita uma chave intermediária e seu conjunto de valores. Ela mescla esses

valores para formar um conjunto possivelmente menor de valores (DEAN &

GHEMAWAT, 2008, p. 1).

f f f f f

g g g g g

Lista usada no map

Lista resultante do map

Lista usada no fold

Valor Inicial Valor Final

Variável Intermediária

Função f

Função g

Page 17: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

16

Para ser preciso, MapReduce pode referir-se a três conceitos distintos, mas

relacionados. Primeiro, MapReduce é um modelo de programação. Segundo,

MapReduce pode referir-se ao framework de execução, que coordena a execução

de programas escritos neste estilo particular de tecnologia. Finalmente, MapReduce

pode se referir à implementação de software do modelo de programação e do

framework de execução, como é o caso das várias implementação existentes, como

a ferramenta proprietária do Google, e a solução em código aberto do Hadoop, para

processadores multicore (Phoenix) e etc. (LIN & DYER, 2010, p. 21).

2.2 MAPREDUCE

Como visto, MapReduce é um modelo de programação especificado em

funções map e reduce. Pares de chave/valor formam a estrutura básica de dados

em MapReduce. Parte do projeto de algoritmos MapReduce envolve impor a

estrutura de chave/valor em conjuntos de dados com qualquer tipo de dado (inteiro,

texto, etc). Em alguns algoritmos, as chaves de entrada não são particularmente

significativas e são simplesmente ignoradas durante o processamento, enquanto em

outros casos chaves de entrada são usados para identificar exclusivamente um dado

(LIN & DYER, 2010, p. 22).

Em MapReduce, o programador define a função map e a função reduce com

as seguintes assinaturas (onde [ e ] representam uma lista de valores) :

map: (k1, v1) [(k2, v2)]

reduce: (k2, [v2]) [(k3, v3)]

A entrada para um trabalho MapReduce começa com os dados

armazenados no sistema de arquivos distribuído. Como podemos ver na Figura 2.2,

os algoritmos devem levar um conjunto de pares chave/valor de entrada e produzir

um conjunto de pares chave/valor de saída. O usuário (programador) da biblioteca

MapReduce modela o algoritmo como duas funções Map e Reduce. O Map escrito

pelo programador leva um par de entradas e produz um conjunto de pares

chave/valor intermediários. Posteriormente, são unidos todos os valores

Page 18: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

17

intermediários associados com a mesma chave e passa o resultado para a função

Reduce. A função Reduce, também escrita pelo programador, aceita uma chave

intermediária e seu conjunto de valores. A função Reduce mescla esses valores

para formar um conjunto possivelmente menor de valores (DEAN & GHEMAWAT,

2008, p. 1). Os dados intermediários chegam a cada redutor em ordem, classificadas

pela chave, no entanto, nenhuma relação de ordenação é garantida para chaves

através de diferentes redutores. Pares chave/valor de saída de cada redutor são

escritos persistentemente no sistema de arquivos distribuído enquanto que pares de

chave/valor intermediários são transitórios e não preservados. A saída termina em

vários arquivos no sistema de arquivos distribuído, em que corresponde ao número

de redutores (LIN & DYER, 2010, p. 22).

Figura 2.2: Vista simplificada do funcionamento de um trabalho MapReduce

(Adaptado de: LIN & DYER, 2010, p. 23).

K1 V1 K1 V1 K1 V1 K1 V1

reducer reducer reducer

K2 V2 K2 V2 K2 V2 K2 V2

K3 V3

Shuffle e Sort: Agregação de Valores por Chaves

K2 [V2] K2 [V2] K2 [V2]

mapper mapper mapper mapper

K3 V3 K3 V3

Page 19: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

18

2.2.1 Funcionamento

Os dados de entrada da função Map estão distribuídas em várias máquinas,

dividido automaticamente em um conjunto de M divisões, que podem ser

processadas em paralelo por máquinas diferentes. Os dados de entrada da função

Reduce estão distribuída em R partições do espaço intermediário. A Figura 2.3

mostra o fluxo total de uma operação MapReduce. Quando o programa do usuário

(programador) chama a função MapReduce, ocorre a seguinte sequência de ações

(DEAN & GHEMAWAT, 2008, p. 2).

Figura 2.3: Fluxo de uma operação do modelo MapReduce (Adaptado de: DEAN &

GHEMAWAT, 2008, p. 3).

Operação (1): Primeiramente a biblioteca do MapReduce divide os arquivos

de entrada em M blocos de tamanho fixo na casa das dezenas de MB por bloco de

dados. Em seguida começa as cópias do programa em um cluster de máquinas.

Operação (2): Um das cópias do programa é o mestre e o restante são os

escravos, que recebem tarefas do mestre. Há M tarefas map e R tarefas reduce para

Arquivos

de entrada

Fase de

Map

Fase de

Reduce

Arquivos

de saída

Arquivos Intermediários

(em disco local)

Programa de

usuário

Mestre

Escravo

Escravo

Escravo

Escravo

Escravo

Bloco 0

Bloco 1

Bloco 2

Bloco 3

Bloco 4

Arquivo de

saída0

Arquivo de

saída1

(1) Replicação (1) Replicação

(1) Replicação

(2) Tarefa map (2) Tarefa reduce

(4) Escrita local

(3) Leitura (6) Escrita

(5) Leitura remota

Page 20: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

19

ser atribuído, o mestre escolhe as máquinas ociosas e atribui a cada um delas uma

tarefa map ou reduce.

Operação (3): O escravo que executa uma tarefa map lê o conteúdo do

bloco de entrada e analisa os pares chave/valor encontrados, passando-os para a

função map definida pelo usuário. A função map produz os pares chave/valor

intermediários, que são armazenados em buffer na memória.

Operação (4): Periodicamente, os pares em buffer são gravados no disco

local, dividido em R regiões pela função de particionamento. Os endereços desses

pares no disco local são passados para o mestre, que é responsável por encaminhar

esses endereços para os escravos reduce.

Operação (5): Quando um escravo reduce é notificado pelo mestre sobre

esses endereços, ele usa chamadas de procedimento remoto para ler os dados do

disco local de cada escravo map. Quando um escravo reduce tem que ler todos os

dados intermediários para sua partição, ele classifica os dados pela chave para que

todos os valores que têm a mesma chave sejam agrupados juntos.

Operação (6): O escravo reduce itera sobre os dados classificados e para

cada chave intermediária única, ele passa a chave e o conjunto correspondente de

valores intermediários para a função reduce do usuário. A saída da função de

reduce é anexada a um arquivo de saída final para cada partição do reduce.

Operação (7): Quando todas as tarefas map e reduce forem concluídas, o

mestre reativa o programa do usuário para a recuperação do resultado final.

Após a conclusão, a saída da execução do MapReduce está disponível em

R arquivos de saída. Normalmente, os programadores não precisam combinar esses

arquivos em um único arquivo, pois muitas vezes eles são usados como entrada

para outra trabalho MapReduce ou são usados para outro aplicativo distribuído

(DEAN & GHEMAWAT, 2008, p. 3).

Para cada tarefa map e reduce, o mestre armazena o estado (ocioso, em

andamento ou concluído) e a identidade da máquina escravo. O mestre é o canal

através do qual a localização das regiões de arquivo intermediário é transferida das

tarefas map para as tarefas reduce. Antes, para cada tarefa map concluída, o mestre

Page 21: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

20

armazena os endereços e os tamanhos das regiões de arquivo intermediário

produzidos pela tarefa map. Essas informações são recebidas quando as tarefas

map são concluídas e é enviada incrementalmente para o escravo que tem em

andamento as tarefas reduce (DEAN & GHEMAWAT, 2008, p. 3).

2.3 FRAMEWORK DE EXECUÇÃO MAPREDUCE

O MapReduce separa os algoritmos de execução dos detalhes do

sistema paralelo e distribuído, como a distribuição de dados, o balanceamento de

carga, o tratamento de falhas entre outros. Um programa MapReduce, é referido

como um trabalho (work), consistindo em um código para fase Map, um código para

fase Reduce e mais os parâmetros de configuração. O desenvolvedor envia o

trabalho para um nó mestre do cluster e o framework de execução (runtime) cuida

de tudo (LIN & DYER, 2010, p. 26).

Cada trabalho MapReduce é dividido em unidades menores chamadas de

tarefas (job). Existem trabalhos que têm milhares de tarefas que precisam ser

atribuídas ao cluster. Em muitos casos o número das tarefas é maior que o número

de máquinas em um cluster, levando o framework definir a ordem de prioridade de

execução das tarefas. A ideia do MapReduce é mover o código e não os dados. O

agendador de tarefas localiza as máquinas que têm os dados para ser processados,

se isso não for possível, as novas tarefas serão iniciadas em outros lugares e os

dados necessários serão transmitidos através da rede (LIN & DYER, 2010, p. 26-

27).

Em MapReduce , a sincronização é realizada entre a fases Map e Reduce. A

tarefa reduce não pode começar antes que todas as emissões dos pares chave/valor

das tarefas map tenham sido concluídas e que todos os pares chave/valor

intermediários tenham sido transferidos, agrupados e classificados (LIN & DYER,

2010, p. 27-28).

O framework de execução MapReduce deve realizar todas as tarefas

anteriores em um ambiente onde os erros e falhas são frequentes. A biblioteca

MapReduce é projetada para tolerar falhas de máquina com elegância em uma

Page 22: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

21

ambiente de centenas ou milhares de máquinas. Para lidar com falhas das máquinas

escravas, o mestre se comunica com todos os escravos periodicamente, se

nenhuma resposta for recebida em um determinado período de tempo, o mestre

marca o escravo como “falho”. Com isso, qualquer tarefa map ou reduce em

andamento é reagendamento para outra máquina (DEAN & GHEMAWAT, 2008, p.

3).

2.4 IMPLEMENTAÇÃO

Implementação MapReduce pode se referir a implementação de software do

modelo de programação e do framework de execução. Muitas implementações

diferentes do modelo de programação MapReduce são possíveis, dependendo

somente do ambiente (DEAN & GHEMAWAT, 2008, p. 2). Já existem várias

implementações do modelo, mantendo ou não a mesma abstração básica, mas suas

capacidades variam consideravelmente. Entre elas foram desenvolvidas várias

implementações de código fonte aberto, mantido pela comunidade de software livre,

destacando-se o Apache Hadoop, que é utilizado neste trabalho.

2.4.1 Google MapReduce

Google MapReduce é uma implementação proprietária da Google, projetado

em C++ podendo executar aplicações escritos em várias linguagens de

programação. Essa implementação do MapReduce é direcionada para o ambiente

de computação da Google feito por grandes aglomerados de PCs. O GFS (Google

File System) é um sistema de arquivos distribuído desenvolvido pela Google, é

usado para gerenciar os dados armazenados sobre os discos rígidos do grid

computacional. O sistema de arquivos usa replicação para fornecer disponibilidade e

confiabilidade em cima de hardware não confiável. O programador envia trabalhos

para um sistema de agendamento e cada tarefa do trabalho é mapeado pelo

agendador para um conjunto de máquinas disponíveis dentro de um cluster (DEAN

& GHEMAWAT, 2008, p. 2).

Page 23: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

22

2.4.2 Apache Hadoop

Apache Hadoop é uma implementação de código aberto do MapReduce

implementado em Java, que permite o processamento distribuído e o

armazenamento de grandes conjuntos de dados em clusters de computadores de

máquinas comuns. Ele fornece um sistema de arquivos distribuído (HDFS) que

armazena dados sobre os nós do cluster, proporcionando elevada largura de banda

agregada em todo o cluster. Hadoop MapReduce pode executar aplicações

implementada em várias linguagem, podendo ser escrita em Java , Ruby , Python e

C++.

As tecnologias MapReduce e Hadoop Distributed File System são projetadas

para detectar e lidar com falhas na camada de aplicação, entregando um serviço

altamente disponível em ambiente propenso a falhas. Outros projetos de código

aberto para uma proposta específica foram construídos com Hadoop, na qual foram

incorporados ao seu ecossistema, tornando uma infraestrutura cada vez mais

completa (HADOOP, 2014).

A aplicação Hadoop em um aglomerado de máquinas utiliza cinco

componentes diferentes, o NameNode, o DataNode, o SecondaryNameNode, o

JobTracker e o TaskTracker. O NameNode gerencia os arquivos de metadados

armazenados no HDFS, como a estrutura de diretório de arquivos e a localização

das cópias dos blocos de dados. O DataNode é o responsável pelo armazenamento

dos dados no HDFS. O SecondaryNameNode fornece backup e compactação de

metadados do sistema de arquivos. O JobTracker fornece comando e controle para

o gerenciamento do trabalho, lidando com a distribuição e gerenciamento das

tarefas. O TaskTracker fornece serviços de execução para as tarefas MapReduce,

gerenciando a execução no cluster e executando as tarefas Map e as tarefas

Reduce.

2.4.3 Twister

Twister é uma implementação em Java de código aberto e uma extensão do

MapReduce otimizado para computação iterativa. O Twister usa uma infraestrutura

Page 24: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

23

de mensagens, publicação/assinatura, para a comunicação e transferência de dados

e suporta longa duração de tarefas map e reduce. Além disso, fornece uma

extensão de programação para o MapReduce, permitindo o Twister suportar

computação MapReduce iterativa, isso é feito através do adicionamento de uma

nova fase para o MapReduce chamado "Combine", que atua como um outro nível de

redução, pode ser usada para produzir uma saída coletiva a partir de todas as

saídas da fase reduce (EKANAYAKE et al., 2010, p. 1).

2.4.4 Phoenix

O Phoenix é uma versão do MapReduce implementada em C e de código

aberto, direcionado para sistemas multicore e multiprocessadores simétricos de

memória compartilhada. Em contraste com o sistema MapReduce original que foi

projetado para clusters, o Phoenix usa threads de memória comparti lhada para

implementar o paralelismo. A implementação lança vários threads de trabalho para

executar as funções map e reduce do usuário (YOO et al., 2009, p. 2). Phoenix

consiste em uma API (bibliotecas) para a programação de aplicativo e um

framework que lida com a paralelização, gerenciamento de recursos e de

recuperação de falhas. A implementação do Phoenix fornece uma API para C e C++.

(RANGER et al., 2007, p. 3).

2.4.5 Mars

Mars é uma implementação MapReduce para processadores gráficos

(GPUs). Mars explora grande quantidades threads paralelo dentro da GPU, esconde

a complexidade de programação da GPU por trás da interface MapReduce. Mars

fornece um pequeno conjunto de APIs, implementadas em C/C++, para os

desenvolvedores que não requer nenhum conhecimento de renderização gráfica (HE

et al., 2008, p. 4-5).

Page 25: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

24

2.4.6 CELL MapReduce

Cell MapReduce é uma implementação do modelo MapReduce escrito em C

para processador Cell. Este modelo fornece uma abstração para máquina simples,

escondendo a paralelização e o hardware. A arquitetura Cell é uma arquitetura de

memória distribuída, é um projeto de alto nível que se assemelha ao projeto do

Google, enquanto a granularidade das operações é semelhante ao Phoenix. O

modelo de programação é adequado a vários programas de dados paralelos,

mapeando naturalmente para a arquitetura Cell (KRUIJF & SANKARALINGAM,

2007).

2.4.7 MRPGA

Uma extensão para o MapReduce para paralelização automática de

Algoritmos Genéticos com a programação sequencial através de três componentes:

Map, Reduce, e Reduce, chamado MRPGA (MapReduce for Parallel Genetic

Algorithms). A aplicação do usuário pode ser implementado em C++, C# e Visual

Basic, ou com qualquer linguagem suportada pela plataforma “.NET” (JIN et al.,

2008, p. 1-6).

2.5 CONCLUSÃO

MapReduce é um modelo de programação para o processamento de

grandes conjuntos de dados em ambiente computacional paralelo e distribuído. O

paradigma é poderoso, mas simples o suficiente para o desenvolvimento das

aplicações BigData. Além disso, existe uma variedade de implementação, algumas

de código fonte aberto para diversos ambientes e propósitos.

Para testar o modelo de programação MapReduce apresentaremos no

próximo capítulo a implementação MapReduce de código aberto Apache Hadoop,

demonstrando suas características, estrutura e funcionamento.

Page 26: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

25

3 HADOOP

O Apache Hadoop, ou simplesmente Hadoop, é uma ferramenta para

processamento de grande quantidade de dados em aglomerados computacionais,

disponibilizando recursos para o desenvolvimento de soluções em sistemas paralelo

e distribuídos em um único arcabouço.

Este capítulo descreve o Apache Hadoop, suas características, estrutura e

funcionamento. Na seção 3.1 é apresentando uma visão geral da ferramenta. Na

seção 3.2 é demonstrado o sistema de arquivos distribuído HDFS. Na seção 3.3,

demonstra-se o framework Hadoop MapReduce, suas características e execução,

finalizando com uma conclusão na seção 3.4.

3.1 INTRODUÇÃO

Hadoop é um implementação MapReduce de código aberto, escrito em Java

para o processamento e armazenamento em larga escala, utilizando máquinas

comuns, sendo seus principais componentes o Framework MapReduce e o Hadoop

Distributed File System (HDFS).

Hadoop permite o processamento distribuído e o armazenamento de

grandes conjuntos de dados em clusters de computadores, fornecendo um sistema

de arquivos distribuído que armazena dados sobre os nós de computação,

proporcionando elevada largura de banda agregada em todo o cluster. O Framework

MapReduce e Hadoop Distributed File System (HDFS) são projetados para detectar

e lidar com falhas na camada de aplicação, entregando um serviço altamente

disponível em ambiente propenso a falhas (HADOOP, 2014).

3.1.1 Componentes

A aplicação Hadoop em um aglomerado utiliza cinco componentes

(daemons) diferentes. Três deles, o NameNode, o DataNode e o

SecondaryNameNode, compõem o sistema de arquivos HDFS; os outros dois

componentes, o JobTracker e o TaskTracker, integram o framework MapReduce.

Page 27: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

26

O NameNode gerencia os arquivos de metadados armazenados no HDFS

incluindo informações críticas, como a estrutura de diretório de arquivos e a

localização das cópias dos blocos de dados do arquivo. A máquina que executa o

processo do servidor NameNode é o mestre HDFS (VENNER, 2009, p. 73).

O DataNode realiza o armazenamento dos dados no HDFS. Como o HDFS

é um sistema de arquivos distribuído, necessita diversas instâncias do DataNode.

Cada DataNode fornece serviços de armazenamento em blocos para o HDFS

(VENNER, 2009, p. 73).

O SecondaryNameNode fornece backup e compactação de metadados do

sistema de arquivos fornecendo backup quase em tempo real dos metadados para o

NameNode. Há pelo menos um caso deste servidor executando em um cluster. O

NameNode secundário também mescla o histórico de alterações de metadados, o

log de edição, na imagem do sistema de arquivos do NameNode (VENNER, 2009, p.

73).

O JobTracker fornece comando e controle para o gerenciamento do

trabalho. Ele também lida com a distribuição e gerenciamento de tarefas. Há uma

instância desse servidor executando em um cluster. A máquina que executa o

servidor JobTracker é o mestre MapReduce (VENNER, 2009, p. 72).

O TaskTracker fornece serviços de execução para a tarefa MapReduce.

Cada TaskTracker gerencia a execução de tarefas em um nó do cluster. Um

TaskTracker executa uma tarefa Map ou uma tarefa Reduce designada a ele. Há

uma instância do TaskTracker por nó escravo no cluster (VENNER, 2009, p. 72).

3.1.2 Modo de Execução

Há três modos de execução: Modo Local, Modo Pseudo Distribuído e Modo

Completamente Distribuído.

Modo Local (Standalone Mode) é a configuração padrão de execução do

Hadoop. Não existem daemons sendo executados e tudo é executado em uma única

Máquina Virtual Java (JVM). Nessa configuração, todo o processamento da

Page 28: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

27

aplicação é executado apenas na máquina local, não sendo necessário usar o HDFS

para armazenar os arquivos. Esse modo é adequado para a execução de programas

MapReduce durante o desenvolvimento, uma vez que é mais fácil de testar e

depurar.

Modo Pseudo Distribuído (Pseudo Distributed Mode) é o modo no qual são

aplicadas todas as configurações necessárias para execução em um aglomerado,

porém os daemons do Hadoop são executados na máquina local, simulando assim

um aglomerado de pequena escala.

Modo Completamente Distribuído (Fully Distributed Mode) é o modo no qual

os daemons do Hadoop rodam em um cluster de máquinas. Este modo é utilizado

para o processamento distribuído da aplicação Hadoop em um aglomerado real.

3.2 HDFS

Quando um conjunto de dados supera a capacidade de armazenamento de

uma única máquina física, torna-se necessário particioná-lo através de um número

de máquinas separadas. Sistemas de arquivos que gerenciam o armazenamento

através de uma rede de máquinas são chamados de sistemas de arquivos

distribuído (WHITE, 2010, p. 41).

O HDFS é um sistema de arquivos distribuído projetado para armazenar de

forma confiável grandes conjuntos de dados e para proporcionar alta tolerância a

falhas, funciona em grandes aglomerados de máquinas comuns, destinado ao

armazenamento e transmissão de arquivos de centenas de Megabytes a Terabytes

de dados. O HDFS fornece acesso de alta taxa de transferência de dados adequado

para aplicações que têm grandes conjuntos de dados (WHITE, 2010, p. 41-42).

HDFS utiliza o conceito de bloco, cujo tamanho padrão é de 64 MB. Como

em um sistema de arquivos tradicionais, os arquivos no HDFS são quebrados em

pedaços de blocos, que são armazenados como unidades independentes.

Entretanto, quando um arquivo for menor do que um único bloco, o espaço restante

do bloco poderá ser utilizado. O beneficio que o bloco de abstração traz para um

sistema de arquivos distribuído é que um arquivo pode ser maior do que qualquer

Page 29: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

28

disco único na rede. Além disso, os blocos se encaixam bem com a replicação para

fornecer tolerância a falhas e disponibilidade. Para evitar problemas com os blocos

corrompidos e disco e falha da máquina, cada bloco é replicado para um pequeno

número de máquinas fisicamente separado (WHITE, 2010, p. 43-44).

Um cluster HDFS tem dois tipos de nó que operam em um padrão de

mestre/escravo. Possui um nó mestre chamado NameNode, e uma série de

escravos chamados DataNodes. O NameNode gerencia o espaço de nomes do

sistema de arquivos, mantém as informação da árvore de arquivos e dos metadados

no disco local. O NameNode também conhece os DataNodes onde todos os blocos

dos arquivos estão localizados. DataNode armazenam e recuperam blocos quando é

solicitado e apresentam um relatório ao NameNode periodicamente com listas de

blocos que estão sendo armazenado (WHITE, 2010, p. 44).

Sem o NameNode, o sistema de arquivos não pode ser usado, pois os

arquivos seriam irrecuperáveis. Por esse motivo, o Hadoop proporciona dois

mecanismos para fazer a NameNode resistente a falhas, através do backup ou

SecondaryNameNode .

O primeiro mecanismo é fazer backup dos arquivos que compõem o estado

persistente de metadados do sistema de arquivos. Hadoop pode ser configurado

para que o NameNode grave seu estado de persistente para múltiplos sistemas de

arquivos.

O segundo mecanismo é por execução de um NameNode secundário

chamado de SecondaryNameNode, que age diferente do NameNode. O seu

principal papel é mesclar periodicamente a imagem namespace com o log de

edição. Ele mantém uma cópia da imagem namespace mesclado, que pode ser

usado em caso de falha do NameNode (WHITE, 2010, p. 44-45).

3.3 FRAMEWORK MAPREDUCE

Um dos principais componente do Hadoop é um framework para

processamento paralelo e distribuído de grandes conjuntos de dados para grandes

aglomerados computacionais. Permite a execução de tarefa simples, escondendo os

Page 30: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

29

detalhes da paralelização, tolerância a falhas, distribuição de dados e

balanceamento.

3.3.1 Execução do Trabalho

Há quatro entidades independentes na execução do trabalho MapReduce: o

cliente, que envia o trabalho de MapReduce; o JobTracker, que coordena a

execução do trabalho; os TaskTrackers, que executam as tarefas do trabalho que foi

dividido; e, o sistema de arquivos distribuídos HDFS, que é usado para o

compartilhamento de arquivos de trabalho entre as outras entidades (WHITE, 2010,

p. 167).

O processo de execução do trabalho MapReduce no Hadoop é feito através

das seguintes etapas: processo de envio do trabalho, inicialização, atribuição e

execução de tarefa e a conclusão do trabalho MapReduce. Esses passos são

explicados a seguir.

Envio de Trabalhos: O processo de submissão solicita ao JobTracker um

novo ID de trabalho, em seguida verifica a especificação de saída do trabalho e

calcula as divisões de entrada para o trabalho. Os recursos necessários para

execução do trabalho são copiados, incluindo o arquivo JAR do trabalho, o arquivo

de configuração, e as divisões de entrada, para o sistema de arquivos do

JobTracker. E no final indica ao JobTracker que o trabalho está pronto para

execução (WHITE, 2010, p. 167-169).

Inicialização do Trabalho: Quando o JobTracker recebe uma chamada de

submissão de trabalho, ele coloca o trabalho em uma fi la interna onde o agendador

de tarefas vai buscá-lo e inicializá-lo. A inicialização envolve a criação de um objeto

para representar o trabalho que está sendo executado, que encapsula as tarefas e

informações para o acompanhamento do seu status e progresso. Para criar a lista

de tarefas a serem executadas, o agendador de tarefas recupera primeiro as

divisões de entrada do sistema de arquivos compartilhado. Em seguida, cria uma

tarefa map para cada divisão de entrada, e o número de tarefas reduce é definido

pelo agendador (WHITE, 2010, p. 169).

Page 31: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

30

Atribuição de tarefas: Tasktrackers executam um loop simples que envia

periodicamente chamadas Heartbeats1 para o JobTracker. O Heartbeats funcionam

como um canal de mensagens que dizer ao JobTracker que uma TaskTracker está

ativo. Como parte dos Heartbeats, o TaskTracker vai indicar se ele está pronto para

executar uma nova tarefa. Tasktrackers tem um número fixo de slots2 para as tarefas

map e para tarefas reduce, podendo executar tarefas map e reduce

simultaneamente. O agendador padrão preenche os slots vazios com as tarefas map

antes das tarefas reduce (WHITE, 2010, p. 169).

Execução de Tarefas: Após a atribuição da tarefa no TaskTracker, o

próximo passo é a execução da tarefa. Para isso ele deve localizar a aplicação

"JAR", copiando do sistema de arquivos compartilhado para o sistema de arquivos

do TaskTracker. Em seguida, ele deve criar um diretório de trabalho local para a

tarefa, e criar uma instância de TaskRunner para execução dela. TaskRunner lança

uma nova JVM para executar cada tarefa, de modo que todos os erros da aplicação

map e reduce do usuário não afetem o TaskTracker (WHITE, 2010, p. 170).

Conclusão do trabalho: Quando o JobTracker recebe uma notificação de

que a última tarefa para um trabalho é concluído, ele muda o status do trabalho para

"sucesso". Se o trabalho foi concluído com êxito, o usuário é informado e

posteriormente o JobTracker limpa o estado de funcionamento do trabalho e instrui

TaskTrackers a fazer o mesmo (WHITE, 2010, p. 172-173).

3.3.2 Partitioners e Combiners

Existem dois elementos adicionais que completam o modelo de

programação: Partitioners (particionadores) e Combiners (combinadores).

Partitioners são responsáveis por dividir as chaves intermediárias e atribuir

os pares chave/valor intermediário para as tarefas reduce, ou seja, especifica para

onde o par chave/valor intermediário deve ser copiado. Dentro de cada tarefa

reduce, as chaves são processadas em ordem de classificação. O Particionador

1 São “sinais de vida” para verificar se o componente hadoop está “vivo”.

2 São espaços para armazenamento e execução das tarefas.

Page 32: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

31

mais simples envolve calcular o valor Hash da chave e, em seguida, tomar o resto

da divisão (mod) desse valor com o número de tarefas reduce, ou seja, hash(key)

mod R. Isso atribui aproximadamente o mesmo número de chaves para tarefas

reduce (LIN & DYER, 2010, p. 28-29).

Combiners são uma otimização no MapReduce que permite a agregação

local. O combinadores é como se fosse um “mini-reducers” que ocorrem na saída da

fase Map, antes da fase shuffle e sort (especificado em seguida) podendo reduzir o

número de pares de chave/valore intermediários, tonando mais eficiente, pois os

pares de chave/valor precisam ser copiados em toda a rede, tornado a troca de

dados mais rápido. Cada combinador opera isoladamente e, portanto, não tem

acesso a saída intermediária de outras funções map. O combinador recebe os pares

chave/valore associados a cada chave. O combinador pode emitir qualquer número

de pares chave/valor, mas o seu tipo deve ser o mesmo da saída da fase Map, pois

se o combinador não ocorrer, a saída da função map será a entrada da função

reduce (LIN & DYER, 2010, p. 29).

3.3.3 Shuffle e Sort

MapReduce garante que a entrada para cada reduce é classificada por

chave. O processo pelo qual o sistema executa a classificação (Sort), e transfere

das saídas do map para a entrada do reduce, é conhecido como o Shuffle. De certa

maneira, o shuffle é o coração do MapReduce (WHITE, 2010, p. 177).

Na fase Map quando a função map começa a produzir a saída, não é

simplesmente gravado no disco. O processo é mais complexo, é tira proveito de

buffer, escrevendo na memória e fazer algumas pré-classificação por razões de

eficiência como pode se visto na Figura 3.1. Cada tarefa map tem um buffer de

memória circular na qual é escrito sua saída. O buffer é de 100 MB por padrão, um

tamanho que pode ser alterado. Quando o conteúdo da memória intermediária

atinge um determinado tamanho começará a transferência (spill) do conteúdo para o

disco. A saída map continuará sendo escrito no buffer, enquanto o spill acontece,

mas se o buffer enche durante este tempo, o map irá bloquear até que o spill estiver

completo (WHITE, 2010, p. 177).

Page 33: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

32

Figura 3.1. Shuffle e Sort em MapReduce (WHITE, 2010, p.178).

Antes de gravar no disco, ocorre uma divisão dos dados em partições

(partition) correspondentes aos reduce. Em cada partição é executada uma

classificação (sort) por chave na memória, e se existe uma função Combiner, esta é

executada usando saída da classificação. Para cada spill um novo arquivo é criado,

então no fim da tarefa map pode haver vários arquivos Spill. Antes que a tarefa seja

concluída, os arquivos Spill são mesclados (merge) em um único arquivo de saída

dividido e classificado. Se a função combinadora for especificada, o número de spill

será menor, reduzindo assim o espaço em disco, e a quantidade de dados a ser

transferida para o reduce (WHITE, 2010, p. 178).

Na fase Reduce, o arquivo de saída map é armazenado no disco local do

TaskTracker que executou a tarefa map, mas agora é necessário pelo TaskTracker

que executará as tarefas de reduce. Além disso, a tarefa reduce precisa das

partiçãos específicas das saídas map de todas as tarefas map do cluster. As tarefas

map podem terminar em momentos diferentes, por isso a tarefa reduce começará a

copiar os seus resultados, assim que cada um é concluído. Isto é conhecido como a

fase de cópia da tarefa reduce (WHITE, 2010, p. 179).

As saídas de map são copiados para a memória do TaskTracker Reduce, se

forem pequenas o suficiente, se não, são copiados para o disco. Quando o buffer de

memória atinge um tamanho limite, ou atinge um limite do número de saídas de

Page 34: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

33

map, os dados são fundidos e transferidos (Spill) para o disco. Como as cópias são

acumuladas no disco, é feito antecipadamente a fusão (merge) em um grande

arquivo ordenado (WHITE, 2010, p. 179).

Quando todas as saídas map forem copiadas, a tarefa reduce passa para a

fase de classificação, que funde as saídas map, mantendo a sua ordem de

classificação. A fusão salva em um caminho para o disco, alimentando diretamente a

função reduce, que é a última fase, a fase reduce. Durante a fase de redução, a

função reduce é chamada para cada chave da saída classificada. A saída resultante

dessa fase é escrito diretamente no sistema de arquivos de saída, geralmente o

HDFS. Neste caso o nó do TaskTracker também executará um DataNode (WHITE,

2010, p. 179-180).

3.3.4 Aplicações

A aplicação MapReduce do Hadoop usa uma biblioteca do MapReduce (API)

que está no pacote org.apache.hadoop.mapreduce e outras do pacote

org.apache.hadoop, como o subpacote io e fs.Path além das API do próprio Java. A

aplicação deve ter as classes que representam as funções map e reduce, uma

classe principal (Drive) e as classes auxiliares da lógica de execução.

Ao invés de usar tipos Java, Hadoop fornece seu próprio conjunto de tipos

básicos que são otimizados para serialização de rede. Estes se encontram no

pacote org.apache.hadoop.io.

Hadoop usa seu próprio formato de serialização de dados, através da

interface Writables. Essa interface define dois métodos, o write() para escrever o

seu estado no fluxo binário pelo DataOutput, e o readFields() para a leitura de seu

estado no fluxo binário pelo DataInput. Qualquer chave ou valor do framework

MapReduce Hadoop implementa essa interface. Hadoop vem com uma grande

variedade de classes de Writable, na qual possui implementação para quase todos

os tipos primitivos do Java, conforme a Tabela 3.1.

Page 35: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

34

Tabela 3.1: Representação do tipo primitivo Java em implementação do Writable.

Tipo Primitivo do Java Implementação Writable

boolean BooleanWritable

byte ByteWritable

int IntWritable

long LongWritable

float FloatWritable

double DoubleWritable

Além do que estão na Tabela 3.1 há várias outras implementações, como os

tipos: Text, um Writable para sequencias UTF-8; NullWritable, um tipo que tem uma

serialização de comprimento zero; ObjectWritable, para propósito geral. É possível

escrever uma implementação personalizada tendo o controle sobre a representação

binária e a ordem de classificação (WHITE, 2010, p. 96-97).

A função map é representada por uma classe derivada da classe abstrata

Mapper, que é encontrada no pacote org.apache.hadoop.mapreduce. A classe

abstrata Mapper é um tipo genérico, que lhe permite trabalhar com qualquer tipo de

chave ou valor, os quatro parâmetros especificam a chave de entrada, valor de

entrada, a chave de saída e valor de saída (WHITE, 2010, p. 20-21).

Essa classe declara quatro métodos, o setup, o map, o cleanup e o run, que

pode ser usada pela aplicação do usuário. O framework primeiro chama o método

setup() que é executado uma vez no início da tarefa, em seguida é chamado o

método map() para cada par chave/valor da divisão de entrada. Finalizando com a

chamada do método cleanup() que é executado uma vez no fim da tarefa. O método

run() é uti lizado para ter um controle mais completo sobre a execução do Mapper.

A função reduce é representada por uma classe derivada da classe abstrata

Reducer, um tipo genérico semelhante ao Mapper que se encontram no mesmo

pacote. O Reducer tem quatro parâmetros que são usados para especificar o tipo de

entrada e saída da função reduce. Os tipos de entrada da função reduce devem

coincidir com os tipos de saída da função de map. A classe Reducer tem quatro

métodos, o setup, o reduce, o cleanup e o run, três são semelhantes ao do Mapper.

Page 36: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

35

O framework executa os métodos da mesma forma que é executado na tarefa map,

porém o método reduce() é chamado uma vez para cada chave.

Os parâmetros de configuração do trabalho são efetuados na classe

principal (Drive), onde são definidos os caminhos de entrada e saída dos arquivos,

as classes Mapper, Reducer, Combiner e Partitioner, os tipos de saída e entrada,

além disso, é efetuado o controle, a execução e monitoramento do trabalho.

3.4 CONCLUSÃO

Hadoop é uma implementação MapReduce de código aberto, utilizado para

o processamento e armazenamento em larga escala, utilizando máquinas comuns, e

traz simplicidade para o desenvolvimento e execução de aplicação paralelo e

distribuídos. Os principais componente são o Hadoop Distributed File System o

Framework MapReduce que dão suporte a execução da aplicação MapReduce. No

capítulo seguinte apresentaremos a base teórica do Algoritmo Genético (AG) e do

Problema do Caixeiro Viajante (PCV) para a modelagem de uma aplicação

MapReduce.

Page 37: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

36

4 AG & PCV

O Algoritmo Genético (AG) é uma técnica de otimização utilizada como

busca global, empregada em situações nas quais o número de valores ou

combinações aplicáveis para resolver um determinado problema é muito alto

(BRYANT, 2000; MISHRA, 2011; PACHECO, 1999). Este é o caso do Problema do

Caixeiro Viajante (PCV), em que o número de combinações de caminhos aumenta

exponencialmente em função do número de cidades.

O PCV é um problema de otimização que consiste em encontrar o menor

caminho em um conjunto de cidades, sendo utilizada em pesquisas e aplicações de

diferentes áreas, como da matemática, da engenharia e ciência da computação.

Para essa classe de problema não existe recurso computacional para resolvê-lo em

tempo hábil, tornando a utilização de método de força bruta difícil, necessitando o

uso de técnica de busca, como o caso dos Algoritmos Genéticos que não necessita

explorar todas as soluções possíveis para encontrar uma boa solução.

Este capítulo apresenta a técnica do Algoritmo Genético e o Problema do

Caixeiro Viajante, apresentando uma visão geral e seus conceitos. Na seção 4.1 é

definida a técnica do Algoritmo Genético e as características dos Operadores

Genéticos. Na seção 4.2 é apresentado o Problema do Caixeiro Viajante seus

conceitos e métodos AG particulares. Finalizando, na seção 4.3 com as

considerações do capítulo.

4.1 ALGORITMOS GENÉTICOS

Algoritmos Genéticos (AG) são técnicas de otimização baseadas na

evolução natural. Essas técnicas incluem a ideia da sobrevivência do mais apto em

um algoritmo de pesquisa, que não necessita explorar todas as soluções possíveis

no espaço de busca para obter um bom resultado (BRYANT, 2000, p. 2).

O AG usa um processo evolutivo para criar uma população de possíveis

respostas para um problema, em seguida, combina as melhores soluções criando

uma nova geração de soluções que devem ser melhor do que a geração anterior.

Page 38: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

37

Este processo é constituído pelas seguintes etapas:

a) Inicialização: é a criação da população inicial para o primeiro ciclo do

algoritmo; a criação é geralmente realizada de forma aleatória.

b) Avaliação: avalia-se a aptidão das soluções analisando sua resposta

ao problema proposto.

c) Seleção: indivíduos são selecionados para a reprodução; a seleção é

baseada na aptidão dos indivíduos.

d) Cruzamento: características das soluções escolhidas são

recombinadas, gerando novos indivíduos.

e) Mutação: características dos indivíduos resultantes do processo de

reprodução são alteradas.

f) Atualização: os indivíduos criados nesta geração são inseridos na

população.

g) Finalização: verifica se as condições de encerramento da evolução

foram atingidas.

Inicialmente deve ser definido o conceito para "indivíduo", encontrando a

melhor codificação adequada para a solução do problema. A população inicial é

então selecionada, geralmente de forma aleatória, calculando-se a aptidão de cada

indivíduo. Esta aptidão é usada para encontrar os indivíduos para cruzamento, e

recombinados para criar novos indivíduos que são copiados para a nova geração.

Alguns indivíduos são escolhidos ao acaso para sofrer mutação. Após esse

processo, uma nova geração é formada e o processo é repetido até que algum

critério de parada tenha sido atingido. Neste ponto, o indivíduo que está mais

próximo do ideal é decodificado e o processo é concluído (BRYANT, 2000, p. 2-3).

4.1.1 Indivíduos e a População

Os indivíduos codificam possíveis soluções do espaço de busca de um

problema. A representação dessas soluções define a estrutura do cromossomo3 a

3 Segundo Pacheco (1999) o cromossomo é uma estrutura de dados que representa uma das possíveis

soluções do espaço de busca do problema.

Page 39: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

38

ser manipulado, e depende do tipo de problema e do que se deseja manipular pelo

algoritmo genético.

O AG usa nomenclatura relacionada com os termos que podemos encontrar

na biologia. O indivíduo do AG, de acordo com a Figura 4.1, é composto de um ou

mais cromossomo e um valor adaptativo associado (fitness). O cromossomo é uma

cadeia de caracteres codificada de parâmetros. Normalmente, um indivíduo contém

apenas um cromossomo, que representa o conjunto de parâmetros chamados de

genes. O gene (ou caractere) é a versão codificada de um parâmetro do problema a

ser resolvido. O alelo é o valor que um gene pode assumir e o lócus é a posição que

gene ocupa no cromossomo (ALBA, 1999, p. 3).

Figura 4.1. Detalhe do indivíduo AG (ALBA, 1999, p. 4).

A população é um conjunto de indivíduos candidatos à solução do problema,

ela é uma parte do espaço de busca de um problema. O tamanho da população irá

depender do problema (HUANG & LIN, 2010, p. 5).

A população possui como características o número de geração, o grau de

convergência, a diversidade e o elitismo. O número de geração é quantas vezes a

população passa pelo processo de seleção, reprodução, mutação e atualização. O

grau de convergência representa a aproximação da média de adaptação da geração

atual em relação a anteriores. A diversidade mede o grau de variação entre os

indivíduos presentes na população; ela é fundamental para a amplitude da busca. O

baixo valor da diversidade está vinculado ao fenômeno de convergência prematura,

isto é, quando a população converge e não consegue sair de uma média de

adaptação sub-ótima (ótima local). O elitismo é composto pelos indivíduos mais

adaptados da população, onde são sempre mantidos a cada geração (LUCAS, 2002,

p. 9).

Page 40: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

39

4.1.2 Inicialização

A inicialização da população de um AG determina o processo de criação dos

indivíduos para o primeiro ciclo do algoritmo. Geralmente, a população inicial é

formada a partir de um conjunto de indivíduos aleatoriamente criados, com o objetivo

de fornecer maior diversidade, para garantir uma boa abrangência do espaço de

busca.

Existem várias alternativas ao método randômico, destinadas a suprir

deficiências na criação aleatória de indivíduos de representação mais complexa,

algumas técnicas são: Inicialização Randômica Uniforme, em que cada gene do

indivíduo é um valor do conjunto de alelos, sorteado de forma aleatoriamente

uniforme; Inicialização Randômica não Uniforme, em que os valores do gene tendem

a ser escolhidos com uma frequência maior do que o restante; e na Inicialização

Randômica Com “Dope”, no qual os indivíduos otimizados são inseridos em meio à

população aleatoriamente gerada (LUCAS, 2002, p. 10-11).

4.1.3 Processo de Avaliação e Seleção

A avaliação é feita através de uma função que representa o problema,

fornecendo uma medida de aptidão para cada indivíduo na população. A função de

aptidão indica a qualidade de um indivíduo para solução do problema. Em muitos

casos, calcular o grau de adaptação dos indivíduos pode ser uma tarefa complexa, e

se levarmos em conta que esta operação é massivamente repetida ao longo do

processo de evolução, seu custo pode ser consideravelmente alto (LUCAS, 2002, p.

12).

No algoritmo genético, o processo de seleção escolhe os melhores

indivíduos para o cruzamento, baseada na aptidão dos indivíduos, efetuando-se um

sorteio, onde os mais aptos possuem maior probabilidade de serem escolhidos para

a reprodução, perpetuando-o para a próxima geração, mantendo as boas

características da espécie.

Page 41: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

40

A seleção opera de forma determinística, isto é, um indivíduo só consegue

sobreviver em um ambiente se for capaz de se reproduzir, de acordo com suas

características, de responder de forma adequada a todos os fenômenos de seu

meio. A seleção também é cumulativa, pois os benefícios do processo de seleção

são mantidos de uma geração para a outra (LUCAS, 2002, p. 12).

Existem vários métodos para efetuar a seleção, dentre os quais se

destacam: a seleção por Ranking, onde os indivíduos da população são ordenados

de acordo com seu valor de aptidão, sendo os melhores ranqueados (os mais aptos)

os escolhidos para a próxima geração. A seleção por Giro de Roleta, onde é

atribuída uma probabilidade para cada indivíduo em função do seu valor de aptidão;

os que possuem as maiores possibilidades são os escolhidos a passar para a

próxima geração. Seleção por Torneio, em que grupos de soluções são escolhidos

aleatoriamente e os indivíduos mais aptos dentro de cada grupo são selecionados

para ficar para a próxima geração. E a seleção Uniforme, em que todos os

indivíduos possuem a mesma probabilidade de serem selecionados.

4.1.4 Processo de Cruzamento e Mutação

O cruzamento (crossover) é um mecanismo de recombinação de soluções. É

o processo fundamental dos AG, que possibilita a troca e manipulação de material

genético entre indivíduos trazendo melhoria para sua população. O cruzamento

consiste na escolha de dois indivíduos, resultante do processo de seleção, que são

combinados para permitir a criação de um ou mais indivíduos filhos. Há vários

métodos de escolha de pares para o cruzamento, que pode ser por escolha

aleatória, escolha entre indivíduos semelhantes ou entre indivíduos diferentes.

A mutação é realizada após o cruzamento. Baseado em uma probabilidade

predeterminada, é feita uma escolha aleatória de um indivíduo, em seguida, é

escolhido aleatoriamente um ponto ou uma parte do cromossomo do indivíduo para

fazer mutação.

A mutação é um operador exploratório, responsável por provocar pequenas

alterações genéticas nos indivíduos, permitindo ampliar o espaço de busca do

Page 42: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

41

problema, na tentativa de chegar a soluções possíveis na qual o operador de

cruzamento não encontraria. As principais funções da mutação é a inserção de

novas características e a reposição de material genético perdido nos outros

processos, aumentando assim a diversidade na população.

4.1.5 Processo de Atualização e Finalização

Os indivíduos resultantes do processo de cruzamento e mutação são

inseridos na população de acordo com a técnica de atualização adotada pelo AG,

gerando assim uma nova população. Essa técnica determina o critério de

substituição dos indivíduos de uma população para a próxima geração.

Segundo Pacheco (1999), a atualização pode ser feita pela troca de todos os

indivíduos da população anterior pelos novos indivíduos gerados, ou ainda, a troca

de toda a população com elitismo, ou seja, o indivíduo mais apto da população

anterior é mantido na nova população. Outra técnica elitista é a troca parcial da

população em que são gerados novos indivíduos para substitui os piores indivíduos

da população anterior, permitindo ou não a presença de indivíduos duplicados.

O último passo é realizado por um teste que observa se algum critério de

parada foi satisfeito, finalizando o processo de evolução. Nos AGs, o critério de

parada pode ser: pelo número de gerações que corresponde ao total de ciclos de

evolução de um AG; pelo total de indivíduos, que é o total de tentativas em um

experimento, ou seja, o produto do tamanho da população pelo número de

gerações; e pelo grau de convergência da população, ou seja, o grau de

proximidade dos valores da avaliação de cada indivíduo da população.

4.2 PROBLEMA DO CAIXEIRO VIAJANTE

O Problema do Caixeiro Viajante (PCV), no inglês Traveling Salesman

Problem (TSP), é um problema de otimização NP-difícil mais estudada. Sua

popularidade se deve ao fato que PCV é fácil de formular, apesar de difícil solução,

tem um grande número de aplicações, tais como problema de roteamento de

Page 43: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

42

veículos, a reformulação de motores de turbinas em aeronaves e otimização das

tarefas de máquinas industriais (GUTIN, 2009, p. 1). O PCV consiste em encontrar o

menor caminho para um caixeiro viajante que, dado um conjunto de cidades, deve

visitar todas elas precisamente uma vez, com exceção à cidade de origem na qual

deve ser feito o retorno.

Tem duas versões do PCV, o simétrico e o assimétrico. O PCV Simétrico

(PCVS) é um grafo completo não direcionado com pesos nas arestas, como pode

ser visto na Figura 4.2. O PCV Assimétrico (PCVA) é um grafo direcionado completo,

também com pesos sobre suas arestas, cujo objetivo é encontrar um ciclo

Hamiltoniano de peso mínimo, ou seja, que a soma dos pesos das arestas do ciclo

seja o menor possível. Um ciclo Hamiltoniano em um grafo e é frequentemente

chamado de tour (turnê ou caminho).

Figura 4.2: Grafo completo no plano Euclidiano.

O PCVA tem o número de caminhos possíveis dada pela fórmula ,

onde n é o número de cidades e o PCVS tem o número de caminhos igual a

, pois a direção do caminho não importa (GUTIN, 2009, p. 1). Nos dois

casos o número de caminhos possíveis para n cidades é muito grande, quase

exponencial como se pode ver na Tabela 4.1. A utilização do método de força bruta,

que examina todos os passeios possíveis, torna-se impraticável mesmo para

instâncias de problemas de tamanho moderado.

Page 44: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

43

Tabela 4.1: Números possíveis de caminho em função do número de cidades no

problema do caixeiro viajante simétrico (PCVS).

Número de

cidades

Número de

caminhos Escala

Número de

cidades Número de caminhos Escala

3 1 13 239.500.800 4 3 14 3.113.510.400 Bilhões

5 12 15 43.589.145.600 6 60 16 653.837.184.000

7 360 17 10.461.394.944.000 Trilhões

8 2.520 Mil 18 177.843.714.048.000 9 20.160 19 3.201.186.852.864.000 Quatrilhões

10 181.440 20 60.822.550.204.416.000 11 1.814.400 Milhões 21 1.216.451.004.088.320.000 Quintilhões

12 19.958.400 22 25.545.471.085.854.720.000

O PCV Euclidiana é um caso especial de PCVS em que os vértices são

pontos no plano euclidiano e o peso em cada aresta é a distância euclidiana entre os

seus terminais, conforme é visto na Figura 4.2. Se os vértices de um grafo

representar um conjunto de cidades e a distância euclidiana for calculada em um

sistema de coordenadas cartesianas, então a distância entre duas cidades i e j é

dada pela equação (4.1), onde cada cidade é representada por uma coordenada (x,

y).

Para resolver o PCV é necessário conhecer as distâncias entre todas as

cidades. Os métodos de resolução podem ser divididos em duas grandes classes:

Algoritmos Exatos e Heurísticas PCV ou Algoritmos de Aproximação PCV.

Algoritmos Exatos são métodos para resolver o problema PCV, ou seus

casos especiais para otimização, quando queremos obter um passeio ideal. Isto não

pode ser possível, se o algoritmo exigir tempo de execução de várias horas ou dias.

Page 45: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

44

Heurísticas PCV ou Algoritmos de Aproximação PCV é aplicado se houver

alguma garantia de aproximação, aplicado quando o tempo de execução for limitado

ou os dados não são exatos (GUTIN, 2009, p. 4).

O AG é uma técnica de otimização que pode ser empregada no caso do

PCV. Para isso, é necessário definir a representação da solução, a função que

avalia a aptidão das soluções gerada pelo algoritmo e os operadores genéticos para

gerar novas soluções, preservando as condições inerentes do problema. Tais

questões são detalhadas a seguir.

4.2.1 Codificação

No problema do caixeiro viajante a solução (indivíduo) é codificada em uma

lista sequenciada de n cidades a serem visitadas. As cidades (gene) são

representadas pelos caracteres de um alfabeto válido. Esta lista de cidades é o

cromossomo do algoritmo genético, representando uma cadeia de caracteres. Além

da forma básica de codificação binária, também pode ser usada uma sequência de

letras, de números inteiros ou qualquer sequência de símbolos, desde que a

decodificação tenha algum significado para o problema.

A codificação conhecida como Representação Matricial é um dos métodos

usado para codificação de um caminho do problema do caixeiro viajante. A partir de

um problema envolvendo um grafo é preciso codificar uma lista de auxílio, conforme

é visto na Figura 4.3. Essa lista é uma matriz que é criada pela seguinte condição:

se houver aresta entre o nó i ao nó j, a matriz recebe 1 (um) na posição (i,j), caso

contrário recebe 0 (zero). Poderíamos, então, usar a matriz ou concatenar suas

linhas para criar uma longa sequência de zeros e uns (BRYANT, 2000, p. 10-11).

Page 46: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

45

Figura 4.3: Codificação da “Representação Matricial”.

Outro método é o sequenciamento de caracteres4 de duas maneiras

diferentes, conforme é visto na Figura 4.4. O primeiro (a) é uma Sequência

Ordenada (C1, C2,...,Cn) o que implica que o caminho vai de C1 a C2 seguindo a

ordem até Cn, e retornando para C1. A segunda (b) maneira de representar o

problema do caixeiro viajante é com a Notação do Ciclo (Cycle Notation), com uma

cadeia de caracteres (C1, C2,..., Cn), no qual o caminho é feito indo da cidade i para

cidade Ci, até formar um ciclo (BRYANT, 2000, p. 11).

Figura 4.4: Codificação “sequencial”: a) Sequência Ordenada; b) Notação do Ciclo.

4 Em Bryant (2000) os caracteres são números inteiro, mas se usar outros tipos de caracteres indexados com

um número inteiro funciona da mesma forma.

D

A

B

C

Caminho

Sequência: C1 C2 C3 C4 índice: A=1, B=2, C=3, D=4

a)

Caminho codificado: ACBD

A C B D C1 C2 C3 C4

b)

(C1, C2, C3, C4) = (C, D, B, A)

Caminho codificado: CDBA

A C B D 1 3 2 4

C4 ↘ C1 ↘ C3 ↘ C2

A C C B B D D A i Ci i Ci i Ci i Ci 1 C1 3 C3 2 C2 4 C4

C D B A

A C B D

Trajetória do Caminho

Trajetória do Caminho

D

A

B

C

i\j A B C D

A 0 0 1 0 A C

B 0 0 0 1 B D

C 0 1 0 0 C B

D 1 0 0 0 D A

Caminho codificado: 0010.0001.0100.1000

Caminho Lista de auxílio Trajetória do Caminho

Page 47: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

46

4.2.2 Aptidão

A avaliação do indivíduo é realizada através de uma função que representa

o problema, fornecendo uma medida de aptidão para cada indivíduo da população.

A função de avaliação para problema PCV deve encontrar o peso do ciclo

Hamiltoniano sobre um grafo do problema, ou seja, a soma dos pesos de todas as

arestas do ciclo. Sendo o peso de cada aresta a distância entre duas cidades, então

o peso (custo) de cada caminho é distância total percorrida pelo caixeiro viajante ao

visitar todas as cidades, conforme a equação (4.2). Quanto menor o custo

(distância), maior será a aptidão de um cromossomo (caminho) e, portanto melhor

será a solução. O objetivo do PCV, portanto, é encontrar uma solução de menor

custo (distância).

O custo de uma solução (C1, C2,..., Cn) é dado por (4,2), onde n e o número

de cidades e d(Ci, Cj) é a distância entre as cidades Ci e Cj.

4.2.3 Operadores de cruzamento

Vários métodos de cruzamento foram desenvolvidos para o problema do

caixeiro viajante. Esses operadores devem preservar a condição de que todas as

cidades devem ser visitadas exatamente uma vez, e sua função deve aplicar

permutações de valores, pois o problema PCV é de natureza combinatória.

O operador de Cruzamento de Mapeamento Parcial (PMX), do inglês

Partially Mapped Crossover, primeiramente seleciona aleatoriamente dois pontos de

corte nos cromossomos pais, conforme é visto na Figura 4.5, no qual formam a

seção de mapeamento. Em seguida, é feito o mapeamento entre os genes das

seções a partir de suas posições, então os genes dos cromossomos dos pais são

trocados de acordo com o mapeamento, ou seja, se o mapeamento for feito entre x

e y então onde houver x será trocado por y e vice-versa. Assim os pais 1 e 2 forma

respectivamente os filhos 1 e 2.

Page 48: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

47

Figura 4.5: Funcionamento do operador PMX.

Este cruzamento é mais adequado quando é usado com a representação da

Notação do Ciclo, pois preserva mais da estrutura dos pais, ou seja, mais arestas

são transferidas para os filhos. No entanto, esta representação pode obter caminhos

ilegais, necessitando elaborar uma rotina de reparo para criar caminhos legais

(BRYANT, 2000, p. 12-13).

O operador Cycle Crossover (CX) cria descendentes cujas posições são

ocupadas por elementos correspondentes de cada um dos pais, conforme é visto na

Figura 4.6. Inicialmente é feito a escolha do primeiro gene de um dos pais, para

permanecer no cromossomo; assim, o próximo gene que permanecerá no primeiro

cromossomo será o correspondente do gene atual no segundo cromossomo, de

acordo com sua posição. Dessa forma, se o gene atual for x e seu correspondente

for y, então o y do primeiro cromossomo permanecerá. Esse procedimento ocorre

até retornar ao gene inicial. Completando o ciclo, as posições que não passaram

pelo processo são preenchidas com os genes correspondentes do outro

cromossomo, sendo este procedimento válido para os dois pais.

D J

E A

F B

Mapeamento

Pai 1 ABC | DEF | GHIJ

Pai 2 GHI | JAB | EFCD

Seção de mapeamento

Pontos de corte

Pai 2 GHI | JAB | EF C D

DEF AB J

Filho 2 GHI | DEF | AB C J

Filho 1: EFCJABGHID

Filho 2: GHIDEFABCJ

Pai 1 AB C | DEF | GHI J

EF JAB D

Filho 1 EF C | JAB | GHI D

Page 49: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

48

Figura 4.6: Funcionamento do operador CX.

Este cruzamento é mais adequado com a representação de Sequência

Ordenada. Este processo assegura que cada cromossomo seja legal, porém é

possível que a herança genética dos pais acabe. Isso não é um problema, pois

geralmente só ocorre se os pais tiverem alta aptidão, podendo ainda ser uma boa

escolha (BRYANT, 2000, p. 14).

O operador Order Crossover (OX) parte da escolha de dois pontos de corte

e reorganiza o resto dos genes para gerar um caminho válido, conforme é visto na

Figura 4.7. Um filho é criado com a seção de um dos cromossomos, completando a

parti do segundo ponto de corte, com os genes do outro cromossomo a partir do

mesmo ponto, exceto com os genes que se repete na seção inicial. Este mesmo

processo é feito para o segundo filhos com a seção do cromossomo do segundo pai.

Pai 1: ABCDEFGHIJ

Pai 2: GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

Filho 1: AHIJEBGFCD

Filho 1:

Inicio do ciclo Fim do ciclo Cruzamento

ABCDEFGHIJ

GHIJABEFCD

Filho 2: GBCDAFEHIJ

Filho 2:

ABCDEFGHIJ

GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

ABCDEFGHIJ

GHIJABEFCD

Page 50: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

49

Figura 4.7: Funcionamento do operador OX.

Este cruzamento é mais adequado quando é usado com a representação de

Sequência Ordenada, pois preserva mais as estruturas ordenadas dos

cromossomos dos pais, promovendo assim a herança genética.

Além desses, existem outros operadores que se aplicam ao problema do

caixeiro viajante, como o operador Matrix Crossover (MX), um operador que usar a

representação matricial, e o Modified Order Crossover (MOX), que é semelhante ao

operador OX, mas com apenas um ponto de corte (BRYANT, 2000, p. 15-16).

4.2.4 Operadores de mutação

Há vários operadores de mutação apropriados para problemas de

permutações de valores, até operadores de mutação heurística apropriados para o

problema do caixeiro viajante.

Alguns operadores de mutação que podem ser usados são: por inserção,

deslocamento, intercâmbio recíproco e por inversão. A mutação por inserção é

quando há uma seleção aleatória de uma cidade e sua inserção em uma posição

aleatória. A mutação por deslocamento é quando selecionamos um subcaminho e

insere-o em uma posição aleatória. Temos também intercâmbio recíproco onde há

uma escolha de duas cidades aleatórias e há uma troca de posição. O operador de

inversão é uma forma diferente de mutação, que consiste na escolha aleatória de

Pai 1 ABC | DEF | GHIJ

Pai 2 GHI | JAB | EFCD

1º 2 º

XXX | DEF | XXXX

[EF]C[D]GHIJAB CGHIJAB

JABDEFCGHI

Filho 1:

XXX | JAB | XXXX

GHI[JAB]CDEF GHICDEF

DEFJABGHIC

Filho 2:

Page 51: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

50

dois pontos de inversão no cromossomo e em seguida, inverte-se a ordem dos

genes entre os dois pontos.

Há também operadores de mutação heurística como os operadores 2-opt, 3-

opt e Or-opt, que efetuam a recombinação de arestas (subcaminho) se a condição

de redução do custo for satisfeita. A diferença entre esses operadores é o número

de arestas que sofrem a mutação (BRYANT, 2000, p. 18).

4.3 CONCLUSÃO

Algoritmo Genético é uma técnica para busca global, ideal para problema,

como o Problema do Caixeiro Viajante, que tem um espaço de busca muito grande.

O próximo capítulo apresenta a modelagem do Algoritmo Genético no

modelo de programação MapReduce para o Problema do Caixeiro Viajante e sua

implementação para o Hadoop.

Page 52: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

51

5 IMPLEMENTAÇÃO

Os Algoritmos Genéticos possuem características que não permitem ser

exatamente expressa no modelo MapReduce. Para resolver esse problema, foi

desenvolvido formas de modelar o AG usando a proposta original da técnica

MapReduce. O uso da técnica MapReduce no AG proporciona uma alta capacidade

de encontrar um bom resultado em um espaço de busca extremamente grande,

podendo resolver problemas complexos como o do PCV.

Este capítulo apresenta a modelagem do Algoritmo Genético no modelo de

programação MapReduce para o Problema do Caixeiro Viajante. Na seção 5.1 é

feita uma análise dos modelos proposto por outros autores para a modelagem do

AG. Na seção 5.2 são comparadas as formas e características das modelagens

proposta e de outros possíveis modelos. Na seção 5.3 é demonstrada a modelagem

do AG para o problema do caixeiro viajante no MapReduce e seu funcionamento.

Na seção 5.4 são apresentadas as características da implementação do algoritmo

para Hadoop. Na seção 5.5 são relatados os resultados obtidos na simulação do

algoritmo. Finalizando com as considerações finais na seção 5.6.

5.1 TRABALHOS RELACIONADOS

A técnica MapReduce permite fácil desenvolvimento de aplicações

distribuídas, porém muitas aplicações não podem ser exatamente expressa com

MapReduce devido suas características. É o caso das aplicações de natureza

iterativa, pois não segue o padrão de duas fases do MapReduce (JIN et al., 2008, p

1).

Segundo Ekanayake et al. (2010), MapReduce pode ser aplicada em vários

campos, como agrupamento de dados, aprendizado de máquina e visão

computacional, onde muitos algoritmos iterativos são comuns, como é caso dos

Algoritmos Genéticos. Entretanto, para criar as iterações em uma implementação

MapReduce é necessário a execução de várias tarefas MapReduce, porém isso

gera múltiplos acessos ao sistema de arquivos distribuído, provocando um alto custo

de desempenho.

Page 53: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

52

Considerando que a técnica MapReduce não fornece suporte eficiente para

as aplicações iterativas, algumas melhorias foram propostas com o uso de

extensões, como o Twister (EKANAYAKE et al., 2010) , o HaLoop (BU et al., 2010) e

o MRPGA (JIN et al., 2008), implementações que modificam o modelo original para

poder implementar a iteratividade.

Sendo o Algoritmo Genético uma aplicação iterativa, autores apresentaram

pesquisas para modelar o AG usando a proposta original da técnica MapReduce. No

trabalho de Verma et al.(2009) foi definido que cada iteração do AG fosse uma tarefa

MapReduce separada em que as funções map executassem as operações de

avaliação, e as funções reduce o restante das outras operações. Essa mesma

modelagem é utilizada no trabalho de Huang & Lin (2010), na implementação de um

AG para resolver o problema Job Shop Scheduling Problem5 (JSSP), com objetivo

de demonstrar o impacto do tamanho da população no resultado e no tempo de

convergência. Outro trabalho que usa a mesma modelagem é de Er & Erdogan

(2014), que avalia a aplicação dos Algoritmos Genéticos para resolver o Problema

do Caixeiro Viajante usando o framework MapReduce Hadoop; essa mesma linha de

pesquisa é utilizada também por Mishra (2011).

No trabalho de Keco & Subasi (2012) é apresentado um modelo de

paralelização de Algoritmo Genético usando o Hadoop. O modelo usa apenas uma

tarefa MapReduce para todas as iterações do AG e também concentra todo o seu

processamento na função map, reduzindo a quantidade operação de

leitura/gravação no HDFS. Esse modelo foi comparado com o modelo apresentado

em Verma et al.(2009), ambos usando o problema OneMax6.

5.2 MODELO AG EM MAPREDUCE

Ao contrário da modelagem proposta por Verma et al.(2009), a modelagem

deste trabalho propõe que as iterações do AG sejam criadas em uma única tarefa

MapReduce, semelhante ao apresentado por Keco & Subasi (2012). Isso minimiza o

acesso ao sistema de arquivos distribuído, reduzindo o custo de desempenho, pois

5 Problema de Sequenciamento de Tarefas .

6 Problema para maximizar o número de variáveis com o valor 1 (um) em uma String Binária .

Page 54: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

53

as iterações do algoritmo ocorrem sobre a memória principal das máquinas

presentes na rede de computadores. Na Tabela 5.1 são demonstradas as possíveis

formas de se criar as gerações da iteração do AG, com as gerações locais e globais

criadas respectivamente pela iteração na função map e reduce.

Tabela 5.1: Possíveis formas de modelagem do AG para o MapReduce.

Modelagem do AG

Iteração (Gerações)

Map Combiner Partitioner Reduce

Proposta por Verma et

al.(2009)

Por tarefa MapReduce

separada

Avaliação da Aptidão

Não é utilizado

Modificado para partição

randômico

Seleção, Cruzamento

e Mutação

Proposta de Verma modificado

Gerações Globais Na função

Reduce

Avaliação da Aptidão

Não é utilizado

Padrão ou modificação se

necessário

Seleção, Cruzamento, Mutação e

Avaliação

Proposta de Keco & Subasi (2012)

Gerações Locais na função Map

Avaliação, Seleção, Cruzamento

e Mutação

Não é utilizado

Padrão Seleção

Combiner Gerações Locais na função

Combiner

Avaliação da Aptidão

Seleção, Cruzamento, Mutação e

Avaliação

Padrão Seleção

Dupla Geração

Gerações Locais & Globais

Avaliação, Seleção, Cruzamento

e Mutação

Não é utilizado

Padrão ou modificação se

necessário

Seleção, Cruzamento, Mutação,

Avaliação

Conforme é visto na Tabela 5.1, a modelagem proposta por Verma et

al.(2009) define que cada geração do AG é feita em uma única tarefa MapReduce,

mas como pretende-se que todas as gerações sejam criadas em uma única tarefa

MapReduce esse modelo é inadequado. Entretanto, modificando esse modelo para

que as gerações fossem criadas na fase Reduce não aproveitaria todo o poder do

processamento distribuído, acarretando mais tempo para convergência.

Para ter mais aproveitamento do sistema distribuído, podem ser usadas

iterações na fase Map para criar gerações, como proposto por Keco & Subasi

(2012). Isso pode ser feito com as técnicas de agregação local Combiner ou In-

Mapper Combining (LIN & DYER, 2010), porém essa abordagem não aproveitaria a

diversidade da população que estaria em outras subpopulações. Portanto, para

aproveitar todo o poder computacional do MapReduce e a diversidade da população

é proposta a modelagem Dupla Geração, que cria gerações locais na fase Map,e

gerações globais na fase Reduce.

Page 55: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

54

A modelagem de Dupla Geração cria paralelamente várias gerações em

uma única tarefa MapReduce. Há dois tipos de gerações, as gerações locais criada

na fase map e as gerações globais, criadas na fase reduce. As gerações locais

podem ser criadas pela função Combiner, porém o Hadoop não garante quantas

vezes o Combiner é aplicado, ou se é mesmo aplicado. A alternativa é que as

gerações locais sejam criadas pela função map, através da técnica In-Mapper

Combining, na qual incorpora as funcionalidades do Combiner diretamente dentro da

função map. As gerações globais são criadas pela função reduce que usa uma

subpopulação composta por vários indivíduos provenientes de diferentes gerações

locais.

Na modelagem do fluxo de dados proposta por Verma et al.(2009), a chave

é representada pelo indivíduo (cadeia de cidades a serem visitadas), e o valor pela

aptidão do indivíduo, que corresponde à distância percorrida no caminho. O fluxo de

dados proposto neste trabalho equivale ao inverso da modelagem anterior, ou seja,

a chave é representada pela aptidão e o valor é representado pelo indivíduo, isso

permite o agrupamento dos indivíduos pela aptidão, criando subpopulações7 de

indivíduos de alta aptidão, possibilitando que a função reduce utilize os melhores

materiais genéticos (sub-caminho) para gerar novos indivíduos com melhor aptidão.

Essa abordagem foi usada para acelerar a convergência, pois o modelo de Dupla

Geração usa uma só tarefa MapReduce.

5.3 MODELAGEM DO PROBLEMA

O problema do caixeiro viajante tem o objetivo de encontrar o menor

caminho para se percorrer em um conjunto de cidades. A codificação desse caminho

pode ser feita através dos métodos apresentados na seção 4.2.1. Neste trabalho é

usado um PCV Simétrico Euclidiano, como é exemplificado na Figura 5.1 para um

PCVS de dez cidades. Os caminhos são codificados através da representação de

Sequência Ordenada8, em que as cidades são representadas pela letra do alfabeto

(A, B,..., Z). Para simplificar a demonstração da solução, optou-se por empregar uma

7 Deve-se notar que nem todas as subpopulações criadas são de alta aptidão.

8 Essa codificação é usada por ser mais simples e adequada para os arquivos de texto de entrada e saída usados

no Hadoop.

Page 56: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

55

cadeia de cidades (letras) que represente um passeio circular completo, sem

repetição de visitas entre trechos, como é explicado a seguir.

Figura 5.1: Mapa das cidades do PCVS no plano euclidiano.

Para resolver o problema é necessário conhecer as distâncias entre todas as

cidades. Considerando que as cidades são ponto no plano euclidiano, como visto na

Figura 5.1, o processo para encontrar a distância euclidiana entre as cidades é

realizado pelo uso das coordenadas dessas cidades com a equação (1).

(1)

Onde:

.

A título de exemplo, adotou-se os valores de coordenadas relativas para

cálculo das distâncias entre as cidades, como visto na Tabela 5.2. Para esse

problema, os caminhos podem ser representados pela sequência das dez primeiras

letras do alfabeto, como a sequência “ABCDEFGHIJ”.

1 2 3 4 5 6 7 8 9 10 11 x

y

11

10

9

8

7

6

5

4

3

2

1

0

A

B

C

D

E

F

G

H

I

J

Page 57: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

56

Tabela 5.2: Coordenadas relativas das cidades no plano euclidiano.

Cidade x y

A 1 2

B 7 9

C 3 3

D 1 5

E 4 3

F 5 6

G 2 4

H 8 3

I 9 2

J 6 9

Dessa forma, pode-se calcular a distância percorrida em um caminho, por

exemplo, no cálculo do caminho “ABCDEFGHIJ” da Figura 5.2.

Figura 5.2: Exemplo do cálculo da distância entre as cidades.

5.3.1 Modelagem do Algoritmo Genético

Normalmente, os Algoritmos Genéticos necessitam lidar com grandes

quantidades de indivíduos, pois grandes populações aceleram a convergência para

A

B

C

D

E H

I

J

F

G

Caminho: ABCDEFGIJ = )

Sendo as coordenadas e então:

.

Sendo esse cálculo válido para todo então:

) =

Caminho: ABCDEFGIJ

Distância:

Page 58: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

57

uma ótima solução. Isso requer o uso de técnicas para o processamento dessa

grande quantidade de dados, fato que justifica a adoção da técnica MapReduce.

O algoritmo básico para ser aplicado no MapReduce pode ser resumido da

seguinte forma. Antes de começar o processo do AG, é criada uma população com

indivíduos aleatórios; em seguida, são calculadas as aptidões dos novos indivíduos.

Dando início ao processo AG, as iterações criam varias gerações; em cada geração

são selecionados os melhores indivíduos que são utilizados pelos métodos de

cruzamento e de mutação. Para gerar uma nova população, esses novos indivíduos

são submetidos a um novo cálculo de aptidão, em seguida, verifica-se se o AG

atingiu um determinado número de gerações para poder finalizar. Tais

procedimentos são detalhados a seguir.

Inicialmente, é usada uma função aleatória para gerar populações com

grande diversidade. Existem várias alternativas para essa função, como apresentado

na seção 4.1.2. Neste trabalho é usada a Inicialização Randômica Uniforme.

Cada indivíduo da população é avaliado para determinar o valor de sua

aptidão - essa avaliação é feita de acordo com seção 4.2.2. O valor de aptidão é

usado por vários métodos que efetuam a seleção, como os que são apresentados

na seção 4.1.3. Este trabalho usa a seleção por Ranking, e a atualização é feita

através da troca de toda a população.

Após o processo de seleção, os indivíduos são escolhidos em pares de

acordo com a sua ordem na população, esses pares são usados pelo operador de

cruzamento para criar novos indivíduos. Há vários operadores de cruzamento

especializados para o PCV, que podem ser vistos na seção 4.2.3. O operador OX é

o método de cruzamento mais adequado para representação de Sequência

Ordenada (codificação usada neste trabalho), preservando assim mais as estruturas

ordenadas dos cromossomos pais, promovendo a herança genética aos seus

descendentes.

Após o cruzamento, uma amostra dos indivíduos sofre a operação de

mutação. Alguns operadores de mutação são descritos na seção 4.2.4,

especializados para o PCV; neste trabalho é usado o operador de mutação por

intercâmbio recíproco.

Page 59: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

58

Durante o processo de cada geração, o melhor indivíduo é comparado com

o melhor encontrado anteriormente, isso permite que o AG armazene o melhor

indivíduo entre todas as gerações, procedimento que se repete até atingir o número

predefinido de gerações.

5.3.2 Modelagem do MapReduce

Para implementar o AG na técnica MapReduce, deve-se utilizar um modelo

que se adapte à organização dessa técnica. Neste trabalho é usada a modelagem

Dupla Geração para que o AG seja executado em uma única tarefa MapReduce. O

modelo Dupla Geração cria dois tipos de gerações, as gerações locais e as

gerações globais, cada uma executa todo o processo do AG descrito na seção

anterior, além disso, a fase Shuffle e Sort9 funciona como um processo de seleção

global.

As gerações locais são criadas por uma iteração na função map. Com uma

população de entrada o processo AG cria novas gerações de indivíduos, que no final

são enviados junto com o melhor indivíduo encontrado (elitismo global) para a fase

intermediária (Shuffle e Sort).

As gerações globais são criadas por uma iteração na função reduce, que

recebe da fase intermediária um conjunto de indivíduos que forma a população

inicial para o processo AG criar novas gerações. No final, o melhor individuo

encontrado é enviado para a saída da função.

O resumo de todo o processo é melhor visto na Figura 5.3. A população de

entrada é gerada randomicamente fora da tarefa MapReduce. Essa população é

dividida entre as tarefas map. Cada divisão forma uma subpopulação local, que é

processada pela função map através do processo AG. Dependendo do tamanho

dessa subpopulação, ela pode ser dividida em grupos menores, que são usadas

como entrada para novos processos AG. A saída da função tem como chave a

aptidão e o como valor um indivíduo, que é representado por um cromossomo

9 É a fase intermediária em que o framework MapReduc e executa a classificação (Sort) e a transferência de

dados da fase map para a fase reduce, que é conhecida como o Shuffle (embaralhamento).

Page 60: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

59

(caminho) e sua aptidão (a distância do caminho). A função reduce recebe uma

subpopulação formada por indivíduos de aptidão aproximada que é usada por um só

processo AG, enviando um só indivíduo no final de cada função reduce.

Figura 5.3: Funcionamento do processamento MapReduce para o Algoritmo

Genético no modelo Dupla Geração.

O poder do processamento paralelo permite dividir a população em várias

tarefas map, que corresponde à execução paralela de vários processos AG sobre

uma subpopulação. Na fase reduce podem ser criadas varias tarefas reduce, que

proporciona a execução paralela de vários processos AG, em que cada tarefa

reduce executa um só processo AG.

Sob a perspectiva da visão de fluxo de dados, o funcionamento do AG na

técnica MapReduce é descrito da seguinte forma, considerando a codificação de

cidades (em forma de letras) adotado neste capítulo.

Inicialmente os dados utilizados são provenientes de um arquivo texto, em

que cada linha é uma representação codificada de um indivíduo, como por exemplo:

ABCDEIGHFJ

GIJABEFCDH

BEFGHIJACD

EBGFHCDIJA

Entrada Map Saída Reduce Shuffle

& Sort

População

Randômica

Subpopula

ção Local

AG AG Subpopula

ção Geral

Melhores

Indivíduos

Page 61: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

60

Os dados do arquivo de entrada formam pares chave/valor: a chave é o

número da linha (que não é tratado no arquivo), e o valor é própria linha que

representa o indivíduo. A função map avalia e armazena uma quantidade de linhas

(indivíduos) em uma lista, formando a população inicial para o processo AG gerar

novos indivíduos, esses são emitidos na forma do par aptidão/indivíduo

(chave/valor), sendo que a chave é o arredondamento da aptidão para um número

inteiro e o valor é um par <cromossomo/aptidão>10. No final de cada emissão há um

retorno da coleta de dados de entrada, se ainda houver dados de entrada, o

processo AG da função map se repete, emitindo novos pares aptidão/indivíduo como

no exemplo:

( 53, <ABCDEFGHIJ, 53.3475288096413>)

( 51, <GHIJABEFCD, 50,6532924781218>)

( 53, <EBFHGIJACD, 52.8074130652778>)

( 51, <EBHFCDIJGA, 51.4288322764095>)

A saída da função map é processada pela fase intermediária (Shuffle e Sort),

agrupando os pares aptidão/indivíduo (chave/valor) pela aptidão, porém essa forma

gera o risco de executar várias funções reduce com um só indivíduo, tornando inútil

o processo AG; isso é evitado se a chave do par aptidão/indivíduo for uma

aproximação da aptidão. Após a fase intermediária os dados são enviados para a

fase reduce da seguinte forma:

(51, [<GHIJABEFCD, 50,6532924781218>, <EBHFCDIJGA, 51.4288322764095>])

(53, [<ABCDEFGHIJ, 53.3475288096413>, <EBFHGIJACD, 52.8074130652778>])

Para cada chave há uma lista de indivíduos, que é usada pela função reduce

para gerar uma nova população através do processo AG. Na função reduce a chave

não é utilizada e a lista é usada como população inicial. No final da tarefa é emitido o

melhor indivíduo de cada função reduce através do par aptidão/indivíduo, como

desta forma:

(27.866056254812328, ACEHIBJFDG)

(28.014106081769356, GFJBHIECAD)

Todo esse processo de fluxo de dados pode ser visto na Figura 5.4.

10

Na modelagem MapReduce o par <cromossomo/aptidão> e o cromossomo (caminho) tem a mesma denominação “Indivíduo”.

Page 62: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

61

Figura 5.4: Fluxo lógico de dados do processo MapReduce para o AG.

Na essência do processo, as funções map e reduce mantém o controle dos

melhores indivíduos, no qual são sempre enviados pelo fluxo de dados. Isso resulta

na saída dos melhores indivíduos encontrados para o PCV. No término do processo

é realizada a gravação das saídas da fase reduce em um arquivo no sistema de

arquivos do Hadoop (o HDFS).

5.4 IMPLEMENTAÇÃO

Com base na estrutura de funcionamento do algoritmo genético PCV, esta

seção apresenta a implementação da aplicação denominado PCV-AG, no contexto

da tecnologia MapReduce do Hadoop. Para facilitar o entendimento da solução, as

funções principais de mapeamento e redução estão codificadas em forma de

algoritmos; as listagens em código Java encontram-se na seção de anexos.

5.4.1 Algoritmo

A função map é implementada pela classe MAPPER, descrito no algoritmo

da Figura 5.5. Nessa classe há três métodos:

1) MAP: trata e processa os valores de entrada para criar novos indivíduos,

inserindo cada um em uma nova população (grupo da subpopulação), que tem o

tamanho gerenciado por um controle de balanceamento, esse controle chama o

método GERACAOLOCAL quando a população atingir um determinado tamanho.

Entrada | map |

| shuffle

reduce > Saída

ABCDEIGHFJ

GIJABEFCDH

BEFGHIJACD

EBGFHCDIJA

( 0, ABCDEIGHFJ)

( 1, GIJAB EFCDH)

( 2, BEFGHIJACD)

( 3, EBGFHCDIJA)

( 53, < ABCDEFGHIJ, 53.3475288096413>)

( 51, <GHIJABEFCD, 50,6532924781218>)

( 53, <EBFHGIJACD, 52.8074130652778>)

( 51, <EBHFCDIJGA, 51.4288322764095>)

(51, [<GHIJABEFCD, 50,6532924781218>, <EBHFCDIJGA, 51.4288322764095>])

(53, [<ABCDEFGHIJ, 53.3475288096413>, <EBFHGIJACD, 52.8074130652778>])

(27.866056254812328, ACEHIBJFDG)

(28.014106081769356, GFJBHIECAD)

27.866056254812328, ACEHIBJFDG

28.014106081769356, GFJBHIEC AD

Page 63: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

62

2) GERACAOLOCAL: responsável por criar a iteração que executa o

processo AG, para criar uma nova geração de indivíduos que são emitidos para fase

intermediária.

3) CLEANUP: é a última função executada pela classe MAPPER, que

chama o método GERACAOLOCAL para processar os últimos indivíduos que não

passaram pelo controle de balanceamento.

Os métodos MAP e GERACAOLOCAL implementam o Algoritmo Genético e

os métodos CLEANUP e GERACAOLOCAL são os que implementam a técnica In-

Mapper Combining.

O Indivíduo do algoritmo é uma estrutura de dados formada pelos atributos

Cromossomo e Aptidão, instanciado como um objeto (Indivíduo) que irá compor a

lista População. Tal lista (População) fornece os métodos Adicionar, Tamanho e

Limpar, que respectivamente realizam as operações de inserir um novo elemento,

retornar o número de elementos, e excluir todos os elementos da lista.

O objeto OperaçãoGenética é uma instância de uma classe de apoio que

implementa todos os métodos do processo AG (seleção, cruzamento, mutação e

cálculo da aptidão), como podem ser vistos nas linhas 16-19. Além desses há

também dois métodos, TaxaMutação e MelhorIndivíduo, que proveem suporte às

operações principais. A TaxaMutação recebe um valor (taxa) que é usado pelo

método mutação; essa taxa varia entre os algoritmos Map e Reduce, que deve ser,

respectivamente, um valor baixo (BaixaTaxa) e um valor alto (AltaTaxa). O método

MelhorIndivíduo retorna (inserindo na lista) o melhor indivíduo encontrado nas

execuções dos métodos do objeto OperaçãoGenética. A variável

ValorDeBalanceamento define o tamanho da lista População e controla quando

processo AG será executado. As variáveis Geração e CondiçãoDeParada define,

respectivamente, o número da execuções do processo AG e o número máximo de

iteração desse processo.

O algoritmo Map provê dois métodos de apoio, o Arredondar e o Emite. O

Arredondar é usado para transformar o número real do atributo Aptidão do Indivíduo

para um número inteiro; esse valor é armazenado na variável Aptidão. O método

Page 64: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

63

Emite permite gerar os dados (a variável Aptidão e o Indivíduo) para fase

intermediária.

1: classe MAPPER 2: atributo População novo objeto lista [Indivíduo ] 3: atributo OperaçãoGenética novo objeto OperaçãoGenética 4: método MAP (chave, valor) 5: Indivíduo novo objeto Indivíduo 6: Indivíduo.Cromossomo valor 7: Indivíduo.Aptidão OperaçãoGenética.CalcularAptidão(Indivíduo) 8: População.Adicionar(Indivíduo) 9: OperaçãoGenética.TaxaMutação(BaixaTaxa) 10: se (População.Tamanho() = ValorDeBalanceamento) 11: GeracaoLocal () 12: método GERACAOLOCAL () 13: variável CondiçãoDeParada NúmeroMáximoDeGerações 14: variável Geração 0 15: enquanto (Geração < CondiçãoDeParada) 16: População OperaçãoGenética.Seleção(População) 17: População OperaçãoGenética.Cruzamento(População) 18: População OperaçãoGenética.Mutação(População) 19: População OperaçãoGenética.CalcularAptidão(População) 20: Geração Geração + 1 21: fimEnquanto 22: População.Adicionar(OperaçãoGenética.MelhorIndivíduo()) 23: para todo Indivíduo em População faça 24: variável Aptidão Arredondar(Indivíduo. Aptidão) 25: Emite (Chave Aptidão, Valor Indivíduo) 26: fimParaTodo 27: População.Limpar() 28: método CLEANUP () 29: GeraçãoLocal () Figura 5.5: Código Map do Algoritmo Genético MapReduce.

A função reduce é implementada pela classe REDUCER, descrita no

algoritmo da Figura 5.6. Essa classe tem o método REDUCE, responsável por criar a

iteração que executa o processo AG, que manipula uma subpopulação de indivíduos

de entrada, que é processada para gerar novos indivíduos. No final, o melhor

indivíduo encontrado na subpopulação é emitido para a saída da função.

Page 65: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

64

1: classe REDUCER 2: atributo População novo objeto lista [Indivíduo ] 3: atributo OperaçãoGenética 4: método REDUCE (Chave Aptidão, Valor [Indivíduo ] ) 5: População Valor 6: OperaçãoGenética novo objeto OperaçãoGenética 7: OperaçãoGenética.TaxaMutação(AltaTaxa) 8: variável CondiçãoDeParada NúmeroMáximoDeGerações 9: variável Geração 0 10: enquanto (Geração < CondiçãoDeParada) 11: População OperaçãoGenética.Seleção(População) 12: População OperaçãoGenética.Cruzamento(População) 13: População OperaçãoGenética.Mutação(População) 14: População OperaçãoGenética.CalcularAptidão(População) 15: Geração Geração + 1 16: fimEnquanto 17: Indivíduo OperaçãoGenética.MelhorIndivíduo() 18: variável Cromossomo Indivíduo.Cromossomo 19: variável Aptidão Indivíduo.Aptidão 20: Emite (Chave Aptidão, Valor Cromossomo) 21: População.Limpar() Figura 5.6: Código Reduce do Algoritmo Genético MapReduce.

A técnica MapReduce define que os dados do fluxo de dados podem ser de

qualquer tipo. Isso permite que os indivíduos (presentes no fluxo de dados) do

modelo Dupla Geração, sejam definidos como um par cromossomo/aptidão. Dessa

forma, os indivíduos podem ser definidos por uma classe em uma instância que é

vista na linha 5 do algoritmo da Figura 5.5. Tais objetos (indivíduos) são os principais

dados da tarefa MapReduce para a aplicação PCV-AG.

As operações do Algoritmo Genético estão fracamente acoplados ao

algoritmo do MapReduce, isso permite abstraí-los da implementação apresentada na

tecnologia MapReduce, concentrando-os separadamente em uma só classe

denominada “OperaçãoGenética”, como pode-se observar na linhas 16-19 da Figura

5.5, e 11-14 da Figura 5.6, especificamente onde ocorre o processo AG. Assim,

torna o algoritmo Map e Reduce mais simples e flexível para ser adaptado a outros

contextos de problema que sigam o paradigma do Caixeiro Viajante.

Page 66: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

65

5.4.2 Implementação em Java

Com base no diagrama de classes da Figura 5.7, e dos algoritmos

apresentados na seção anterior, a aplicação PCV-AG pode é codificada na

linguagem Java (linguagem nativa do Hadoop), cuja listagem completa está

localizada na seção de Anexos. A seguir, trechos dos códigos na implementação

são destacados para explicar as características particulares na tecnologia Hadoop.

Figura 5.7: Diagrama de classe do PCV-AG para o MapReduce.

A Figura 5.8 apresenta o código simplificado da classe Individuo. A classe

Indivíduo é uma implementação da interface Writable (ver seção 3.3.4) que

armazena dois valores: o cromossomo do indivíduo que é uma cadeia de caractere

(String) e sua aptidão que é um número real (double). Os objetos dessa classe são

usados em todo processamento da aplicação PCV-AG e no fluxo de dados do

MapReduce.

Page 67: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

66

Figura 5.8: Código simplificado da classe Indivíduo.

A Figura 5.9 apresenta o código simplificado do CaixeiroViajanteMapper. A

classe CaixeiroViajanteMapper é uma extensão da superclasse Mapper (ver seção

3.3.4), onde é definido os tipos de entradas e de saída. Os tipos da chave e valor de

entrada são respectivamente Object e Text. Os tipos da chave e valor de saída são

respectivamente IntWritable e Indivíduo. A classe possui os atributos população e

operacaoGenetica que são, respectivamente, uma lista de Indivíduo e um objeto do

tipo OperaçãoGenética, que são usados para a criação dos grupos de indivíduos,

para o armazenamento do melhor indivíduo e para fornecer as operações para o

processo AG.

Figura 5.9: Código simplificado da classe CaixeiroViajanteMapper.

A classe CaixeiroViajanteMapper também possui dois métodos herdadas

da classe Mapper, os métodos map() e cleanup(), e um método auxiliar

geraçãoLocal(). O método map() tem três parâmetros, os dois primeiros são

public class CaixeiroViajanteMapper extends Mapper<Object, Text, IntWritable, Individuo> { private ArrayList<Individuo> populacao = new ArrayList<Individuo>(); private OperacaoGenetica operacaoGenetica = new OperacaoGenetica(); @Override public void map(Object key, Text value, Context context) throws IOException, InterruptedException {…} public void geracaoLocal(Context context) throws IOException, InterruptedException {…}

@Override protected void cleanup(Context context) throws IOException, InterruptedException {…} }

public class Individuo implements Writable { private String cromossomo; private double aptidao; @Override public void write(DataOutput out) throws IOException {…} @Override public void readFields(DataInput in) throws IOException {…} }

Page 68: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

67

corespondentes ao par chave/valor de entrada e o último ao objeto Context11. O

método geraçãoLocal() recebe como argumento o objeto Context, usado para a

emissão dos indivíduos para a fase intermediária.

Na Figura 5.10 é visto o código simplificado do CaixeiroViajanteReducer. A

classe CaixeiroViajanteReducer é uma extensão da superclasse Reducer (ver

seção 3.3.4), onde é definido os tipos de entradas e de saída. Os tipos da chave e

valor de entrada são, respectivamente, IntWritable e Indivíduo. Os tipos da chave e

valor da saída são, respectivamente, DoubleWritable e Text. A classe possui os

mesmos atributos da classe CaixeiroViajanteMapper para a mesma finalidade.

Figura 5.10: Código simplificado da classe CaixeiroViajanteReducer.

A classe CaixeiroViajanteReducer herda da superclasse Reducer o método

reduce(), no qual tem três parâmetros, os dois primeiro são correspondentes ao par

chave/valor de entrada, e o último ao objeto Context. O método cria as gerações

através do mesmo processo AG através do atributo operacaoGenetica, empregando

o objeto Context para a emissão do melhor indivíduo encontrado.

Na Figura 5.11 é apresentado o código simplificado da classe

OperacaoGenetica. A classe OperaçãoGenética é uma classe auxiliar que executa

todas as funcionalidades das operações do AG. Os principais atributos são

melhorIndivíduo, alfabeto, distâncias e taxaMutação. O atributo melhorIndivíduo tem

o objetivo de guardar o melhor indivíduo encontrado durante o processo AG. Os

atributos alfabeto e distâncias armazenam as principais informações das cidades. O

atributo taxaMutação define a porcentagem de mutação da população. A classe

11

Objeto que permite que aplicação se comunique e envie dados para o framework do Hadoop.

public class CaixeiroViajanteReducer extends Reducer<IntWritable, Individuo, DoubleWritable, Text> { private ArrayList<Individuo> populacao = new ArrayList<Individuo>(); private OperacaoGenetica operacaoGenetica; @Override public void reduce(IntWritable key, Iterable<Individuo> values, Context context) throws IOException, InterruptedException {…} }

Page 69: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

68

OperaçãoGenética tem os métodos principais, calcularAptidão(), seleção(),

cruzamento(), mutação() e os auxiliares setTaxaMutação() e getMelhorIndivíduo().

Figura 5.11: Código simplificado da classe OperacaoGenetica.

Os métodos calcularAptidão, seleção, cruzamento e mutação, recebem uma

população de indivíduos para efetuar sua operação genética, e no final retornam a

população processada. O método setTaxaMutação() define a porcentagem usada

pelo método mutação(); essa taxa é diferente para as funções map e reduce. O

método getMelhorIndivíduo() retorna o melhor indivíduo armazenado no atributo

melhorIndivíduo.

Finalmente, a classe CaixeiroViajante é a classe que executa o trabalho

MapReduce. Para isso, a partir do método estático main(), há o controle da

execução do trabalho, a definição da entrada e saída do caminho do arquivo ou

diretório dos dados, a especificação de quais classes fazem parte da função map e

reduce, e o controle dos tipos de entrada e saída das funções map e reduce. No

final, o método monitora o progresso do trabalho MapReduce.

public class OperacaoGenetica { private Individuo melhorIndividuo = new Individuo(); private int tamanhoIndividuo = 10; private double taxaMutacao = 5/100; private String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private int[][] distancias = {{ 1, 2 }, { 7, 9 }, { 3, 3 }, { 1, 5 }, {

4, 3 }, { 5, 6 }, { 2, 4 }, { 8, 3 }, { 9, 2 }, { 6, 9 }}; public ArrayList<Individuo> calcularAptidao(ArrayList<Individuo>

populacao) public ArrayList<Individuo> selecao( ArrayList<Individuo> populacao) public ArrayList<Individuo> cruzamento(ArrayList<Individuo> populacao) public ArrayList<Individuo> mutacao(ArrayList<Individuo> populacao) public Individuo getMelhorIndividuo()

public void setTaxaMutacao(double taxa) }

Page 70: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

69

5.5 TESTES E AVALIAÇÃO DE RESULTADOS

Para testar o algoritmo da aplicação PCV-AG foi usado um PCVS de vinte

cidades, com base no desempenho do algoritmo, para encontrar as melhores

soluções em função do número de indivíduos da população inicial. A aplicação é

executada em um só computador, no modo local (standalone mode) do Hadoop, que

é o mais indicado para o desenvolvimento da aplicação AG MapReduce, porém não

fornece todo o poder de processamento paralelo presente no modo distribuído em

uma rede de computadores. Portanto, as análises estão focadas apenas no

potencial da modelagem MapReduce, e não no poder de processamento paralelo,

que é apenas simulado no modo local.

5.5.1 Ambiente operacional e cenário de execução

A aplicação PCV-AG é implementado em Java e utiliza a API do Hadoop

1.2.1, Java 1.7, e a IDE12 Eclipse JEE Enterprise (Juno) com o hadoop-eclipse-

plugin 1.2.

A execução foi realizada em modo local (standalone mode) em uma

máquina de 1,67 GHz de processamento, com 1GB de memória principal. O sistema

operacional é o Ubuntu (versão 12.04.3), simulando o ambiente Hadoop no Eclipse,

com o uso do plugin hadoop-eclipse-plugin 1.2.

O PCVS usado para os testes tem a mesma descrição do exemplo anterior,

porém o número de cidades e as coordenadas são diferentes. Esse novo cenário

apresenta 20 (vinte) cidades, cujo espaço de busca é maior que 60,822 quatrilhões

de possibilidades de caminhos. As coordenadas cartesianas dessas cidades estão

descritas na Tabela 5.3.

12

Ambiente de Desenvolvimento Integrado.

Page 71: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

70

Tabela 5.3: Coordenada das cidades do problema.

Cidade X Y Cidade x y

A 1 8 K 17 10

B 1 10 L 17 8

C 2 13 M 16 5

D 3 15 N 15 3

E 5 16 O 13 2

F 8 17 P 10 1

G 10 17 Q 8 1

H 13 16 R 5 2

I 15 15 S 3 3

J 16 13 T 2 5

As coordenadas das cidades formam uma figura circular de acordo com a

Figura 5.12, escolhida pelo fato de ser possível reconhecer visualmente o melhor

caminho e comparar com os caminhos encontrados pela aplicação. O melhor

indivíduo é representado pela ordem da sequência dos pontos

“ABCDEFGHIJKLMNOPQRST”, com aptidão igual a 51,1867651013453.

Figura 5.12: Mapa do conjunto de 20 cidades no plano euclidiano.

As funções map e reduce da aplicação PCV-AG possuem em cada

processo AG uma iteração de 10 (dez) gerações. Na função map, a taxa de

mutação é definida em 5% da população, e o balanceamento em 100 (cem)

indivíduos.

Na função reduce a taxa de mutação é de 90%. Essa taxa deve ser alta, pois

cada tarefa reduce recebe indivíduos de aptidão aproximados, aumentando assim a

A

G

C

E

F

I

J

H

B

D

L

K

P Q

M

N

O R

S

T

Page 72: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

71

possibilidade de indivíduos semelhantes e, com isso, elevando o risco de

convergência prematura. A população inicial é gerado aleatoriamente, através de

uma aplicação MapReduce.

5.5.2 Simulações e resultados obtidos

No trabalho de Huang & Lin (2010) é demonstrada uma implementação de

um AG MapReduce para resolver o problema Job Shop Scheduling Problem, com o

objetivo de demonstrar o impacto do tamanho da população no resultado e no tempo

de convergência. O resultado obtido no trabalho demonstra que quanto maior a

escala da população, não só tendem a encontrar melhores soluções, mas também

exige menos gerações. O teste realizado aqui, demonstra o mesmo resultado,

porém não é avaliado o tempo de convergência por estar sendo usada uma só

maquina. Outro item que não é avaliado é o número de geração, pois esse número é

um valor predefinido no algoritmo do MapReduce, que impossibilita a análise do

desempenho do algoritmo baseado no número de geração.

O teste foi realizado sobre 5 (cinco) escalas de população, de acordo com a

Tabela 5.4, em que cada escala foi gerada 4 (quatro) populações de indivíduos

aleatórios, que por sua vez são realizadas cinco execuções da aplicação PCV-AG,

resultando na saída de várias dezenas de indivíduos, na faixa de 80 a 150, na qual

só foi selecionado o melhor.

Em cada escala houve 20 execuções, resultando em 20 melhores

indivíduos. Desses, foi retirado o melhor, o pior e uma média. Para comparação, foi

retirado de cada população inicial a aptidão dos melhores, e definido o melhor, o pior

e a média das melhores aptidões por escala.

Page 73: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

72

Tabela 5.4: Aptidão das Populações Iniciais e das Populações Finais resultante das

execuções do PCV-AG.

Escala População Inicial População Final Melhor Inicial

Pior Inicial

Média Inicial

Melhor Gerado

Pior Gerado

Média Gerada

1000 124,0074 151,8577 132,2208 80,59109 110,0509 98,69151

10000 123,6807 148,7945 136,6492 69,36951 94,82906 84,77589

20000 120,0181 139,7515 131,6790 71,57708 93,43644 82,72006

30000 129,9764 134,2425 131,9972 59,28971 88,4677 77,65220

40000 130,0537 136,1151 132,2208 65,53783 83,86628 75,50903

Os resultados obtidos são comprovados no gráfico da Figura 5.13,

enfatizando que o aumento no número de indivíduos da população, demonstra que a

aplicação gera indivíduos próximos da melhor solução. Esta afirmação pode ser

observada pela linha da média gerada, e também pela tendência das linhas do

melhor e pior individuo gerado. A média dos melhores indivíduos iniciais tende a

permanecer constante, reforçando que a convergência dos indivíduos gerados se

deve ao número de indivíduos da população inicial.

Figura 5.13: Tendência gerada pelo aumento de escala da população.

O melhor e pior indivíduo encontrados podem ser vistos graficamente na

Figura 5.14. O melhor indivíduo é o caminho representado pela sequência

0

20

40

60

80

100

120

140

160

0 10000 20000 30000 40000 50000

Ap

tid

ão (

Tam

anh

o

do

cam

inh

o)

Número de indivíduo da população

PIOR INICIAL

MÉDIA INICIAL

MELHOR INICIAL

PIOR GERADO

MÉDIA GERADA

MELHOR GERADO

MELHOR CAMINHO

Page 74: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

73

“ONMKLJHIGFEDCBATSRQP” de aptidão 59.289708664779766, e o pior indivíduo

é o caminho “JIHSCFEDBARTQPONKLMG”, de aptidão 110.05093343072689.

Figura 5.14: Melhor e pior indivíduo encontrado entre os melhores.

Por não estar sendo executado no modo distribuído, o tempo de execução

da aplicação foi de 5 a 49 segundos, dependendo do tamanho da escala da

população.

5.5.3 Desempenho da Modelagem Dupla Geração

Na modelagem Dupla Geração, para a criação das iterações na fase map é

utilizada a técnica in-mapper combining, cujo efeito colateral danoso é provocar um

gargalo de escalabilidade, um problema para o modelo que pretende escalar e

trabalhar com grande população. A solução é utilizar um controle de balanceamento

para processar um número predefinido de indivíduos. Entretanto, nesse tipo de

abordagem o número de indivíduos dessas subpopulações deve ser definido

empiricamente, o que afeta a qualidade da geração local, pois como foi

demonstrado, o tamanho da população inicial afeta o grau de convergência.

A condição de convergência do algoritmo foi determinada com base em um

número predefinido de gerações, situação que pode não encontrar o melhor

indivíduo, mas uma aproximação. Se for utilizada uma condição de convergência

Melhor Indivíduo Pior Indivíduo

Page 75: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

74

que dependa do valor da aptidão, uma tarefa map pode levar muito tempo para a

convergência, até travar todo o processo MapReduce, pois a fase Reduce depende

da conclusão da fase anterior, podendo induzir o framework MapReduce a finalizar a

tarefa pela sua lentidão. A consequência da abordagem adotada é que a aplicação

pode não gerar o melhor individuo, e sim um indivíduo de alta aptidão, como pode

ser visto no gráfico da Figura 5.13, tendo como fator de convergência mais

significativo o tamanho da escala da população.

Na modelagem do fluxo de dados, o par chave/valor de saída da função map

é definido pelo par aptidão/indivíduo, dessa forma, durante a fase intermediária os

indivíduos de diferentes populações são agrupados por aptidão aproximada, no qual

são usados pela função reduce, criando novas gerações. Essa abordagem foi usada

para acelerar a convergência, mas surge a dificuldade com o aumento da

possibilidade de cruzamento de indivíduos semelhantes, elevando o risco de

convergência prematura, ficando presa no ótimo local. Para resolver esse problema,

foi definido no algoritmo genético, na fase Reduce, uma alta taxa de mutação,

suficiente para sair do ótimo local. Apesar disso, independente da taxa de mutação,

a função reduce tende a gerar melhores indivíduos em relação à entrada, causada

pela diversidade da população das tarefas map.

5.6 CONSIDERAÇÕES FINAIS

Este capítulo apresentou a modelagem de Algoritmo Genético na técnica

MapReduce, para resolver o Problema do Caixeiro Viajante. Foi proposta uma

modelagem e implementação para a execução simples do AG em uma única tarefa

MapReduce.

O AG é uma técnica de otimização usada para encontrar solução de um

problema, como no caso do Problema do Caixeiro Viajante. O MapReduce fornece a

escalabilidade de dados e o processamento necessário para o AG, potencializando

a capacidade de encontrar um bom resultado em um espaço de busca

extremamente grande.

Page 76: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

75

Os Algoritmos Genéticos possuem características que não permitem ser

exatamente expressa no modelo MapReduce. Para resolver esse problema, foi

desenvolvido formas diferentes de modelar o AG.

A modelagem do AG desse trabalho usa as melhores características

apresentadas por outros modelos, criando um novo modelo que aproveita os

recursos da diversidade da população, do processamento e do tempo de execução.

É possível usar outras formas de modelagem, como o uso do Combiner para criar

novas iterações, e do Partitioner para criar novas formas de seleção global para a

fase Reduce.

A medição do tempo de convergência da aplicação não foi avaliada pelo fato

da aplicação está sendo executada no modo local. Para fazer essa avaliação seria

necessário executar em modo distribuído do Hadoop em um cluster de máquinas

organizados em uma rede de computadores.

Considerando as limitações do ambiente operacional (modo local), foi

escolhido um cenário mais simples, com um exemplo considerado pequeno de

cidades, ainda assim produzindo um bom espaço de busca para as análises dos

resultados.

O controle de balanceamento possui um valor que define o tamanho das

subpopulações da tarefa map. Nos testes realizados foi definido um baixo valor, mas

dependendo do problema pode aumentar até a capacidade dos recursos

computacionais que o Hadoop e a máquina podem fornecer. Tais recursos são

demandados a partir da definição do número de divisões da população inicial, que

provoca a criação de várias subpopulações e, consequentemente, na criação de

vários processos AG. Quando maior o número do valor de balanceamento menor

será o número de processos AG, que, por sua vez, maior será o tamanho da

subpopulação. O resultado desse ajuste, pode melhorar a qualidade dos indivíduos

nas gerações, mas também necessitará de mais recurso computacional, podendo

atingir o limite dos recursos disponíveis para uma única tarefa map.

A aplicação usa a técnica MapReduce para processar grande volume de

indivíduos, dessa forma a avaliação da aplicação é baseada nos resultados

encontrados em função do tamanho da população inicial. O número de gerações foi

Page 77: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

76

definido baixo para que a diversidade da população se sobressaia e seja verificado o

impacto da população inicial, mas o número de gerações pode ser maior,

dependendo da necessidade do problema a ser usado. O resultado encontrado na

simulação da aplicação não diz o tamanho da população necessário para encontrar

uma solução próxima do ideal, e sim que ela deve ser um volume grande de

indivíduos, fato que justifica a utilização do MapReduce para escalar esse grande

volume.

A condição de parada do processo AG por número de gerações é utilizado

para evitar que o framework MapReduce interrompa a execução das tarefas map da

aplicação. No entanto, o processo AG pode utilizar outra condição de parada, como

a por grau de convergência da população, modelando em uma forma adequada em

que todas as tarefas não sejam interrompidas na execução.

A saída da função map é processada pela fase intermediária. Os dados são

agrupados pela aptidão, porém essa forma pode gerar população unitária (de único

indivíduo) para a função reduce. A possível solução para esse problema é definir

uma chave intermediária que seja uma aproximação da aptidão. A forma adotada

neste trabalho foi um arredondamento da chave intermediária para um número

inteiro, no entanto isso pode não ser o suficiente. Neste caso, a melhor alternativa é

o calcular o arredondamento da chave para a dezena ou centena mais próxima.

Assim, o método de arredondamento a ser adotado depende somente da dispersão

dos valores das aptidões. O impacto na qualidade das gerações que o

arredondamento tem no Reduce é semelhante ao controle de balanceamento tem no

Map, pois ambos são responsáveis por delimitar a população inicial para os

processos AGs.

A modelagem proposta não foi comparada com outros modelos para verificar

sua vantagem e desvantagem. Para verificar se o modelo sana os problemas

apresentados por outros modelos, o ambiente de execução (deste trabalho) deveria

executar em modo distribuído, assim seria possível comparar os resultados da

execução da implementação com os outros modelos que aplicam a eficiência dos

ambientes operacionais.

Page 78: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

77

O resultado avaliado, foi um modelo para a execução simplificada do AG em

única tarefa MapReduce, aproveitando as característica paralela e distribuída da

técnica MapReduce, bem como a diversidade oferecida por uma grande população.

Dessa forma, o modelo não realiza a distribuição das operações do AG, e sim o

paralelismo de vários processos AG em várias tarefas do MapReduce.

Page 79: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

78

CONCLUSÃO

A técnica MapReduce é um modelo de programação utilizado para o

processamento de grandes conjuntos de dados, baseado no ambiente

computacional paralelo e distribuído, que provê escalabilidade e simplificação para o

desenvolvimento de aplicações com essas características. Alguns frameworks

MapReduce estão disponíveis no mercado de software, entre eles o Hadoop, que é

utilizado para o processamento e armazenamento de dados em larga escala,

organizados em clusters de computadores de máquinas comuns. Os recursos e

vantagem que a técnica MapReduce proporciona, torna essa tecnologia adequada

para ser aplicada em vários campos, como o tratamento e análise de agrupamentos

de dados, aprendizado de máquina, visão computacional, entre outros, como é caso

dos Algoritmos Genéticos.

Algoritmo Genético é uma técnica de otimização utilizada como busca

global, empregada em problemas nas quais o número de soluções possíveis para

sua resolução é muito alto. Dessa forma, os recursos computacionais tradicionais

tornam-se inviáveis para resolvê-lo em tempo hábil. Exemplo disso, é o caso do

Problema do Caixeiro Viajante (PCV), no qual o número de combinações de

caminhos para percorrer um conjunto de cidades aumenta exponencialmente em

função do número de cidades. PCV é um problema típico de otimização que é

bastante utilizado em pesquisas e aplicações de diferentes áreas.

Um dos desafios presentes em AG é a necessidade de ter uma grande

quantidade de indivíduos para encontrar uma boa solução, exigindo poder e

escalabilidade dos recursos computacionais. Os AGs possuem algumas

características de natureza paralela, fato que permite ser processado em um arranjo

computacional em uma rede, ou cluster de computadores. Porém, isso requer uma

preparação de rotinas adicionais para a paralelização e distribuição dos processos

AG, dificultando a programação da solução. Para resolver esse problema, uma

alternativa viável é a adoção da técnica MapReduce, que simplifica o algoritmo de

implementação, permitindo processar grande quantidade de indivíduos e reduzindo

o tempo de execução na busca de um bom resultado. Porém, modelar um AG em

Page 80: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

79

MapReduce não é trivial, exigindo a criação de estratégias para o uso eficiente das

duas técnicas.

Este trabalho investigou pesquisas acadêmicas que foram desenvolvidas

para modelar AGs usando a técnica MapReduce. A modelagem proposta neste

trabalho foi empregada e adaptadas algumas características apresentadas nos

modelos investigados, resultando em uma proposição de projeto simplificada para o

AG do tipo PCV. Isso foi possível ser realizado em uma única tarefa MapReduce,

aproveitando as qualidades paralela e distribuída da técnica.

Com base no modelo proposto, foi implementado uma aplicação para a

resolução do PCV. Para facilitar o desenvolvimento do software, a aplicação foi

projetada e executada em modo local, em apenas um computador, fato que

influenciou na escolha de exemplos mais simples, com população de indivíduos que

fossem adequadas para o processamento em uma máquina, e para a melhor

compreensão da codificação da solução. O número de gerações foi definido baixo e

a avaliação da aplicação foi baseada nos resultados encontrados em função do

tamanho da população inicial.

O modelo proposto apresenta algumas restrições: apresenta um método

pouco flexível para controle da população, possui um risco elevado de convergência

prematura, além da possibilidade de ocorrer o travamento da execução em

decorrência de uma escolha inadequada do número predefinido de gerações.

Apesar dessas limitações, o resultado demonstra que o modelo proposto é eficiente

na execução de grande quantidade de dados, situação que reforça o uso da técnica

MapReduce. A evidência disso é comprovada quando se estabelece um tamanho

maior da população inicial, fator que eleva a tendência de encontrar indivíduos de

alta aptidão, mas, em contrapartida, exige poder de processamento distribuído e

paralelo, qualidades presentes na solução MapReduce.

Como trabalhos futuros, pretende-se avaliar o modelo proposto na execução

de testes em cluster de computadores para resolver PCV mais complexos; analisar o

desempenho e o tempo médio de execução em um cenário real; comparar o

desempenho da proposta com outras pesquisas disponíveis na literatura; adaptar o

Page 81: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

80

modelo para resolver outros problemas de otimização; aplicar as funções Combiner

e Partitioner para melhorar o desempenho do modelo proposto.

Enfatiza-se a contribuição deste trabalho em situações reais enfrentados no

cotidiano, como a identificação de melhores rotas para a logística de distribuição de

cargas, na visitação de turistas em localidades e logradouros em um grande centro

urbano, além de problemas típicos de otimização no planejamento do transporte

público. Outras aplicações encontram-se na área industrial de manufatura de

equipamentos eletrônicos, com a otimização de layout de placas de circuito

impresso, buscando encontrar as melhores configurações.

Page 82: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

81

REFERÊNCIAS BIBLIOGRÁFICAS

ALBA, E.; TROYA, J. M. A Survey of Parallel Distributed Genetic Algorithms. Complexity, v. 4, n. 4, p.31-52, 1999. Disponível em: < http://

http://neo.lcc.uma.es/Articles/albatroyaxx_2.pdf >. Acesso em: 10 jan. 2014, 17:16.

BU, Y.; HOWE, B.; BALAZINSKA, M.; ERNST D. M. HaLoop: Efficient Iterative Data Processing on Large Clusters. In: Proceeding of the VLDB Endowment, v.3,

n. 1-2, p. 285-296, 2010. Disponível em: < http://www.ics.uci.edu/~yingyib/papers/HaLoop_camera_ready.pdf>. Acesso em: 07

set. 2014, 21:15.

BRYANT, K.; BENJAMIN, A. Genetic Algorithms and the Traveling Salesman Problem. In: Proceeding of 1st GNT Regional Conference on Mathematics, Statistics

and Applications. 2000. Disponível em: < http://... >. Acesso em: 06 fev. 2014, 19:57.

DEAN, J.; GHEMAWAT, S. MapReduce: Simplified Data Processing on Large Clusters. Communications of the ACM, 51 (1): 107-113, 2008. Disponível em:

<http://www.ccs.neu.edu/home/lieber/courses/csg113/f08/materials/p107-dean.pdf>.

Acesso em: 28 set. 2013, 18:47.

EMC. Disponível em: <http://brazil.emc.com/>. Acesso em: 20 set. 2014, 17:31.

EKANAYAKE, J.; LI, H.; ZHANG, B.; GUNARATHNE, T.; BAE, S.-H.; QIU, J.; FOX, G.; Twister: A Runtime for Iterative MapReduce. In: HPCA ’10: Proceedings of the

19th ACM International Symposium on High Performance Distributed Computing.

ACM, 2010. p. 810–81. <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.212.5045&rep=rep1&type=pdf>Acesso em: 29 set. 2013, 19:13.

ER, H.; ERDOGAN, N. Parallel Genetic Algorithm to Solve Traveling Salesman Problem on MapReduce Framework using Hadoop Cluster. arXiv preprint arXiv:

1401.6267, 2014. Disponível em: <http://arxiv.org/ftp/arxiv/papers/1401/1401.6267.pdf> Acesso em: 25 abr. 2014, 17:47.

GOLDMAN, A.; KON, F.; PEREIRA. F.; POLATO, I.; PEREIRA, R.F. Apache Hadoop: conceitos teóricos e práticos, evolução e novas possibilidades . XXXI

Jornadas de Atualizações em Informática, 2012. Disponível em: < http://www.ime.usp.br/~ipolato/JAI2012-Hadoop.pdf>. Acesso em: 29 set. 2013, 17:44.

GUTIN, G. Traveling salesman problem. In: Floudas, C.A., Pardalos, P.M. (eds)

Encyclopedia of Optimization, pp. 3935-3944. Springer, New York, 2009. Disponível

em: <http://eprints.pascal-network.org/archive/00005214/01/TSPentry.pdf >. Acesso em: 25 abr. 2014, 17:35.

HADOOP. Disponível em: <http://hadoop.apache.org/>. Acesso em: 04 mar. 2014, 12:52.

Page 83: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

82

HE, B.; FANG, W.; LUO, Q.; GOVINDARAJU, N.; WANG, T. Mars: A MapReduce Framework on Graphics Processors. In: PACT ‘08, Proceedings of the 17th

International Conference on Parallel Architectures and Compilation Techniques,

Toronto, Ontario, Canada, 2008. p. 260-269 Disponível em: < http://www.cse.ust.hk/gpuqp/Mars_tr.pdf>. Acesso em: 11 dez. 2013, 19:05.

HUANG, D.; LIN, J.; Scaling Populations of a Genetic Algorithm for Job Shop Scheduling Problems using MapReduce. In: Cloud Computing Technology and

Science (CloudCom), 2010 IEEE Second International Conference on. Washington

DC, IEEE, 2010. p. 780-785. Disponível em: < http://hcil2.cs.umd.edu/trs/2010-14/2010-14.pdf >. Acesso em: 10 jan. 2014, 17:23.

JIN, C.; VECCHIOLA, C.; BUYYA, R. MRPGA: An Extension of MapReduce for Parallelizing Genetic Algorithms. In: eScience ’08: Fourth IEEE International

Conference on eScience. Washington DC, EUA, 2008. p. 214-221. Disponível em:

<http://www.buyya.com/papers/MapReduce-GA-eScience2008.pdf>. Acesso em: 29 set. 2013, 19:54.

KRUIJF, M.; SANKARALINGAM, K. MapReduce for the Cell B.E. Architecture.

Technical Report TR1625, Department of Computer Sciences, The University of Wisconsin-Madison, Madison, 2007, Disponível em: <

http://pages.cs.wisc.edu/~dekruijf/docs/mapreduce-cell.pdf >. Acesso em: 21 dez. 2013, 11:04.

KECO, D.; SUBASI, A. Parallelization of genetic algorithms using Hadoop Map/Reduce. SouthEast Europe Journal of Sorft Computing, v. 1, n. 2, 2012.

Disponível em: <

http://www.researchgate.net/profile/Abdulhamit_Subasi/publication/258858471_Parallelization_of_genetic_algorithms_using_Hadoop_ Map/Reduce >. Acesso em: 09 set. 2014, 23:17.

LIN, J.; DYER, C. Data-Intensive Text Processing with MapReduce. Morgan &

Claypool Publishers, 2010. Disponível em: <http://beowulf.csail.mit.edu/18.337-

2012/MapReduce-book-final.pdf>. Acesso em: 29 set. 2013, 20:02.

LUCAS, Diogo C. Algoritmos Genéticos: uma Introdução. 2002. Disponível em: <

.inf.ufrgs.br alvares INF01048IA Aposti laAlgoritmosGeneticos.pdf >. Acesso

em: 01 set. 2013, 11:33.

MISHRA, A.; Genetic Algorithm for the Travelling Salesman Problem on

Hadoop. New York, Rochester, 2011. Tese de Doutorado. Rochester Institute of

Technology. Disponível em: <http://www.cs.rit.edu/~axm1820/Project_Report_Final.pdf >. Acesso em: 08 set.

2014, 10:32.

PACHECO, M. Algoritmos Genéticos: Princípios e Aplicações. ICA: Laboratório

de Inteligência Computacional Aplicada. Departamento de Engenharia Elétrica. Pontifícia Universidade Católica do Rio de Janeiro, 1999. Disponível em: <http://www2.ica.ele.puc-rio.br/Downloads/38/CE-Apostila-Comp-Evol.pdf>. Acesso

em: 01 set. 2013, 11:36.

Page 84: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

83

RANGER, C.; RAGHURAMAN, R.; PENMETSA, A.; BRADSKI , G.; KOZYRAKIS, C., Evaluating MapReduce for multi-core and multiprocessor systems. In: HPCA

’07: Proceedings of the 2007 IEEE 13th International Symposium on High Performance Computer Architecture, 2007, Washington, DC, USA. Anais... IEEE

Computer Society, 2007. p.13–24. Disponível em: < http://pages.cs.wisc.edu/~david/courses/cs758/Fall2009/papers/mapreduce.pdf>.

Acesso em: 11 dez. 2013, 19:11.

VERMA, A.; LLOR`A, X.; GOLDBERG, D.; CAMPBELL, R. Scaling Genetic Algorithms using MapReduce. In: Intelligent Systems Design and Applications,

2009, ISDA ’09. Ninth International Conference on. IEEE, 2009. P. 13-18. Disponível em: < http://www.verma7.com/pdfs/ISDA09_MR_GA.pdf>. Acesso em: 29 set. 2013,

17:26.

VENNER, Jason. Pro Hadoop : Build Scalable, Distribuited Applications in the Cloud. USA, Apress, 2009. Disponível em: < http:// >. Acesso em: 10 jan. 2014,

17:40.

WHITE, Tom. Hadoop: The Definitive Guide. 2.ed. Sebastopol, O'Reilly Media,

2010. Disponível em: < http://ce.sysu.edu.cn/hope/UploadFiles/Education/2011/10/201110221516245419.pd

f>. Acesso em: 29 set. 2013, 16:45.

YOO, R.M.; ROMANO, A.; KOZYRAKIS, C., Phoenix Rebirth: Scalable MapReduce on a Large-Scale Shared-Memory System. In IISWC, 2009. p. 198-

207, Disponível em: < http://csl.stanford.edu/~christos/publications/2009.scalable_phoenix.iiswc.pdf>.

Acesso em: 11 dez. 2013, 18:56.

Page 85: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

84

ANEXO A

Implementação da classe Individuo.

import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import org.apache.hadoop.io.Writable; public class Individuo implements Writable { private String cromossomo; private double aptidao; @Override public void write(DataOutput out) throws IOException { out.writeUTF(cromossomo); out.writeDouble(aptidao); } @Override public void readFields(DataInput in) throws IOException { this.cromossomo = in.readUTF(); this.aptidao = in.readDouble(); } @Override public String toString() { return cromossomo + "\t" + aptidao; } public String getCromossomo() { return this.cromossomo; } public void setCromossomo(String individuo) { this.cromossomo = individuo; } public double getAptidao() { return aptidao; } public void setAptidao(double aptidao) { this.aptidao = aptidao; } public String[] getIndArray() { String[] individuo = new String[this.cromossomo.length()]; for (int i = 0; i < this.cromossomo.length(); i++) { individuo[i] = ""+this.cromossomo.charAt(i); } return individuo; } public void setIndArray(String[] individuo) { this.cromossomo = ""; for (String i: individuo) { if(i != null){ this.cromossomo += i; } } } }

Page 86: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

85

Implementação da classe CaixeiroViajanteMapper .

import java.io.IOException; import java.util.ArrayList; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; public class CaixeiroViajanteMapper extends Mapper<Object, Text, IntWritable, Individuo> { private ArrayList<Individuo> populacao = new ArrayList<Individuo>(); private OperacaoGenetica operacaoGenetica = new OperacaoGenetica(); @Override public void map(Object key, Text value, Context context) throws IOException, InterruptedException { ArrayList<Individuo> popula = new ArrayList<Individuo>(); Individuo individuo = new Individuo(); individuo.setCromossomo(value.toString()); popula.add(individuo); popula = operacaoGenetica.calcularAptidao(popula); populacao.add(popula.get(0)); operacaoGenetica.setTaxaMutacao(0.05); if (populacao.size() == 100) { geracaoLocal(context); } } public void geracaoLocal(Context context) throws IOException, InterruptedException { int CondicaoDeParada = 10; int geracao = 0; while (CondicaoDeParada != geracao) { populacao = operacaoGenetica.selecao(populacao); populacao = operacaoGenetica.cruzamento(populacao); populacao = operacaoGenetica.mutacao(populacao); populacao = operacaoGenetica.calcularAptidao(populacao); geracao++; } populacao.add(operacaoGenetica.getMelhorIndividuo()); int Aptidao; for (Individuo individuo : populacao) { Aptidao = (int) Math.round(individuo.getAptidao()); context.write(new IntWritable(Aptidao), individuo); } populacao.clear(); } @Override protected void cleanup(Context context) throws IOException, InterruptedException { geracaoLocal(context); } }

Page 87: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

86

Implementação da classe CaixeiroViajanteReducer .

import java.io.IOException; import java.util.ArrayList; import org.apache.hadoop.io.DoubleWritable; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; public class CaixeiroViajanteReducer extends Reducer<IntWritable, Individuo, DoubleWritable, Text> { private ArrayList<Individuo> populacao = new ArrayList<Individuo>(); private OperacaoGenetica operacaoGenetica; @Override public void reduce(IntWritable key, Iterable<Individuo> values, Context context) throws IOException, InterruptedException { operacaoGenetica = new OperacaoGenetica(); operacaoGenetica.setTaxaMutacao(0.9); for (Individuo val : values) {populacao.add(val); } if(populacao.size() == 1) { operacaoGenetica.setMelhorIndividuo(populacao.get(0)); } int CondicaoDeParada = 10; int geracao = 0; while (geracao < CondicaoDeParada) { populacao = operacaoGenetica.selecao(populacao); populacao = operacaoGenetica.cruzamento(populacao); populacao = operacaoGenetica.mutacao(populacao); populacao = operacaoGenetica.calcularAptidao(populacao); geracao++; } Individuo ind = operacaoGenetica.getMelhorIndividuo(); context.write(new DoubleWritable(ind.getAptidao()), new Text(ind.getCromossomo())); populacao.clear(); } }

Implementação da classe CaixeiroViajante .

import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.DoubleWritable; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class CaixeiroViajante { public static void main(String[] args) throws Exception { if (args.length != 2) { args = new String[2]; args[0] = System.getProperty("user.dir") + "/Input"; args[1] = System.getProperty("user.dir") + "/Output"; } Job job = new Job(); job.setJarByClass(CaixeiroViajante.class); job.setJobName("Problema do Caixeiro Viajante");

Page 88: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

87

FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(CaixeiroViajanteMapper.class); job.setReducerClass(CaixeiroViajanteReducer.class); job.setMapOutputKeyClass(IntWritable.class); job.setMapOutputValueClass(Individuo.class); job.setOutputKeyClass(DoubleWritable.class); job.setOutputValueClass(Text.class); System.exit(job.waitForCompletion(true) ? 0 : 1); } }

Implementação da classe OperacaoGenetica.

import java.io.IOException; import java.util.ArrayList; import java.util.Random; public class OperacaoGenetica { private Individuo melhorIndividuo = new Individuo(); private int tamanhoIndividuo = 20; private double taxaMutacao = 5/100; private String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private int[][] distancias = { { 1, 8 }, { 1,10 }, { 2,13 }, { 3,15 }, { 5,16 }, { 8,17 }, { 10,17}, { 13,16}, { 15,15}, { 16,13}, { 17,10}, { 17,8 }, { 16,5 }, { 15,3 }, { 13,2 }, { 10,1 }, { 8, 1 }, { 5, 2 }, { 3, 3 }, { 2, 5 } }; public ArrayList<Individuo> calcularAptidao(ArrayList<Individuo> populacao) throws IOException { ArrayList<Individuo> popula = new ArrayList<Individuo>(); double aptidao =0; int x1, x2, y1, y2, pos; String[] indString; for (Individuo indi : populacao) { indString = new String[tamanhoIndividuo]; indString = indi.getIndArray(); for (int j = 0; j < tamanhoIndividuo; j++) { pos = alfabeto.indexOf(indString[j]); x1 = distancias[pos][0]; y1 = distancias[pos][1]; pos=alfabeto.indexOf(indString[(j+1)%tamanhoIndividuo]); x2 = distancias[pos][0]; y2 = distancias[pos][1]; aptidao+=Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2)); } indi.setAptidao(aptidao); setMelhorIndividuo(indi); popula.add(indi); aptidao = 0; } return popula; } public ArrayList<Individuo> selecao( ArrayList<Individuo> populacao) throws IOException { int tamanhoPop = populacao.size(); Individuo[] popula = new Individuo[tamanhoPop]; popula = populacao.toArray(popula);

Page 89: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

88

popula = QuickSort(popula, 0, tamanhoPop - 1); populacao.clear(); for(int i=0;i<(popula.length*(1-0.3));i++){populacao.add(popula[i]);} for(int i=0; i<(popula.length*0.3); i++){populacao.add(popula[i]);} return populacao; } private Individuo[] QuickSort(Individuo[] pop, int inicio, int fim) { int meio; if (inicio < fim) { int topo, indice; Individuo pivo; pivo = pop[inicio]; topo = inicio; for (indice = inicio + 1; indice <= fim; indice++) { if (pop[indice].getAptidao() < pivo.getAptidao()) { pop[topo] = pop[indice]; pop[indice] = pop[topo + 1]; topo++; } } pop[topo] = pivo; meio = topo; QuickSort(pop, inicio, meio); QuickSort(pop, meio + 1, fim); } return pop; } public ArrayList<Individuo> cruzamento(ArrayList<Individuo> populacaoA) throws IOException { int tamanhoPop = populacaoA.size(); Individuo[] populacao = new Individuo[tamanhoPop]; populacao = populacaoA.toArray(populacao); populacaoA.clear(); String[] indPai1,indPai2, indFilho1, indFilho2; int pp = 3, sp = 7, k, c1, c2; int tamanhoSecao = (int) tamanhoIndividuo/2; Random r = new Random(); boolean presente; for (int i = 0; i < tamanhoPop; i += 2) { indFilho1 = new String[tamanhoIndividuo]; indFilho2 = new String[tamanhoIndividuo]; pp = r.nextInt(tamanhoSecao - 1); sp = pp+tamanhoSecao; if (i + 1 < tamanhoPop) { indPai1 = populacao[i].getIndArray(); indPai2 = populacao[i + 1].getIndArray(); for (int c = pp; c <= sp; c++) { indFilho1[c] = indPai1[c]; indFilho2[c] = indPai2[c]; } c1 = sp + 1; c2 = sp + 1; for (int j=sp+1; j!=pp; j=(j + 1)%tamanhoIndividuo) { do { presente = false; for (k = pp; k <= sp; k++) { presente |= indPai2[c2].equals(indFilho1[k]);} if (!presente) {indFilho1[j] = indPai2[c2];} c2 = (c2 + 1) % tamanhoIndividuo;

Page 90: Aplicação da Técnica Mapreduce na Modelagem de Algoritmos Genéticos para o “Problema do Caixeiro Viajante”

89

} while (presente); do { presente = false; for (k = pp; k <= sp; k++) { presente |= indPai1[c1].equals(indFilho2[k]);} if (!presente) {indFilho2[j] = indPai1[c1];} c1 = (c1 + 1) % tamanhoIndividuo; } while (presente); } Individuo indF1 = new Individuo(); Individuo indF2 = new Individuo(); indF1.setIndArray(indFilho1); indF2.setIndArray(indFilho2); populacaoA.add(indF1); populacaoA.add(indF2); } else { populacaoA.add(populacao[i]); } } return populacaoA; } public ArrayList<Individuo> mutacao(ArrayList<Individuo> populacao) throws IOException { int tamanhoPop = populacao.size(); String cidade; String[] indString; Individuo indi; Random indRandom = new Random(); int ri, rc1, rc2; if(tamanhoPop == 1){taxaMutacao = 1;} for (int i = 0; i < tamanhoPop * taxaMutacao; i++) { ri = indRandom.nextInt(tamanhoPop); indi = populacao.get(ri); indString = indi.getIndArray(); rc1 = indRandom.nextInt(tamanhoIndividuo); rc2 = indRandom.nextInt(tamanhoIndividuo); cidade = indString[rc1]; indString[rc1] = indString[rc2]; indString[rc2] = cidade; indi.setIndArray(indString); populacao.set(ri, indi); } return populacao; } public Individuo getMelhorIndividuo() {return melhorIndividuo;} public void setMelhorIndividuo(Individuo ind) { if (getMelhorIndividuo().getAptidao() == 0 || getMelhorIndividuo().getAptidao() > ind.getAptidao()){ Individuo MelhorInd = new Individuo(); MelhorInd.setCromossomo(ind.getCromossomo()); MelhorInd.setAptidao(ind.getAptidao()); this.melhorIndividuo = MelhorInd; } } public double getTaxaMutacao(){return this.taxaMutacao;} public void setTaxaMutacao(double taxa){this.taxaMutacao = taxa; } }