Reputation: 73
I'm trying to create a very simple 'evolutionary' algorithm in python.
I initially want to create a population of ~100 individuals with four numerical attributes (a1-4), use a function to get a score from these attributes, then remove the worst scoring 20 individuals.
This is what I have so far
import random
population = 100
class Individual(object):
def __init__(self, a1, a2, a3, a4):
self.a1 = a1
self.a2 = a2
self.a3 = a3
self.a4 = a4
starting_population = list()
for i in range (population):
a1 = random.randint(1,10)
a2 = random.randint(1,10)
a3 = random.randint(1,10)
a4 = random.randint(1,10)
starting_population.append(Individual(a1,a2,a3,a4))
def fitness(x):
fitness = a1*a2/a3*a4
return fitness
I'm stuck on how to apply a function to the members of the population list?
Also, I'm very new to Python and I'm sure I've done some things badly, so any tips are very appreciated!
Thank you
Upvotes: 1
Views: 374
Reputation: 24234
First, you should make fitness
a method of Individual
:
import random
population = 100
class Individual(object):
def __init__(self, a1, a2, a3, a4):
self.a1 = a1
self.a2 = a2
self.a3 = a3
self.a4 = a4
def fitness(self):
fitness = self.a1*self.a2/self.a3*self.a4
return fitness
starting_population = list()
for i in range (population):
a1 = random.randint(1,10)
a2 = random.randint(1,10)
a3 = random.randint(1,10)
a4 = random.randint(1,10)
starting_population.append(Individual(a1,a2,a3,a4))
If you want to remove the 20 least scoring ones, first sort them by fitness, then take a slice of the list:
sorted_people = sorted(starting_population, key=lambda i:i.fitness())
fit_people = sorted_people[20:]
You could also filter them according to the value of their fitness, like that, using a list comprehension:
fit_people = [i for i in starting_population if i.fitness() > 0.5]
Upvotes: 0
Reputation: 25895
What is wrong with looping?
for person in starting_population:
person.fitness = person.a1*person.a2/person.a3*person.a4 #Add fitness to object
Also note, the order of operations is:
((a1*a2)/a3)*a4)
in case you meant something different. You may consider making fitness a method of an individual:
class Individual(object):
def __init__(self, a1, a2, a3, a4):
self.a1 = a1
self.a2 = a2
self.a3 = a3
self.a4 = a4
def fitness(self,x):
fitness = self.a1*self.a2/self.a3*self.a4
return fitness
starting_population = list()
for i in range (population):
a1 = random.randint(1,10)
a2 = random.randint(1,10)
a3 = random.randint(1,10)
a4 = random.randint(1,10)
starting_population.append(Individual(a1,a2,a3,a4))
so you immediately can call starting_population[i].fitness()
, or calculate the value in __init__
and make it a field.
Another solution, dropping the object clarity of code in favor of a numpy
array for speed:
import numpy.random as rnd
rnd.seed(78943598743)
starting_population=rnd.randint(1,10,size=100*4).reshape(100,4) #100 rows, 4 columns, each row a person
fitness_vector = starting_population[:,0]*starting_population[:,1]/starting_population[:,2]*starting_population[:,3]
Upvotes: 1