Roulette wheel

mattia gervaz at gmail.com
Thu Mar 5 16:05:17 EST 2009


Il Thu, 05 Mar 2009 18:07:29 +0100, Peter Otten ha scritto:

> mattia wrote:
> 
>> The last question: how can I improve readability in this piece of code?
>> 
>> def crossover(pop, prob=0.6):
>>     """
>>     With a crossover probability cross over the parents to form new
>>     offspring. If no crossover was performed, offspring is the exact
>>     copy of parents. """
>>     cpop = []
>>     for i in range(0, len(pop), 2):
>>         # crossover
>>         if prob > random():
>>             crossover_point = randint(0, len(pop[i])-1) nchromosome1 =
>>             pop[i][:crossover_point] + pop[i+1][crossover_point:]
>>             nchromosome2 = pop[i+1][:crossover_point] +
>>             pop[i][crossover_point:]
>>         else:
>>             nchromosome1 = pop[i][:]
>>             nchromosome2 = pop[i+1][:]
> 
>>         cpop += [nchromosome1] + [nchromosome2]
> 
> I'd write that as
> 
> cpop.append(nchromosome1)
> cpop.append(nchromosome2)
> 
> thus avoiding the intermediate lists.
> 
>>     return cpop
>> 
>> And with this one my example is complete!
> 
> Just for fun here's an alternative version of your function
> 
> def generate_crossover(pop, prob):
>     for a, b in zip(*[iter(pop)]*2):
>         if prob > random():
>             cut = randrange(len(a))
>             a, b = a[:cut] + b[cut:], b[:cut] + a[cut:]
>         yield a
>         yield b
>             
> def crossover(pop, prob=0.6):
>     return list(generate_crossover(pop, prob))
> 
> but as the original is a bit clearer I recommend that you stick with it.
> 
> Peter

OK, yield gives me a generator function, so I can use for x in my_func(), 
good.

Last readability snip:

def selection(fitness, population):
    """
    Select the parent chromosomes from a population according to their
    fitness (the better fitness, the bigger chance to be selected)
    """
    selected_population = []
    fap = get_fitness_and_population(fitness, population)
    pop_len = len(population)
    # elitism (it prevents a loss of the best found solution)
    elite_population = sorted(fap)
    selected_population += [elite_population[pop_len-1][1]] + 
[elite_population[pop_len-2][1]]

def get_fitness_and_population(fitness, population):
    return [(fitness(x), x) for x in population]



More information about the Python-list mailing list