Algorítimos Genéticos

professor

O que são algoritmos genéticos?

Algoritmos genéticos (AGs) pertencem à família dos algoritmos evolucionários. Eles imitam o processo de seleção natural da biologia. Assim, soluções para problemas complexos podem ser encontradas. Cada possível solução é representada como um “indivíduo” em uma população. Esses indivíduos geralmente são codificados como cadeias binárias ou números reais. A qualidade de cada um é medida por uma função de aptidão (*fitness*). Quanto maior o valor de aptidão, melhor é a solução. Portanto, o algoritmo busca maximizar (ou minimizar) essa função.

Principais operadores evolutivos

Três operadores biológicos são simulados: seleção, cruzamento e mutação. A seleção escolhe os indivíduos mais aptos para reprodução. O cruzamento combina partes de dois pais para gerar filhos. A mutação introduz pequenas alterações aleatórias em um indivíduo. Dessa forma, a diversidade genética é mantida ao longo das gerações. Esses operadores são aplicados repetidamente até um critério de parada. Exemplos de critério incluem número máximo de gerações ou convergência.

Formulação matemática básica

Seja uma população de tamanho *N* na geração *t*: P(t) = {x_1(t), x_2(t), ..., x_N(t)}. Cada indivíduo x_i possui um vetor de genes. A função aptidão é f(x_i), que retorna um valor real. A probabilidade de seleção do indivíduo *i* é proporcional a f(x_i). Para maximização, usa-se p_i = f(x_i) / Σ f(x_j). No cruzamento de um ponto, dois pais trocam genes após uma posição *k*. A mutação flip inverte um bit com probabilidade p_m (taxa de mutação). A nova população P(t+1) é formada pelos filhos e, talvez, pelos melhores pais (elitismo). O processo iterativo busca o ótimo global x* tal que f(x*) ≥ f(x) para todo x. Matematicamente, o AG é um método estocástico de otimização. Ele não exige derivadas nem convexidade da função objetivo. Por isso, é amplamente usado em problemas com muitos máximos locais.

Exemplo clássico: maximização de uma função

Considere a função f(x) = x * sen(10π * x) + 1 no intervalo [0, 1]. O objetivo é encontrar o valor de x que maximiza f(x). Esta função possui várias oscilações, sendo um teste comum para AGs. O máximo global aproximado ocorre em torno de x ≈ 0.85, com f ≈ 2.85. Resolveremos este problema com um AG binário de 20 bits (precisão ~ 1e-6). Enunciado do problema: Implemente um algoritmo genético para maximizar f(x) no domínio dado. Use população de 50 indivíduos, 100 gerações, taxa de cruzamento 0.8 e mutação 0.01. Adote seleção por roleta e elitismo (manter o melhor indivíduo). Ao final, exiba o melhor x encontrado e seu valor de f(x). Gere dois gráficos: (1) evolução do melhor fitness por geração; (2) população final sobre a curva da função. A resolução em Python para o Google Colab está abaixo. O código é autoexplicativo e utiliza apenas NumPy e Matplotlib. Ao executar, o gráfico da esquerda mostra a melhora contínua do fitness. O gráfico da direita exibe todos os indivíduos finais espalhados perto do pico. O asterisco azul indica a melhor solução encontrada pelo AG. Esse exemplo demonstra a robustez do método mesmo sem conhecimento prévio. A convergência é alcançada, embora com variabilidade entre execuções. Para problemas reais, ajustes nos parâmetros são frequentemente necessários. Assim, os algoritmos genéticos oferecem uma ferramenta flexível e poderosa. Eles são aplicados em engenharia, finanças, robótica e muito mais. Com a prática, você poderá adaptá-los a seus próprios desafios.

Computação Evolucionaria

professora

O que é Computação Evolucionária?

Computação evolucionária (CE) é um subcampo da inteligência artificial inspirado na teoria da evolução natural. Ela utiliza mecanismos como seleção, cruzamento e mutação para resolver problemas de otimização e busca. Diferentemente de métodos tradicionais, a CE não exige derivadas ou informações gradientes. Em vez disso, ela trabalha com uma população de soluções candidatas, que evoluem ao longo de gerações. Esse processo é estocástico e robusto para espaços de busca complexos e multimodais.

Frequentemente, a CE é aplicada quando o espaço de soluções é enorme ou pouco compreendido. Por exemplo, ela pode projetar antenas, ajustar hiperparâmetros de redes neurais ou criar rotas logísticas. Sua flexibilidade é um grande atrativo, embora o custo computacional possa ser elevado. No entanto, com o aumento da capacidade de processamento, seu uso tem se popularizado rapidamente.

Fundamentos Matemáticos

Para entender a CE, precisamos formalizar alguns conceitos básicos. Uma solução é representada como um vetor \(\mathbf{x} = (x_1, x_2, …, x_n)\) em um domínio \(\mathcal{D}\). A qualidade dessa solução é medida por uma função de aptidão (fitness) \(f: \mathcal{D} \rightarrow \mathbb{R}\). O objetivo é encontrar \(\mathbf{x}^*\) que maximize (ou minimize) \(f(\mathbf{x})\). Formalmente, temos:

