Il Fri, 06 Mar 2009 22:28:00 +0100, Peter Otten ha scritto: > mattia wrote: > >> Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto: >> >>> mattia wrote: >>> >>>> Hi, I'm new to python, and as the title says, can I improve this >>>> snippet (readability, speed, tricks): >>>> >>>> def get_fitness_and_population(fitness, population): >>>> return [(fitness(x), x) for x in population] >>>> >>>> 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) # take >>>> the only 2 best solutions >>>> elite_population = sorted(fap) >>>> selected_population += [elite_population[pop_len-1][1]] + >>>> [elite_population[pop_len-2][1]] >>>> # go on with the rest of the elements for i in range(pop_len-2): >>>> # do something >>> >>> def selection1(fitness, population, N=2): >>> rest = sorted(population, key=fitness, reverse=True) best = >>> rest[:N] del rest[:N] >>> # work with best and rest >>> >>> >>> def selection2(fitness, population, N=2): >>> decorated = [(-fitness(p), p) for p in population] >>> heapq.heapify(decorated) >>> >>> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p >>> for f, p in decorated] >>> # work with best and rest >>> >>> Both implementations assume that you are no longer interested in the >>> individuals' fitness once you have partitioned the population in two >>> groups. >>> >>> In theory the second is more efficient for "small" N and "large" >>> populations. >>> >>> Peter >> >> Ok, but the fact is that I save the best individuals of the current >> population, than I'll have to choose the others elements of the new >> population (than will be N-2) in a random way. The common way is using >> a roulette wheel selection (based on the fitness of the individuals, if >> the total fitness is 200, and one individual has a fitness of 10, that >> this individual will have a 0.05 probability to be selected to form the >> new population). So in the selection of the best solution I have to use >> the fitness in order to get the best individual, the last individual >> use the fitness to have a chance to be selected. Obviously the old >> population anf the new population must have the same number of >> individuals. > > You're right, it was a bad idea. > > Peter
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)] -- http://mail.python.org/mailman/listinfo/python-list