From f2584f87cb70cde871d2f1691ee0cf9b9a0e07f5 Mon Sep 17 00:00:00 2001 From: coolneng Date: Tue, 25 May 2021 16:53:59 +0200 Subject: [PATCH] Implement position crossover operator --- src/genetic_algorithm.py | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/genetic_algorithm.py b/src/genetic_algorithm.py index bbf8dd8..a34fbf8 100644 --- a/src/genetic_algorithm.py +++ b/src/genetic_algorithm.py @@ -1,5 +1,5 @@ from numpy import sum, append, arange, delete, where -from numpy.random import randint, choice +from numpy.random import randint, choice, shuffle from pandas import DataFrame @@ -44,14 +44,22 @@ def evaluate_element(element, data): return sum(fitness) -def select_random_genes(matching_genes, parents, m): +def select_distinct_genes(matching_genes, parents, m): cutoff = randint(m) - distinct_genes = delete(arange(m), matching_genes) - first_parent_genes = parents[0].point.iloc[distinct_genes[cutoff:]] - second_parent_genes = parents[1].point.iloc[distinct_genes[:cutoff]] + distinct_indexes = delete(arange(m), matching_genes) + first_parent_genes = parents[0].point.iloc[distinct_indexes[cutoff:]] + second_parent_genes = parents[1].point.iloc[distinct_indexes[:cutoff]] return first_parent_genes, second_parent_genes +def select_random_genes(matching_genes, parents, m): + random_parent = parents[randint(len(parents))] + distinct_indexes = delete(arange(m), matching_genes) + genes = random_parent.point.iloc[distinct_indexes].values + shuffle(genes) + return genes + + def repair_offspring(offspring, parents, m): while len(offspring) != m: if len(offspring) > m: @@ -64,6 +72,7 @@ def repair_offspring(offspring, parents, m): offspring = offspring.append( {"point": best_point, "distance": 0}, ignore_index=True ) + random_parent.drop(index=best_index, inplace=True) return offspring @@ -73,20 +82,31 @@ def get_matching_genes(parents): return where(first_parent == second_parent) -def uniform_crossover(parents, m): +def populate_offspring(values): offspring = DataFrame(columns=["point", "distance"]) - matching_genes = get_matching_genes(parents) - offspring["point"] = parents[0].point.iloc[matching_genes] - first_genes, second_genes = select_random_genes(matching_genes, parents, m) - offspring["point"] = offspring["point"].append(first_genes) - offspring["point"] = offspring["point"].append(second_genes) + for element in values: + aux = DataFrame(columns=["point", "distance"]) + aux["point"] = element + offspring = offspring.append(aux) offspring["distance"] = 0 + offspring = offspring[1:] + return offspring + + +def uniform_crossover(parents, m): + matching_indexes = get_matching_genes(parents) + matching_genes = parents[0].point.iloc[matching_indexes] + first_genes, second_genes = select_distinct_genes(matching_genes, parents, m) + offspring = populate_offspring(values=[matching_genes, first_genes, second_genes]) viable_offspring = repair_offspring(offspring, parents, m) return viable_offspring -def position_crossover(parents, n): - genotypes = [parents[0].point.values, parents[1].point.values] +def position_crossover(parents, m): + matching_genes = get_matching_genes(parents) + shuffled_genes = select_random_genes(matching_genes, parents, m) + offspring = populate_offspring(values=[matching_genes, shuffled_genes]) + return offspring def crossover(mode, parents, m):