quarta-feira, 17 de março de 2010

Sejamos selectivos!

Existem vários métodos de selecção. A grande questão que se coloca a um designer é a seguinte: como seleccionar os progenitores de modo a garantir qualidade mas ao mesmo tempo não fazer convergir prematuramente a população para um máximo local?

A selecção por torneio procura responder a essa questão. No caso mais comum o torneio tem uma dimensão entre 2 e 5 e é determinista , isto é, o melhor é sempre escolhido para reprodução e variação. O Sérgio Santos manda a sua solução:

def torneio(num_progenitores, populacao):
tam_torneio = 5
progenitores = []

for n in range(num_progenitores):
elems_torneio = []
for i in range(tam_torneio):
elems_torneio.append(choice(populacao))
elems_torneio.sort(key=itemgetter(1))
progenitores.append(elems_torneio[0])
return progenitores

O que podemos dizer. Bem, desde logo que funciona. Em segundo lugar, usa o método choice do módulo random. Usa um padrão de desenho simples: a partir de uma lista vazia vai acumulando os resultados parciais nessa lista. Conclusão: está bom!

Mas vou apresentar-vos uma alternativa:


def tournament_sel(population, numb_offspring, t_size):
return [one_tournament(population,t_size) for count in range(numb_offspring)]

def one_tournament(population,size):
"""Maximization Problem.Deterministic"""
pool = sample(population, size)
pool.sort(key=itemgetter(1), reverse=True)
return pool[0]

Quais são as diferenças principais? A separação do problema em duas partes, o uso de listas por comprensão (padrão de desenho alternativo) e o uso do método sample do módulo random para me dar de uma só vez todos os candidatos do torneio. No meu caso faço uma escolha sem reposição. Usando o choice a escolha é com reposição.

Ernesto Costa (com contributos de Sérgio Santos)

Sem comentários:

Enviar um comentário