Fix uniform crossover operator
This commit is contained in:
parent
04fd66425e
commit
f71aa2e1e2
|
@ -49,10 +49,11 @@ def evaluate_individual(individual, data):
|
||||||
|
|
||||||
|
|
||||||
def select_distinct_genes(matching_genes, parents, m):
|
def select_distinct_genes(matching_genes, parents, m):
|
||||||
cutoff = randint(m)
|
first_parent = parents[0].query("point not in @matching_genes")
|
||||||
distinct_indexes = delete(arange(m), matching_genes)
|
second_parent = parents[1].query("point not in @matching_genes")
|
||||||
first_parent_genes = parents[0].point.iloc[distinct_indexes[cutoff:]]
|
cutoff = randint(len(first_parent.point.values))
|
||||||
second_parent_genes = parents[1].point.iloc[distinct_indexes[:cutoff]]
|
first_parent_genes = first_parent.point.values[cutoff:]
|
||||||
|
second_parent_genes = second_parent.point.values[:cutoff]
|
||||||
return first_parent_genes, second_parent_genes
|
return first_parent_genes, second_parent_genes
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,23 +68,26 @@ def select_random_genes(matching_genes, parents, m):
|
||||||
def repair_offspring(offspring, parents, m):
|
def repair_offspring(offspring, parents, m):
|
||||||
while len(offspring) != m:
|
while len(offspring) != m:
|
||||||
if len(offspring) > m:
|
if len(offspring) > m:
|
||||||
best_index = offspring["distance"].astype(float).idxmax()
|
best_index = offspring["distance"].idxmax()
|
||||||
offspring.drop(index=best_index, inplace=True)
|
offspring.drop(index=best_index, inplace=True)
|
||||||
elif len(offspring) < m:
|
elif len(offspring) < m:
|
||||||
random_parent = parents[randint(len(parents))]
|
random_parent = parents[randint(len(parents))]
|
||||||
best_index = random_parent["distance"].astype(float).idxmax()
|
while True:
|
||||||
|
best_index = random_parent["distance"].idxmax()
|
||||||
best_point = random_parent["point"].loc[best_index]
|
best_point = random_parent["point"].loc[best_index]
|
||||||
offspring = offspring.append(
|
|
||||||
{"point": best_point, "distance": 0}, ignore_index=True
|
|
||||||
)
|
|
||||||
random_parent.drop(index=best_index, inplace=True)
|
random_parent.drop(index=best_index, inplace=True)
|
||||||
|
if not any(offspring["point"].isin([best_point])):
|
||||||
|
break
|
||||||
|
offspring = offspring.append(
|
||||||
|
{"point": best_point, "distance": 0, "fitness": 0}, ignore_index=True
|
||||||
|
)
|
||||||
return offspring
|
return offspring
|
||||||
|
|
||||||
|
|
||||||
def get_matching_genes(parents):
|
def get_matching_genes(parents):
|
||||||
first_parent = parents[0].point
|
first_parent = parents[0].point.values
|
||||||
second_parent = parents[1].point
|
second_parent = parents[1].point.values
|
||||||
return where(first_parent == second_parent)
|
return where(first_parent == second_parent)[0]
|
||||||
|
|
||||||
|
|
||||||
def populate_offspring(values):
|
def populate_offspring(values):
|
||||||
|
@ -99,8 +103,7 @@ def populate_offspring(values):
|
||||||
|
|
||||||
|
|
||||||
def uniform_crossover(parents, m):
|
def uniform_crossover(parents, m):
|
||||||
matching_indexes = get_matching_genes(parents)
|
matching_genes = get_matching_genes(parents)
|
||||||
matching_genes = parents[0].point.iloc[matching_indexes]
|
|
||||||
first_genes, second_genes = select_distinct_genes(matching_genes, parents, m)
|
first_genes, second_genes = select_distinct_genes(matching_genes, parents, m)
|
||||||
offspring = populate_offspring(values=[matching_genes, first_genes, second_genes])
|
offspring = populate_offspring(values=[matching_genes, first_genes, second_genes])
|
||||||
viable_offspring = repair_offspring(offspring, parents, m)
|
viable_offspring = repair_offspring(offspring, parents, m)
|
||||||
|
@ -116,9 +119,13 @@ def position_crossover(parents, m):
|
||||||
|
|
||||||
|
|
||||||
def crossover(mode, parents, m):
|
def crossover(mode, parents, m):
|
||||||
|
split_parents = [parents[i : i + 2] for i in range(0, len(parents), 2)]
|
||||||
if mode == "uniform":
|
if mode == "uniform":
|
||||||
return uniform_crossover(parents, m)
|
crossover_func = partial(uniform_crossover, m=m)
|
||||||
return position_crossover(parents, m)
|
else:
|
||||||
|
crossover_func = partial(position_crossover, m=m)
|
||||||
|
offspring = [*map(crossover_func, split_parents)]
|
||||||
|
return offspring
|
||||||
|
|
||||||
|
|
||||||
def element_in_dataframe(individual, element):
|
def element_in_dataframe(individual, element):
|
||||||
|
|
Loading…
Reference in New Issue