Implement tournament selection
This commit is contained in:
parent
4b1a9c3709
commit
300678156c
|
@ -33,8 +33,7 @@ class Individual(object):
|
|||
return one, two
|
||||
|
||||
def mutate(self):
|
||||
rand.randint(1, 10)
|
||||
if rand.randint(1, 10) % 2 == 0:
|
||||
if rand.random() < 0.5:
|
||||
self.x = self.get_rand_param()
|
||||
else:
|
||||
self.y = self.get_rand_param()
|
||||
|
|
|
@ -9,14 +9,21 @@ class Lifecycle(object):
|
|||
self.population = Population(self.params["population_size"])
|
||||
self.best_fit = list()
|
||||
self.average_fit = list()
|
||||
self.iterations = 0
|
||||
|
||||
def start(self):
|
||||
for epoch in range(0, self.params["iter"]):
|
||||
for epoch in range(0, self.params["epochs"]):
|
||||
self.iterations += 1
|
||||
elite = self.params["elite"]
|
||||
crossover = self.params["crossover"]
|
||||
self.population.advance_generation(elite, crossover)
|
||||
self.population.advance_generation(elite, crossover_rate=crossover, n_arena=4)
|
||||
self.best_fit.append(self.population.best_fitness())
|
||||
self.average_fit.append(self.population.avg_fitness())
|
||||
if epoch > 50:
|
||||
recent_best = self.best_fit[-50:]
|
||||
if max(recent_best) - min(recent_best) < 0.02:
|
||||
break
|
||||
|
||||
|
||||
def best_fitness(self):
|
||||
return self.population.best_fitness()
|
||||
|
@ -33,4 +40,5 @@ class Lifecycle(object):
|
|||
def get_csv(self):
|
||||
id = {'id': self.id}
|
||||
best_fitness = {'best_fit': self.best_fitness()}
|
||||
return {**id, **best_fitness, **self.params}
|
||||
iter = {'iter': self.iterations}
|
||||
return {**id, **best_fitness, **self.params, **iter}
|
||||
|
|
15
src/main.py
15
src/main.py
|
@ -8,14 +8,15 @@ import time
|
|||
param_example = {'population_size': 10,
|
||||
'elite': round(0.1 * 10),
|
||||
'crossover': round(0.6 * 10),
|
||||
'iter': 1000}
|
||||
'epochs': 1000,
|
||||
'iter': 0}
|
||||
|
||||
|
||||
def gen_param(pop, elite, crossover, iter):
|
||||
def gen_param(pop, elite, crossover, epochs):
|
||||
return {'population_size': pop,
|
||||
'elite': round(elite * pop),
|
||||
'crossover': round(crossover * pop),
|
||||
'iter': iter}
|
||||
'epochs': epochs}
|
||||
|
||||
|
||||
outputs = Queue()
|
||||
|
@ -39,9 +40,9 @@ instances = list()
|
|||
|
||||
id = 0
|
||||
|
||||
for i in [x * 0.01 for x in range(20, 80, 5)]:
|
||||
for i in [x * 1 for x in range(0, 100)]:
|
||||
instances.append(Process(name="Thread-%d" % i, target=run_instance,
|
||||
args=[Lifecycle(id, gen_param(20, 0.1, i, 50)), outputs]))
|
||||
args=[Lifecycle(id, gen_param(50, 0, 0.5, 500)), outputs]))
|
||||
id += 1
|
||||
|
||||
start_time = time.time()
|
||||
|
@ -50,7 +51,7 @@ for instance in instances:
|
|||
instance.start()
|
||||
|
||||
while len([t for t in instances if t.is_alive()]) != 0:
|
||||
print("here")
|
||||
print("Processes left: %d" % len([t for t in instances if t.is_alive()]))
|
||||
sleep(1)
|
||||
|
||||
end_time = time.time()
|
||||
|
@ -61,5 +62,3 @@ while not outputs.empty():
|
|||
output_file.close()
|
||||
|
||||
print("Execution took %f seconds" % (end_time - start_time))
|
||||
|
||||
#ga.generate_graph(show=True)
|
||||
|
|
|
@ -72,7 +72,7 @@ class Population(object):
|
|||
|
||||
return sorted_members
|
||||
|
||||
def advance_generation(self, n_elite, n_crossover):
|
||||
def advance_generation(self, n_elite, crossover_rate=0.5, n_arena=4):
|
||||
new_generation = list()
|
||||
|
||||
# elitism
|
||||
|
@ -80,25 +80,37 @@ class Population(object):
|
|||
new_generation.append(member)
|
||||
|
||||
# parent
|
||||
for ind in range(0, n_crossover):
|
||||
parent_one = self.roulette()
|
||||
parent_two = self.roulette()
|
||||
x, y = parent_one.crossover(parent_two)
|
||||
new_generation.append(x)
|
||||
new_generation.append(y)
|
||||
# for ind in range(0, n_crossover):
|
||||
# self.roulette_crossover(new_generation)
|
||||
|
||||
while len(new_generation) < len(self.members):
|
||||
new_generation.append(self.roulette())
|
||||
if n_arena > 0:
|
||||
x, y = self.tournament_selection(n_arena, crossover_rate)
|
||||
else:
|
||||
x, y = self.roulette_crossover()
|
||||
|
||||
new_generation.append(x)
|
||||
new_generation.append(y)
|
||||
|
||||
self.members = new_generation
|
||||
|
||||
self.mutate(10)
|
||||
|
||||
self.check_termination()
|
||||
|
||||
def remove_member(self, member):
|
||||
self.members.remove(member)
|
||||
|
||||
def check_termination(self):
|
||||
# todo: complete
|
||||
pass
|
||||
def roulette_crossover(self):
|
||||
parent_one = self.roulette()
|
||||
parent_two = self.roulette()
|
||||
return parent_one.crossover(parent_two)
|
||||
|
||||
def tournament_selection(self, arena_size, rate):
|
||||
parents = list()
|
||||
for i in range(arena_size):
|
||||
parents.append(self.members[rand.randint(0, len(self.members) - 1)])
|
||||
parents = sorted(parents, key=lambda x: x.fitness(), reverse=True)
|
||||
|
||||
if rand.random() < rate:
|
||||
return parents[0].crossover(parents[1])
|
||||
else:
|
||||
return parents[0], parents[1]
|
||||
|
|
Loading…
Reference in New Issue
Block a user