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.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to