def eaSteadyState(toolbox, population, ngen, halloffame=None): """The is the steady-state evolutionary algorithm """ _logger.info("Start of evolution") # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) # Begin the generational process for gen in range(ngen): _logger.info("Evolving generation %i", gen) p1, p2 = toolbox.select(population, 2) p1 = toolbox.clone(p1) p2 = toolbox.clone(p2) toolbox.mate(p1, p2) child = random.choice([p1, p2]) toolbox.mutate(child) child.fitness.values = toolbox.evaluate(child) if halloffame is not None: halloffame.update(child) # Select the next generation population population[:] = toolbox.select(population + [child], len(population)) # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values for ind in population] fits_t = zip(*fits) # Transpose fitnesses for analysis minimums = map(min, fits_t) maximums = map(max, fits_t) length = len(population) sums = map(sum, fits_t) sums2 = [sum(x*x for x in fit) for fit in fits_t] means = [sum_ / length for sum_ in sums] std_devs = [abs(sum2 / length - mean**2)**0.5 for sum2, mean in zip(sums2, means)] _logger.debug("Min %s", ", ".join(map(str, minimums))) _logger.debug("Max %s", ", ".join(map(str, maximums))) _logger.debug("Avg %s", ", ".join(map(str, means))) _logger.debug("Std %s", ", ".join(map(str, std_devs))) _logger.info("End of (successful) evolution") return population
def eaMuCommaLambda(toolbox, population, mu, lambda_, cxpb, mutpb, ngen, halloffame=None): """This is the :math:`(\mu~,~\lambda)` evolutionary algorithm. First, the individuals having an invalid fitness are evaluated. Then, the evolutionary loop begins by producing *lambda* offsprings from the population, the offsprings are generated by a crossover, a mutation or a reproduction proportionally to the probabilities *cxpb*, *mutpb* and 1 - (cxpb + mutpb). The offsprings are then evaluated and the next generation population is selected **only** from the offsprings. Briefly, the operators are applied as following :: evaluate(population) for i in range(ngen): offsprings = generate_offsprings(population) evaluate(offsprings) population = select(offsprings) .. note:: Both produced individuals from the crossover are put in the offspring pool. """ assert lambda_ >= mu, "lambda must be greater or equal to mu." assert (cxpb + mutpb) <= 1.0, ("The sum of the crossover and mutation" "probabilities must be smaller or equal to 1.0.") _logger.info("Start of evolution") evaluations = 0 # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit _logger.debug("Evaluated %i individuals", len(invalid_ind)) if halloffame is not None: halloffame.update(population) # Begin the generational process for gen in range(ngen): _logger.info("Evolving generation %i", gen) evaluations = 0 offsprings = [] nb_offsprings = 0 while nb_offsprings < lambda_: #for i in xrange(lambda_): op_choice = random.random() if op_choice < cxpb: # Apply crossover ind1, ind2 = random.sample(population, 2) ind1 = toolbox.clone(ind1) ind2 = toolbox.clone(ind2) toolbox.mate(ind1, ind2) del ind1.fitness.values del ind2.fitness.values offsprings.append(ind1) offsprings.append(ind2) nb_offsprings += 2 elif op_choice < cxpb + mutpb: # Apply mutation ind = random.choice(population) # select ind = copy.deepcopy(ind) # clone toolbox.mutate(ind) del ind.fitness.values offsprings.append(ind) nb_offsprings += 1 else: # Apply reproduction offsprings.append(random.choice(population)) nb_offsprings += 1 # Remove the exedant of offsprings if nb_offsprings > lambda_: del offsprings[lambda_:] # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offsprings if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit _logger.debug("Evaluated %i individuals", len(invalid_ind)) if halloffame is not None: halloffame.update(offsprings) # Select the next generation population population[:] = toolbox.select(offsprings, mu) # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values for ind in population] fits_t = zip(*fits) # Transpose fitnesses for analysis minimums = map(min, fits_t) maximums = map(max, fits_t) length = len(population) sums = map(sum, fits_t) sums2 = [sum(x*x for x in fit) for fit in fits_t] means = [sum_ / length for sum_ in sums] std_devs = [abs(sum2 / length - mean**2)**0.5 for sum2, mean in zip(sums2, means)] #_logger.debug("Min %s", ", ".join(map(str, minimums))) #_logger.debug("Max %s", ", ".join(map(str, maximums))) #_logger.debug("Avg %s", ", ".join(map(str, means))) #_logger.debug("Std %s", ", ".join(map(str, std_devs))) _logger.info("End of (successful) evolution")