\[ \mathbf{x}^* = \arg\max_{\mathbf{x} \in \mathcal{D}} f(\mathbf{x}) \]

A seleção é baseada na aptidão relativa de cada indivíduo. Uma abordagem comum é a seleção por roleta, onde a probabilidade \(p_i\) do indivíduo \(i\) ser escolhido é:

\[ p_i = \frac{f(\mathbf{x}_i)}{\sum_{j=1}^{N} f(\mathbf{x}_j)} \]

para problemas de maximização (assumindo aptidões positivas). Em seguida, o cruzamento (recombinação) combina dois pais para gerar dois filhos. Para representação binária, o cruzamento de um ponto é dado por:

\[ \mathbf{y}_1 = (x_1^{(1)}, …, x_k^{(1)}, x_{k+1}^{(2)}, …, x_n^{(2)}) \] \[ \mathbf{y}_2 = (x_1^{(2)}, …, x_k^{(2)}, x_{k+1}^{(1)}, …, x_n^{(1)}) \]

onde \(k\) é o ponto de corte aleatório. Já a mutação introduz variação aleatória, geralmente com probabilidade \(p_m\). Para variáveis contínuas, a mutação gaussiana adiciona um ruído \(\mathcal{N}(0, \sigma^2)\):

\[ x’_i = x_i + \mathcal{N}(0, \sigma^2) \]

Esses operadores são aplicados repetidamente até que um critério de parada seja satisfeito. A convergência não é garantida para o ótimo global, mas empíricamente é muito eficaz.

Algoritmo Genético Canônico

O algoritmo genético (AG) é o exemplo mais conhecido de CE. Ele segue um fluxo simples: inicialização, avaliação, seleção, cruzamento, mutação e substituição. Cada geração produz uma nova população, geralmente do mesmo tamanho da anterior. A pressão seletiva direciona a busca para regiões promissoras do espaço. Contudo, a diversidade deve ser mantida para evitar convergência prematura.

Parâmetros importantes incluem o tamanho da população, a taxa de cruzamento e a taxa de mutação. Taxas altas de mutação podem transformar o AG em uma busca aleatória pura. Por outro lado, taxas muito baixas reduzem a capacidade de explorar novas áreas. O equilíbrio entre exploração e explotação é obtido por meio de ajustes empíricos. Muitas variantes existem, como o algoritmo de evolução diferencial e a programação genética.

Exemplo Clássico: Maximização de uma Função

Considere o problema de maximizar a função \(g(x) = x \cdot \sin(10\pi x) + 1\) no intervalo \([0, 1]\). Essa função é altamente oscilatória e possui múltiplos máximos locais. O máximo global está próximo de \(x = 0.85\), com valor aproximado de 1.85. Nosso objetivo é encontrar esse ponto usando um algoritmo genético simples. A aptidão será o próprio valor da função, e a representação será um vetor de bits (codificação binária).

Abaixo apresentamos um código Python completo para resolver esse problema no Google Colab. Ele utiliza uma população de 50 indivíduos, 20 gerações, cruzamento de dois pontos e mutação bit-flip. Ao final, são gerados dois gráficos: a evolução do melhor fitness e a função com o melhor ponto encontrado. O código é autoexplicativo e comentado para facilitar o entendimento de iniciantes.

Esse código é executado diretamente no Colab e produz dois gráficos claros. O primeiro mostra a evolução do melhor e da média da aptidão ao longo das gerações. O segundo exibe a função contínua e o ponto vermelho que representa a melhor solução. Você pode alterar o número de gerações ou a taxa de mutação para observar mudanças. A convergência é rápida, e geralmente o algoritmo encontra um valor próximo de 1.85.

Considerações Finais

A computação evolucionária é uma ferramenta poderosa e acessível para problemas difíceis. Ela não requer conhecimento profundo de cálculo ou álgebra linear. Contudo, é importante entender seus parâmetros e limitações. Muitas melhorias podem ser incorporadas, como elitismo, adaptação de taxas e nichos. A área é ativa em pesquisa, com aplicações em engenharia, finanças e robótica.

Para um iniciante, recomendamos começar com o algoritmo genético clássico. Depois, explore variantes como evolução diferencial ou estratégias evolutivas. Lembre-se de que a CE não garante o ótimo global, mas oferece boas aproximações. Seu caráter estocástico exige múltiplas execuções para resultados confiáveis. Por fim, a combinação com outras técnicas híbridas tem sido cada vez mais utilizada.

Este material foi elaborado para fornecer uma base sólida e prática. Esperamos que você experimente o código e modifique os parâmetros livremente. A evolução artificial é fascinante e repleta de possibilidades criativas. Boa sorte em sua jornada no mundo da computação evolucionária!