Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fitness proportionate selection (roulette wheel selection) in Python

I have a list of objects (Chromosome) which have an attribute fitness (chromosome.fitness is between 0 and 1)

Given a list of such objects, how can I implement a function which returns a single chromosome whose chance of being selected is proportional to its fitness? That is, a chromosome with fitness 0.8 is twice as likely to be selected as one with fitness 0.4.

I've found a few Python and pseudocode implementations, but they are too complex for this requirement: the function needs only a list of chromosomes. Chromosomes store their own fitness as an internal variable.

The implementation I already wrote was before I decided to allow chromosomes to store their own fitness, so was a lot more complicated and involved zipping lists and things.

----------------------------EDIT----------------------------

Thanks Lattyware. The following function seems to work.

def selectOne(self, population):
    max     = sum([c.fitness for c in population])
    pick    = random.uniform(0, max)
    current = 0
    for chromosome in population:
        current += chromosome.fitness
        if current > pick:
            return chromosome
like image 746
Ivy Avatar asked Apr 25 '12 21:04

Ivy


1 Answers

Use numpy.random.choice.

import numpy.random as npr
def selectOne(self, population):
    max = sum([c.fitness for c in population])
    selection_probs = [c.fitness/max for c in population]
    return population[npr.choice(len(population), p=selection_probs)]
like image 95
cw' Avatar answered Oct 23 '22 04:10

cw'