Um Jogo de Othello Evolutivo

70
Trabalho de Conclusão de Curso Um Jogo de Othello Evolutivo Anderson Lemos Camelo [email protected] Orientador: Roberta Vilhena Vieira Lopes Co-orientador: Valter Wellington Ramos Junior Maceió, Abril de 2011

description

Os jogos eletrônicos são uma das formas de entretenimento de mais sucesso no mundo. Desde a sua criação eles estão em um processo de constante evolução, onde os fabricantes procurammelhorar a sua qualidade empregando técnicas de diversas áreas de pesquisa da computação no seu desenvolvimento.Atualmente, o maior desafio para os desenvolvedores de jogos é a criação de um jogo com um bom desafio para o jogador, já que os jogos alcançaram um patamar gráfico e sonoro bem próximo da realidade. Diversos algoritmos já estão sendo testados pelas produtoras de jogos com o intuito de simular uma inteligência humana convincente.Assim, com objetivo de validar novas técnicas de Inteligência Artificial para jogos, este trabalho propõe uma análise comparativa entre novos e antigos algoritmos representados, respectivamente, pelas técnicas de Algoritmos Genéticos e Poda alfa-beta, utilizados na estrutura de tomada de decisão de jogos eletrônicos.Esse pensamento levou ao desenvolvimento de um jogo de tabuleiro conhecido como Othello. Um jogo onde é necessário que se tenha um mínimo de estratégia para alcançar a vitória. O desenvolvimento desse jogo vai servir para avaliação do desempenho desses algoritmos aplicados em um ambiente de tomada de decisão, onde existe ainda o índice de incerteza proporcionado pela a contínua interação com o usuário.No fim, será realizado um estudo de caso com o intuito de analisar os pontos fortes e fracos de cada uma dessas abordagens.

Transcript of Um Jogo de Othello Evolutivo

Trabalho de Conclusão de Curso

Um Jogo de Othello Evolutivo

Anderson Lemos [email protected]

Orientador:Roberta Vilhena Vieira Lopes

Co-orientador:Valter Wellington Ramos Junior

Maceió, Abril de 2011

Anderson Lemos Camelo

Um Jogo de Othello Evolutivo

Monografia apresentada como requisito parcial paraobtenção do grau de Bacharel em Ciência da Com-putação do Instituto de Computação da UniversidadeFederal de Alagoas.

Orientador:

Roberta Vilhena Vieira Lopes

Co-orientador:

Valter Wellington Ramos Junior

Maceió, Abril de 2011

Monografia apresentada como requisito parcial para obtenção do grau de Bacharel em Ciên-cia da Computação do Instituto de Computação da Universidade Federal de Alagoas, aprovadapela comissão examinadora que abaixo assina.

Roberta Vilhena Vieira Lopes - OrientadorInstituto de Computação, Campus A. C. Simões

Universidade Federal de Alagoas

Valter Wellington Ramos Junior - Co-orientadorComputação

FAA-IESA/FACIMA

Luiz Cláudius Coradine - ExaminadorInstituto de Computação

Universidade Federal de Alagoas

Manoel Agamemnon Lopes - ExaminadorInstituto de Computação

Universidade Federal de Alagoas

Maceió, Abril de 2011

Resumo

Os jogos eletrônicos são uma das formas de entretenimento de mais sucesso no mundo. Desdea sua criação eles estão em um processo de constante evolução, onde os fabricantes procurammelhorar a sua qualidade empregando técnicas de diversas áreas de pesquisa da computação noseu desenvolvimento.

Atualmente, o maior desafio para os desenvolvedores de jogos é a criação de um jogo comum bom desafio para o jogador, já que os jogos alcançaram um patamar gráfico e sonoro bempróximo da realidade. Diversos algoritmos já estão sendo testados pelas produtoras de jogoscom o intuito de simular uma inteligência humana convincente.

Assim, com objetivo de validar novas técnicas de Inteligência Artificial para jogos, estetrabalho propõe uma análise comparativa entre novos e antigos algoritmos representados, res-pectivamente, pelas técnicas de Algoritmos Genéticos e Poda alfa-beta, utilizados na estruturade tomada de decisão de jogos eletrônicos.

Esse pensamento levou ao desenvolvimento de um jogo de tabuleiro conhecido como Othello.Um jogo onde é necessário que se tenha um mínimo de estratégia para alcançar a vitória. O de-senvolvimento desse jogo vai servir para avaliação do desempenho desses algoritmos aplicadosem um ambiente de tomada de decisão, onde existe ainda o índice de incerteza proporcionadopela a contínua interação com o usuário.

No fim, será realizado um estudo de caso com o intuito de analisar os pontos fortes e fracosde cada uma dessas abordagens.

Palavras-chave: Inteligência Artificial, Algoritmos Genéticos, Poda alfa-beta, Jogos deTabuleiro e Othello.

i

Abstract

Video games are one of the most successful entertainment in the world. Since its creation theyare in a constant process of evolution, where developers seek to improve their quality usingtechniques from diverse areas of computing research in its development.

Currently, the biggest challenge for game developers is to create a game with a good chal-lenge for the player as the games reached a level of graphics and sound very close to reality.Several algorithms are already being tested by the game companies in order to simulate a con-vincing human intelligence.

Thus, in order to validate the new artificial intelligence techniques for games, this paperproposes a comparative analysis between new and old algorithms represented respectively bythe techniques of Genetic Algorithms and alpha-beta Pruning, used in decision-making structureof electronic games.

This thought led to the development of a board game called Othello. A game where it isnecessary to have a minimum strategy for victory. The development of this game will serve toevaluate the performance of these algorithms applied in a decision-making environment, wherethere is still the uncertainty provided by the continuous interaction with the user.

In the end, there will be a case study in order to analyze the strengths and weaknesses ofeach approach.

Keywords: Artificial Intelligence, Genetic Algorithms, alfa-beta Pruning, Board Game andOthello.

ii

Agradecimentos

O período de realização desse trabalho de conclusão de curso, foi marcado por uma fase bastanteagitada da minha vida, causada principalmente pelo meu ingresso no mercado de trabalho queacabou me afastando da área acadêmica e, conseqüentemente, atrasando a sua elaboração.

Para que eu pudesse encontrar a força e o incentivo necessários para transpor os obstáculose as dificuldades encontradas durante esse período foi necessário fé e o apoio de muitas pessoas,sendo algumas delas fundamentais.

Sendo assim, agradeço primeiro a Deus, afinal é ele quem escreve certo por linhas tortas.Em segundo lugar, agradeço a minha família pelo amor e a cumplicidade durante esse pe-

ríodo tão difícil.Agradeço aos grandes amigos, Dalton Eugênio de Barros, nós somos a prova viva de que

não se vence uma guerra lutando sozinho; e Rui Braga das Chagas Júnior, pela amizade e,principalmente, por me lembrar dia após dia que eu não era nada sem um diploma.

Agradeço a Prof.a Dr.a Roberta Vilhena Vieira Lopes, minha orientadora, por fornecer oestímulo inicial e os subsídios necessários para uma primeira reflexão sobre o tema.

Agradeço também a Lucas Cherem de Camargo Rodrigues, exímio jogador de Othello, poraceitar testar essa aplicação.

Agradeço as bandas a-ha e The Cranberries, por fazerem parte da trilha sonora da minhavida.

Por último, mas não menos importante, agradeço a todas as pessoas que duvidaram da minhacapacidade e colocaram meu talento a prova.

iii

Sumário

1 Introdução 11.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Minimax 32.1 História . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 O Algoritmo Minimax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3 A Poda alfa-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3 Algoritmo Genético 123.1 História . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.2 Fundamentos Biológicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3 O Algoritmo Genético . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.4 Codificação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3.4.1 Codificação Binária . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.4.2 Codificação por Permutação . . . . . . . . . . . . . . . . . . . . . . . 23

3.5 Operadores Genéticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.5.1 Cruzamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.5.2 Mutação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.6 Avaliação e Seleção de Cromossomos . . . . . . . . . . . . . . . . . . . . . . 283.7 Parâmetros de um Algoritmo Genético . . . . . . . . . . . . . . . . . . . . . . 30

4 Othello 324.1 História . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.2 Regras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

4.2.1 Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.2.2 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.2.3 Preparação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.2.4 O Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.2.5 Fim de Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364.2.6 Vencedor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5 Desenvolvimento da Aplicação 375.1 Linguagem e ferramentas utilizadas para o desenvolvimento . . . . . . . . . . 375.2 Arquitetura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.2.1 Pacote GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395.2.2 Pacote Domínio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

iv

SUMÁRIO v

5.2.3 Pacote IA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.3 Forma de implementação dos Algoritmos . . . . . . . . . . . . . . . . . . . . 45

5.3.1 Implementação da Poda alfa-beta . . . . . . . . . . . . . . . . . . . . 455.3.2 Implementação do Algoritmo Genético . . . . . . . . . . . . . . . . . 47

5.4 Aplicação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.5 Outras Implementações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6 Estudo de Caso 53

7 Conclusão e Trabalhos Futuros 567.1 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Lista de Figuras

2.1 John von Neumann . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Exemplo de árvore de decisão para o Jogo da Velha . . . . . . . . . . . . . . . 62.3 Heurística de conflito aplicada aos estados do Jogo da Velha . . . . . . . . . . 72.4 Exemplo de Minimax com antecipação de dois níveis . . . . . . . . . . . . . . 72.5 Exemplo de Minimax com poda alfa-beta . . . . . . . . . . . . . . . . . . . . 10

