Is there a better way of doing this?

Scott David Daniels Scott.Daniels at Acm.Org
Fri Mar 6 17:13:47 EST 2009


mattia wrote:
> Here is my last shot, where I get rid of all the old intermediate 
> functions:
> 
> def selection(fitness, population):
>     lp = len(population)
>     roulette_wheel = []
>     for x in population:
>         roulette_wheel += [x]*fitness(x)
>     selected_population = [[]]*lp
>     selected_population[:2] = sorted(population, key=fitness, 
> reverse=True)[:2]
>     selected_population[2:] = [choice(roulette_wheel) for _ in range
> (lp-2)]
Try something like this to choose likely couples:

     import random
     import bisect

     def choose_pairs(fitness_population, decider=random):
         '''Pick and yield pairs weighted by fitness for crossing.

         We assume weighted_population has fitness already calculated.
         decide is a parameter to allow testing.
         '''
         total = 0
         cumulative = []
         candidates = []
         for fitness, individual in set(fitness_population):
             # calculate total weights, extract real candidates
             if fitness > 0:
                 total += fitness
                 cumulative.append(total)
                 candidates.append(individual)
         assert len(candidates) > 1
         while True:
             # pick a candidate by weight
             c0 = decider.random() * total
             first = bisect.bisect_left(cumulative, c0)
             if first:
                 weighting = cumulative[first] - cumulative[first - 1]
             else:
                 weighting = cumulative[0]
             # pick another distinct candidate by fitness
             c1 = choice = decider.random() * (total - weighting)
             if choice >= cumulative[first] - weighting:
                 choice += weight # adjust to avoid selecting first
             second = bisect.bisect_left(cumulative, choice)
             yield candidates[first], candidates[second]

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list