From 046b1a043ac709204bd2b745331d3f97d8aa0144 Mon Sep 17 00:00:00 2001 From: coolneng Date: Sun, 20 Jun 2021 05:18:36 +0200 Subject: [PATCH] Implement uniform generational genetic algorithm --- src/genetic_algorithm.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/genetic_algorithm.py b/src/genetic_algorithm.py index d2152de..c305ccd 100644 --- a/src/genetic_algorithm.py +++ b/src/genetic_algorithm.py @@ -4,6 +4,7 @@ from pandas import DataFrame from math import ceil from functools import partial from multiprocessing import Pool +from copy import deepcopy from preprocessing import parse_file @@ -169,7 +170,7 @@ def mutate(offspring, data, probability=0.001): return offspring -def get_individual_index(population, element): +def get_individual_index(element, population): for index in range(len(population)): if population[index].fitness.values[0] == element.fitness.values[0]: return index @@ -178,25 +179,34 @@ def get_individual_index(population, element): def tournament_selection(population): individuals = [population[randint(len(population))] for _ in range(2)] best_element = max(individuals, key=lambda x: x.fitness.values[0]) - population_index = get_individual_index(population, best_element) + population_index = get_individual_index(best_element, population) return best_element, population_index -def generational_replacement(previous_population, current_population): +def check_element_population(element, population): + for item in population: + if all(element.point.values) == all(item.point.values): + return True + return False + + +def generational_replacement(prev_population, current_population): new_population = current_population - best_previous_individual = max(previous_population, key=lambda x: all(x.fitness)) - if best_previous_individual not in new_population: - worst_index = new_population.index( - min(new_population, key=lambda x: all(x.fitness)) - ) + best_previous_individual = max(prev_population, key=lambda x: x.fitness.values[0]) + if check_element_population(best_previous_individual, new_population): + worst_element = min(new_population, key=lambda x: x.fitness.values[0]) + worst_index = get_individual_index(worst_element, new_population) new_population[worst_index] = best_previous_individual return new_population def get_best_elements(population): - first_index = population.index(max(population, key=lambda x: all(x.fitness))) - population.pop(first_index) - second_index = population.index(max(population, key=lambda x: all(x.fitness))) + select_population = deepcopy(population) + first_element = max(select_population, key=lambda x: x.fitness.values[0]) + first_index = get_individual_index(first_element, select_population) + select_population.pop(first_index) + second_element = max(select_population, key=lambda x: x.fitness.values[0]) + second_index = get_individual_index(second_element, select_population) return first_index, second_index @@ -231,7 +241,7 @@ def evaluate_population(population, data, cores=4): def select_parents(population, n, mode): - select_population = population + select_population = deepcopy(population) parents = [] if mode == "generational": for _ in range(n): @@ -255,8 +265,8 @@ def genetic_algorithm(n, m, data, select_mode, crossover_mode, max_iterations=10 offspring = mutate(offspring, data) population = replace_population(population, offspring, select_mode) population = evaluate_population(population, data) - best_solution, _ = get_best_elements(population) - return best_solution + best_index, _ = get_best_elements(population) + return population[best_index] n, m, data = parse_file("data/GKD-c_11_n500_m50.txt")