I'm trying to do the elitism method to get the best fitness value of each of the generations I generate, keeping beyond the fitness the values of X and Y to be an individual of the next generation, however, I can't apply a logic using dict that Solve the problem. It remains to get this detail right to be able to finalize the complete implementation and carry out the general revisions.
import random
def generate_population(size, x_boundaries, y_boundaries):
lower_x_boundary, upper_x_boundary = x_boundaries
lower_y_boundary, upper_y_boundary = y_boundaries
population = []
for i in range(size):
individual = {
'x': random.uniform(lower_x_boundary, upper_x_boundary),
'y': random.uniform(lower_y_boundary, upper_y_boundary),
}
population.append(individual)
return population
def fitness(individual):
x = individual['x']
y = individual['y']
return abs((-(100*(x*x - y)*(x*x - y) + (1 - x)*(1-x))))
def sort_population_by_fitness(population):
return sorted(population, key=fitness)
def choice_by_roulette(sorted_population, fitness_sum):
drawn = random.uniform(0, 1)
accumulated = 0
for individual in sorted_population:
fitnessX = fitness(individual)
probability = fitnessX / fitness_sum
accumulated += probability
if drawn <= accumulated:
return individual
def crossover(choice_a, choice_b):
xa = choice_a['x']
ya = choice_a['y']
xb = choice_b['x']
yb = choice_b['y']
#xa = xa*xb
#xa = xa**0.5
#ya = ya*yb
#ya = ya**0.5
return {'x': xa+0.01, 'y': ya+0.01}
def mutate(new_individual):
x = new_individual['x']
y = new_individual['y']
flagx = 0
flagy = 0
new_x = x*(1+random.uniform(-0.01/2, 0.01/2))
new_y = y*(1+random.uniform(-0.01/2, 0.01/2))
while flagx == 1:
if (new_x > 2) or (new_x < -2):
new_x = x*(1+random.uniform(-0.01/2, 0.01/2))
flagx = 1
else:
flagx = 0
while flagy == 1:
if (new_y > 2) or (new_y < -2):
new_y = y*(1+random.uniform(-0.01/2, 0.01/2))
flagy = 1
else:
flagy = 0
return {'x': new_x, 'y': new_y}
def eletism(x_gen, milior):
pior = sort_population_by_fitness(x_gen)
fitness(pior)
print(pior)
#for i in x_gen:
#print(teste['x'])
#x = teste['x']
#y = teste['y']
#print(milior)
return pior
def make_next_gen(population):
next_gen = []
sorted_population = sort_population_by_fitness(population)
soma_fitness = sum(fitness(individual)for individual in population)
for i in range(9):
first_choice = choice_by_roulette(sorted_population, soma_fitness)
second_choice = choice_by_roulette(sorted_population, soma_fitness)
new_individual = crossover(first_choice, second_choice)
drawn = random.randint(1,5)
if drawn == 1:
new_individual = mutate(new_individual)
next_gen.append(new_individual)
return next_gen
generations = 100
population = generate_population(size=10, x_boundaries=(-2, 2), y_boundaries=(-2, 2))
i = 0
while i!= generations:
for individual in population:
print(individual, fitness(individual))
population = make_next_gen(population)
i += 1
best_individual = sort_population_by_fitness(population)[-1]
print(best_individual, fitness(best_individual))