diff --git a/src/genetic_algorithm.py b/src/genetic_algorithm.py index 73556ef..7561fb5 100644 --- a/src/genetic_algorithm.py +++ b/src/genetic_algorithm.py @@ -1,11 +1,10 @@ -from numpy import sum, append, arange, delete, intersect1d +from numpy import sum, append, intersect1d from numpy.random import randint, choice, shuffle from pandas import DataFrame from math import ceil from functools import partial from multiprocessing import Pool from copy import deepcopy -from itertools import chain, repeat from preprocessing import parse_file @@ -59,7 +58,7 @@ def select_distinct_genes(matching_genes, parents, m): return first_parent_genes, second_parent_genes -def select_random_genes(matching_genes, parents): +def select_shuffled_genes(matching_genes, parents): first_parent = parents[0].query("point not in @matching_genes") second_parent = parents[1].query("point not in @matching_genes") first_genes = first_parent.point.values @@ -78,20 +77,23 @@ def select_random_parent(parents): return random_parent +def get_best_point(parents, offspring): + while True: + random_parent = deepcopy(select_random_parent(parents)) + best_index = random_parent["distance"].idxmax() + best_point = random_parent["point"].iloc[best_index] + random_parent.drop(index=best_index, inplace=True) + if best_point not in offspring.point.values: + return best_point + + def repair_offspring(offspring, parents, m): while len(offspring) != m: if len(offspring) > m: best_index = offspring["distance"].idxmax() offspring.drop(index=best_index, inplace=True) elif len(offspring) < m: - # NOTE Refactor into its own function - while True: - random_parent = select_random_parent(parents) - best_index = random_parent["distance"].idxmax() - best_point = random_parent["point"].loc[best_index] - random_parent.drop(index=best_index, inplace=True) - if best_point not in offspring.point.values: - break + best_point = get_best_point(parents, offspring) offspring = offspring.append( {"point": best_point, "distance": 0, "fitness": 0}, ignore_index=True ) @@ -125,7 +127,7 @@ def uniform_crossover(parents, m): def position_crossover(parents): matching_genes = get_matching_genes(parents) - first_genes, second_genes = select_random_genes(matching_genes, parents) + first_genes, second_genes = select_shuffled_genes(matching_genes, parents) first_offspring = populate_offspring(values=[matching_genes, first_genes]) second_offspring = populate_offspring(values=[matching_genes, second_genes]) return first_offspring, second_offspring