Simplified adapt_population

This commit is contained in:
SimpleArt
2021-01-23 19:10:31 -05:00
parent 8c7c7beb5b
commit f4ba75561d

View File

@ -181,54 +181,39 @@ class GA(Attributes):
if self.adapt_population_flag == False: if self.adapt_population_flag == False:
return return
# Amount of the population desired to converge (default 50%) self.parent_selection_impl()
amount_converged = round(self.percent_converged*len(self.population))
# Difference between best and i-th chromosomes # Strongly cross the best chromosome with all other chromosomes
best_chromosome = self.population[0] for n, parent in enumerate(self.population.mating_pool):
tol = lambda i: self.dist(best_chromosome, self.population[i])
# First non-zero tolerance after amount_converged/4 if self.population[n] != self.population[0]:
for i in range(amount_converged//4, len(self.population)):
tol_i = tol(i) # Strongly cross with the best chromosome
if tol_i > 0: # May reject negative weight or division by 0
try:
self.crossover_individual_impl(
self.population[n],
parent,
weight = -3/4,
)
# If negative weights can't be used or division by 0, use positive weight
except ValueError:
self.crossover_individual_impl(
self.population[n],
parent,
weight = +1/4,
)
# Stop if we've filled up an entire population
if len(self.population.next_population) >= len(self.population):
break break
# First significantly different tolerance # Replace worst chromosomes with new chromosomes, except for the previous best chromosome
for j in range(i, len(self.population)): min_len = min(len(self.population)-1, len(self.population.next_population))
tol_j = tol(j) self.population[-min_len:] = self.population.next_population[:min_len]
if tol_j > 2*tol_i:
break
# Strongly cross the best chromosome with the worst chromosomes
for n in range(len(self.population)-1, i-1, -1):
# Strongly cross with the best chromosome
# May reject negative weight or division by 0
try:
self.crossover_individual_impl(
self.population[n],
best_chromosome,
weight = min(0.25, 2 * tol_j / (tol(n) - tol_j))
)
# If negative weights can't be used or division by 0,
# Cross with j-th chromosome instead
except (ValueError, ZeroDivisionError):
self.crossover_individual_impl(
self.population[n],
self.population[j],
weight = 0.75
)
if len(self.population.next_population) >= len(self.population) - i:
break
# Replace worst chromosomes with new chromosomes
self.population[-len(self.population.next_population):] = self.population.next_population
self.population.next_population = [] self.population.next_population = []
self.population.mating_pool = []
def initialize_population(self): def initialize_population(self):