sábado, 8 de março de 2014

Execute-se

Os algoritmos de inspiração biológica são algoritmos estocásticos. Significa isso, dentre outras coisas, que duas execuções consecutivas do mesmo algoritmo, mesmo com a mesma parametrização e população inicial dá, em geral, resultados diferentes. Daí que seja necessário executar os algoritmos várias vezes a analisar os resultados obtidos do ponto de vista estatístico, por exemplo, indicado os valores médios e o desvio padrão. Podemos alterar o nosso código acrescentando em particular uma nova função responsável pelas várias execuções e armazenamento dos resultados.
import matplotlib.pyplot as plt
from random import random,randint, shuffle, uniform,sample
from operator import itemgetter
from math import sqrt
from copy import deepcopy

def run(numb_runs,numb_generations,size_pop, size_cromo, prob_mut,prob_cross,selection,recombination,mutation,survivors, fit_func, phenotype,elite,t_size):
    best,average = sea(numb_generations,size_pop, size_cromo, prob_mut,prob_cross,selection,recombination,mutation,survivors, fit_func, phenotype,elite,t_size)
    best_of_best = [best]
    average_of_average = [average] 
    for i in range(numb_runs-1):
        best,average = sea(numb_generations,size_pop, size_cromo, prob_mut,prob_cross,selection,recombination,mutation,survivors, fit_func, phenotype,elite,t_size)
        best_of_best.append(best)
        average_of_average.append(average)
    best_by_gener = list(zip(*best_of_best))
    average_by_gener = list(zip(*average_of_average))
    data_best = [max(elem) for elem in best_by_gener]
    data_average = [sum(elem)/len(elem) for elem in average_by_gener]
    display(data_best, data_average)
Como se pode observar a função run chama o algoritmo evolucionário várias vezes, e espera que este devolva os valores do melhor indivíduo em cada geração e a média da qualidade dos indivíduos da população, também aqui em cada geração.

Por outro lado, a visualização é feita de modo simples, estando implementada para o caso concreto dos números de João Brandão.
def display(best,average):
    x = list(range(len(best)))
    plt.title('João Brandão using a Simple EA.')
    plt.xlabel('Generation')
    plt.ylabel('Fitness')
    plt.grid(True)
    plt.plot(x,best, label='Best')
    plt.plot(x,average, label='Average')
    plt.legend(loc='lower right')
    plt.show()
Estes gráficos são muito informativos e devemos aprender a interpretá-los. Dizem-nos, por exemplo, quantas gerações foram necessárias em média para alcançar a melhor solução; quando o valor do melhor e a média estão muito juntas significa uma perda de diversidade da população (e se isso acontece muito cedo indicia convergência prematura); se o melhor e a média estão muito afastados pode querer dizer que tivemos sorte a encontrar um elemento muito bom (o que pode acontecer por o problema ser muito difícil).

Sem comentários:

Enviar um comentário