Source code for infpy.genepy.population
#
# Copyright John Reid 2007
#
from random import random
from itertools import chain
[docs]class Population(object):
"""
A collection of individuals of a particular species
"""
species = None # defines initialisation, reproduction, and mutation
fitness_fn = None # scores an individual
minimise = True # minimise or maximise the fitness?
breeding_proportion = .1 # proportion of population selected as parents
carry_over_parents = True # include parents in next generation?
p_mutation = .1 # chance of mutation of an individual at each generation
post_generation_process = None # function to be called at end of every generation
def __init__(
self,
size,
species,
fitness_fn
):
self.species = species
self.fitness_fn = fitness_fn
self.individuals = [ self.species.random_individual() for i in xrange(size) ]
[docs] def generation(self):
"Run through a generation"
self.score_individuals()
self.select_parents()
self.reproduce()
self.combine_generations()
self.mutate()
if self.post_generation_process:
self.post_generation_process(self)
[docs] def score_individuals(self):
for i in self.individuals: i.fitness = self.fitness_fn(i)
[docs] def select_parents(self):
self.individuals.sort(key=lambda x: x.fitness, reverse=not self.minimise)
self.most_fit = self.individuals[0]
num_parents = int(self.breeding_proportion*len(self.individuals))
self.parents = self.individuals[:num_parents]
[docs] def reproduce(self):
# how many children
if self.carry_over_parents: num_children = len(self.individuals) - len(self.parents)
else: num_children = len(self.individuals)
from random import choice
self.children = [ self.species.mate(choice(self.parents), choice(self.parents)) for i in xrange(num_children) ]
[docs] def combine_generations(self):
self.individuals = list(chain(self.parents,self.children))
[docs] def mutate(self):
for i in self.individuals:
if random() < self.p_mutation:
self.species.mutate(i)