3.1 John H. Holland . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 Teoria da seleção natural de Darwin aplicada ao pescoço da girafa . . . . . . . 153.3 Exemplo de cromossomo com codificação binária . . . . . . . . . . . . . . . . 163.4 População P(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.5 Cálculo da função de aptidão de P(0) . . . . . . . . . . . . . . . . . . . . . . . 173.6 Pares selecionados da população P(0) . . . . . . . . . . . . . . . . . . . . . . 173.7 Cruzamento do primeiro par de indivíduos selecionados de P(0) . . . . . . . . 183.8 Cruzamento do segundo par de indivíduos selecionados de P(0) . . . . . . . . . 193.9 População P(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.10 Cálculo da função de aptidão de P(1) . . . . . . . . . . . . . . . . . . . . . . . 193.11 Pares selecionados da população P(1) . . . . . . . . . . . . . . . . . . . . . . 203.12 Cruzamento do primeiro par de indivíduos selecionados de P(1) . . . . . . . . 203.13 Transmissão do segundo par de indivíduos de P(1) para a geração seguinte . . . 213.14 População P(2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.15 Cálculo da função de aptidão de P(2) . . . . . . . . . . . . . . . . . . . . . . . 213.16 AG visualizado como método paralelo de subida de encosta . . . . . . . . . . . 223.17 Exemplo de cromossomos com codificação binária . . . . . . . . . . . . . . . 233.18 Exemplo de cromossomo com codificação por permutação . . . . . . . . . . . 233.19 Exemplo de cruzamento uniponto . . . . . . . . . . . . . . . . . . . . . . . . 253.20 Exemplo de cruzamento multiponto . . . . . . . . . . . . . . . . . . . . . . . 253.21 Exemplo de cruzamento uniforme . . . . . . . . . . . . . . . . . . . . . . . . 253.22 Exemplo de cruzamento ordenado . . . . . . . . . . . . . . . . . . . . . . . . 263.23 Exemplo de cruzamento parcialmente mapeado . . . . . . . . . . . . . . . . . 273.24 Exemplo de cruzamento circular . . . . . . . . . . . . . . . . . . . . . . . . . 273.25 Exemplo de mutação binária . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.26 Exemplo de mutação com troca recíproca . . . . . . . . . . . . . . . . . . . . 283.27 Exemplo de seleção por roleta . . . . . . . . . . . . . . . . . . . . . . . . . . 293.28 Exemplo de seleção por classificação . . . . . . . . . . . . . . . . . . . . . . . 30

4.1 Tabuleiro do jogo Go, de origem chinesa . . . . . . . . . . . . . . . . . . . . . 324.2 Configuração inicial do tabuleiro de Othello . . . . . . . . . . . . . . . . . . . 344.3 Exemplo de uma possível jogada inicial . . . . . . . . . . . . . . . . . . . . . 34

vi

LISTA DE FIGURAS vii

4.4 Três possibilidades de jogadas para as peças brancas . . . . . . . . . . . . . . 344.5 Exemplo de jogada inválida por espaço em branco . . . . . . . . . . . . . . . . 354.6 Exemplo de boa jogada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.7 Exemplo de uma tentativa inválida de virar peças por tabela . . . . . . . . . . . 364.8 Resultado da jogada da figura 4.7 . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.1 Diagrama de pacotes da aplicação . . . . . . . . . . . . . . . . . . . . . . . . 385.2 Diagrama de classes simplificado do pacote gui . . . . . . . . . . . . . . . . . 405.3 Diagrama de classes simplificado do pacote domínio . . . . . . . . . . . . . . 415.4 Diagrama de classes simplificado do pacote minimax . . . . . . . . . . . . . . 425.5 Diagrama de classes simplificado do pacote ag . . . . . . . . . . . . . . . . . . 435.6 Avaliação estática do tabuleiro do jogo Othello . . . . . . . . . . . . . . . . . 465.7 Exemplo de estado do jogo Othello . . . . . . . . . . . . . . . . . . . . . . . . 465.8 Tabela de dificuldade da Poda alfa-beta . . . . . . . . . . . . . . . . . . . . . 475.9 Coordenadas do tabuleiro de Othello . . . . . . . . . . . . . . . . . . . . . . . 475.10 Exemplo de codificação para o jogo Othello . . . . . . . . . . . . . . . . . . . 485.11 Exemplo de população intercalada usada para cálculo de aptidão . . . . . . . . 495.12 Exemplo de cromossomo intercalado usado para cálculo de aptidão . . . . . . . 495.13 Tabela de dificuldade do Algoritmo Genético . . . . . . . . . . . . . . . . . . 515.14 Interface gráfica da aplicação . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.15 Interface gráfica de configuração do jogo . . . . . . . . . . . . . . . . . . . . . 52

6.1 Gráfico de tempo médio de resposta dos algoritmos . . . . . . . . . . . . . . . 546.2 Gráfico de pontuação média dos algoritmos . . . . . . . . . . . . . . . . . . . 556.3 Gráfico de vitórias dos algoritmos . . . . . . . . . . . . . . . . . . . . . . . . 55

Lista de Tabelas

6.1 Resumo dos resultados obtidos após a execução da classe de benchmark . . . . 53

viii

Capítulo 1

Introdução

Segundo VIEIRA FILHO (2005), a Inteligência Artificial (IA), vem sendo aplicada em jogosdesde os anos 70, onde surgiram os primeiros jogos simples e de recursos escassos. Muitos pro-gramadores dessa época implementavam padrões de movimentos ou movimentos repetitivose/ou aleatórios para os personagens controlados pelo computador como sendo a única inteli-gência existente no jogo (SCHWAB, 2004). No decorrer dos anos a IA em jogos teve umcrescimento tímido em relação ao crescimento da IA como um todo. Até recentemente as em-presas desenvolvedoras de jogos não faziam nenhum esforço para melhorar a IA dos jogos queproduziam.

No início do século XXI os jogos de computador vêm se tornando cada vez mais realistas,o que atrai novos jogadores e aumentam os lucros dos fabricantes. Nesse processo de buscapor mais realismo pode-se citar a melhoria dos gráficos do jogo, o que implica em melhoriados componentes de hardware, melhoria dos enredos, melhoria da jogabilidade e, despontandocomo fator diferencial, melhoria da inteligência artificial. Os jogadores sempre buscam um jogoque não seja nem muito fácil e nem muito difícil ao ponto de ser impossível de se completar oobjetivo, eles buscam um jogo onde predomine o equilíbrio de dificuldade. Para alcançar esseequilíbrio é necessário recorrer a IA, pois é ela quem concede ao computador uma inteligênciasemelhante a que os humanos possuem, tornando o jogo mais interessante e realista.

1.1 Motivação

Diante do grande crescimento do mercado de jogos eletrônicos, verificou-se a necessidade deestudar com mais detalhes o desempenho de novos algoritmos de Inteligência Artificial. As-sim, este trabalho se propõe a analisar os impactos da utilização de algoritmos evolucionáriospara solucionar problemas que antes eram resolvidos por algoritmos de busca seqüencial. O al-goritmo evolucionário que será foco de estudo é o Algoritmo Genético, e seu desempenho serácomparado ao de um algoritmo tradicional de busca seqüencial conhecido como Poda alfa-beta,ambos aplicados sobre o mesmo domínio, o do jogo de tabuleiro chamado Othello. A natureza

1

1.2. OBJETIVO 2

impar e a simplicidade desse jogo, em comparação a outros jogos de tabuleiro, foram fatoresdecisivos para sua escolha, o que torna possível focar as atenções no estudo dos dois algorit-mos. O diferencial deste trabalho consiste no fato de que o Algoritmo Genético será aplicadodiretamente na estrutura da tomada de decisão da aplicação ao invés de ser utilizado no ajustedo comportamento, isto é, do desempenho da aplicação, prática que já se tornou tradição nodesenvolvimento de jogos de computador.

1.2 Objetivo

O objetivo desse trabalho é implementar um jogo virtual de Othello onde o jogador poderádecidir entre enfrentar um computador que simula o comportamento de um jogador humanopor meio de Algoritmo Genético ou de Poda alfa-beta. Ao fim da fase de desenvolvimento,será realizado um estudo de caso com o intuito de analisar os pontos fortes e fracos de cada umdesses algoritmos.

1.3 Descrição

Esse trabalho se inicia com a apresentação das duas técnicas de Inteligência Artificial estuda-das, a fim de deixar o leitor a par da história e dos conceitos de cada um dos algoritmos. Assim,no capítulo 2 será estudado o algoritmo Minimax e sua otimização através da técnica de Podaalfa-beta. Em seguida, no capítulo 3, serão explicados os conceitos evolucionários do Algo-ritmo Genético. No capítulo 4 será apresentado o domínio da aplicação na forma do jogo dojogo Othello. No capítulo 5 serão explicados todos os detalhes envolvidos no processo de de-senvolvimento da aplicação. No capitulo 6 será apresentado um estudo de caso com o objetivode analisar os resultados obtidos. Por último, no capítulo 7 será feita as considerações finaissobre esse trabalho.

Capítulo 2

Minimax

O algoritmo Minimax faz parte de uma família de algoritmos de busca seqüencial usado, princi-palmente, nas áreas de teoria da decisão, teoria dos jogos, estatísticas e filosofia, para minimizara perda máxima possível em situações de conflito entre duas ou mais partes com interesses opos-tos. O algoritmo Minimax foi inspirado nos conceitos matemáticos da teoria dos jogos, sendoinicialmente aplicado em jogos de soma zero, abrangendo tanto as situações nas quais os joga-dores fazem jogadas alternadas quanto simultâneas, tendo sido depois expandido a jogos maiscomplexos e à tomada de decisões na presença de incerteza.

Uma versão simples deste algoritmo lida com jogos de tabuleiro nos quais um jogador podeperder, empatar ou ganhar. Se o jogador A pode ganhar com apenas uma jogada, então a suamelhor jogada será essa. Se o jogador B sabe que uma determinada jogada pode levar o jogadorA a ganhar com apenas uma jogada, enquanto que outra jogada pode levar o jogador A a nomáximo empatar, então a sua melhor jogada será essa. Com o avanço do jogo, torna-se fácil verqual é a melhor jogada. O algoritmo Minimax ajuda a encontrar a melhor jogada, começandodo fim para o início do jogo; em cada passo assume-se que o jogador A está a tentar maximizaras suas chances de ganhar, enquanto que o jogador B está a tentar minimizar as chances de Aganhar.

2.1 História

Registros antigos sobre teoria dos jogos remontam ao ano de 1713. Em correspondência di-rigida a Nicolas Bernoulli, James Waldegrave propõem uma solução de estratégia mista deMinimax para a versão de duas pessoas do jogo “le Her”. Contudo, Waldegrave não estendeusua abordagem para uma teoria geral. No ano de 1913, Ernst Zermelo publicou o primeiroteorema matemático da teoria dos jogos, o teorema afirma que o jogo de xadrez é estritamentedeterminado, isto é, em cada estágio do jogo pelo menos um dos jogadores tem uma estratégiaem mão que lhe dará a vitória ou conduzirá o jogo ao empate. Outro grande matemático quese interessou em jogos foi Emile Borel, que reinventou as soluções Minimax e publicou quatro

3

2.2. O ALGORITMO MINIMAX 4

artigos sobre jogos estratégicos. Ele achava que a guerra e a economia podiam ser estudadas deuma maneira semelhante (SARTINI & GARBUGIO, 2004).

Em seu início, a teoria dos jogos chamou pouca atenção. O grande matemático John vonNeumann mudou esta situação. Em 1928, ele demonstrou que todo jogo finito de soma zerocom duas pessoas possui uma solução em estratégias mistas. A demonstração original usavatopologia e análise funcional e era muito complicada de se acompanhar. Em 1937, ele forneceuuma nova demonstração baseada no teorema do ponto fixo de Brouwer. John von Neumann, quetrabalhava em muitas áreas da ciência, mostrou interesse em economia e, junto com o econo-mista Oscar Morgenstern, publicou o clássico The Theory of Games and Economic Behaviour

em 1944 e, com isto, a teoria dos jogos invadiu a economia e a matemática aplicada (SARTINI& GARBUGIO, 2004).

Figura 2.1: John von Neumann

2.2 O Algoritmo Minimax

Segundo LUGER (2004), em jogos cujo espaço de estado pode ser exaustivamente delineado, adificuldade primordial é levar em conta as ações do adversário. Para isso, é necessário assumirque o adversário usa o mesmo conhecimento sobre o espaço de estados que você e que aplicaeste conhecimento num esforço consistente para vencer o jogo.

O Minimax busca o espaço do jogo levando em consideração a existência de um oponente“hostil” e essencialmente imprevisível, para tanto, ele simula um jogo entre dois jogares cha-mados de MIN e MAX. O significado destes nomes pode ser entendido facilmente: MAXrepresenta o jogador que tenta vencer, ou MAXimizar a sua vantagem. MIN é o adversário quetenta MINimizar o escore de MAX (LUGER, 2004).

Dado um jogo entre esses dois jogadores, MIN e MAX, o jogo começa com uma jogada deMAX que se reveza com MIN realizando jogadas até o jogo terminar. Ao fim do jogo, o ven-cedor é premiado e o perdedor é penalizado. Segundo RUSSUEL & NORVIG (2004), um jogodesse tipo pode ser definido como um problema de busca e possui os seguintes componentes:

• Estado inicial: consiste numa posição qualquer no tabuleiro e identifica o jogador queiniciará jogando.

2.2. O ALGORITMO MINIMAX 5

• Função sucessor: função que aponta os possíveis movimentos válidos para o estado atual.

• Teste de término: função que determina em quais estados o jogo chega ao fim, essesestados são chamados estado terminais.

• Função utilidade: função que dá um valor mensurável aos estados terminais. Esses valo-res informarão ao algoritmo se essa solução é boa ou ruim.

A partir do estado inicial, o algoritmo desenvolve uma árvore de busca atribuído um estadopara cada um de seus nós e rotulando cada nível dessa árvore de acordo com quem está reali-zando o movimento naquele ponto do jogo, MIN ou MAX. Em cada nó, o jogador da vez usa afunção sucessor para determinar seu conjunto de possíveis jogadas, e cada uma delas leva a umnó situado em um nível abaixo, formando a árvore de jogadas até os estados finais. O algoritmoMinimax calcula valor de cada solução a partir do estado inicial, utilizando computação recur-siva simples dos valores de cada estado sucessor. O método recursivo percorre um caminhodescendente até chegar às folhas da árvore onde é usada a função utilidade para descobrir osvalores de cada nó folha da árvore e depois esse valor é retornado até o nó raiz do algoritmo debusca (RUSSUELL & NORVIG, 2004).

Segue abaixo uma explicação superficial das principais etapas do algoritmo Minimax:

1. Gerar toda a árvore do jogo;

2. Aplicar a função utilidade a cada estado terminal;

3. Propagar a utilidade dos nós terminais para níveis superiores:

(a) Quando no nível superior é a vez de MIN fazer um movimento, escolher o menorvalor.

(b) Quando no nível superior é a vez de MAX fazer um movimento, escolher o maiorvalor.

4. No nodo raiz, MAX escolhe o movimento que leva ao maior valor.

Um bom exemplo sobre o funcionamento do algoritmo Minimax pode ser descrito pelafigura 2.2. A partir do estado inicial MAX tem nove movimentos possíveis. O jogo vai sealterando com a colocação de um X por MAX e a colocação de um O por MIN até ser alcançadonós de folhas que correspondem ao estado terminal, ou seja, o jogador deve ter três símbolosem uma linha ou todos os quadrados são preenchidos. O número em cada nó representa o valorde utilidade do estado terminal, nesse caso os valores 1, -1 e 0, sendo os valores altos bons paraMAX e valores baixos bons para MIN. Após esses valores serem propagados de volta para onodo raiz, cabe a MAX usar essa informação para escolher sua melhor jogada (RUSSUELL &NORVIG, 2004).

2.2. O ALGORITMO MINIMAX 6

Figura 2.2: Exemplo de árvore de decisão para o Jogo da Velha

Segundo LUGER (2004), ao se aplicar Minimax a jogos mais complicados, raramente épossível expandir o grafo de espaço até os nós folhas. Em vez disso, o espaço de estadosé buscado até um número de níveis predefinido, conforme os recursos disponíveis de tempoe memória. Esta estratégia é chamada de antecipação para n níveis, onde n é o número deníveis a serem explorados. Como as folhas deste subgrafo não são estados finais do jogo, não épossível atribuí-lhes valores que reflitam uma vitória ou uma derrota. Em vez disso, atribui-sea cada nó um valor de acordo com alguma função de avaliação heurística de modo que o valordessa função se aproxime ao máximo do resultado obtido pela função utilidade. O valor que épropagado de volta ao nó raiz não é uma indicação de que uma vitória pode ou não ser alcançadacomo na figura 2.2, é simplesmente o valor heurístico do melhor estado que pode ser alcançadoem n movimentos a partir do nó inicial.

O primeiro passo para se minimaximizar para um número fixo de níveis é definir uma funçãoheurística que nos passe informações mais detalhadas sobre o conflito ocorrido no jogo. Amaioria dos jogos de disputa entre dois jogadores usam uma forma simples de heurística noqual é medida a vantagem de um jogador sobre o outro. Em jogos como damas, a vantagemde peças é importante, assim uma heurística simples poderia calcular a diferença no número depeças pertencentes a MAX e a MIN e tentar maximizar a diferença entre estas medidas de peças.No caso do Jogo da Velha, jogo utilizado no cenário de explicação desse algoritmo, foi adotadauma heurística que calcula a diferença entre o número de retas (linhas, colunas ou diagonais)abertas para o jogador X e para o jogador O como mostra a figura 2.3:

2.2. O ALGORITMO MINIMAX 7

Figura 2.3: Heurística de conflito aplicada aos estados do Jogo da Velha

A partir de agora, usaremos o termo função utilidade para nos referir a heurística de apro-ximação definida como U(n) = X(n)−O(n), onde X(n) é o total de linhas vitoriosas possíveispara X, O(n) é o total de linhas vitoriosas possíveis para O e U(n) é a avaliação total do estadon.

A figura 2.4 mostra uma antecipação de dois níveis para o Jogo da Velha. Primeiro o al-goritmo escolhe o ramo a que representa uma possível jogada de MAX. Depois MIN precisarealizar uma jogada, ao escolher o ramo d o algoritmo chega a um nodo folha, nesse momento,o Minimax utiliza a função utilidade para descobrir o valor heurístico para a configuração atualdo tabuleiro e em seguida propaga o valor 1 para o nó acima. Esse processo é repetido nosramos e, f, g e h, onde se obtêm os valores 0, 1, 0 e -1 respectivamente. Agora o nodo MINprecisa escolher quais dessas jogadas é mais favorável a ele, o valor -1 é escolhido e propagadode volta. Esse mesmo processo volta a acontecer nos ramos b e c, onde se obtêm os valores -2e 1 respectivamente. Agora cabe ao nodo MAX escolher a jogada mais favorável entre a, b e c,o valor escolhido é o ramo de valor 1.

Figura 2.4: Exemplo de Minimax com antecipação de dois níveis

O processo descrito na figura 2.4 pode ser representado matematicamente pela resolução daequação abaixo:

MINIMAX(raiz) = max(a,b,c)

MINIMAX(raiz) = max(min(d,e, f ,g,h),min(i, j, l,m,n),min(o, p))

MINIMAX(raiz) = max(min(1,0,1,0,−1),min(−2,−1,0,−1,0),min(1,2))

2.3. A PODA ALFA-BETA 8

MINIMAX(raiz) = max(−1,−2,1)MINIMAX(raiz) = 1

O algoritmo Minimax executa uma exploração completa em profundidade de toda a árvoredo jogo. Se a profundidade é m e existem b movimentos o tempo que o algoritmo demorará emexecutar é de O(bm). A complexidade do espaço é definida por O(bm) para um algoritmo quegera todos os sucessores de uma vez ou O(m) para um algoritmo que gera um sucessor por vez.É claro que em jogos, o custo de tempo é totalmente impraticável, mas o algoritmo serve comobase para análise matemática de jogos e algoritmos práticos (RUSSUELL & NORVIG, 2004).

Abaixo o pseudocódigo do algoritmo Minimax:

ROTINA minimax(nó, profundidade)SE nó terminal OU profundidade = 0 ENTÃO

RETORNE o valor da heurística do nóFIM-SESE o nó representa a jogada de MAX ENTÃO

v←−∞

PARA CADA filho DE nóv← max(v, minimax(filho, profundidade-1))

FIM-PARARETORNE v

FIM-SESE o nó representa a jogada de MIN ENTÃO

v←+∞

PARA CADA filho DE nóv← min(v, minimax(filho, profundidade-1))

FIM-PARARETORNE v

FIM-SEFIM-ROTINA

2.3 A Poda alfa-beta

O grande problema do algoritmo Minimax é que o número de estados examinados no jogo éexponencial em relação ao número de movimentos. Para LUGER (2004), isso acontece porqueo algoritmo busca todos os ramos no espaço, incluindo muitos que poderiam ser ignoradosou podados por um algoritmo mais inteligente. Um método proposto no final dos anos 1950por Allen Newell e Herbert Simon para aperfeiçoar a busca do algoritmo Minimax é a Podaalfa-beta. Nela, o algoritmo elimina galhos da árvore que comprovadamente não podem trazer

2.3. A PODA ALFA-BETA 9

resultados melhores, interrompendo a busca naquele trecho da árvore. Desta forma, o tempode processamento é reduzido, mas o resultado da busca é o mesmo nas duas técnicas (KORF,1996).

A idéia para a busca alfa-beta é simples, dois valores chamados alfa e beta são criadosdurante a busca. O valor alfa, associado aos nós MAX, não pode decrescer, e o valor beta,associado aos nós MIN, não pode aumentar. Suponha que o valor MAX seja x. Então, MAXnão precisa considerar qualquer valor retropropagado menor ou igual a x que seja associadocom qualquer nó MIN abaixo dele. Alfa é o pior que MAX pode “marcar”, dado que MINtambém faça o “melhor” possível. Da mesma forma, se MIN tem um valor beta de y, ele nãoprecisa considerar qualquer nó MAX abaixo que tenha um valor maior ou igual a y (LUGER,2004).

A figura 2.5 mostra como seria a busca do exemplo da figura 2.4 usando a Poda alfa-beta.Inicialmente, o processo de busca é idêntico ao Minimax tradicional, ou seja, o algoritmo desceatravés do ramo a de MAX e do ramo d de MIN até encontrar um nodo folha onde faz uso dafunção utilidade para descobrir o valor heurístico do estado corrente. O valor 1 é propagado devolta para MIN que por sua vez atribui esse valor a beta, como o ancestral MAX não possui valoralfa a busca se repete nos ramos e, f, g e h, onde se obtêm os valores 0, 1, 0 e -1 respectivamente.Por fim, MIN escolhe o menor desses valores, atualiza o valor de beta para -1 e propaga essevalor para o nodo MAX que adiciona o valor -1 ao seu alfa. O algoritmo prossegue atravésdos ramos b de MAX e i de MIN até achar outro nodo folha. Ao aplicar a função utilidade éencontrado o valor -2 que em seguida é propagado de volta para o nodo MIN acima. Agora, MINatualiza seu valor beta corrente para -2 e diferentemente do que ocorreu nos ramos anteriores,o nodo MIN possui um ancestral MAX com valor alfa. Nesse instante, é feito o teste de cortebaseado nas seguintes regras:

• Poda Alfa: Se nó for MIN e seu ancestral MAX possuir valor al f a ≥ beta, então todosos ramos abaixo de MIN são podados.

• Poda Beta: Se nó for MAX e seu ancestral MIN possuir valor beta ≤ al f a, então todosos ramos abaixo de MAX são podados.

Então, ao realizarmos o teste de corte com os valores correntes de alfa e beta, temos −1≥−2, logo é realizada uma poda alfa no ramos j, l, m e n. Por último, o algoritmo avança nosramos c de MAX e o de MIN onde se depara novamente com um nodo folha. Ao aplicar afunção utilidade é encontrado o valor 1 que é retropropagado para MIN atualizar seu valor beta.Novamente, como MIN possui um ancestral MAX com valor alfa é realizado o teste de corte,al f a ≥ beta→−1 ≥ 1, logo, dessa vez não há poda e o algoritmo prossegue no ramo p ondeé encontrado o valor 2. O valor retorna para MIN, como esse é o último ramo pesquisado nãopode haver mais nenhuma poda, então MIN escolhe o menor valor entre 1 e 2, e propaga de

2.3. A PODA ALFA-BETA 10

volta para o nodo MAX acima. MAX por sua vez, escolhe o maior valor entre -1 e 1, e propagapara o nó raiz concluindo assim a busca com poda alfa-beta.

Figura 2.5: Exemplo de Minimax com poda alfa-beta

Assim como na figura 2.4, o processo descrito na figura 2.5 também pode ser representadomatematicamente pela resolução da equação abaixo:

MINIMAX(raiz) = max(a,b,c)

MINIMAX(raiz) = max(min(d,e, f ,g,h),min(i, j, l,m,n),min(o, p))

MINIMAX(raiz) = max(min(1,0,1,0,−1),min(−2,B,C,D,E),min(1,2))MINIMAX(raiz) = max(−1,A,1), onde A≤−2MINIMAX(raiz) = 1

A efetividade da Poda alfa-beta dependente da ordem que é feita a análise dos sucessores.Se por exemplo, na busca da figura 2.5, o algoritmo gerasse seus sucessores levando em con-sideração alguma estratégia não aleatória, a busca poderia ser iniciada pelo ramo c, assim, emvez de podarmos apenas quatro ramos (j, l, m e n) poderíamos podar até oito ramos (e, f, g, h,j, l, m e n).

Supondo que uma ordenação fortuita de estados no espaço de busca seja feita, então alfa-

beta precisará examinar apenas O(bm/2) nós para escolher entre o melhor, em vez de O(bm) doMinimax, significando um fator de ramificação efetivo igual a

√b em vez de b, com isso, alfa-

beta pode efetivamente dobrar a profundidade do espaço de busca com um compromisso fixo deespaço/tempo de computação. No caso de não haver ordenação, o número de nós examinadospor alfa-beta seria de O(b3m/4), ou seja, bem próximo ao número examinado por Minimax;entretanto, a busca é feita em apenas um passo.

Uma importante consideração sobre os procedimentos Minimax e Poda alfa-beta é que ava-liações em qualquer profundidade fixa podem ser muito enganosas. Quando uma heurísticaé aplicada com antecipação limitada, é possível que a profundidade da antecipação não possa

2.3. A PODA ALFA-BETA 11

detectar que um caminho heuristicamente promissor leve a uma situação ruim mais tarde nojogo. Se o seu adversário no jogo de xadrez oferecer uma torre como uma isca para pegar asua dama e a avaliação antecipar apenas até o nível em que a torre é oferecida, a avaliaçãoserá influenciada por este estado. Infelizmente, a seleção deste estado pode causar a perda dojogo! Este é o chamado efeito de horizonte. Ele é normalmente enfrentado avançando a buscamais profundamente por vários níveis para estados que parecem ser excepcionalmente bons.Entretanto, este aprofundamento seletivo da busca em áreas importantes não fará desaparecer oefeito horizonte. A busca precisa parar em algum lugar e ela será cega para os estados que seescondam além deste ponto (LUGER, 2004).

Abaixo o pseudocódigo da Poda alfa-beta:

ROTINA alfabeta(nó, profundidade, α, β)SE nó terminal OU profundidade = 0 ENTÃO

RETORNE o valor da heurística do nóFIM-SESE o nó representa a jogada de MAX ENTÃO

v←−∞

PARA CADA filho DE nóv← max(v, alfabeta (filho, profundidade-1, α, β))SE v = β ENTÃO

RETORNE vFIM-SEα← max(v, α)

FIM-PARARETORNE v

FIM-SESE o nó representa a jogada de MIN ENTÃO

v←+∞

PARA CADA filho DE nóv← min(v, minimax(filho, profundidade-1, α, β))SE v = α ENTÃO

RETORNE vFIM-SEβ← min(v, β)

FIM-PARARETORNE v

FIM-SEFIM-ROTINA

Onde o algoritmo é inicialmente chamado com α = -∞ e β = +∞.

Capítulo 3

Algoritmo Genético

Os Algoritmos Genéticos (AG) fazem parte de uma família de algoritmos de aprendizagem demáquina inspirados em analogias biológicas e podem ser utilizados para solucionar problemasde busca e otimização. AG tem suas raízes na Computação Evolucionária (CE) e propõemum modelo de aprendizagem que simulam a forma mais elegante e poderosa da natureza: aevolução de formas de vida de plantas e animais. Charles Darwin disse: “... não há limitespara a vida...”. Através de um processo simples de introdução de variações em gerações su-cessivas e eliminando seletivamente os indivíduos menos ajustados, emergem numa populaçãoadaptações de crescente capacidade e diversidade. Evolução e emergência ocorrem em popula-ções de indivíduos corporificados, cujas ações afetam outros indivíduos e que, por sua vez, sãoafetados por outros indivíduos. Assim, as pressões seletivas não surgem apenas do ambienteexterno, mas também de interações entre membros de uma população. Um ecossistema temmuitos membros, cada um com papéis e habilidades apropriadas à sua própria sobrevivência,mas mais importante que isso, cujo comportamento acumulativo molda e é moldado pelo restoda população (LUGER, 2004).

3.1 História

Historicamente, os primeiros passos na área de Computação Evolucionária aconteceram no iní-cio dos anos sessenta quando um grupo de biólogos e geneticistas tiveram a idéia de tentarsimular os processos vitais de um ser humano em um computador, o chamado “processo ge-nético”. Dentre os cientistas destacam-se os nomes de Barricelli, Fraser, Martin e Cockerham(GOLDBERG, 1989).

Nos anos seguintes, o biólogo Ingo Rosenberg introduziu o conceito de Estratégias Evo-lutivas. Em sua tese de doutorado, ele simulou uma população de seres unicelulares, comcromossomos de 20 genes e 16 alelos, enfatizando a mutação e recombinação como operadoresessenciais ao processo de busca e no espaço de parâmetros (GOLDBERG, 1989).

12

3.1. HISTÓRIA 13

No final dos anos sessenta, um estudante de doutorado chamado John H. Holland tentavadesenvolver um método computacional que se prestasse para abordar fenômenos gerados porsistemas adaptativos complexos. Os fenômenos gerados por estes sistemas são aqueles cujosresultados dependem das interações não lineares entre vários agentes adaptativos. Por exemplo,a seca do nordeste brasileiro é um fenômeno deste tipo (CARVALHO, 2008).

No decorrer do seu trabalho, Holland percebeu que existia uma nítida semelhança entre osfenômenos que estudava e o processo de evolução das espécies de Darwin, pois assim como àinteração entre os agentes adaptativos determinava o resultado dos fenômenos investigados porele, a interação entre os fatores ambientais determinava a próxima população de uma determi-nada região (CARVALHO, 2008).

Com base nesta constatação, Holland propôs um modelo de sistemas de aprendizagem demáquina conhecido como Algoritmos Genéticos. Tais modelos implementavam populaçõesde indivíduos contendo um genótipo, formado por cromossomos representados por cadeias de“bits” aos quais se aplicavam operadores de seleção, recombinação e mutação (DAVIS, 1991).Todo esse trabalho resultou no livro Adaptation in Natural and Artificial Systems publicado em1975, hoje considerado um clássico sobre Algoritmos Genéticos.

Figura 3.1: John H. Holland

Ainda nesse período, Bagley, utilizou em sua dissertação AG aplicados a representaçõesmais complexas, incluindo regras de produção, para evoluir conjuntos de regras adaptadas parainteragir com o ambiente dando origem aos chamados Sistemas Classificadores.

No início dos anos noventa, John Koza usou AG para combinar e aplicar mutação em frag-mentos de código de programas na tentativa de evoluir um programa de computador. Ele cha-mou seu método de Programação Genética. Foram usados programas em LISP porque progra-mas nessa linguagem podem ser expressos na forma de árvores, que são objetos utilizados pelosAG (OBITKO, 1998).

Nos últimos anos, AG tem se tornado objeto freqüente de estudo para pesquisadores decomunidades acadêmicas de todo o mundo, principalmente aqueles que procuram um métodoalternativo para encontrar boas soluções para os chamados problemas Polinomiais Não Deter-minísticos (NP) da qual fazem parte problemas como o do caixeiro viajante, do roteamento deveículos e o da satisfatibilidade booleana.

3.2. FUNDAMENTOS BIOLÓGICOS 14

3.2 Fundamentos Biológicos

A principal inspiração para o modelo de Algoritmos Genéticos proposto por Holland vem daSíntese Evolutiva Moderna, cuja base de seus conceitos vem da combinação da genética comobase para a herança biológica de Gregor Mendel e da teoria de evolução das espécies por meiode seleção natural de Charles Darwin.

Da genética, sabe-se que todos os organismos vivos são constituídos de células. No núcleode cada célula de um determinado organismo, existem cadeias de moléculas de ácido deso-xirribonucléico (DNA) onde estão gravadas suas características. Estas cadeias de DNA estãoassociadas com proteínas formando estruturas conhecidas como cromossomos. O cromossomoé constituído de genes, que são regiões nas moléculas de DNA que contém informação genéticaque codifica uma determinada proteína. Basicamente, podemos dizer que cada gene codificauma determinada feição, por exemplo, cor dos olhos. Conjunto de genes relacionados comdeterminada feição são chamados alelos. A posição específica que cada gene ocupa dentro docromossomo chamada de lócus. O conjunto completo de material genético formado por todosos cromossomos de um organismo é chamado genoma. O conjunto de todos os genes no ge-noma é o seu genótipo. O conjunto das características observáveis que compõem a estrutura eo comportamento de um organismo é denominado o seu fenótipo. Estas características surgemda interação do genótipo com o ambiente.

Durante a reprodução sexuada ocorre à troca de material genético entre os dois indivíduos.Através de um processo chamado meiose, o número de cromossomos de cada indivíduo é redu-zido à metade, e através da fecundação eles são combinados para formar novos cromossomosque dará origem a um novo indivíduo. Essa descendência recém criada pode sofrer uma mu-tação, ou seja, pequenas alterações acidentais ou induzidas nos genes, que poderão ter reper-cussões nas características do novo ser. O fenômeno da mutação tem uma probabilidade muitoreduzida. Quando acontece, o gene de um filho fica diferente do gene correspondente de ambosos pais.

Da teoria da evolução das espécies, sabe-se que a vida na terra começou com a evoluçãoda célula, a partir da qual se desenvolveram os organismos mais simples. Estes deram origemaos organismos mais complexos. Todos os novos genes e novas informações surgiram pormutação e recombinação. A seleção natural é o processo chave dessa teoria e age selecionandoas características apropriadas para melhorar a adaptação dos organismos. O conceito centralda seleção natural é a aptidão evolutiva de um organismo. Isto mede a contribuição genéticade um organismo para a geração seguinte. Contudo, não é o mesmo que o número total dedescendentes: a aptidão mede a proporção de gerações subsequentes que carregam os genes deum organismo. Por consequência, se um alelo aumenta a aptidão mais do que outros alelos domesmo gene, então em cada geração esse alelo tornar-se mais comum dentro da população. Se oambiente mudar, características que previamente eram neutras ou prejudiciais podem tornar-sebenéficas ou vice-versa.

3.3. O ALGORITMO GENÉTICO 15

Figura 3.2: Teoria da seleção natural de Darwin aplicada ao pescoço da girafa

Um bom exemplo sobre como a seleção natural pode agir sobre os indivíduos de uma dadapopulação em determinado ambiente pode ser descrito pela figura 3.2. Em um primeiro mo-mento, as girafas provavelmente apresentavam pescoços de comprimentos variáveis. Com otempo, a competição e a seleção natural levaram a sobrevivência das girafas de pescoço longo,um a vez que elas conseguiam alimentar-se melhor do que as girafas de pescoço curto. Por fim,apenas as girafas de pescoço longo sobreviveram à competição. Portanto, pela seleção naturalocorreu a evolução.

3.3 O Algoritmo Genético

Algoritmos Genéticos são baseados numa metáfora biológica: eles vêem o aprendizado comouma competição numa população de soluções evolutivas, candidatas para o problema. Umafunção “aptidão” avalia cada solução para decidir se ela contribuirá para a próxima geração desoluções. Então, através de operações análogas à transferência de genes na reprodução sexual,o algoritmo cria uma nova população de soluções candidatas (LUGER, 2004).

Segue abaixo o pseudocódigo do Algoritmo Genético. Suponha que P(t) defina uma popu-lação de soluções candidatas, xt

i , no tempo t: P(t) = xt1, xt

2, ..., xtn

ROTINA algoritmo genetico ()Ajuste o tempo t← 0;Gere uma população aleatória P(t);Avalie a aptidão de cada indivíduo da população P(t);ENQUANTO condição de parada não for satisfeita FAÇA

ENQUANTO população descendente P’(t) não estiver completa FAÇASelecione com base na aptidão um bom par de indivíduosde P(t) para produzir descendentes;Produza descendentes destes pares usandoos operadores genéticos Cruzamento e Mutação;

3.3. O ALGORITMO GENÉTICO 16

Adicione os descendentes gerados na população P’(t);ENQUANTO-FIMP(t)← P’(t);Ajuste o tempo t← t + 1;Avalie a aptidão de cada indivíduo da população P(t);

ENQUANTO-FIMRETORNE indivíduo com melhor aptidão de P(t);

ROTINA-FIM

Para entendermos melhor o funcionamento do algoritmo descrito acima, suponha que de-sejamos usar Algoritmos Genéticos para aprender a classificar cadeias de 0s e 1s com oitocaracteres de modo que após duas gerações nos retorne a solução mais próxima da soluçãoideal definida como 01010101.

A primeira coisa a se pensar é sobre como representar uma dada solução para o problemana estrutura genética de um cromossomo. Como nosso problema consiste numa cadeia bináriade bits, essa representação se dá de forma simples e natural com um cromossomo formado poroito genes, onde cada um desses genes codifica uma característica definida como 0 ou 1, comomostra a figura 3.3.

Figura 3.3: Exemplo de cromossomo com codificação binária

A segunda coisa a se pensar é sobre quais serão as condições de parada do algoritmo. Comonosso problema busca uma determinada solução, nada mais natural que definirmos essa soluçãocomo uma condição de parada para o algoritmo, ou seja, o algoritmo para após encontrar asolução ideal 01010101 com valor de aptidão igual a 8. No entanto, sabemos que a idéia básicado AG consiste em evoluir sua população de soluções durante várias gerações sem oferecernenhuma garantia de que a solução ideal seja realmente encontrada. Assim, é razoável definiruma segunda condição de parada para que o algoritmo não fique no chamado loop infinito.Uma boa condição seria definir um determinado número de gerações descendentes, no nossoproblema o algoritmo para quando a variável t for igual a 2.

Inicialmente, o algoritmo genético inicializa a variável t com valor zero e gera a popula-ção P(0) aleatoriamente. Por exemplo, considere que P(0) foi inicializado com a populaçãomostrada na figura 3.4, composta por quatro indivíduos.

3.3. O ALGORITMO GENÉTICO 17

Figura 3.4: População P(0)

Após gerar uma população inicial, o algoritmo avalia o grau de adaptação de cada indivíduodessa população através de uma função de aptidão, f(xt

i) que retorna a adaptação do indivíduono tempo t. Por exemplo, definiremos nossa função aptidão de forma a somar um ponto paracada 0 situado em um gene impar e para cada 1 situado em um gene par do cromossomo comomostra a figura 3.5.

Figura 3.5: Cálculo da função de aptidão de P(0)

Após avaliar cada indivíduo, o algoritmo deve checar se alguma condição de parada foisatisfeita. Como podemos ver, nenhum indivíduo da população P(0) tem aptidão igual a 8, alémdisso, t é menor que 2. Logo, nenhuma condição de parada pode ser satisfeita.

O próximo passo do AG será produzir uma nova população P(1) descendente de P(0). Paraque isso seja possível, o algoritmo precisa selecionar em cada iteração do laço de formação danova população um par de indivíduos para aplicar os operadores genéticos. Geralmente cadapar selecionado produz dois descendentes, assim, serão necessários dois pares para formar umanova população com quatro indivíduos. Como no caso da evolução natural, a aptidão de umindivíduo determina em que extensão ele se reproduz, sendo que aqueles indivíduos que têmavaliações mais altas recebem maiores probabilidades de se reproduzirem. Por exemplo, con-sidere que o algoritmo selecione em cada iteração os pares da figura 3.6. Note que o indivíduocom adaptação igual a seis foi selecionado duas vezes.

Figura 3.6: Pares selecionados da população P(0)

3.3. O ALGORITMO GENÉTICO 18

Após o algoritmo selecionar o primeiro par de indivíduos de P(0), podemos proceder coma operação de cruzamento. O cruzamento toma o cromossomo dos dois indivíduos e os divide,trocando seus genes para produzir dois novos indivíduos. A figura 3.7 ilustra o cruzamentodo primeiro par de indivíduos selecionados. O operador divide os cromossomos ao meio eforma dois filhos cujo segmento inicial se origina de um dos pais e cujo segmento final vemde outro pai. Note que a divisão de um cromossomo no meio é uma escolha arbitrária. Estadivisão pode até mesmo ser ajustado aleatoriamente ou mudado durante o processo de solução.Além disso, é importante deixar claro que o operador de cruzamento é aplicado com uma dadaprobabilidade para cada par de cromossomos, sendo esta probabilidade chamada de taxa decruzamento. Quando não ocorre cruzamento, os filhos são iguais aos pais e certas característicassão preservadas com isso.

Figura 3.7: Cruzamento do primeiro par de indivíduos selecionados de P(0)

Terminada a operação de cruzamento do primeiro par de indivíduos de P(0), o algoritmoprocede com a operação de cruzamento do segundo par de indivíduos como mostra a figura3.8. Podemos perceber que algo de anormal aconteceu com um dos dois filhos gerados nessecruzamento. O primeiro gene do cromossomo (marcado com vermelho) que deveria herdaro valor 0 acabou ficando com o valor 1. Assim como na reprodução sexuada, o processo dedivisão de cromossomos para formar descendentes pode sofre uma mutação. A mutação éum operador genético que age visando aumentar a diversidade das soluções geradas de umapopulação para outra. Ele também é aplicado com uma dada probabilidade, a taxa de mutação.Em nosso problema a mutação funciona da seguinte forma, a cada quatro descendentes geradosum sofre mutação, ou seja, uma taxa de mutação de 25% sobre os cromossomos da população.Após um cromossomo ser selecionado para mutação, é usado a inversão em um de seus oitogenes de forma aleatória mudando seu valor de 0 para 1 ou vice-versa.

3.3. O ALGORITMO GENÉTICO 19

Figura 3.8: Cruzamento do segundo par de indivíduos selecionados de P(0)

Ao fim da execução do laço de formação da população P’(0), o algoritmo substitui P(0) pelanova população P’(0) e incrementa a variável t como mostra a figura 3.9.

Figura 3.9: População P(1)

Agora que o algoritmo gerou a população descendente P(1), ele deve calcular o grau deadaptação dessa nova população como mostra a figura 3.10. Com base nos valores gerados po-demos perceber nitidamente a evolução da população P(1) sobre sua população ancestral P(0).Curiosamente, a população P(1) mesmo mais evoluída acabou ficando mais distante soluçãoideal do problema, ou seja, os indivíduos com melhor aptidão das populações P(0) e P(1) pos-suem respectivamente aptidões 6 e 5. Esse tipo de comportamento das versões mais tradicionaisAG pode ser considerado uma falha, no entanto ela pode ser corrigida facilmente com adiçãode outros operadores genéticos como, por exemplo, o Elitismo (DEJONG, 1975), que consisteem manter o melhor cromossomo de uma geração para outra durante a utilização do algoritmo,com a intenção de preservar a melhor solução encontrada até então.

Figura 3.10: Cálculo da função de aptidão de P(1)

Após formar sua primeira descendência, o algoritmo deve verificar novamente se algumadas suas condições de parada foi satisfeita. Analisando o estado atual do algoritmo, podemos

3.3. O ALGORITMO GENÉTICO 20

ver que nenhuma condição de parada foi satisfeita, pois além de nenhum indivíduo da populaçãoP(1) ter aptidão igual a 8, t também é menor que 2.

Mais uma vez o algoritmo deve selecionar bons pares de indivíduos para produzir descen-dentes, existe muitos métodos para selecionar indivíduos pela sua aptidão como, por exemplo, aseleção por roleta e a seleção por classificação que veremos adiante. Mas para nosso problema,considere que uma forma de seleção qualquer tenha selecionado pares da figura 3.11.

Figura 3.11: Pares selecionados da população P(1)

Após selecionar bons pares para produzir descendentes, o algoritmo inicia a operação decruzamento do primeiro par de indivíduos de P(1) como mostra a figura 3.12. Podemos per-ceber que ocorreu uma mutação no descendente com gene marcado de vermelho. A mutaçãoé importante porque a população inicial pode excluir algum componente essencial da solução.No nosso exemplo, usamos um operador de cruzamento simples, que gera seus descendentesrecombinando cromossomos que foram divididos ao meio. Isso significa que caso a populaçãoinicial não tenha pelo menos dois indivíduos, um com o valor 0101 na primeira metade de seucromossomo e outro com o mesmo valor na segunda metade de seu cromossomo, o algoritmonão será capaz de encontrar a solução ideal sem a ajuda do operador de mutação.

Figura 3.12: Cruzamento do primeiro par de indivíduos selecionados de P(1)

O algoritmo continua sua execução selecionando o segundo par de indivíduos de P(1) parauma possível operação de cruzamento. A figura 3.13 ilustra o resultado dessa operação. Comomencionado anteriormente, a operação de cruzamento é realizada de acordo com uma deter-minada taxa de cruzamento. Em nosso problema, adotamos uma taxa de 75%, ou seja, a cadaquatro pares de indivíduos selecionados para produzir descendentes, um não par não realizao cruzamento. Quando isso acontece, os filhos gerados dessa operação são copias exatas deseus pais. Ou, seguindo a mesma linha de raciocínio, podemos simplesmente dizer que os paisselecionados foram adicionados diretamente na nova população.

3.3. O ALGORITMO GENÉTICO 21

Figura 3.13: Transmissão do segundo par de indivíduos de P(1) para a geração seguinte

Ao fim da execução do laço de formação da população P’(1), o algoritmo substitui P(1) pelanova população P’(1), incrementa a variável t e calcula o grau de adaptação da população comomostram as figuras 3.14 e 3.15.

Figura 3.14: População P(2)

Figura 3.15: Cálculo da função de aptidão de P(2)

Após formar sua segunda descendência, o algoritmo finalmente para. Apesar de não havernenhum indivíduo da população P(2) com aptidão igual a 8, a variável t já alcançou o valor2, satisfazendo assim uma de suas condições de parada. Ao fim de sua execução, o algoritmoretorna o indivíduo melhor adaptado, ou seja, 11010101.

Esses resultados nos mostram o quão poderoso o AG pode ser. Da seleção natural, tivemosa garantia de que os indivíduos mais adaptados reproduziriam mais freqüência. Da genética, ti-vemos a garantia de que os genes desses indivíduos seriam transmitidos para seus descendentes.Assim, após algumas gerações podemos vimos uma população mais adaptada emergir.

Uma importante vantagem do algoritmo genético está na natureza paralela da sua busca.Os algoritmos genéticos implementam uma forma poderosa de subida de encosta que mantém

3.4. CODIFICAÇÃO 22

múltiplas soluções. A figura 3.16 mostra múltiplas soluções convergindo para pontos ótimosnum espaço de busca. Nesta figura, o eixo horizontal representa os pontos possíveis num espaçode soluções, enquanto que o eixo vertical reflete a qualidade dessas soluções. Os pontos sobrea curva são membros da população corrente de soluções candidatas do algoritmo genético.Inicialmente, as soluções estão espalhadas por todo o espaço de soluções possíveis. Após váriasgerações, elas tendem a se agruparem em torno de soluções de alta qualidade (LUGER, 2004).

Figura 3.16: AG visualizado como método paralelo de subida de encosta

Agora que já conhecemos o funcionamento do AG, na próxima seção abordaremos de formamais detalhada temas como codificação, operadores genéticos, avaliação, seleção e parâmetrosmais utilizados em algoritmos.

3.4 Codificação

A codificação é a primeira coisa que devemos pensar quando tentamos resolver um problemautilizando Algoritmos Genéticos. Existem várias formas de se representar um cromossomo,no entanto, essa escolha dependerá muito do problema a ser resolvido. As duas formas decodificação mais bem sucedidas são a codificação binária e a codificação por permutação.

3.4.1 Codificação Binária

A codificação binária foi o primeiro tipo de representação proposto por Holland. Devido asua simplicidade, a codificação binária permite várias combinações de cromossomos, mesmocom número reduzido de alelos. No entanto, esta codificação não é natural para muitos tipos deproblemas e algumas vezes é preciso fazer correções antes e até mesmo depois dos cruzamentose mutações. A representação de um cromossomo nessa codificação é feita através de uma cadeiade bits composta por 0s e 1s.

3.4. CODIFICAÇÃO 23

Figura 3.17: Exemplo de cromossomos com codificação binária

Um bom exemplo para demonstramos a utilização da codificação binária é o problema desatisfação de uma Forma Normal Conjuntiva (FNC). Uma expressão está na sua forma normalconjuntiva quando ela for uma seqüência de cláusulas ligada por uma relação e (∧). Cada umadas cláusulas está na forma de uma disjunção, o ou (∨), de literais. Por exemplo, se os literaisforem a, b, c, d, e e f, então a expressão

(¬a ∨ c) ∧ (¬a ∨ c ∨ ¬e) ∧ (¬b ∨ c ∨ d ∨ ¬e) ∧ (a ∨ ¬b ∨ c) ∧ (¬e ∨ f)

está na FNC (LUGER, 2004).Satisfazer uma FNC significa que devemos encontrar uma atribuição de verdadeiro ou falso

(1 ou 0) para cada um dos seis literais, de modo que a expressão FNC seja avaliada comoverdadeira. Assim, uma representação natural para o problema de satisfação da FNC é umaseqüência de seis bits, cada bit, ordenadamente, representando verdadeiro (1) ou falso (0) paracada um dos seis literais, novamente na ordem a, b, c, d, e e f. Assim:

101010

indica que a, c e e são verdadeiros b, d e f são falsos e o exemplo de expressão FNC é, portanto,falso (LUGER, 2004).

3.4.2 Codificação por Permutação

A codificação por permutação ou path é usada principalmente em problemas cuja ordenaçãoseja um fator importante na escolha de uma boa solução. A representação de um cromossomonessa codificação é feita através de um conjunto de números inteiros que representam uma po-sição numa seqüência. Assim como na codificação binária, para alguns tipos de cruzamentos emutações, são necessárias correções na estrutura do cromossomo para manter a sua consistên-cia, ou seja, para que representem uma seqüência válida.

Figura 3.18: Exemplo de cromossomo com codificação por permutação

3.5. OPERADORES GENÉTICOS 24

Um bom exemplo para demonstramos a utilização da codificação por permutação é o clás-sico problema do caixeiro viajante (TSP - traveling salesperson problem). A descrição do pro-blema é a seguinte:

“Um caixeiro viajante deve visitar N cidades como parte de um roteiro de vendas. Existe

um custo (por exemplo, a quilometragem ou tarifa aérea) associado a cada par de cidades

no roteiro. Encontre o caminho com menor custo em que o caixeiro viajante inicie numa

cidade numa cidade, visite todas as cidades exatamente uma vez e retorne ao ponto inicial.”

Uma representação para esse problema seria associar um número a cada cidade, por exem-plo, 1, 2, ..., N; de modo que cada cromossomo formado descreva a ordem em que o caixeirovisitará as cidades.

3.5 Operadores Genéticos

Os operadores genéticos são os principais elementos de um Algoritmo Genético, são eles osresponsáveis pela evolução das soluções durante a execução da aplicação. Existem vários tiposde operadores genéticos, no entanto, o cruzamento e a mutação são os dois operadores maiscomuns e então presentes na maioria das implementações. Segundo RAMOS & SALGADO(2001), o cruzamento é o responsável pela convergência da população, enquanto que a mutaçãotem como objetivo introduzir e manter variedade genética. Dependendo do tipo de codificaçãoescolhido, podem existir várias formas de se implementar esses operadores.

3.5.1 Cruzamento

Segundo RAMOS & SALGADO (2001), o cruzamento (crossover) é o operador genético res-ponsável pela criação de novos cromossomos através da recombinação do material genético dedois cromossomos já existentes na população. Existem várias formas de se implementar esseoperador, no entanto, o mais importante é que essa implementação garanta os alelos (ou caracte-rísticas) transmitidos para os cromossomos filhos sejam exatamente os mesmos do cromossomoque os transmitiu.

3.5.1.1 Cruzamento para Codificação Binária

Dos vários tipos de cruzamentos utilizados para codificação binária, podemos destacar o uni-ponto, o multiponto e o uniforme.

O cruzamento uniponto é aquele que possuí um único ponto de corte definido aleatoria-mente. A figura 3.19 ilustra esse tipo de cruzamento. Nele, o primeiro filho herda os bits doprimeiro pai até o ponto de corte, e a partir desse ponto herda os bits do segundo pai. Analoga-mente, o segundo filho acaba herdando os bits restantes.

3.5. OPERADORES GENÉTICOS 25

Figura 3.19: Exemplo de cruzamento uniponto

O cruzamento multiponto funciona de forma semelhante ao cruzamento uniponto, só quecom mais de um ponto de corte como mostra a figura 3.20.

Figura 3.20: Exemplo de cruzamento multiponto

No cruzamento uniforme, é gerada uma máscara aleatória que indica quais os genes dosdois cromossomos que vão ser trocados. Os descendentes são formados da seguinte forma, parao primeiro filho, onde a máscara for 0 será herdado o bit do primeiro pai e onde a máscara for1 será herdado o bit do segundo pai. Analogamente, o segundo filho acaba herdando os bitsrestantes como mostra a figura 3.21.

Figura 3.21: Exemplo de cruzamento uniforme

3.5. OPERADORES GENÉTICOS 26

3.5.1.2 Cruzamento para Codificação por Permutação

Dos vários tipos de cruzamentos utilizados para codificação por permutação, podemos destacaro cruzamento ordenado, o cruzamento parcialmente mapeado e o cruzamento circular.

No cruzamento ordenado, os descendentes são gerados escolhendo uma subseqüência decidades de um dos pais e preservando a ordem relativa das cidades do outro pai. A figura 3.22ilustra o cruzamento ordenado. Após definirmos dois pontos de corte, o primeiro filho herdaa subseqüência de cidades (4567) que estão entre os dois pontos de corte do primeiro pai, emseguida, a partir do segundo ponto de corte é herdada seqüência relativa de cidades (31289) dosegundo pai, omitindo-se as repetições e obedecendo à seqüência vai do segundo ponto de corteaté o final do cromossomo e do início do cromossomo até o primeiro ponto de corte. O segundofilho é gerado seguindo a mesma linha de raciocínio.

Figura 3.22: Exemplo de cruzamento ordenado

No cruzamento parcialmente mapeado, assim como no cruzamento anterior, os descenden-tes são gerados escolhendo uma subseqüência de cidades de um dos pais. No entanto, os genesdo outro pai são extraídos preservando a ordem e a posição do maior número de cidades possí-veis. Por fim, os genes restantes são escolhidos através de um mapeamento entre os dois pais.Considere o exemplo ilustrado na figura 3.23. Após definirmos dois pontos de corte, o primeirofilho herda a subseqüência de cidades (4567) que estão entre os dois pontos de corte do primeiropai. Após isso, é feito um mapeamento de cada cidade dessa subseqüência para a cidade situadana mesma posição do cromossomo do segundo pai (4-8, 5-7, 6-6, 7-9). Por último, os genesrestantes são herdados do segundo pai obedecendo ao posicionamento original (412 e 35), eno caso de haver algum gene repetido (4 e 5), ele será substituído pelo seu respectivo númeromapeado (812 e 39). O segundo filho é gerado seguindo a mesma linha de raciocínio.

3.5. OPERADORES GENÉTICOS 27

Figura 3.23: Exemplo de cruzamento parcialmente mapeado

No cruzamento circular, os descendentes são gerados de forma que cada cidade e sua res-pectiva posição no cromossomo venham de um dos pais sem que ocorra repetição de cidades.O primeiro descendente é gerado a partir da primeira cidade do primeiro pai (1xxxxxxxx) comomostra a figura 3.24. A próxima cidade a ser escolhida será a cidade correspondente a primeiraposição do segundo pai, mas na posição em que ela aparece no primeiro pai (1xx4xxxxx). Emseguida, selecionamos a cidade da quarta posição do segundo pai, mas na posição que ela apa-rece no cromossomo do primeiro pai (1xx4xxx8x), e assim sucessivamente até não termos maisopções (1234xxx8x). Por fim, completamos as posições vazias com as cidades situadas nes-sas mesmas posições no cromossomo do segundo pai (123476985). O segundo filho é geradoseguindo a mesma linha de raciocínio.

Figura 3.24: Exemplo de cruzamento circular

3.5.2 Mutação

A mutação é um operador genético que tem o objetivo de aumentar a diversidade genética deuma população a cada geração. Usando apenas o cruzamento a população de soluções podeconvergir para o que chamamos de máximo local, ou seja, quando todos os cromossomos dapopulação possuem um determinado alelo alfa e, no entanto, a melhor solução necessita deum alelo beta já extinto. Esse problema pode ser resolvido com mutação que, utilizada combaixas probabilidades, pode alterar o valor desse alelo e evitar que o algoritmo fique presonesse máximo local.

3.6. AVALIAÇÃO E SELEÇÃO DE CROMOSSOMOS 28

3.5.2.1 Mutação para Codificação Binária

A mutação utilizada para codificação binária funciona de forma bastante simples, selecionandoum cromossomo e mudando aleatoriamente o valor de alguns de seus bits de 0 para 1 e vice-versa.

Figura 3.25: Exemplo de mutação binária

3.5.2.2 Mutação para Codificação por Permutação

Assim como na mutação para codificação binária, a mutação para codificação path também ébastante simples. A chamada mutação com troca recíproca sorteia dois genes do cromossomoe inverte suas posições.

Figura 3.26: Exemplo de mutação com troca recíproca

3.6 Avaliação e Seleção de Cromossomos

Segundo RAMOS & SALGADO (2001), a avaliação da qualidade de um cromossomo e dasolução que ele representa é feita por uma função de aptidão (Fitness Function). A função deaptidão é a única ligação que o AG tem com o problema que se pretende resolver.

Por exemplo, suponha que precisássemos implementar uma função de aptidão para o pro-blema da FNC mostrado na seção 3.4.1 deste capítulo. A escolha de uma função de aptidãopara esta população de cadeia de bits não é muito fácil. Por um lado, uma atribuição de valo-res verdade para literais tornará a expressão verdadeira ou, então, a expressão será falsa. Seuma atribuição específica tornar a expressão verdadeira, então a solução foi encontrada; casocontrário, ela não é a solução. À primeira vista parece difícil determinar uma função de aptidãoque possa julgar a “qualidade” de cadeias de bits como soluções potenciais (LUGER, 2004).

3.6. AVALIAÇÃO E SELEÇÃO DE CROMOSSOMOS 29

Entretanto, existem várias alternativas. Uma delas seria observar que a expressão FNCcompleta é composta pela conjunção de cinco cláusulas. Assim, podemos conceber um sistemade avaliação que nos permita ordenar as soluções de padrões de bits num intervalo de 0 a 5,dependendo do número de cláusulas que o padrão satisfaz. Assim, o padrão:

110010 tem aptidão de 1,010010 tem aptidão de 2,010011 tem aptidão de 3 e101011 tem aptidão de 5 e é uma solução (LUGER, 2004).

Os valores retornados pela função de aptidão são geralmente chamados mérito. É atravésdo mérito que selecionamos os cromossomos para gerar descendentes. Quanto maior for essevalor, maior probabilidade o cromossomo tem de ser escolhido. No entanto, é importante quecromossomos com mérito baixo também sejam selecionados com menor freqüência porque ne-les também podem conter algum componente essencial para a solução. Existem vários métodospara selecionar cromossomos segundo seu valor de mérito. Dentre eles podemos destacar osmétodos seleção por roleta e seleção por classificação.

Na seleção por roleta é criado um circulo imaginário dividido em regiões chamado roleta,onde cada cromossomo da população ocupa uma região da roleta proporcional ao seu mérito.A seleção é feita lançando uma bolinha imaginária na roleta, o cromossomo que representar aregião onde a bolinha parar é selecionado para participar do processo de geração da nova popu-lação. Assim, os cromossomos cujas regiões possuem maior área terão maior probabilidade deserem selecionados mais vezes. Na figura 3.27 podemos ver um exemplo de seleção por roleta.

Figura 3.27: Exemplo de seleção por roleta

Como podemos ver esse método não é eficiente para populações onde a diferença entreos méritos forem grandes. Como no exemplo acima, onde o cromossomo com melhor méritoocupa uma região que representa 47% de toda a roleta. Com isso, os demais cromossomos terãochances muito baixas de serem selecionados.

A seleção por classificação é usada para contornar esse problema. Ela classifica os cromos-somos pelo valor de seu mérito. Assim, o pior cromossomo fica classificado como 1, o segundopior como 2 e assim sucessivamente de forma que o melhor cromossomo seja classificado como

3.7. PARÂMETROS DE UM ALGORITMO GENÉTICO 30

n, onde n é igual ao número de cromossomos da população. A figura 3.28 ilustra um exemplode seleção por classificação. Como podemos ver agora todos os cromossomos possuem chancesmais homogêneas de serem selecionados. Entretanto, este método pode resultar numa menorconvergência, porque os melhores cromossomos não se distinguem muito dos outros.

Figura 3.28: Exemplo de seleção por classificação

3.7 Parâmetros de um Algoritmo Genético

Agora que conhecemos os principais elementos que constituem a base de um Algoritmo Gené-tico, faremos uma breve discussão sobre como ajustá-los para se obter o melhor desempenhoda aplicação. São eles:

• Codificação: Depende somente do problema a ser resolvido. A codificação binária é amais indicada, no entanto, podemos optar por outros tipos de codificação como a porpermutação ou outra qualquer. O mais importante é garantir que a codificação utilizadasuporte os operadores genéticos.

• Tamanho da população: O número de cromossomos da população compromete o de-sempenho da aplicação. Populações pequenas podem levar à convergência para máximoslocais devido à reduzida diversidade genética. Por outro lado, populações com tama-nho muito grande normalmente não a aumentam o desempenho da aplicação. SegundoOBITKO (1998), um bom tamanho para a população é cerca de 20-30 cromossomos,entretanto às vezes tamanhos de 50-100 cromossomo são relatados como melhores.

• Seleção: Existem várias formas de se selecionar cromossomos pelo seu mérito. No en-tanto, devermos ter consciência que o tipo de seleção escolhido afetará diretamente aforma com que a população irá convergir.

• Taxa de cruzamento: O operador de cruzamento é responsável gerar novas soluções parao problema. Por esse motivo, esse operador desse ser usado sob grande probabilidade.Segundo OBITKO (1998), a taxa de cruzamento deve ficar entre 80% a 95%. Entretanto,existem alguns tipos de problemas que funcionam melhor com taxas de 60%.

3.7. PARÂMETROS DE UM ALGORITMO GENÉTICO 31

• Taxa de mutação: O operador de mutação é responsável pela diversidade genética dapopulação. Assim, uma taxa de mutação muito elevada pode levar a uma procura quasealeatória. Portanto, segundo LACERDA & CARVALHO (1999), para evitar uma variaçãomuito abrupta de uma população para outra, é recomendada a utilização de pequenas taxasde mutação, normalmente entre 0,1% e 5%.

Capítulo 4

Othello

4.1 História

Othello é um jogo de tabuleiro de estratégia. Ele se baseia no jogo chamado Reversi, inventadoem 1883 e ganhou popularidade considerável na Inglaterra no final do século XIX. Os créditosda criação do jogo são reivindicados separadamente pelos ingleses Lewis Waterman e John W.Mollett. O jogo teve sua primeira referência confiável na edição de 21 de agosto de 1886 doThe Saturday Review. Mais tarde, em 1895, um artigo do New York Times dizia: “Reversi éalgo como Go, e é jogado com 64 peças.” Em 1898, uma conhecida editora de jogos alemãchamada Ravensburger teve como um dos seus primeiros lançamentos o jogo Reversi. Doislivros europeus do século XVIII são mencionados na página 14 do livro Othello Quarterlyde 1989. Eles fazem referência a um jogo muito semelhante ao Reversi Inglês, levantandoespeculações de que a sua origem seja mais antiga do que parece ser.

Figura 4.1: Tabuleiro do jogo Go, de origem chinesa

Com um novo conjunto de regras criado na cidade japonesa de Mito em 1971, a empresa dejogos Tsukuda Original Co. registrou o jogo com o nome de Othello. O nome foi inspirado naobra de Shakespeare chamada Othello, o Mouro de Veneza. O jogo faz referência ao conflitoentre o general Othello e seu suboficial Iago que movido por inveja conspira contra o romanceentre general, que é negro e seu grande amor Desdêmona, que é branca. O jogo também podeser comparado a uma competição de inveja, tema central da obra, uma vez que o objetivo dojogo consiste em tomar posse das peças de seu adversário.

32

4.2. REGRAS 33

Em 2002, um comunicado da imprensa sobre as origens do jogo não fez nenhuma mençãoà versão original:

“Othello foi inventado pelo entusiasta de jogos japonês, Goro Hasegawa em 1971. Ele

escolheu James R. Becker, para ajudá-lo a desenvolver e comercializar o jogo. Inspirado

em ‘Go’, um antigo jogo de estratégia chinês, Hasegawa procurou criar um jogo rico em

estratégia, mas que fosse acessível para um jogador casual. Becker simplificou o jogo,

cunhou o slogan, ‘Um minuto para aprender... Uma vida para dominar’ e nomeou este

novo jogo após ouvir o clássico de Shakespeare, por causa das peças pretas e brancas.

Othello foi introduzido pela primeira vez no Japão em 1973, pela Tsukuda Original Co.,

que por sugestão de Becker organizou a Associação Japonesa de Othello.”

No Brasil, a Grow Jogos e Brinquedos S.A. foi o último fabricante do jogo.

4.2 Regras

4.2.1 Componentes

• 01 tabuleiro de 8x8

• 64 discos bi-coloridos: de um lado do disco é preto e do outro lado desse disco é branco.

• 02 jogadores: um branco e um preto.

4.2.2 Objetivo

O objetivo de cada jogador é fazer com que, no final da partida, haja o maior número possívelde peças de sua cor com no tabuleiro.

4.2.3 Preparação

• Sorteiam-se quem jogará com a cor preta e quem ficará com a cor branca. A cor pretasempre inicia a partida.

• Coloque quatro peças nas casas centrais do tabuleiro, duas com face preta para cima eduas com face branca, conforme mostra a figura 4.2.

• As peças restantes devem se divididas entre os dois jogadores.

4.2. REGRAS 34

Figura 4.2: Configuração inicial do tabuleiro de Othello

4.2.4 O Jogo

O primeiro a jogar coloca, no tabuleiro, uma peça com a face preta voltada para cima, de modoa fazer com que uma das peças brancas fique entre duas pretas.

Figura 4.3: Exemplo de uma possível jogada inicial

Cada vez que um jogador cercar uma peça de outra cor em duas extremidades, ela será vi-rada, isto é, mudará de cor e de dono. Portanto, as peças não podem ser colocadas no tabuleiroem qualquer posição, mas deve-se ter sempre como objetivo cercar uma ou mais peças adver-sárias. Se, na sua vez de jogar, você não puder colocar nenhuma peça de modo a virar, pelomenos, umas das peças do outro jogador, você perderá a vez e o adversário jogará novamente.

Assim, o resultado da jogada que vemos na figura anterior é a conquista de uma posiçãopara as peças pretas, com a transformação da peça branca em preta.

Figura 4.4: Três possibilidades de jogadas para as peças brancas

4.2. REGRAS 35

A seguir, o adversário coloca uma peça branca no tabuleiro de forma a cercar uma das peçaspretas. Perceba que, no exemplo acima, há três possibilidades de jogada para as peças brancas:na vertical, na horizontal e a diagonal.

No início da partida, são relativamente poucas as alternativas de jogada, porém, conformeos lances vão ocorrendo, torna-se possível cercar várias peças adversárias. No entanto, para quevocê possa virar todas numa única jogada, não pode haver nenhum espaço vazio entre elas.

Figura 4.5: Exemplo de jogada inválida por espaço em branco

No caso acima, a peça preta assinalada não poderia ser colocada nessa posição. Uma boaopção de jogada seria, por exemplo:

Figura 4.6: Exemplo de boa jogada

O que ocasionaria a conquista de duas peças brancas.É possível, simultaneamente, cercar peças em mais de um sentido: horizontal, vertical e

diagonal, mas todas as peças cercadas devem ser viradas. Não se podem virar apenas algumas,mesmo que seja interessante do ponto de vista estratégico.

Uma peça só pode ser virada como resultado direto de uma jogada, tendo que estar, obriga-toriamente, na mesma linha da peça atacante. Não é possível, então, virar peças por tabela.

4.2. REGRAS 36

Figura 4.7: Exemplo de uma tentativa inválida de virar peças por tabela

Na figura acima, a colocação da peça preta assinalada provocará apenas o giro das duaspeças brancas ao lado dela, enquanto que as duas peças brancas da vertical continuam imóveis,pois não foram cercadas como resultado direto da jogada, conforme podemos verificar na figura4.8.

Figura 4.8: Resultado da jogada da figura 4.7

Também não é permitido voltar à jogada. Assim que você colocar uma peça, deverá, obri-gatoriamente, dar continuidade ao jogo, mesmo que o resultado lhe seja desfavorável depois.

As peças do não mudam mais de posição. O giro de peças, com a conseqüente troca decores, ocorre sempre nas posições onde foram originalmente colocadas.

4.2.5 Fim de Jogo

A partida termina quando não houver mais lugar no tabuleiro para a colocação de peças, ouquando não houver mais possibilidade de jogada.

4.2.6 Vencedor

O jogador que tiver mais peças de sua cor no tabuleiro será o vencedor.

Capítulo 5

Desenvolvimento da Aplicação

Neste capítulo serão discutidos os detalhes de implementação do projeto proposto por esse tra-balho. O projeto consiste em criar uma versão do jogo Othello cuja as regras foram apresentadasno capítulo 4, e dois jogadores virtuais, um representando a Poda alfa-beta e outro o AlgoritmoGenético, discutidos respectivamente nos capítulos 2 e 3 deste trabalho. Assim, discutiremos osprincipais métodos e classes responsáveis pela interação do usuário com a aplicação, por validaras regras do jogo e pelo comportamento de cada inteligência artificial estudada no projeto.

5.1 Linguagem e ferramentas utilizadas para o desenvolvi-mento

Dentre as várias linguagens de programação atuais, optou-se por desenvolver a aplicação uti-lizando a linguagem Java. A principal razão desta escolha foi o fato de já está habituado àlinguagem, sendo esta, utilizada para desenvolver sistemas de grande porte em nosso cotidianode trabalho. Além disso, não é tão difícil encontrar outras razões que justifique essa escolha,umas delas é a portabilidade. Diferentemente das linguagens convencionais, que são compi-ladas para código nativo, a linguagem Java é compilada para um bytecode que é interpretadopela máquina virtual java (JVM). Isso significa que uma aplicação feita em Java pode ser exe-cutada em qualquer plataforma que dê suporte a uma JVM. Podemos ainda citar o suporte aprogramação multithread que permite aumentar o desempenho de uma aplicação executando-a paralelamente em vários processadores. Por fim, por ser uma linguagem bastante flexível edifundida atualmente, está mais que justificada sua escolha.

Para desenvolver a aplicação foi utilizado o kit de desenvolvimento da linguagem Java ver-são 1.6.0, distribuído pela Oracle Corporation, em conjunto com a IDE Eclipse 3.3.0. As ima-gens utilizadas foram criadas utilizando a ferramenta Paint Shop Pro Photo X2 versão 12.5 depropriedade da Corel Corporation.

Os links dos sites dos proprietários dessas ferramentas estarão disponíveis na bibliografiadeste trabalho.

37

5.2. ARQUITETURA 38

5.2 Arquitetura

Hoje em dia, o sucesso ou o fracasso de um projeto de software está diretamente ligado a formacom que ele foi concebido, ou seja, aos princípios da boa engenharia de software. Apesar deo projeto proposto apresentar uma baixa complexidade se comparado aos grandes softwarescomerciais, tentamos adotar algumas boas práticas que nós ajudasse a alcançar nosso objetivoe que facilitasse sua compreensão por parte de terceiros.

No caso específico desse projeto, foi seguida uma filosofia orientada a objetos com focona arquitetura e em sua modelagem visual. Assim, foi necessário recorrer ao UML (UnifiedModeling Language) como ferramenta auxiliar de modelagem e desenvolvimento de projeto.

O projeto está dividido em três partes principais - gui ou interface, domínio e ia. A figura5.1 ilustra esta divisão. O pacote gui está situado na parte superior do diagrama, sua função éagrupar todas as classes de interface gráfica. É através dessas classes que o jogador interage como jogo posicionando suas pedras no tabuleiro. O pacote situado na parte central do diagramaé o de domínio, sua função é agrupar todas as classes responsáveis por controlar as regras denegocio da aplicação. As classes de domínio armazenam informações sobre o estado atual dojogo como, por exemplo, pontuação e espaços vagos no tabuleiro. Situado na parte inferior dodiagrama, temos o pacote de ia (Inteligência Artificial). Sua função é agrupar todas as classesresponsáveis por implementar os jogadores virtuais da aplicação, mais especificamente, a Podaalfa-beta e o Algoritmo Genético.

Figura 5.1: Diagrama de pacotes da aplicação

A seguir, discutiremos de forma mais detalhada a responsabilidade de cada um desses pa-cotes, assim como o funcionamento e interação das suas respectivas classes e métodos.

5.2. ARQUITETURA 39

5.2.1 Pacote GUI

Ao iniciar a aplicação, o usuário será posto no papel de um jogador, e, portanto deve se submeteràs características impostas ao mesmo. Sua interação com a aplicação se dará por meio de umainterface gráfica que o colocará diante de um jogo virtual de Othello idêntico a um jogo real.

A linguagem Java oferece, dentre as funcionalidades incorporadas à sua API padrão, umextenso conjunto de classes e interfaces para o desenvolvimento de aplicações gráficas. Esseconjunto de componentes gráficos se divide em duas APIs, a AWT (Abstract Windowing To-olkit) e a Swing. A primeira API agrupa funcionalidades gráficas que estão presentes desde aprimeira versão do Java, que operam tendo por base as funcionalidades de bibliotecas gráficasdo sistema onde a aplicação está sendo executada. Já a segunda API é uma extensão padro-nizada da AWT, mas trabalha de uma maneira totalmente diferente. Ela renderiza por contaprópria todos os componentes gráficos deixando aparência independente do sistema operacio-nal.

Assim, visando tornar a interação com o usuário o mais simples e perceptível possível,optou-se por utilizar a API Swing em nosso projeto. A figura 5.2 ilustra a interação de suasprincipais classes no pacote gui. Como podemos ver, a criação de uma interface gráfica envolvetipicamente a criação de um container, um componente que pode receber outros componentes.Em nosso caso, os principais containeres utilizados foram o JFrame, o JPanel e o JDialog.Após a sua criação, esses containeres estarão aptos a receber componentes de interface com ousuário, como por exemplo, o tabuleiro e suas pedras. Os principais componentes utilizadospara essa função foram o JLabel, o JButton, o JRadioButton e o ImageIcon. Finalmente, épreciso especificar quais devem ser os efeitos das ações dos usuários quando realizadas sobrecada um desses componentes, como por exemplo, um clique do mouse sobre o tabuleiro. Isto sedá através da especificação de classes que manipulam eventos, projetadas para a aplicação. Emnosso projeto, foram usadas a interface ActionListener e a classe MouseAdapter para determinaro comportamento da aplicação.

O container central da aplicação é a classe Reversi, é a parti dela que podemos executar aaplicação. A classe Reversi estende da classe JFrame e agrega atributos como Tabuleiro, Con-figuração e Sobre, seus eventos são tratados pela classe MenuActionListener que implementa ométodo actionPerformed da interface ActonListener. A classe Tabuleiro é a principal classe dopacote gui, ela estende da classe JPanel e é responsável por “materializar” o tabuleiro do jogoe suas respectivas pedras na tela do usuário. Além disso, ela agrega as duas principais clas-ses tratadoras de eventos desse projeto, JogadaComputadorListener que também implementa ométodo actionPerformed da interface ActionListener e JogadorListener que estende de Mou-seAdapter e reescreve os métodos mouseEntered, mouseExited e mouseClicked. Por fim, éela quem faz a comunicação entre o pacote gui e o pacote de domínio agregando o atributoControleJogo. Finalmente temos as classes Configuração e Sobre, ambas estendendo da classeJDialog. Essas classes possuem um papel secundário para a aplicação, enquanto a primeira

5.2. ARQUITETURA 40

implementa uma tela de configuração pertinente ao jogo, a segunda apenas exibe informaçõessobre a aplicação e seus criadores.

Figura 5.2: Diagrama de classes simplificado do pacote gui

É importante explicarmos com mais detalhes as formas com que o jogador humano e o joga-dor computador interagem com o jogo. A classe responsável por tratar os eventos gerados pelojogador humano, quando este possui a vez de jogar, é a classe JogadorListener, sua interaçãocom o jogo é feita pelos métodos mouseEntered, mouseExited e mouseClicked. Ao passar omouse por uma casa vazia do tabuleiro é gerado um evento que chama o método mouseEnteredque, em seguida, consulta o domínio do jogo para saber se aquela casa é uma possível jogada,caso seja, uma pedra com a cor do jogador humano aparecerá sobre o espaço vazio. Ao retirar omouse dessa casa, é gerado outro evento que chama o método mouseExited. O método consultao domínio do jogo para saber se aquela pedra foi realmente jogada, caso não, a casa volta aficar vazia. Por último, temos o método mouseClicked, esse método é chamado após clicarmosem alguma casa do tabuleiro, caso essa casa já esteja marcada como uma possível jogada, ométodo atualiza o domínio do jogo fixando uma pedra representando a sua cor naquela posiçãodo tabuleiro. Por outro lado, a classe responsável por tratar os eventos gerados pelo jogadorcomputador é a classe JogadaComputadorListener, ela é ativada por um atributo do tipo Timerque possui os métodos start e stop. Quando o jogador humano perde a vez, é dado um start, equando o jogador computador perde a vez, é dado um stop. Depois de ativada, a classe Joga-

5.2. ARQUITETURA 41

daComputadorListener chama sua implementação para o método actionPerformed, este por suavez, que faz uma requisição de jogada para o domínio que, por sua vez, delega para a classe dopacote ia referente à inteligência artificial escolhida.

5.2.2 Pacote Domínio

O pacote de domínio é o mais importante de toda a aplicação, dentre suas principais funçõespodemos citar o gerenciamento da partida, a validação das regras envolvidas no jogo, a ma-nutenção do estado corrente da partida e a ligação entres todos os pacotes da aplicação. Essepacote agrega três classes, são elas ControleJogo, EstadoJogo e Pedra, e sua interação pode servista na figura 5.3.

Figura 5.3: Diagrama de classes simplificado do pacote domínio

A classe ControleJogo é a principal classe desse pacote, é ela quem gerencia as partidas deOthello controlando os turnos entre os jogadores, aplicando e validando as regras entre outrascoisas. Dentre seus principais métodos, podemos citar:

• buscaJogadaComputador: Esse método verifica qual inteligência artificial foi escolhidae delega a busca da jogada para a sua respectiva classe no pacote ia. A jogada recebida épassada como parâmetro para o método realizaJogada;

• realizaJogada: Esse método é quem de fato realiza uma jogada, tanto para tanto para ojogador computador quanto para o jogador humano. Ele atualiza todas as variáveis decontrole e de estado de acordo com as regras do jogo;

• aplicaRegrasJogada: Esse é um método auxiliar usado pelo método realizaJogada. Suafunção é atualizar o tabuleiro do jogo virando as pedras em todas as direções possíveis;

• checaPossivelJogada: Esse método verifica se uma determinada casa vazia no tabuleiroestá apta a se tornar uma jogada efetiva, ou seja, ele checa se é possível virar pelo menos

5.2. ARQUITETURA 42

uma pedra adversária. Esse método é de grande valia para o método mouseEntered dopacote gui;

• checaSeQuemPossuiVezPossuiJogada: Esse método verifica se o jogador que possui a vezestá apto a jogar, ou seja, se possui alguma jogada naquele turno;

• fimJogo: Esse método verifica se o jogo chegou ao fim, seja por falta de espaços vaziosno tabuleiro ou por falta de jogada para ambos os jogadores.

A classe EstadoJogo implementa o estado do jogo Othello, é ela que mantém as informaçõesrelacionadas à posição e a cor de cada pedra no tabuleiro, a pontuação dos jogadores, o jogadorque possui a vez, além de todo o histórico de jogadas da partida. O principal método dessaclasse é o método heurística, sua função é avaliar a configuração corrente do tabuleiro e atribuirum valor mensurável para a jogada. Esse método é um sinônimo das funções utilidade e aptidãoque foram discutidas, respectivamente, nos capítulos 2 e 3 desse trabalho.

A classe Pedra tem a função apenas de representar uma pedra de Othello do mundo real. Seumétodo inverterCor é usado para inverter a cor da pedra quando for virada após uma jogada.

5.2.3 Pacote IA

O pacote ia reúne as classes responsáveis por implementar a inteligência do jogador computa-dor. Pode ser considerado o pacote mais importante da aplicação do ponto de vista acadêmicopelo fato de agrupar os algoritmos que serão alvos de estudo desse trabalho. Esse pacote sedivide em dois subpacotes, denominados minimax e ag.

O pacote minimax contém apenas uma classe chamada Busca, ela foi criada inicialmentecom intuito de agrupar vários algoritmos de busca seqüencial, no entanto, foi implementadoapenas o algoritmo Minimax com sua otimização alfa-beta. Como podemos ver na figura 5.4,a classe Busca apresenta uma estrutura bastante simples, seu principal método é buscaMinima-xAlfaBeta que implementa os conceitos de busca seqüencial apresentado no capitulo 2 dessetrabalho.

Figura 5.4: Diagrama de classes simplificado do pacote minimax

5.2. ARQUITETURA 43

O método buscaMinimaxAlfaBeta é um método recursivo, ou seja, que chama ele próprio.Ele se vale dos parâmetros jogo (EstadoJogo), profundidade (int), alfa (int), beta (int) e base(int), para percorrer toda a árvore de estados de uma partida de Othello. O parâmetro EstadoJogoé o nó inicial da árvore de estados, na primeira chamada do método é passado o estado correnteda partida que está em andamento. Esse parâmetro é utilizado pelo atributo ControleJogo parasimular os diferentes estados da árvore de busca. O parâmetro profundidade define a quantidademáxima de níveis que o algoritmo poderá descer na sua busca pela melhor jogada, ou seja,sua antecipação para n níveis. Esse parâmetro é definido de forma proporcional a dificuldadeescolhida, ou seja, quando mais difícil mais profunda será a busca, e é decrementado a cadanível que desce. Os parâmetros alfa e beta são utilizados para realizar as podas alfas e betasvistas na seção 2.3 desse trabalho. Os valores desses parâmetros são atualizados a cada chamadadesse método. O parâmetro base é utilizado para marcar o nível do nó pai.

O pacote ag é responsável por agrupar as classes que implementam o Algoritmo Genéticoapresentado no capítulo 3 desse trabalho. Esse pacote agrega quatro classes, são elas Algo-ritmoGenetico, Cromossomo, Gene e MisturaCromossomo, e sua interação pode ser vista nafigura 5.5.

Figura 5.5: Diagrama de classes simplificado do pacote ag

A classe AlgoritmoGenetico é a principal classe desse pacote, é ela quem gera a populaçãoinicial, avalia e seleciona os cromossomos, aplica os operadores de recombinação e mutação

5.2. ARQUITETURA 44

para formar novas populações, entre outras atribuições. É importante destacarmos que essaclasse mantém e evolui duas populações de cromossomos, uma representando as possíveis açõespara o jogador computador e outra representando as possíveis ações de seu adversário, o jogadorhumano. Os motivos dessa abordagem serão explicados com mais detalhes nas seções seguintes,por hora, só precisamos ter em mente que assim como qualquer jogo, em Othello também existeum conflito de interesse. Isso significa que a vitória numa partida não depende apenas das suasjogadas, mas sim do beneficio que elas trarão diante das jogadas do seu adversário que tambémtenta vencer a partida. Dentre os principais métodos utilizados por essa classe, podemos citar:

• gerarPopulacaoInicial: Esse método gera as populações iniciais do computador e de seuadversário, o jogador;

• combinarPopulacoes: Esse método gera uma terceira população formada pelo produtocartesiano entre a população do computador e a população do jogador. Essa terceira po-pulação será usada na avaliação da aptidão de cada cromossomo dessas duas populações;

• avaliarPopulacoes: Esse método avalia a aptidão da população do computador e da po-pulação do jogador. A avaliação é feita através da população combinada;

• selecaoPorClassificacao: Esse método implementa a seleção por classificação vista naseção 3.6 desse trabalho;

• selecaoElitismo: Esse método implementa o operador de elitismo comentado na seção3.3 desse trabalho;

• cycleCrossover: Esse método implementa uma variação do cruzamento circular visto naseção 3.5.1.2 desse trabalho;

• mutacaoPorTrocaReciproca: Esse método implementa a mutação por troca recíprocavista na seção 3.5.2.2 desse trabalho;

• gerarNovaPopulacao: Esse método faz uso dos operadores genéticos para produzir novaspopulações para o computador e para o jogador.

As classes Cromossomo e Gene servem apenas para representar a estrutura da codificaçãoescolhida para implementação. Enquanto o Cromossomo representa um conjunto de jogadas, oGene representa a posição de uma única jogada, ou seja, sua coordenada no tabuleiro. Final-mente, temos a classe JuntaCromossomo, ela é uma classe auxiliar usada pelo método avaliar-Populacoes para representar dois cromossomos intercalados.

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 45

5.3 Forma de implementação dos Algoritmos

Agora que já conhecemos os conceitos gerais que envolvem as duas técnicas de inteligênciaartificial estudada nesse trabalho, bem como detalhes da arquitetura da aplicação envolvendo ocomportamento de suas principais classes e métodos. Chegou à hora de apresentarmos os deta-lhes específicos de nossa implementação para o algoritmo de Poda alfa-beta e para o AlgoritmoGenético.

5.3.1 Implementação da Poda alfa-beta

A nossa implementação para o algoritmo de Poda alfa-beta possui, basicamente, os mesmoscomponentes e segue as mesmas etapas vista no capítulo 2 desse trabalho. No entanto, doispontos importantes valem apena serem discutidos, o primeiro diz respeito à função utilidadeconcebida para o jogo Othello e o segundo diz respeito aos níveis de dificuldade definidos parao jogo quando fizer uso dessa técnica.

A função utilidade adotada foi concebida levando em conta os seguintes critérios: vantagemde pedras do computador sobre o adversário e peso associado a casa do tabuleiro onde a pedrafoi jogada. A vantagem de pedras representa diretamente o conflito de interesses entre os doisjogadores de Othello, que consiste em ter a posse de um número maior de pedras que seu ad-versário. Assim, segundo esse critério, a melhor jogada será aquela que conduzir a partida paraum estado onde o computador possua maior vantagem de pedras possíveis. No entanto, comoestamos fazendo uso de uma antecipação para n níveis, a adoção de um critério de avaliaçãorelativamente simples poderia não ser suficiente para conduzir o computador para uma vitóriavisto que essa vantagem pode ser apenas uma vantagem momentânea usada como armadilha porparte do adversário. Assim, visando diminuir a ação do efeito de horizonte sobre a heurística,adotamos um segundo critério de avaliação para a função utilidade. Ele consiste em associarum peso a cada casa do tabuleiro levando em conta a importância dessa casa para a estratégiado jogo, ou seja, quanto mais importante for a casa maior será o seu peso. Entretanto, para defi-nirmos uma matriz de pesos seriam necessários anos de experiência em Othello, coisa que nãopossuímos no momento. Para solucionar esse problema recorremos à ALLIOT & DURAND(1996), que em seu experimento fez uso de algoritmos genéticos para moldar uma matriz depesos para um tabuleiro de Othello como mostra na figura 5.6. Por fim, definimos a funçãoutilidade como:

U(e) = 0,65×V (e)+0,35×C(P(e)),

onde V(e) é a diferença entre o número de pedras do computador e o número de pedras dojogador adversário, P(e) é o peso da casa onde a última pedra foi jogada, C(e) é um conversorde peso para a escala de mérito definida entre -64 e 64, e U(e) é o valor do mérito do estado e.

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 46

Figura 5.6: Avaliação estática do tabuleiro do jogo Othello

Em termos práticos, vejamos como o algoritmo calcula o valor da função utilidade para oestado ilustrado na figura 5.7, onde temos o computador no controle das pedras de cores pretase sua última jogada apontada pela seta vermelha:

U(e) = 0,65×V (e)+0,35×C(P(e));U(e) = 0,65× (pedrasPretas− pedrasBrancas)+0,35×C(−240);U(e) = 0,65× (6−8)+0,35× (−64);U(e) =−1,3+−22,4;U(e) =−23,7

logo, por se tratar de um valor de mérito negativo, dificilmente o algoritmo escolheria umajogada como essa.

Figura 5.7: Exemplo de estado do jogo Othello

A aplicação apresenta três níveis de dificuldade: iniciante, intermediário e grand othello.Para definirmos esses níveis de dificuldade para o algoritmo de Poda alfa-beta, adotamos umaantecipação para n níveis para representar cada uma delas. Assim, através de testes de usuárioanalisamos o tempo de resposta do jogo para os diferentes níveis de profundidade a fim de des-cobrir qual a profundidade máxima que a aplicação consegue atingir num intervalo aceitável detempo sem que houvesse problemas de congelamento da aplicação. Assim, a partir da profun-didade máxima encontrada, moldamos os diferentes níveis de dificuldade deste algoritmo comomostra a figura 5.8.

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 47

Figura 5.8: Tabela de dificuldade da Poda alfa-beta

5.3.2 Implementação do Algoritmo Genético

A visão evolutiva para solução de um problema apresentada por Holland em seu algoritmo temservido de base em pesquisas que buscam por soluções para problemas de alta complexidade.Assim, para ajustar-se ao problema apresentado por uma partida de jogo de Othello, foi neces-sário realizar algumas modificações no modelo de algoritmo genético apresentado no capítulo3 deste trabalho, como também definir quais parâmetros e implementações serão utilizadas noprojeto. Tais modificações e definições são relativas à codificação, a função de aptidão, a formade seleção, aos operadores genéticos, a condição de parada, a taxa de elitismo e aos níveis dedificuldade implementados.

5.3.2.1 Codificação

Após analisarmos as inúmeras formas de representação de cromossomo, optou-se por usar acodificação por permutação. A principal vantagem de usar esse tipo de codificação é que ela nospermite representar um gene como um número inteiro pertencente ao conjunto de coordenadasdo tabuleiro de Othello. Assim, como podemos ver na figura 5.9, o gene é representado porum número de dois dígitos, onde o número das dezenas representa uma linha e o número dasunidades representa uma coluna, formando uma jogada definida pelo par coordenado (linha,coluna). Outro fator decisivo para a escolha desse tipo de codificação foi semelhança com oproblema do caixeiro viajante visto na seção 3.4.2 desse trabalho. Enquanto o problema docaixeiro busca a melhor ordenação de cidades para minimizar o gasto total de uma tour pelascidades, o problema do jogo Othello busca, a grosso modo, a melhor ordenação de jogadas paramaximizar sua vantagem de pedras sobre o adversário.

Figura 5.9: Coordenadas do tabuleiro de Othello

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 48

Por fim, definimos o cromossomo como uma lista ordenada de genes de tamanho igual àquantidade de casas do tabuleiro, ou seja, uma lista com 64 jogadas como mostra a figura 5.10.Neste momento, o leitor deve está no mínimo intrigado pela escolha de um cromossomo detamanho fixo tão longo e que no decorrer da partida carregará consigo genes que representamposições do tabuleiro que já foram jogadas. A justificativa para o uso dessa estratégia se dápelo ganho que a aplicação terá por não precisar validar os novos cromossomos nas operaçõesde cruzamento e por não precisar tratar possíveis casos especiais nas operações de cálculo daaptidão dos indivíduos. Além do mais, os genes que não possuem mais utilidade para o jogoem andamento provavelmente não serão prejudiciais para a aplicação visto que estamos ma-nipulando uma lista de prioridade, logo, após algumas gerações os genes úteis tenderão a seposicionar nas primeiras posições do cromossomo enquanto que os genes que não possuíremmais valor se posicionarão no final do cromossomo.

Figura 5.10: Exemplo de codificação para o jogo Othello

5.3.2.2 Função Aptidão

A função de aptidão adotada para o Algoritmo Genético dessa aplicação foi concebida seguindoos mesmos critérios de avaliação da função utilidade vista na seção 5.3.1 desse trabalho. Assim,de forma semelhante ao algoritmo de Poda alfa-beta que estende sua árvore de estados e aplicasua função utilidade em cada um de seus nós folha, nosso AG deve prover de uma estrutura quepermita estender um ramo de árvore específico para fazer uso de sua função aptidão.

A primeira idéia que tivemos foi a de usarmos a abordagem tradicional de AG com umapopulação de cromossomos, onde cada um desses cromossomos representaria uma partida deOthello e seus genes representariam as jogadas do computador e seu adversário. No entanto,essa abordagem peca por representar as jogadas do computador e de seu adversário num mesmocromossomo, isso significa que ao usarmos a função aptidão e operadores genéticos o algoritmoirá evoluir as jogadas do computador e degradar as jogadas do seu adversário. O leitor pode atéestá achando que esta é uma boa solução, mas devemos lembrá-lo que Othello é um jogo ondeexiste um conflito de interesses entre dois jogadores que buscam ganhar a partida. Logo, paravencer a partida, o computador deve dispor de jogadas que se sobressaiam não só sobre aspiores jogadas de seu adversário, como também sobre as melhores. Por fim, nessa abordagema maioria dos cromossomos teria que passar por um processo de correção para que viesse arepresentar partidas válidas de Othello.

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 49

Assim, para contornarmos esse problema recorremos à solução utilizada por RAMOS &SALGADO (2001), que em seu trabalho evoluiu duas populações de cromossomos, uma re-presentando as jogadas do computador e outra representando as jogadas de seu adversário, paraimplementar a inteligência num jogo de xadrez. Segundo essa abordagem, os operadores genéti-cos vão operar nestas duas populações separadamente, originando descendentes mais adaptadospara ambas. Enquanto que a avaliação de seus cromossomos é feita levando em conta não só aqualidade das jogadas isoladamente, mas também as possíveis respostas do adversário. Logo,para se conseguir avaliar estas seqüências de jogadas computador-adversário é criada, em cadaciclo de evolução do AG, uma população misturada, constituída por cromossomos das popu-lações do computador e de seu adversário, intercalados. A figura 5.11 ilustra o processo deformação dessa terceira população.

Figura 5.11: Exemplo de população intercalada usada para cálculo de aptidão

A idéia básica desse processo é obter o produto cartesiano das duas populações, ou seja, umapopulação formada por todos os pares ordenados onde o primeiro elemento é um cromossomodo computador e o segundo é um cromossomo do adversário. Cada um desses cromossomosresultantes é formado por uma seqüência de lances ordenados de forma a representar partidasválidas de um jogo Othello como mostra a figura 5.12.

Figura 5.12: Exemplo de cromossomo intercalado usado para cálculo de aptidão

Por fim, a função de aptidão opera na população intercalada realizando desta maneira múl-tiplas avaliações para cada cromossomo das populações do computador e de seu adversário. Noexemplo da figura 5.11, cada cromossomo do computador é avaliado duas vezes e o seu méritoserá uma média dessas avaliações, dessa forma o cromossomo com maior aptidão será aqueleque se sair melhor sobre todas as estratégias de jogo presentes na população do adversário.

5.3.2.3 Seleção, Cruzamento e Mutação

Agora que já definimos a codificação e a função de aptidão da aplicação, chegou a hora dejustificar as escolhas feitas para as operações de seleção, cruzamento e mutação.

5.3. FORMA DE IMPLEMENTAÇÃO DOS ALGORITMOS 50

Começando pela seleção, optou-se pela seleção por classificação vista na seção 3.6 destetrabalho, porque esta se adapta melhor as populações onde as medidas de mérito se distan-ciam muito de um indivíduo para outro. Além do mais, a seleção por classificação evita quea população convirja rapidamente correndo o risco de ficar estacionada num ponto de máximolocal.

Na operação de cruzamento, optou-se por utilizar o cruzamento circular visto na seção3.5.1.2 deste trabalho, porque este tipo de cruzamento consegue transmitir fielmente as ca-racterísticas dos pais para os filhos evitando assim que a busca por uma boa solução siga umcaminho quase aleatório. Assim, adotou-se uma taxa de cruzamento de 90% para o uso desteoperador.

Finalmente temos o operador de mutação, devido a sua simplicidade optou-se por utilizar amutação por troca recíproca vista na seção 3.5.2.2 deste trabalho aplicada a uma taxa de 2%.

5.3.2.4 Condições de Parada, Elitismo e Níveis de Dificuldades

Os últimos detalhes sobre esta implementação são referentes à condição de parada, a taxa deelitismo e aos níveis de dificuldade.

Como vimos na seção 3.3 deste trabalho, uma boa condição de parada para uma imple-mentação de Algoritmo Genético é quando se encontra uma solução ótima ou satisfatória pararesolver o problema. No entanto, definir uma condição de parada como esta para nosso pro-blema torna-se complicado pelo fato de que nossa função de aptidão não retorna uma medidaabsoluta de satisfação para o problema, mas sim uma satisfação média calculada sobre umapequena amostragem de estratégias de jogo. Assim, mesmo que definíssemos uma vitória porqualquer placar como sendo uma solução satisfatória para o problema, não haveria garantiasde que ela satisfizesse o problema devido ao fato de que o adversário poderia responder comuma estratégia de jogo melhor. Portanto, optou-se simplesmente por estipular um patamar paraa quantidade de gerações de descendentes que serão produzidas. No nosso caso, optou-se pelovalor de 10 gerações antes do AG cessar sua execução.

Quando criamos uma nova população por cruzamento e mutação, nós temos uma grandechance de perder os melhores cromossomos de uma geração para outra como vimos na seção3.3 deste trabalho. Assim, para contornar esse problema foi adotado uso do operador de elitismoque consiste em preservar as melhores soluções de uma geração para outra. Assim, optou-sepor uma taxa de elitismo de 4 indivíduos a fim de prevenir a perda das melhores soluções jáencontradas.

Para definirmos os três níveis de dificuldade para o Algoritmo Genético, adotamos o ta-manho da população como critério mesmo sabendo que o mesmo não deve ser consideradosinônimo de aumento de desempenho da aplicação. A escolha desse critério deu-se através detestes de usuário na qual foram testadas várias combinações de parâmetros, sendo observadoque o tamanho da população era o fator que mais impactava na inteligência do computador.

5.4. APLICAÇÃO 51

Assim, de forma semelhante aos testes feitos para a Poda alfa-beta da seção 5.3.1, moldamosos diferentes níveis de dificuldade do AG como mostra a figura 5.13.

Figura 5.13: Tabela de dificuldade do Algoritmo Genético

5.4 Aplicação

Ao iniciar a aplicação o usuário será colocado diante da tela inicial do jogo como mostra afigura 5.14a. Neste ponto o usuário pode escolher entre começar uma nova partida de Othello,editar as configurações da partida ou simplesmente fechar a aplicação.

(a) Antes de uma partida (b) Após iniciar uma partida

Figura 5.14: Interface gráfica da aplicação

Ao optar por uma nova partida, o usuário é então posto diante de um tabuleiro virtual deOthello e com suas respectivas pedras posicionadas para começar a partida como mostra afigura 5.14b. A interação do jogador se dá através da ação de posicionar a seta do mouse sobreuma casa qualquer do tabuleiro que represente uma possível jogada, onde automaticamenteaparecerá uma pedra de sua cor sobre o espaço vazio, caso o jogador deseje realizar esta jogadabasta dar um clique sobre este espaço que a ação de jogar será finalizada. Independente de quemdê o primeiro lance, o jogador sempre fará uso das pedras de cor branca. Mesmo sabendo que as

5.5. OUTRAS IMPLEMENTAÇÕES 52

regras do jogo dizem que o primeiro a jogar será aquele que tiver a posse das pedras de cor preta,optou-se por não implementá-la visto que a mesma não é trivial para o funcionamento do jogoe acabaria consumindo um tempo precioso que preferimos usar em aspectos mais importantesdesse trabalho.

Na parte inferior da aplicação é exibia uma série de informações sobre a partida em an-damento. A barra de cor verde tem a função de “narrar” a partida sinalizando de quem é avez de jogar entre outras coisas. Para o caso da jogada atual pertencer ao usuário será exi-bida a mensagem “Sua vez de jogar” e para o caso da jogada pertencente ao computador amensagem “Aguardando a jogada do computador...”. Ao fim da partida é exibida a mensagem“Você venceu a partida, parabéns!” para a vitória do usuário, “Computador venceu a partida,noob!” indicando vitória do computador ou ainda “Partida terminou empatada” indicando quenão houve vencedor. Ainda nesta área, um pouco abaixo do tabuleiro, também são exibidoso número de pedras conquistadas pelo usuário e pelo computador, variando de zero a 64 paracada um deles.

Ao optar por editar as configurações da partida, uma caixa de diálogo de configuração seabrirá para o usuário. Nela o usuário poderá definir as características da partida que deseja jogarcomo quem começará jogando, qual inteligência artificial será usada pelo computador e qual onível de dificuldade ele desejará enfrentar. As configurações “default” apontam para um inícioaleatório com Algoritmo Genético jogando numa dificuldade iniciante. A caixa de diálogo deconfiguração é exibida na figura 5.15.

Figura 5.15: Interface gráfica de configuração do jogo

5.5 Outras Implementações

Com o objetivo de analisar o desempenho das duas inteligências artificiais estudadas por essetrabalho foi necessário a implementação de uma classe de benchmark. Essa classe simula váriaspartidas entre dois jogadores computador, um usando a técnica de Poda alfa-beta e o outrousando a técnica de Algoritmos Genéticos, com todas as combinações de dificuldade possíveis.Ao fim do processamento é gerado um relatório contendo uma série de dados que serão ao deestudo por este trabalho.

Capítulo 6

Estudo de Caso

Ao fim da nossa implementação foram realizados inúmeros testes com o objetivo de analisar odesempenho das duas inteligências artificiais estudadas por esse trabalho. Assim, com o intuitode descobrir qual foi a IA que melhor se adaptou ao domínio do jogo Othello, realizamos testesexplorando as seguintes situações:

• Algoritmo Genético vs Poda alfa-beta

• Jogador Computador vs Jogador Humano

Os testes para Algoritmo Genético vs Poda alfa-beta foram realizados de forma automáticapela classe de benchmark. Esta classe realiza 10 partidas para cada combinação de inteligênciae dificuldade disponível na aplicação, totalizando 90 partidas disputadas, sendo que cada IArealiza o primeiro lance em metade delas. Ao fim da execução, é gerado um relatório comomostra a tabela 6.1.

Nível Vitórias Vitórias Empates Pontos Pontos Tempos Tempos(AG, αβ)* AG αβ AG** αβ** AG*** αβ***(Inic., Inic.) 7 3 0 41,6 17,8 3,1088 0,0172

(Interm., Inic.) 9 1 0 46,5 17,5 4,0114 0,0165(G. O., Inic.) 9 1 0 43,9 15,5 5,2785 0,0159

(Inic., Interm.) 6 4 0 32,1 31,9 5,2945 0,0840(Interm., Interm.) 4 6 0 27,8 33,7 5,0939 0,1514(G. O., Interm.) 8 2 0 37,6 26,4 5,5942 0,1965

(Inic., G. O.) 2 6 2 25,6 38,4 5,6665 0,7285(Interm., G. O.) 2 8 0 27,8 36,2 5,5079 1,4817(G. O., G. O.) 6 4 0 33 31 5,7163 2,1493

* = Par de níveis de dificuldade do confronto AG vs αβ

** = Média de pontos obtidos

*** = Média de tempo em segundos de cada lance realizado

Tabela 6.1: Resumo dos resultados obtidos após a execução da classe de benchmark

53

54

Como podemos ver, cada linha da tabela representa o resultado do confronto entre as IAse seus respectivos níveis de dificuldade. A primeira coluna tem o papel de identificar o con-fronto como, por exemplo, na linha dois temos o par formado por algoritmos genéticos e podaalfa-beta jogando, respectivamente, com níveis de dificuldade intermediário e iniciante. Asdemais colunas identificam, para cada algoritmo, a quantidade de vitórias, média de pontosconquistados e tempo médio de resposta de uma jogada.

Analisando os tempos de resposta de cada IA podemos perceber que o algoritmo gené-tico responde com um intervalo de tempo bem maior que o apresentado por seu concorrentealfa-beta. No entanto, como podemos ver na figura 6.1, os tempos de resposta do algoritmogenético apresentam pouca variação na medida em que aumentamos a dificuldade do jogo, ouseja, quando aumentamos o tamanho de suas populações. Por outro lado, a poda alfa-beta nosdeixa pistas de um crescimento exponencial de seus tempos de resposta conforme se aprofundaem sua busca, ou seja, quando aumentamos o seu nível de dificuldade. Portanto, esse gráfico nosfaz acreditar que se continuássemos a aumentar a dificuldade de ambos os algoritmos, segundoos critérios apresentados na seção 5.3 deste trabalho, teríamos rapidamente um cenário ondeos tempos de resposta apresentados pela poda alfa-beta ultrapassaria os tempos do algoritmogenético e possivelmente se tornariam impraticáveis pela aplicação.

Figura 6.1: Gráfico de tempo médio de resposta dos algoritmos

Analisando a quantidade de pontos obtidos pelos algoritmos em cada nível de dificuldadejogado, podemos perceber que o algoritmo genético se saiu vitorioso em todos os cenárioscomo mostra a figura 6.2. No entanto, apesar das grandes pontuações conquistadas pelo por ele,podemos perceber que na medida em os níveis de dificuldade foram aumentando a poda alfa-

beta conseguiu diminuir a diferença para o seu concorrente genético. Logo, de forma análogaa análise dos tempos de resposta, acreditamos que em algum ponto no eixo das dificuldades apoda alfa-beta irá conseguir superar o algoritmo genético, entretanto, não temos como especularquando, pois a pontuação de ambos parece crescer de forma semelhante.

55

Figura 6.2: Gráfico de pontuação média dos algoritmos

Encerramos nossa análise sobre o confronto Algoritmo Genético vs Poda alfa-beta com ográfico de vitórias ilustrado na figura 6.3. Nele podemos ver que o algoritmo genético con-quistou uma porcentagem maior de vitórias do que seu concorrente, isso nos faz acreditar queo algoritmo genético pode ser uma boa alternativa para substituir os tradicionais algoritmos debusca em problemas desse tipo. No entanto, vale apena ressaltar que boa parte desse desequilí-brio foi causado pelo fraco desempenho do nível de dificuldade iniciante da poda alfa-beta quenão correspondeu a altura dos demais.

Figura 6.3: Gráfico de vitórias dos algoritmos

Para os testes Jogador Computador vs Jogador Humano convidamos Lucas Cherem de Ca-margo Rodrigues, presidente e criador da Federação Brasileira de Othello (FBOTHELLO). Lu-cas joga Othello há aproximadamente seis anos e durante esse período conquistou vários títulosimportantes como os campeonatos brasileiros de 2008 e 2010, além de uma 3o colocação nopan-americano de 2010. Nos testes, Lucas disputou partidas contra todas as combinações deIA e níveis de dificuldade disponíveis pela aplicação e se saiu vencedor em todas elas. Ao fimele avaliou o jogo como desafiador para jogadores iniciantes e medianos, mas que deixa muitoa desejar contra jogadores experientes. Segundo Lucas, a aplicação carece de estratégias avan-çadas de jogo que priorize a conquista dos cantos do tabuleiro. Por fim, ele elegeu o AlgoritmoGenético como sendo a melhor opção de IA dessa aplicação.

Capítulo 7

Conclusão e Trabalhos Futuros

7.1 Considerações Finais

Este trabalho sugeriu a utilização de um algoritmo evolucionário aplicado diretamente na estru-tura de tomada de decisão de jogos eletrônicos com o intuito de avaliar se os tempos de respostae qualidade do lances retornados são ou não satisfatórios o bastante para adotar essa técnica nolugar dos tradicionais algoritmos que privilegiam a busca exaustiva pelo melhor lance.

Assim, como visto no capítulo anterior, nossa implementação de Algoritmos Genéticos con-seguiu ser bem sucedida ao retornar lances de maior qualidade que nossa implementação parao algoritmo de Poda alfa-beta. Contudo, o AG não conseguiu entregá-los em um intervalo detempo menor que seu concorrente.

Analisando os resultados obtidos e os detalhes da implementação, constatou-se que a natu-reza instável do jogo Othello, que permite que viradas de jogo de um lance para o outro, expôsas fraquezas da Poda alfa-beta através do efeito de horizonte. Por outro lado, o Algoritmo Ge-nético, por se valer de cromossomos longos que permite a ele aprofundar-se até o último lancedo jogo, acabou por conseguir realizar melhores jogadas.

No entanto, essa forma de codificação em conjunto com sua função de aptidão tambémapresentou pontos negativos, em específico no que diz respeito aos tempos de resposta do algo-ritmo. Para se ter idéia do gargalo que se forma, imagine que para avaliar a aptidão de um únicocromossomo é necessário intercalá-lo com todos os cromossomos da população adversária paraem seguida estender a árvore de estados de cada uma deles até o fim.

O baixo desempenho apresentado contra um jogador humano experiente foi encarado comnaturalidade, pois se entende que é um problema exclusivo da função de avaliação dos doisalgoritmos que foi concebida por um jogador iniciante e carente de estratégias avançadas dejogo.

Tendo em vista os fatos mencionados, consideramos viável a substituição de algoritmosde busca seqüencial por algoritmos evolutivos na tomada de decisão de jogos eletrônicos. Noentanto, advertimos os leitores que o sucesso ou fracasso de cada implementação dependerá

56

7.2. TRABALHOS FUTUROS 57

do domínio do jogo e da habilidade do desenvolvedor para adaptar o Algoritmo Genético aoproblema.

7.2 Trabalhos Futuros

Uma proposta deixada por este trabalho seria uma nova implementação do Algoritmo Genéticofazendo uso de multithread, onde cada thread ficaria responsável por calcular o mérito de umdeterminado cromossomo. Assim, acreditamos que essa nova implementação poderia transporos problemas de desempenho da aplicação original.

Outra proposta deixada seria a de melhorar as funções de aptidão e utilidade dos algoritmosanexando a elas estratégias avançadas de jogo que seriam levantadas através de entrevistas comjogadores com experiência nesse tipo de jogo.

Referências Bibliográficas

ALLIOT, J.-M. & DURAND, N. (1996), Artificial Evolution, Springer-Verlag, London,pp. 307–319.

CARVALHO, L. (2008), Um jogo de damas evolutivo, (trabalho de conclusão de curso), Insti-tuto de Computação, Universidade Federal de Alagoas, Maceió.

CATARINA, A. (2005), Algoritmos evolutivos aplicados ao processo de análise de dados ge-ográficos, (trabalho de conclusão de curso), Instituto Nacional de Pesquisas Espaciais, SãoJosé dos Campos.

Corel Corporation (1985-2010), ‘Paint Shop Pro Photo X2’.URL: http://www.corel.com/, último acesso em 25 de dezembro de 2010

DAVIS, L. (1991), Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York.

DEJONG, K. (1975), The analysis and behaviour of a class of genetic adaptive systems, (tesede phd), Department of Computer and Communication Sciences, University of Michigan,Michigan.

Eclipse Foundation (2004-2010), ‘Eclipse IDE for Java EE Developers’.URL: http://www.eclipse.org/downloads/, último acesso em 25 de dezembro de 2010

GALDINO, C. (2007), Inteligência artificial aplicada no desenvolvimento de jogos de compu-tador, (trabalho de conclusão de curso), Universidade Federal de Itajubá, Itajubá.

GOLDBERG, D. (1989), Genetic Algorithms in Search, Optimization, and Machine Learning,Addison-Wesley, Boston.

Grow Jogo e Brinquedos S.A. (n.d.), ‘Reversi: Regras’.URL: http://www.jogos.antigos.nom.br/regrasesc/othelo.pdf, último acesso em 02 de feve-

reiro de 2010

HOLLAND, J. (1986), Machine Learning – An Artificial Intelligence Approach, Vol. 2, MorganKaufmann, Palo Alto, pp. 593–624.

58

REFERÊNCIAS BIBLIOGRÁFICAS 59

KORF, R. (1996), Artificial intelligence search algorithms, (trabalho de conclusão de curso),Computer Science Department, University of California, Los Angeles.

LACERDA, E. & CARVALHO, A. (1999), Sistemas Inteligentes: Aplicações a recursos hídri-

cos e ciências ambientais, Associação Brasileira de Recursos Hídricos, Porto Alegre, pp. 99–150.

LOPES, R. (2003), Um algoritmo genético baseado em tipos abstratos de dados e sua espe-cificação em z, (tese de doutorado em informática), Universidade Federal de Pernambuco,Recife.

LUGER, G. (2004), Inteligência Artificial: Estruturas e estratégias para a solução de proble-

mas complexos, 4a edn, Bookmann, Porto Alegre.

OBITKO, M. (1998), ‘Uma introdução aos algoritmos genéticos com java applets’.URL: http://www.professor.webizu.org/ga/, último acesso em 25 de dezembro de 2010

Oracle Corporation (1977-2010), ‘Java SE Development Kit (JDK)’.URL: http://www.oracle.com/technetwork/java/javase/downloads/index.html, último acesso

em 25 de dezembro de 2010

RAMOS, N. & SALGADO, S. (2001), Jogo de xadrez por algoritmos genético-evolutivos, (tra-balho de conclusão de curso), Instituto Superior Técnico, Lisboa.

RODRIGUES, L. (2006), ‘FBOTHELLO: Federação Brasileira de Othello’.URL: http://www.fbothello.hd1.com.br/index.html, último acesso em 02 de fevereiro de 2010

RUSSUEL, S. & NORVIG, P. (2004), Inteligência Artificial, 2a edn, Editora Campos, Rio deJaneiro.

SARTINI, B. & GARBUGIO, G. (2004), Uma introdução a teoria dos jogos, in ‘II Bienal daSBM’, Bahia.

SCHWAB, B. (2004), AI Game Engine Programming, Charles River Media, Hingham.

VIEIRA FILHO, V. (2005), Revolution ai engine: Desenvolvimento de um motor de inteligên-cia artificial para criação de jogos eletrônicos, (trabalho de conclusão de curso), Centro deInformática, Universidade Federal de Pernambuco, Recife.

Wikipédia: A enciclopédia livre (n.d.), ‘Reversi/Othello’.URL: http://en.wikipedia.org/wiki/Reversi, último acesso em 02 de fevereiro de 2010