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):
|
||||
cutoff = randint(m)
|
||||
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]]
|
||||
first_parent = parents[0].query("point not in @matching_genes")
|
||||
second_parent = parents[1].query("point not in @matching_genes")
|
||||
cutoff = randint(len(first_parent.point.values))
|
||||
first_parent_genes = first_parent.point.values[cutoff:]
|
||||
second_parent_genes = second_parent.point.values[:cutoff]
|
||||
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):
|
||||
while 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)
|
||||
elif len(offspring) < m:
|
||||
random_parent = parents[randint(len(parents))]
|
||||
best_index = random_parent["distance"].astype(float).idxmax()
|
||||
best_point = random_parent["point"].loc[best_index]
|
||||
while True:
|
||||
best_index = random_parent["distance"].idxmax()
|
||||
best_point = random_parent["point"].loc[best_index]
|
||||
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}, ignore_index=True
|
||||
{"point": best_point, "distance": 0, "fitness": 0}, ignore_index=True
|
||||
)
|
||||
random_parent.drop(index=best_index, inplace=True)
|
||||
return offspring
|
||||
|
||||
|
||||
def get_matching_genes(parents):
|
||||
first_parent = parents[0].point
|
||||
second_parent = parents[1].point
|
||||
return where(first_parent == second_parent)
|
||||
first_parent = parents[0].point.values
|
||||
second_parent = parents[1].point.values
|
||||
return where(first_parent == second_parent)[0]
|
||||
|
||||
|
||||
def populate_offspring(values):
|
||||
|
@ -99,8 +103,7 @@ def populate_offspring(values):
|
|||
|
||||
|
||||
def uniform_crossover(parents, m):
|
||||
matching_indexes = get_matching_genes(parents)
|
||||
matching_genes = parents[0].point.iloc[matching_indexes]
|
||||
matching_genes = get_matching_genes(parents)
|
||||
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)
|
||||
|
@ -116,9 +119,13 @@ def position_crossover(parents, m):
|
|||
|
||||
|
||||
def crossover(mode, parents, m):
|
||||
split_parents = [parents[i : i + 2] for i in range(0, len(parents), 2)]
|
||||
if mode == "uniform":
|
||||
return uniform_crossover(parents, m)
|
||||
return position_crossover(parents, m)
|
||||
crossover_func = partial(uniform_crossover, m=m)
|
||||
else:
|
||||
crossover_func = partial(position_crossover, m=m)
|
||||
offspring = [*map(crossover_func, split_parents)]
|
||||
return offspring
|
||||
|
||||
|
||||
def element_in_dataframe(individual, element):
|
||||
|
|
Loading…
Reference in New Issue