Implement tournament selection
This commit is contained in:
parent
4b1a9c3709
commit
300678156c
|
@ -33,8 +33,7 @@ class Individual(object):
|
||||||
return one, two
|
return one, two
|
||||||
|
|
||||||
def mutate(self):
|
def mutate(self):
|
||||||
rand.randint(1, 10)
|
if rand.random() < 0.5:
|
||||||
if rand.randint(1, 10) % 2 == 0:
|
|
||||||
self.x = self.get_rand_param()
|
self.x = self.get_rand_param()
|
||||||
else:
|
else:
|
||||||
self.y = self.get_rand_param()
|
self.y = self.get_rand_param()
|
||||||
|
|
|
@ -9,14 +9,21 @@ class Lifecycle(object):
|
||||||
self.population = Population(self.params["population_size"])
|
self.population = Population(self.params["population_size"])
|
||||||
self.best_fit = list()
|
self.best_fit = list()
|
||||||
self.average_fit = list()
|
self.average_fit = list()
|
||||||
|
self.iterations = 0
|
||||||
|
|
||||||
def start(self):
|
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"]
|
elite = self.params["elite"]
|
||||||
crossover = self.params["crossover"]
|
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.best_fit.append(self.population.best_fitness())
|
||||||
self.average_fit.append(self.population.avg_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):
|
def best_fitness(self):
|
||||||
return self.population.best_fitness()
|
return self.population.best_fitness()
|
||||||
|
@ -33,4 +40,5 @@ class Lifecycle(object):
|
||||||
def get_csv(self):
|
def get_csv(self):
|
||||||
id = {'id': self.id}
|
id = {'id': self.id}
|
||||||
best_fitness = {'best_fit': self.best_fitness()}
|
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,
|
param_example = {'population_size': 10,
|
||||||
'elite': round(0.1 * 10),
|
'elite': round(0.1 * 10),
|
||||||
'crossover': round(0.6 * 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,
|
return {'population_size': pop,
|
||||||
'elite': round(elite * pop),
|
'elite': round(elite * pop),
|
||||||
'crossover': round(crossover * pop),
|
'crossover': round(crossover * pop),
|
||||||
'iter': iter}
|
'epochs': epochs}
|
||||||
|
|
||||||
|
|
||||||
outputs = Queue()
|
outputs = Queue()
|
||||||
|
@ -39,9 +40,9 @@ instances = list()
|
||||||
|
|
||||||
id = 0
|
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,
|
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
|
id += 1
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
@ -50,7 +51,7 @@ for instance in instances:
|
||||||
instance.start()
|
instance.start()
|
||||||
|
|
||||||
while len([t for t in instances if t.is_alive()]) != 0:
|
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)
|
sleep(1)
|
||||||
|
|
||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
|
@ -61,5 +62,3 @@ while not outputs.empty():
|
||||||
output_file.close()
|
output_file.close()
|
||||||
|
|
||||||
print("Execution took %f seconds" % (end_time - start_time))
|
print("Execution took %f seconds" % (end_time - start_time))
|
||||||
|
|
||||||
#ga.generate_graph(show=True)
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Population(object):
|
||||||
|
|
||||||
return sorted_members
|
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()
|
new_generation = list()
|
||||||
|
|
||||||
# elitism
|
# elitism
|
||||||
|
@ -80,25 +80,37 @@ class Population(object):
|
||||||
new_generation.append(member)
|
new_generation.append(member)
|
||||||
|
|
||||||
# parent
|
# parent
|
||||||
for ind in range(0, n_crossover):
|
# for ind in range(0, n_crossover):
|
||||||
parent_one = self.roulette()
|
# self.roulette_crossover(new_generation)
|
||||||
parent_two = self.roulette()
|
|
||||||
x, y = parent_one.crossover(parent_two)
|
|
||||||
new_generation.append(x)
|
|
||||||
new_generation.append(y)
|
|
||||||
|
|
||||||
while len(new_generation) < len(self.members):
|
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.members = new_generation
|
||||||
|
|
||||||
self.mutate(10)
|
self.mutate(10)
|
||||||
|
|
||||||
self.check_termination()
|
|
||||||
|
|
||||||
def remove_member(self, member):
|
def remove_member(self, member):
|
||||||
self.members.remove(member)
|
self.members.remove(member)
|
||||||
|
|
||||||
def check_termination(self):
|
def roulette_crossover(self):
|
||||||
# todo: complete
|
parent_one = self.roulette()
|
||||||
pass
|
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