def crossover_intermediate(population, alpha=None): """ Generated children feature averages of the equivalent parent gene elements. """ assert isinstance(population, Population) assert isinstance(population.individuals[0].gene[0], (bool, int, float)) assert len(population) == 2, "this works with two parents, only." # TODO: How about a universal formula (for p > 2)? gene = [] for gene_index in range(population.gene_size): features_parents = [parent.gene[gene_index] for parent in population.individuals] if alpha is None: # calculate average feature feature = statistics.mean(features_parents) # cast back to original type feature = type(population.individuals[0].gene[0])(feature) else: # reweight according to alpha feature = sum([alpha * features_parents[0], (1 - alpha) * features_parents[1]]) print(feature) gene.append(feature) return Population.from_individuals(individuals=[Individual(gene=gene)])
def crossover_n_point(population, n=1): assert isinstance(population, Population) # select crossover point valid_positions = range(1, population.gene_size-1) points = [random.choice(valid_positions) for _ in range(n)] # generate children from parents children = [] # iterate over children for i in range(len(population)): gene_child = [] # iterate over crossover points for i in range(-1, n): if i == -1: # part left of the first crossover point gene_child += population[0].gene[0:points[0]] continue key = i % population.gene_size - 1 parent = population[key] try: gene_child += parent.gene[points[i]:points[i+1]] except IndexError: # this is the last point gene_child += parent.gene[points[i]:] child_individual = Individual(gene=gene_child) children.append(child_individual) return Population.from_individuals(children)
def ea(SIGMA=SIGMA): # initialize world = World(fitness=fitness) world.population = IntListPopulation(length=MU, gene_size=GENE_SIZE) # iterate over generations for generation_count in range(MAX_GENERATIONS): # log this generation's population to stdout print("%s: %s" % (generation_count, world.population)) # if we reached a sufficiently good solution, stop if min(world.scores) < MIN_FITNESS: break # select rho fittest individuals as parents parents = select(world=world, rho=RHO) # generate children by crossing over the parents children_original = [] while len(children_original) < LAMBDA: children_original += crossover(population=parents) # mutate children children = [mutate(individual=individual, mu=0, sigma=SIGMA) for individual in children_original] # self-adapt mutation strenght using Rechenberg's success rule SIGMA = rechenberg(children_original=children_original, children_mutated=children, fitness=world.fitness, a=A_RECHENBERG, sigma=SIGMA) if MODE == '+': # extend population with children world.population += Population.from_individuals( individuals=children) elif MODE == ',': # replace population with children world.population = Population.from_individuals( individuals=children) # select fittest mu individuals for next generation world.population = select(rho=MU, world=world) # log best individual print("Best individual is %s with a score of %s." % (select(world=world, rho=1)[0], min(world.scores)))
def crossover_mode_bool(population): gene = [] for i in range(len(population[0].gene)): base = sum([1 for parent in population if parent.gene[i-1]]) > \ len(population) / 2 gene.append(base) individual = Individual(gene=gene) return Population.from_individuals(individuals=[individual])
def crossover_dominant(population): """ Collects child gene from equivalent gene elements of a random parent. """ assert isinstance(population, Population) gene = [] for gene_index in range(population.gene_size): parent_index = random.choice(range(len(population))) gene.append(population[parent_index].gene[gene_index]) return Population.from_individuals(individuals=[Individual(gene=gene)])