Il Wed, 04 Mar 2009 21:30:54 +0100, Peter Otten ha scritto: > mattia wrote: > >> Hi everyone, I'm new to python and I want to create some simple code in >> order to code the classical genetic algorithm example: given a >> population of chromosomes, encoded using 1 and 0, find the chromosome >> with the maximum number of 1s. Now, despite all the code used to >> implement the solution, I'm wondering if there is a better way to use >> the so-called roulette wheel selection in this problem. Here I paste >> the code of my solution, any advice will be helpful: > > Your code looks good to me. > >> from random import randint, random >> >> def create_chromosome(min, max, length): >> chromosome = [] >> for i in range(length): >> chromosome.append(randint(min, max)) >> return chromosome >> >> def fitness(chrm, ffunc=sum): >> return ffunc(chrm) > > fitness = sum > > has the same effect, without the extra indirection. > >> def create_population(nelem, min, max, length): >> return [create_chromosome(min, max, length) for i in range(nelem)] >> >> def get_fitness_and_population(population): >> return [(fitness(x), x) for x in population] >> >> def get_roulette_wheel(population): >> roulette_wheel = [] >> index = 0 >> >> for x in get_fitness_and_population(population): >> for j in range(x[0]): >> roulette_wheel.append(index) >> index += 1 > > Make that > > for index, x in enumerate(get_fitness_and_population(population)): > ... > > I'd also pass the the fitness function explicitly around instead of > making it a global. > >> return roulette_wheel >> >> pop = create_population(5, 0, 1, 10) >> rw = get_roulette_wheel(pop) >> print(rw) >> print(len(rw)) >> ri = randint(0, len(rw) - 1) >> print("Random index:", rw[ri], ", value:", pop[rw[ri]]) > > But these are minor nits :) > > Here's a slightly different approach: > > from random import randint, choice > > def create_chromosome(min, max, length): > return [randint(min, max) for i in range(length)] > > def create_population(nelem, min, max, length): > return [create_chromosome(min, max, length) for i in range(nelem)] > > def get_fitness_and_population(population, fitness): > return [(fitness(x), x) for x in population] > > def get_roulette_wheel(weight_value_pairs): > roulette_wheel = [] > for weight, value in weight_value_pairs: > roulette_wheel += [value]*weight > return roulette_wheel > > if __name__ == "__main__": > pop = create_population(5, 0, 1, 10) > fap = get_fitness_and_population(pop, sum) rw = > get_roulette_wheel(fap) > print("Random value:", choice(rw)) > > Note how get_roulette_wheel() is now completeley independent of the > concrete problem you are using it for. > > Peter
Well, thank you very much, I'm new to python and I'm everyday experiencing how in just one line you can write very powerful statements. Loved the line: roulette_wheel += [value]*weight, another useful thing learned today. -- http://mail.python.org/mailman/listinfo/python-list