Skip to content

Instantly share code, notes, and snippets.

@Hydrotoast
Created May 20, 2013 05:12
Show Gist options
  • Save Hydrotoast/5610527 to your computer and use it in GitHub Desktop.
Save Hydrotoast/5610527 to your computer and use it in GitHub Desktop.
# author -- Gio Borje
import random
class GeneticProcessor(object):
def __init__(self, population_size, fitness_fn):
self.population_size = population_size
self.fitness_fn = fitness_fn
def next_gen(self, population):
"""Returns the next generation of a population based on fitness."""
mating_pool = self.select(population)
offspring = self.recombine(mating_pool)
return mating_pool
def select(self, population):
"""Generates a mating pool based on roulette selection."""
fitnesses = [self.fitness_fn(individual) for individual in population]
total_fitness = sum(fitnesses)
rel_fitness = [fitness/total_fitness for fitness in fitnesses]
probs = [sum(rel_fitness[:i+1]) for i, fitness in enumerate(rel_fitness)]
# Perform roulette selection
mating_pool = []
while len(mating_pool) != self.population_size:
r = random.random()
for i, individual in enumerate(population):
if r <= probs[i]:
mating_pool.append(individual)
break
return mating_pool
def total_fitness(self, population):
"""Returns the total fitness of a population."""
return sum(self.fitness_fn(individual) for individual in population)
def recombine(self, mating_pool):
"""Performs recombination on a mating pool to produce offspring."""
cutpoint = random.randint(1, self.population_size - 1)
# Partition the mating pool
left = mating_pool[:len(mating_pool) // 2]
right = mating_pool[len(mating_pool) // 2:]
# Handle the odd case of mates
offspring = [] if len(mating_pool) % 2 == 0 else [mating_pool.pop()]
# Perform crossover
for i in range(len(left)):
offspring.append(right[i][:cutpoint] + left[i][cutpoint:])
offspring.append(left[i][:cutpoint] + right[i][cutpoint:])
return offspring
def generate_population(size):
"""Generates all individuals of the population."""
population = []
bitlength = len(bin(size)[2:])
for i in range(size):
population.append(bin(i)[2:].zfill(bitlength))
return population
def even_ones(chromosome):
"""Prefers chromosomes with 1 at even positions."""
even_sum = sum(eval(allele) for pos, allele in enumerate(chromosome) if pos % 2 == 0)
even_sum -= sum(eval(allele) * 0.5 for pos, allele in enumerate(chromosome) if pos % 2 == 1)
return even_sum
if __name__ == '__main__':
population = generate_population(31)
processor = GeneticProcessor(32, even_ones)
print('Initial Generation', population)
for i in range(1, 40):
population = processor.next_gen(population)
# print('Generation %d %d: %s' % (i, processor.total_fitness(population), population))
print('Final Generation Score %d: %s' % (processor.total_fitness(population), population))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment