Is there a better way of doing this?
mattia
gervaz at gmail.com
Sat Mar 7 00:31:01 CET 2009
Il Fri, 06 Mar 2009 14:13:47 -0800, Scott David Daniels ha scritto:
> 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
Thanks, I've found another solution here: http://www.obitko.com/tutorials/
genetic-algorithms/selection.php
so here is my implementation:
def create_chromosome(min, max, length):
return [randint(min, max) for i in range(length)]
def create_population(nelem, min, max, length):
# preconditions: nelem > 1 and nelem is even
if not nelem > 1:
nelem = 2
if not nelem%2 == 0:
print("The population must have an even number of elements.
Correcting...")
nelem += 1
return [create_chromosome(min, max, length) for i in range(nelem)]
def get_fap(fitness, population):
fap = []
total = 0
for x in population:
f = fitness(x)
fap += [(f, x)]
total += f
return sorted(fap, reverse=True), total
def my_rw():
list, tot = get_fap(sum, pop)
r = randint(0, tot-1)
i = 0
print(r)
for f, e in list:
i += f
print(i)
if i > r:
return e
return [] # never reached
if __name__ == "__main__":
pop = create_population(5, 0, 1, 10)
# selection_mat(sum, pop)
#print(rw(sum, pop))
list, tot = get_fap(sum, pop)
print(list)
print(tot)
for i in range(6):
print(my_rw())
More information about the Python-list
mailing list