Genetic Algorithm Elitism Python

Viewed 46

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))
0 Answers
Related