Finalmente, chegamos a parte mais interessante da série: implementar a GA. Partindo de uma população randômica de k agentes, cada um será testado em uma série de n games aleatórios, conforme discutido no post anterior. A cada geração, os agentes de maior desempenho terão uma probabilidade maior de serem selecionados para reprodução, o que dará origem aos membros da próxima geração, e assim sucessivamente.
Usaremos uma GA contínua, com operações de mutação e crossover relativamente simples, mas que parecem funcionar bem em diversos casos. O encode/decode de um cromossomo binário requer um pouco mais de código e provavelmente o desempenho seria inferior, por isso o evitamos.
O algoritmo nos retornará uma lista com o histórico de todas as gerações, assim podemos visualizar claramente a evolução dos agentes ao longo do tempo. Há uma infinidade de dados e estatísticas interessantes que podem ser modelados, por exemplo: qual a distribuição de probabilidade do número de linhas removidas por um determinado agente? Dado um determinado agente, qual a distribuição de probabilidade da altura da grade? Estamos interessados na evolução dos agentes, por enquanto.
Lembrando que os agentes não sabem qual a próxima peça, o que levante outra questão interessante: qual efeito isso causa no desempenho do agente? As distribuições de probabilidade comentadas acima serão as mesmas? Hora de sujar as mãos...