def eaSimpleWithElitism(population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): # Create a logbook logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Calculate fitness for all population fitnesses = map(toolbox.evaluate, population) # Set fitness to valid value for ind, fit in zip(population, fitnesses): ind.fitness.values = fit if halloffame is None: raise ValueError("halloffame parameter must not be empty!") # Get some best individual halloffame.update(population) hof_size = len(halloffame.items) if halloffame.items else 0 record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(population), **record) # For logbook debuging if verbose: print(logbook.stream) for gen in range(1, ngen + 1): # Select the next generation individuals offspring = toolbox.select(population, len(population) - hof_size) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) ''' Implement cross over and mutation ''' # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): # cross two individuals with probability CXPB if random.random() < cxpb: toolbox.mate(child1, child2) # fitness values of the children # must be recalculated later del child1.fitness.values del child2.fitness.values for mutant in offspring: # mutate an individual with probability MUTPB if random.random() < mutpb: toolbox.mutate(mutant) del mutant.fitness.values # Using DEAP's algorithm # offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # add the best back to population: offspring.extend(halloffame.items) # # Update the hall of fame with the generated individuals halloffame.update(offspring) # Replace the current population by the offspring population[:] = offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} print("Records: {0}".format(record)) logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) return population, logbook
def _eaFunction(population, toolbox, cxpb, mutpb, ngen, ngen_no_change=None, stats=None, halloffame=None, verbose=0): logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # 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) record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) # Begin the generational process wait = 0 for gen in range(1, ngen + 1): # Select the next generation individuals offspring = toolbox.select(population, len(population)) # Vary the pool of individuals offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Get the previous best individual before updating the hall of fame prev_best = halloffame[0] # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Replace the current population by the offspring population[:] = offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) # If the new best individual is the same as the previous best individual, # increment a counter, otherwise reset the counter if halloffame[0] == prev_best: wait += 1 else: wait = 0 # If the counter reached the termination criteria, stop the optimization if ngen_no_change is not None and wait >= ngen_no_change: break return population, logbook
def run(self, NGENS=100): creator.create("FitnessMax", base.Fitness, weights=self.weight) creator.create("Particle", np.ndarray, fitness=creator.FitnessMax, speed=list, smin=None, smax=None, best=None) def generate(size, pmin, pmax, smin, smax): part = creator.Particle(np.random.uniform(pmin, pmax, size)) part.speed = np.random.uniform(smin, smax, size) part.smin = smin part.smax = smax return part def updateParticle(part, best, phi1, phi2): u1 = np.random.uniform(0, phi1, len(part)) u2 = np.random.uniform(0, phi2, len(part)) v_u1 = u1 * (part.best - part) v_u2 = u2 * (best - part) part.speed += v_u1 + v_u2 for i, speed in enumerate(part.speed): if abs(speed) < part.smin: part.speed[i] = math.copysign(part.smin, speed) elif abs(speed) > part.smax: part.speed[i] = math.copysign(part.smax, speed) part += part.speed toolbox = base.Toolbox() toolbox.register("particle", generate, size=self.indSize, pmin=self.rangeGen[0], pmax=self.rangeGen[1], smin=self.smin, smax=self.smax) toolbox.register("population", tools.initRepeat, list, toolbox.particle) toolbox.register("update", updateParticle, phi1=self.phi1, phi2=self.phi2) toolbox.register("evaluate", self.evaluateFuntion) pop = toolbox.population(n=self.popSize) #hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean) stats.register("std", np.std) stats.register("min", np.min) stats.register("max", np.max) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit record = stats.compile(pop) logbook.record(gen=0, evals=len(pop), **record) #print(logbook.stream) best = None #hof.update(pop) for g in range(0, NGENS): for part in pop: part.fitness.values = toolbox.evaluate(part) if part.best is None or part.best.fitness < part.fitness: part.best = creator.Particle(part) part.best.fitness.values = part.fitness.values if best is None or best.fitness < part.fitness: best = creator.Particle(part) best.fitness.values = part.fitness.values for part in pop: toolbox.update(part, best) logbook.record(gen=g, evals=len(pop), **stats.compile(pop)) #print(logbook.stream) return best, best.fitness.values[0]
def evolve(self, population, toolbox, cxpb, mutpb, ngen, stats=None, sizeStats=None, halloffame=None, verbose=__debug__): global current_gen logbook = tools.Logbook() logbook.header = ['gen', 'best_of_gen', 'nevals'] + (stats.fields if stats else []) # 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) record = stats.compile(population) if stats else {} # record.update(sizeStats.compile(population) if sizeStats else {}) best_cost = halloffame[0].fitness.values[0] best_tours = halloffame[0].tours best_giant_tour = [node for node in halloffame[0]] logbook.record(gen=0, best_of_gen=best_cost, nevals=len(invalid_ind),**record) if verbose: print logbook.stream num_gen_no_improve = 0 # Begin the generational process for gen in range(1, ngen+1): current_gen = gen # Select the next generation individuals # offspring = toolbox.select(population, len(population)) # Vary the pool of individuals offspring = self.varAndPTA(population) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Replace the current population by the offspring population[:] = offspring # elitism k best individuals idxs = random.sample(range(len(population)),len(halloffame)) for idx, ind in zip(idxs, halloffame): population[idx]=ind # Update the hall of fame with the generated individuals if halloffame is not None: old_best_fitness = halloffame[0].fitness.values[0] halloffame.update(population) new_best_fitness = halloffame[0].fitness.values[0] if old_best_fitness == new_best_fitness: num_gen_no_improve += 1 else: num_gen_no_improve = 0 self.mut_prob = float(num_gen_no_improve)/50.0 if self.mut_prob > 0.5: self.mut_prob = 0.5 self.cross_prob = 1.0-self.mut_prob if num_gen_no_improve == MAX_NUM_GEN_NO_IMPROVE: break # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} # record.update(sizeStats.compile(population) if sizeStats else {}) logbook.record(gen=gen, best_of_gen=halloffame[0].fitness.values[0], nevals=len(invalid_ind), **record) if verbose: print logbook.stream # return best_cost, best_tours return halloffame[0].fitness.values[0], halloffame[0].tours
def neat_GP_LS(population, toolbox, cxpb, mutpb, ngen, neat_alg, neat_cx, neat_h, neat_pelit, LS_flag, LS_select, cont_evalf, num_salto, SaveMatrix, GenMatrix, pset, n_corr, num_p, params, direccion, problem, stats=None, halloffame=None, verbose=__debug__): """This algorithm reproduce the simplest evolutionary algorithm as presented in chapter 7 of [Back2000]_. :param population: A list of individuals. :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution operators. :param cxpb: The probability of mating two individuals. :param mutpb: The probability of mutating an individual. :param ngen: The number of generation. :param neat_alg: wheter or not to use species stuff. :param neat_cx: wheter or not to use neatGP cx :param neat_h: indicate the distance allowed between each specie :param neat_pelit: probability of being elitist, it's used in the neat cx and mutation :param LS_flag: wheter or not to use LocalSearchGP :param LS_select: indicate the kind of selection to use the LSGP on the population. :param cont_evalf: contador maximo del numero de evaluaciones :param n_corr: run number just to wirte the txt file :param p: problem number just to wirte the txt file :param params:indicate the params for the fitness sharing, the diffetent options are: -DontPenalize(str): 'best_specie' or 'best_of_each_specie' -Penalization_method(int): 1.without penalization 2.penalization fitness sharing 3.new penalization -ShareFitness(str): 'yes' or 'no' :param stats: A :class:`~deap.tools.Statistics` object that is updated inplace, optional. :param halloffame: A :class:`~deap.tools.HallOfFame` object that will contain the best individuals, optional. :param verbose: Whether or not to log the statistics. :returns: The final population. It uses :math:`\lambda = \kappa = \mu` and goes as follow. It first initializes the population (:math:`P(0)`) by evaluating every individual presenting an invalid fitness. Then, it enters the evolution loop that begins by the selection of the :math:`P(g+1)` population. Then the crossover operator is applied on a proportion of :math:`P(g+1)` according to the *cxpb* probability, the resulting and the untouched individuals are placed in :math:`P'(g+1)`. Thereafter, a proportion of :math:`P'(g+1)`, determined by *mutpb*, is mutated and placed in :math:`P''(g+1)`, the untouched individuals are transferred :math:`P''(g+1)`. Finally, those new individuals are evaluated and the evolution loop continues until *ngen* generations are completed. Briefly, the operators are applied in the following order :: evaluate(population) for i in range(ngen): offspring = select(population) offspring = mate(offspring) offspring = mutate(offspring) evaluate(offspring) population = offspring This function expects :meth:`toolbox.mate`, :meth:`toolbox.mutate`, :meth:`toolbox.select` and :meth:`toolbox.evaluate` aliases to be registered in the toolbox. .. [Back2000] Back, Fogel and Michalewicz, "Evolutionary Computation 1 : Basic Algorithms and Operators", 2000. """ logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) pop_file = open( './Results/%s/pop_file_%d_%d.txt' % (problem, num_p, n_corr), 'a') if SaveMatrix: # Saving data in matrix num_r = 9 if GenMatrix: num_salto = 1 num_c = ngen + 1 Matrix = np.empty(( num_c, num_r, )) vector = np.arange(0, num_c, num_salto) else: num_c = (cont_evalf / num_salto) + 1 Matrix = np.empty(( num_c, num_r, )) vector = np.arange(1, cont_evalf + num_salto, num_salto) for i in range(len(vector)): Matrix[i, 0] = vector[i] #num_r-1 Matrix[:, 6] = 0. #Creation of the species if neat_alg: species(population, neat_h) ind_specie(population) if funcEval.LS_flag: for ind in population: sizep = len(ind) + 2 param_ones = np.ones(sizep) param_ones[0] = 0 ind.params_set(param_ones) # 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): funcEval.cont_evalp += 1 ind.fitness.values = fit best = open('./Results/%s/bestind_%d_%d.txt' % (problem, num_p, n_corr), 'a') # save data best_ind = best_pop(population) # best individual of the population fitnesst_best = toolbox.map(toolbox.evaluate_test, [best_ind]) best_ind.fitness_test.values = fitnesst_best[0] best.write( '\n%s;%s;%s;%s;%s;%s' % (0, funcEval.cont_evalp, best_ind.fitness_test.values[0], best_ind.fitness.values[0], len(best_ind), avg_nodes(population))) data_pop = avg_nodes(population) if SaveMatrix: idx = 0 Matrix[idx, 1] = best_ind.fitness.values[0] Matrix[idx, 2] = best_ind.fitness_test.values[0] Matrix[idx, 3] = len(best_ind) Matrix[idx, 4] = data_pop[0] Matrix[idx, 5] = 0. Matrix[idx, 6] = 1 # just an id to know if the current row is full Matrix[idx, 7] = data_pop[1] # max size Matrix[idx, 8] = data_pop[2] # min size np.savetxt('./Matrix/%s/idx_%d_%d.txt' % (problem, num_p, n_corr), Matrix, delimiter=",", fmt="%s") if neat_alg: SpeciesPunishment(population, params, neat_h) out = open('./Results/%s/bestind_str_%d_%d.txt' % (problem, num_p, n_corr), 'a') if funcEval.LS_flag == 1: strg = best_ind.__str__() l_strg = add_subt_cf(strg, args=[]) c = tree2f() cd = c.convert(l_strg) out.write('\n%s;%s;%s;%s;%s;%s' % (0, len(best_ind), best_ind.LS_applied_get(), best_ind.get_params(), cd, best_ind)) else: out.write('\n%s;%s;%s' % (0, len(best_ind), best_ind)) for ind in population: pop_file.write('\n%s;%s' % (ind.fitness.values[0], ind)) ls_type = '' if LS_select == 1: ls_type = 'LSHS' elif LS_select == 2: ls_type = 'Best-Sp' elif LS_select == 3: ls_type = 'LSHS-Sp' elif LS_select == 4: ls_type = 'Best-Pop' elif LS_select == 5: ls_type = 'All-Pop' elif LS_select == 6: ls_type = 'LSHS-test' elif LS_select == 7: ls_type = 'Best set' elif LS_select == 8: ls_type = 'Random set' elif LS_select == 9: ls_type = "Best-Random set" print '---- Generation %d -----' % (0) print 'Problem: ', problem print 'Problem No.: ', num_p print 'Run No.: ', n_corr print 'neat-GP:', neat_alg print 'neat-cx:', neat_cx print 'Local Search:', funcEval.LS_flag if funcEval.LS_flag: print 'Local Search Heuristic: %s (%s)' % (LS_select, ls_type) print 'Best Ind.:', best_ind print 'Best Fitness:', best_ind.fitness.values[0] print 'Test fitness:', best_ind.fitness_test.values[0] print 'Avg Nodes:', avg_nodes(population) print 'Evaluations: ', funcEval.cont_evalp # Begin the generational process for gen in range(1, ngen + 1): if funcEval.cont_evalp > cont_evalf: break print '---- Generation %d -----' % (gen) print 'Problem: ', problem print 'Problem No.: ', num_p print 'Run No.: ', n_corr print 'neat-GP:', neat_alg print 'neat-cx:', neat_cx print 'Local Search:', funcEval.LS_flag if funcEval.LS_flag: print 'Local Search Heuristic: %s (%s)' % (LS_select, ls_type) best_ind = copy.deepcopy(best_pop(population)) if neat_alg: parents = p_selection(population, gen) else: parents = toolbox.select(population, len(population)) if neat_cx: n = len(parents) mut = 1 cx = 1 offspring = neatGP(toolbox, parents, cxpb, mutpb, n, mut, cx, neat_pelit) else: offspring = varOr(parents, toolbox, cxpb, mutpb) if neat_alg: specie_parents_child(parents, offspring, neat_h) offspring[:] = parents + offspring ind_specie(offspring) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): funcEval.cont_evalp += 1 ind.fitness.values = fit else: invalid_ind = [ind for ind in offspring] if funcEval.LS_flag: new_invalid_ind = [] for ind in invalid_ind: strg = ind.__str__() l_strg = add_subt(strg, ind) c = tree2f() cd = c.convert(l_strg) new_invalid_ind.append(cd) fitness_ls = toolbox.map(toolbox.evaluate, new_invalid_ind) for ind, ls_fit in zip(invalid_ind, fitness_ls): funcEval.cont_evalp += 1 ind.fitness.values = ls_fit else: fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): funcEval.cont_evalp += 1 ind.fitness.values = fit orderbyfit = sorted(offspring, key=lambda ind: ind.fitness.values) print len(orderbyfit), len(best_ind) if best_ind.fitness.values[0] <= orderbyfit[0].fitness.values[0]: offspring[:] = [best_ind] + orderbyfit[:len(population) - 1] if neat_alg: SpeciesPunishment(offspring, params, neat_h) population[:] = offspring # population update cond_ind = 0 cont_better = 0 if funcEval.LS_flag: for ind in population: ind.LS_applied_set(0) if LS_select == 1: trees_h(population, num_p, n_corr, pset, direccion) elif LS_select == 2: best_specie(population, num_p, n_corr, pset, direccion) elif LS_select == 3: specie_h(population, num_p, n_corr, pset, direccion) elif LS_select == 4: best_pop_ls(population, num_p, n_corr, pset, direccion) elif LS_select == 5: all_pop(population, num_p, n_corr, pset, direccion) elif LS_select == 6: trees_h_wo(population, num_p, n_corr, pset, direccion) elif LS_select == 7: ls_bestset(population, num_p, n_corr, pset, direccion) elif LS_select == 8: ls_random(population, num_p, n_corr, pset, direccion) elif LS_select == 9: ls_randbestset(population, num_p, n_corr, pset, direccion) # invalid_ind = [ind for ind in population] new_invalid_ind = [] for ind in population: strg = ind.__str__() l_strg = add_subt(strg, ind) c = tree2f() cd = c.convert(l_strg) new_invalid_ind.append(cd) fitness_ls = toolbox.map(toolbox.evaluate, new_invalid_ind) print 'Fitness comp.:', for ind, ls_fit in zip(invalid_ind, fitness_ls): if ind.LS_applied_get() == 1: cond_ind += 1 if ind.fitness.values[0] < ls_fit: print '-', elif ind.fitness.values[0] > ls_fit: cont_better += 1 print '+', elif ind.fitness.values[0] == ls_fit: print '=', funcEval.cont_evalp += 1 ind.fitness.values = ls_fit print '' pop_file.write('\n----------------------------------------%s' % (gen)) for ind in population: pop_file.write('\n%s;%s;%s;%s' % (ind.LS_applied_get(), ind.fitness.values[0], ind, [x for x in ind.get_params()])) else: pop_file.write('\n----------------------------------------') for ind in population: pop_file.write('\n%s;%s;%s;%s;%s;%s' % (ind.LS_applied_get(), ind.LS_story_get(), ind.off_cx_get(), ind.off_mut_get(), ind.fitness.values[0], ind)) best_ind = best_pop(population) if funcEval.LS_flag: strg = best_ind.__str__() l_strg = add_subt(strg, best_ind) c = tree2f() cd = c.convert(l_strg) new_invalid_ind.append(cd) fit_best = toolbox.map(toolbox.evaluate_test, [cd]) best_ind.fitness_test.values = fit_best[0] best.write( '\n%s;%s;%s;%s;%s;%s;%s' % (gen, funcEval.cont_evalp, best_ind.fitness.values[0], best_ind.LS_fitness_get(), best_ind.fitness_test.values[0], len(best_ind), avg_nodes(population))) out.write('\n%s;%s;%s;%s;%s;%s' % (gen, len(best_ind), best_ind.LS_applied_get(), best_ind.get_params(), cd, best_ind)) else: fitnesses_test = toolbox.map(toolbox.evaluate_test, [best_ind]) best_ind.fitness_test.values = fitnesses_test[0] best.write( '\n%s;%s;%s;%s;%s;%s' % (gen, funcEval.cont_evalp, best_ind.fitness_test.values[0], best_ind.fitness.values[0], len(best_ind), avg_nodes(population))) out.write('\n%s;%s;%s' % (gen, len(best_ind), best_ind)) if funcEval.LS_flag: print 'Num. LS:', cond_ind print 'Ind. Improvement:', cont_better print 'Best Ind. LS:', best_ind.LS_applied_get() print 'Best Ind.:', best_ind print 'Best Fitness:', best_ind.fitness.values[0] print 'Test fitness:', best_ind.fitness_test.values[0] print 'Avg Nodes:', avg_nodes(population) print 'Evaluations: ', funcEval.cont_evalp if SaveMatrix: data_pop = avg_nodes(population) if GenMatrix: idx_aux = np.searchsorted(Matrix[:, 0], gen) Matrix[idx_aux, 1] = best_ind.fitness.values[0] Matrix[idx_aux, 2] = best_ind.fitness_test.values[0] Matrix[idx_aux, 3] = len(best_ind) Matrix[idx_aux, 4] = data_pop[0] Matrix[idx_aux, 5] = gen Matrix[idx_aux, 6] = 1 Matrix[idx_aux, 7] = data_pop[1] # max nodes Matrix[idx_aux, 8] = data_pop[2] # min nodes else: if funcEval.cont_evalp >= cont_evalf: num_c -= 1 idx_aux = num_c Matrix[num_c, 1] = best_ind.fitness.values[0] Matrix[num_c, 2] = best_ind.fitness_test.values[0] Matrix[num_c, 3] = len(best_ind) Matrix[num_c, 4] = data_pop[0] Matrix[num_c, 5] = gen Matrix[num_c, 6] = 1 Matrix[num_c, 7] = data_pop[1] #max_nodes Matrix[num_c, 8] = data_pop[2] #min nodes else: idx_aux = np.searchsorted(Matrix[:, 0], funcEval.cont_evalp) Matrix[idx_aux, 1] = best_ind.fitness.values[0] Matrix[idx_aux, 2] = best_ind.fitness_test.values[0] Matrix[idx_aux, 3] = len(best_ind) Matrix[idx_aux, 4] = data_pop[0] Matrix[idx_aux, 5] = gen Matrix[idx_aux, 6] = 1 Matrix[idx_aux, 7] = data_pop[1] #max nodes Matrix[idx_aux, 8] = data_pop[2] #min nodes id_it = idx_aux - 1 id_beg = 0 flag = True flag2 = False while flag: if Matrix[id_it, 6] == 0: id_it -= 1 flag2 = True else: id_beg = id_it flag = False if flag2: x = Matrix[id_beg, 1:8] Matrix[id_beg:idx_aux, 1:] = Matrix[id_beg, 1:] np.savetxt('./Matrix/%s/idx_%d_%d.txt' % (problem, num_p, n_corr), Matrix, delimiter=",", fmt="%s") return population, logbook
def eaSimple(population, toolbox, cxpb, mutpb, elitpb, ngen, randomseed, stats=None, halloffame=None, verbose=__debug__): """This algorithm reproduce the simplest evolutionary algorithm as presented in chapter 7 of [Back2000]_. :param population: A list of individuals. :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution operators. :param cxpb: The probability of mating two individuals. :param mutpb: The probability of mutating an individual. :param etilpb: The probability of elitism :param ngen: The number of generation. :param stats: A :class:`~deap.tools.Statistics` object that is updated inplace, optional. :param halloffame: A :class:`~deap.tools.HallOfFame` object that will contain the best individuals, optional. :param verbose: Whether or not to log the statistics. :returns: The final population :returns: A class:`~deap.tools.Logbook` with the statistics of the evolution The algorithm takes in a population and evolves it in place using the :meth:`varAnd` method. It returns the optimized population and a :class:`~deap.tools.Logbook` with the statistics of the evolution. The logbook will contain the generation number, the number of evalutions for each generation and the statistics if a :class:`~deap.tools.Statistics` is given as argument. The *cxpb* and *mutpb* arguments are passed to the :func:`varAnd` function. The pseudocode goes as follow :: evaluate(population) for g in range(ngen): elitismNum offspringE=selectElitism(population,elitismNum) population = select(population, len(population)-elitismNum) offspring = varAnd(population, toolbox, cxpb, mutpb) offspring=offspring+offspringE evaluate(offspring) population = offspring. This function expects the :meth:`toolbox.mate`, :meth:`toolbox.mutate`, :meth:`toolbox.select` and :meth:`toolbox.evaluate` and :meth::`toolbox.selectElitism`, aliases to be registered in the toolbox. .. [Back2000] Back, Fogel and Michalewicz, "Evolutionary Computation 1 : Basic Algorithms and Operators", 2000. """ logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.mapp(toolbox.evaluate, invalid_ind) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) hof_store = tools.HallOfFame(5 * len(population)) hof_store.update(population) record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(population), **record) if verbose: print(logbook.stream) for gen in range(1, ngen + 1): #Select the next generation individuals by elitism elitismNum=int(elitpb * len(population)) population_for_eli=[toolbox.clone(ind) for ind in population] offspringE = toolbox.selectElitism(population_for_eli, k=elitismNum) # Select the next generation individuals for crossover and mutation offspring = toolbox.select(population, len(population)-elitismNum) # Vary the pool of individuals offspring = varAnd(offspring, toolbox, cxpb, mutpb) # add offspring from elitism into current offspring # generate the next generation individuals # Evaluate the individuals with an invalid fitness for i in offspring: ind = 0 while ind<len(hof_store): if i == hof_store[ind]: i.fitness.values = hof_store[ind].fitness.values ind = len(hof_store) else: ind+=1 invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.mapp(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit offspring[0:0]=offspringE # Update the hall of fame with the generated if halloffame is not None: halloffame.update(offspring) cop_po = offspring.copy() hof_store.update(offspring) for i in hof_store: cop_po.append(i) population[:] = offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=len(offspring), **record) if verbose: print(logbook.stream) return population, logbook
def main(): random.seed(64) population = toolbox.population(n=300) hof = tools.ParetoFront() stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean, axis=0) stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" CXPB, MUTPB, ADDPB, DELPB, NGEN = 0.5, 0.2, 0.01, 0.01, 40 # Evaluate every individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit hof.update(population) record = stats.compile(population) logbook.record(gen=0, evals=len(population), **record) print((logbook.stream)) # Begin the evolution for g in range(1, NGEN): offspring = [toolbox.clone(ind) for ind in population] # Apply crossover and mutation for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() < CXPB: toolbox.mate(ind1, ind2) del ind1.fitness.values del ind2.fitness.values # Note here that we have a different sheme of mutation than in the # original algorithm, we use 3 different mutations subsequently. for ind in offspring: if random.random() < MUTPB: toolbox.mutate(ind) del ind.fitness.values if random.random() < ADDPB: toolbox.addwire(ind) del ind.fitness.values if random.random() < DELPB: toolbox.delwire(ind) del ind.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit population = toolbox.select(population + offspring, len(offspring)) hof.update(population) record = stats.compile(population) logbook.record(gen=g, evals=len(invalid_ind), **record) print((logbook.stream)) best_network = sn.SortingNetwork(INPUTS, hof[0]) print(stats) print(best_network) print((best_network.draw())) print(("%i errors, length %i, depth %i" % hof[0].fitness.values)) return population, logbook, hof
def ga_mu_plus_lambda(self, mu, lambda_, checkpoint_load, checkpoint_fname, checkpoint_freq, sel_best, verbose): """The (mu + lambda) evolutionary algorithm. Adapted from: https://github.com/DEAP/deap/blob/master/deap/algorithms.py The pseudo-code goes as follows: evaluate(population) for g in range(ngen): offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) evaluate(offspring) population = select(population + offspring, mu) First, the individuals having an invalid fitness are evaluated. Second, the evolutionary loop begins by producing "lambda_" offspring from the population, the offspring are generated by the "varOr" function. The offspring are then evaluated and the next generation population is selected from both the offspring and the population. Finally, when "max_gen" generations are done, the algorithm returns a tuple with the final population and a "deap.tools.Logbook" of the evolution. This function expects "toolbox.mate", "toolbox.mutate", "toolbox.select", and "toolbox.evaluate" aliases to be registered in the toolbox. Arguments: mu (float): number of individuals to select for the next generation. lambda_ (int): number of children to produce at each generation. checkpoint_load (str or None): checkpoint file to load, if provided. checkpoint_fname (str): name of the checkpoint file to save. checkpoint_freq (str): checkpoint saving frequency (relative to gen). sel_best (int): number of best individuals to log at each generation. verbose (bool): run in verbosity mode. Returns: tuple: final population and the logbook of the evolution. """ # Create the statistics stats_pop = tools.Statistics() stats_fit = tools.Statistics(key=lambda ind: ind.fitness.values) stats_res = tools.Statistics(key=lambda ind: ind.result) stats = tools.MultiStatistics(population=stats_pop, fitness=stats_fit, result=stats_res) stats.register("value", copy.deepcopy) # If a checkpoint is provided, continue from the given generation if checkpoint_load: # Load the dictionary from the pickled file cp = file.read_pickle(checkpoint_load) # Load the stored parameters population = cp['population'] start_gen = cp['generation'] + 1 logbook = cp['logbook'] random.setstate(cp['rnd_state']) logger.info("Running from a checkpoint!") logger.info("-- Population size: %d", len(population)) logger.info("-- Current generation: %d\n", start_gen) else: # Create the population population = self.toolbox.population(n=self.pop_size) start_gen = 1 # Create the logbook logbook = tools.Logbook() logbook.header = 'gen', 'evals', 'population', 'fitness', 'result' # Get the individuals that are not evaluated invalid_inds = [ind for ind in population if not ind.fitness.valid] # The number of simulation calls to the server is the number of # invalid individuals num_sims = len(invalid_inds) logger.info("Starting the initial evaluation | evaluations: %d", num_sims) # Evaluation start time start_time = time.time() # Evaluate the individuals with an invalid fitness results = self.toolbox.evaluate(invalid_inds) for ind, res_ind in zip(invalid_inds, results): ind.fitness.values = res_ind[0] ind.result = res_ind[1] # Assign the crowding distance to the individuals (no selection is done) population = self.toolbox.select(population, len(population)) record = stats.compile(population) logbook.record(gen=0, evals=num_sims, **record) # Evaluation time total_time = time.time() - start_time mins, secs = divmod(total_time, 60) hours, mins = divmod(mins, 60) msg = f"Finished generation. Elapsed time: {hours:02.0f}h{mins:02.0f}m{secs:02.0f}s" secs = total_time / num_sims mins, secs = divmod(secs, 60) msg += f" | avg: {mins:02.0f}m{secs:02.2f}s/ind\n" logger.info(msg) print( "====================== Starting Optimization ======================\n" ) # Begin the generational process for gen in range(start_gen, self.max_gen + 1): # Vary the population offspring = algorithms.varOr(population, self.toolbox, lambda_, self.cx_prob, self.mut_prob) # Evaluate the individuals with an invalid fitness invalid_inds = [ind for ind in offspring if not ind.fitness.valid] # The number of simulation calls to the server is the number of # invalid individuals num_sims = len(invalid_inds) msg = f"Starting generation {gen}/{self.max_gen} | evaluations: {num_sims}" logger.info(msg) # Evaluation start time start_time = time.time() # Evaluate the individuals with an invalid fitness results = self.toolbox.evaluate(invalid_inds) for ind, res_ind in zip(invalid_inds, results): ind.fitness.values = res_ind[0] ind.result = res_ind[1] # Update the statistics with the population record = stats.compile(population) logbook.record(gen=gen, evals=num_sims, **record) # Save a checkpoint of the evolution if gen % checkpoint_freq == 0: cp = dict(generation=gen, population=population, logbook=logbook, rnd_state=random.getstate()) file.write_pickle(checkpoint_fname, cp) # Evaluation time total_time = time.time() - start_time mins, secs = divmod(total_time, 60) hours, mins = divmod(mins, 60) msg = f"Finished generation. " msg += f"Elapsed time: {hours:02.0f}h{mins:02.0f}m{secs:02.0f}s | " secs = total_time / num_sims mins, secs = divmod(secs, 60) msg += f"avg: {mins:02.0f}m{secs:02.2f}s/ind\n" logger.info(msg) # Show the best individuals of each generation print(f"---- Best {sel_best} individuals of this generation ----") best_inds = tools.selBest(population, sel_best) for i, ind in enumerate(best_inds): print(f"Ind #{i + 1} => ", end='') # Circuit variables/parameters formatted_params = [ f"{key}: {ind[idx]:0.2g}" for idx, key in enumerate(self.circuit_vars) ] print(' | '.join(formatted_params)) # Fitness print("\t Fitness -> ", end='') formatted_fits = [ f"{key}: {ind.fitness.values[idx]:0.2g}" for idx, key in enumerate(list(self.objectives.keys())) ] print(' | '.join(formatted_fits)) # Simulation results print("\t Results -> ", end='') formatted_res = [ f"{key}: {val:0.2g}" for key, val in ind.result.items() ] print(' | '.join(formatted_res)) print("") # Select the next generation population population[:] = self.toolbox.select(population + offspring, mu) return population, logbook
def run_opt(self, pop_size, generations, cores=1, plot=False, log=False, log_path=None, run_id=None, store_params=True, **kwargs): """Runs the optimizer. Parameters ---------- pop_size: int Size of the population each generation. generation: int Number of generations in optimisation. cores: int, optional Number of CPU cores used to run the optimisation. If the 'mp_disabled' keyword is passed to the optimizer, this will be ignored and one core will be used. plot: bool, optional If true, matplotlib will be used to plot information about the minimisation. log: bool, optional If true, a log file describing the optimisation will be created. By default it will be written to the current directory and named according to the time the minimisation finished. This can be manually specified by passing the 'output_path' and 'run_id' keyword arguments. log_path : str Path to write output file. run_id : str An identifier used as the name of your log file. store_params: bool, optional If true, the parameters for each model created during the optimisation will be stored. This can be used to create funnel data later on. """ self._cores = cores self._store_params = store_params self.parameter_log = [] self._model_count = 0 self.halloffame = tools.HallOfFame(1) self.stats = tools.Statistics(lambda thing: thing.fitness.values) self.stats.register("avg", numpy.mean) self.stats.register("std", numpy.std) self.stats.register("min", numpy.min) self.stats.register("max", numpy.max) self.logbook = tools.Logbook() self.logbook.header = ["gen", "evals"] + self.stats.fields start_time = datetime.datetime.now() self._initialize_pop(pop_size) for g in range(generations): self._update_pop(pop_size) self.halloffame.update(self.population) self.logbook.record(gen=g, evals=self._evals, **self.stats.compile(self.population)) print(self.logbook.stream) end_time = datetime.datetime.now() time_taken = end_time - start_time print("Evaluated {} models in total in {}".format( self._model_count, time_taken)) print("Best fitness is {0}".format(self.halloffame[0].fitness)) print("Best parameters are {0}".format(self.parse_individual( self.halloffame[0]))) for i, entry in enumerate(self.halloffame[0]): if entry > 0.95: print( "Warning! Parameter {0} is at or near maximum allowed " "value\n".format(i + 1)) elif entry < -0.95: print( "Warning! Parameter {0} is at or near minimum allowed " "value\n".format(i + 1)) if log: self.log_results(output_path=output_path, run_id=run_id) if plot: print('----Minimisation plot:') plt.figure(figsize=(5, 5)) plt.plot(range(len(self.logbook.select('min'))), self.logbook.select('min')) plt.xlabel('Iteration', fontsize=20) plt.ylabel('Score', fontsize=20) return
def main(pop=10000, CXPB=0.75, MUTPB=0.1, NumGenWithoutConverge=300, file=None): """ Execute Genetic Algorithm. args: pop -> population of GA CXPB -> Crossover Probability MUTPB -> MUTATION Probability NumGenWithoutConverge -> Number of generations without converge file -> if write results in file """ pop = toolbox.population(n=pop) gen, genMelhor = 0, 0 hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean) stats.register("std", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) # Evaluate the entire population list(toolbox.map(toolbox.evaluate, pop)) melhor = min([i.fitness.values for i in pop]) logbook = tools.Logbook() p = stats.compile(pop) logbook.record(gen=0, **p) logbook.header = "gen", 'min', 'max', "avg", "std" print(logbook.stream, file=file) while gen - genMelhor <= NumGenWithoutConverge: # Select the next generation individuals offspring = toolbox.select(pop, len(pop)) # Clone the selected individuals offspring = list(toolbox.map(toolbox.clone, offspring)) # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < CXPB: toolbox.mate0(child1[0], child2[0]) toolbox.mate1(child1[1], child2[1]) del child1.fitness.values del child2.fitness.values for mutant in offspring: if random.random() < MUTPB: toolbox.mutate0(mutant[0]) toolbox.mutate1(mutant[1]) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] list(toolbox.map(toolbox.evaluate, invalid_ind)) # The population is entirely replaced by the offspring pop[:] = offspring gen += 1 minF = min([i.fitness.values for i in pop]) if minF < melhor: melhor = minF genMelhor = gen p = stats.compile(pop) logbook.record(gen=gen, **p) if gen - genMelhor <= NumGenWithoutConverge and gen != 1: print(logbook.stream) else: print(logbook.stream, file=file) hof.update(pop) return pop, stats, hof
def __init__(self, index, n, initial_states, data_states, primitive_sets, archive_size=10, stable_states=None, mstats=None): """ Initialize a species composed of n_individuals individuals. :param index: int, index of this species among all the species :param n: int, number of individuals in this species :param initial_states: 2d list, one or more initial states denoting the starting point of gene network :param data_states: 2d list, all the binary states observed in the experiment :param primitive_sets: list of gputils.NetPrimitiveSet, primitive sets for all the species which is used when cooperating :param archive_size: int, size of the archive for non-dominated individuals :param stable_states: 2d list, once the network reaches a stable state, it should not leave it :param mstats: deap.tools.Statistics or deap.tools.MultiStatistics, statistics to be monitored during evolution """ self.index = index self.n_individuals = n self._experiment_path = None self.log_file = None self.data_states = {tuple(s) for s in data_states } # facilitate data/model space matching self.initial_states = initial_states self.stable_states = stable_states self.primitive_sets = primitive_sets self.pset = self.primitive_sets[index] self.toolbox = self._init_toolbox() self.population = None self.collaboration_pool_size = 3 self.gen = 0 self.stage = 1 self.n_gen_stage1 = 50 # total number of generations in stage1 self._init_evolution() self.stage = 1 self.best_collaboration_history = {} self.hof_stage1 = tools.HallOfFame(archive_size) self.hof_stage2 = Archive(archive_size) self.best_global_fitness = None self.best_local_fitness = None self._n_stagnation = 0 self.is_single_objective = False # if true, then only the global fitness is used self.logbook = tools.Logbook() self.mstats = mstats self.logbook.header = ['index', 'stage', 'gen' ] + mstats.fields if mstats is not None else []
def modEuPlusLambda(self, population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, cutoff=600, start=0, trace_path=None, verbose=__debug__): logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # 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) record = stats.compile(population) if stats is not None else {} logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) gen = 1 overall_best = None # Begin the generational process while gen < ngen + 1 and time.time() - start < cutoff: gen += 1 # Vary the population population.extend(tools.selBest( population, 5)) num = random.randint(900, 1000) / 1000.0 # num = len(population[0]) / 2.0 population.extend( [creator.Individual(self.create_individual(bar=num)) for i in range(10)]) offspring = algorithms.varOr( population, toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) # this_best = max(population, key=lambda x: x.fitness) this_best = tools.selBest(population, 1)[0] if overall_best is None: overall_best = this_best overall_best = tools.selBest([this_best, overall_best], 1)[0] if trace_path is not None: with open(trace_path, 'a') as f: f.write( ','.join([str(time.time() - start), str(sum(overall_best))]) + "\n") # Update the statistics with the new population try: record = stats.compile(population) if stats is not None else {} except: None logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose and gen % 10 == 0: print(logbook.stream) print(f" Score: {sum(overall_best)}") return population, logbook
def run(self, file_name=None): """ Starts simple evolutionary algorithm. :param file_name: Previously saved population file. """ start_time = time.time() logs_dir = self.init_directories() stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean) stats.register("min", np.min) stats.register("max", np.max) toolbox = self.deap_toolbox_init() population = toolbox.population( pop_size=self.evolution_params.pop_size, file_name=file_name) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) if (self.evolution_params.hof_size > 0): halloffame = tools.HallOfFame(self.evolution_params.hof_size) else: halloffame = None # invalid_ind = [ind for ind in population if not ind.fitness.valid] invalid_ind = population seeds = [np.random.randint(0, 2**16) for _ in range(len(invalid_ind))] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind, seeds) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=str(len(invalid_ind)), **record) print(logbook.stream) population.sort(key=lambda ind: ind.fitness.values, reverse=True) # Begin the generational process for gen in range(1, self.evolution_params.ngen + 1): # Select the next generation individuals offspring = toolbox.select( population, len(population) - self.evolution_params.elite) offspring = [toolbox.clone(ind) for ind in offspring] # Apply crossover and mutation on the offspring for i in range(1, len(offspring), 2): if np.random.random() < self.evolution_params.cxpb: offspring[i - 1], offspring[i] = toolbox.mate( offspring[i - 1], offspring[i]) del offspring[ i - 1].fitness.values, offspring[i].fitness.values for i in range(len(offspring)): if np.random.random() < self.evolution_params.mut[1]: offspring[i], = toolbox.mutate(offspring[i]) del offspring[i].fitness.values # Add elite individuals (they lived through mutation and x-over) for i in range(self.evolution_params.elite): offspring.append(toolbox.clone(population[i])) # invalid_ind = [ind for ind in offspring if not ind.fitness.valid] invalid_ind = offspring seeds = [ np.random.randint(0, 2**16) for _ in range(len(invalid_ind)) ] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind, seeds) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Replace the current population by the offspring population[:] = offspring population.sort(key=lambda ind: ind.fitness.values, reverse=True) # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=str(len(invalid_ind)), **record) print(logbook.stream) if (gen % self.logs_every == 0): self.log_all(logs_dir, population, halloffame, logbook, start_time) self.log_all(logs_dir, population, halloffame, logbook, start_time)
def eaAdaptiveWithElitism(population, toolbox, ngen, k1, k2, k3, k4, stats=None, halloffame=None, verbose=__debug__): def getMinAvg(record): return record['min'], record['avg'] def calPc(fitness): # print("Fitness= {}; fMin={}; fAvg={}; k1 = {}".format(fitness, fMin, fAvg, k1)) return (k1 * (fMin - fitness) / (fMin - fAvg)) if fitness >= fAvg else k2 def calPm(fitness): return (k3 * (fMin - fitness) / (fMin - fAvg)) if fitness >= fAvg else k4 # Create a logbook logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Calculate fitness for all population fitnesses = map(toolbox.evaluate, population) # Set fitness to valid value for ind, fit in zip(population, fitnesses): ind.fitness.values = fit if halloffame is None: raise ValueError("halloffame parameter must not be empty!") # Get some best individual halloffame.update(population) hof_size = len(halloffame.items) if halloffame.items else 0 record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(population), **record) # Get min, avg fMin, fAvg = getMinAvg(record) # For logbook debuging if verbose: print(logbook.stream) for gen in range(1, ngen + 1): # Select the next generation individuals offspring = toolbox.select(population, len(population) - hof_size) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) ''' Implement cross over and mutation ''' # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): cxpb = calPc( np.minimum(child1.fitness.values[0], child2.fitness.values[0])) # print("Pc = ", cxpb) # cross two individuals with probability CXPB if random.random() < cxpb: toolbox.mate(child1, child2) # fitness values of the children # must be recalculated later del child1.fitness.values del child2.fitness.values # Recalculate fitness after cross over invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit for mutant in offspring: mutpb = calPm(mutant.fitness.values[0]) # mutate an individual with probability MUTPB if random.random() < mutpb: toolbox.mutate(mutant) del mutant.fitness.values # # Vary the pool of individuals # offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # add the best back to population: offspring.extend(halloffame.items) # # Update the hall of fame with the generated individuals halloffame.update(offspring) # Replace the current population by the offspring population[:] = offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} print("Records: {0}".format(record)) print("Min: {}; Avg{}".format(fMin, fAvg)) logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) return population, logbook
def eaSimple(population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__, results_file="results", post_fix="", kpi="Value"): """This algorithm reproduce the simplest evolutionary algorithm as presented in chapter 7 of Back, Fogel and Michalewicz, "Evolutionary Computation 1 : Basic Algorithms and Operators", 2000. eaSimple originally from https://github.com/DEAP/deap/blob/master/deap/algorithms.py Modified by eleow to - Add saving at every generation - Add progress bar - Add plot of min,max and ave value of fitness function. By having plot, we are able to see if GA is converging and/or improving. If not, we need not waste time. We can stop the run and change objective function or seed, etc """ def toolbox_eval(ind): t_ind.update() return toolbox.evaluate(ind) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) t_ngen = tqdm(range(0, ngen + 1), desc="Creating initial gen") t_ngen.update() # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] t_ind = tqdm(desc="Creating pop", leave=False, total=len(population)) fitnesses = toolbox.map(toolbox_eval, invalid_ind) t_ind.reset() for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: fig = plt.figure() ax = fig.add_subplot(111) ax.set_title('Statistics of population') ax.set_xlabel('Gen Num.') ax.set_ylabel(kpi) # plt.ion() fig.show() fig.canvas.draw() # print(logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): t_ngen.set_description(f"Creating gen {gen}/{ngen}") # Select the next generation individuals offspring = toolbox.select(population, len(population)) # Vary the pool of individuals offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] t_ind.total = len(invalid_ind) fitnesses = toolbox.map(toolbox_eval, invalid_ind) t_ind.reset() for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Replace the current population by the offspring population[:] = offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: ax.clear() ax.set_title('Statistics of population') ax.set_xlabel('Gen Num.') ax.set_ylabel(kpi) df_logbook = pd.DataFrame(logbook) # df_logbook[['avg', 'max', 'min']].plot(ax=ax) ax.plot(df_logbook['avg'], c='red') plt.fill_between(x=df_logbook.index, y1=df_logbook['min'], y2=df_logbook['max']) fig.canvas.draw() # save at the end of each gen top10 = tools.selBest(population, k=10) top10 = [list(t) for t in top10] # convert deap Individual to list # save latest (overwriting file if exists) with open(f"{results_file}.pickle", 'wb') as f: pickle.dump(top10, f) # note down seed, pop size and number of generations for reproducibility, and save as a separate file with open(f"{results_file}{post_fix}.pickle", 'wb') as f: pickle.dump(top10, f) t_ngen.update() t_ind.n = t_ind.total t_ind.close() t_ngen.close() plt.ioff() return population, logbook
def main(): # The cma module uses the numpy random number generator # numpy.random.seed(128) MU, LAMBDA = 10, 10 NGEN = 500 verbose = True # The MO-CMA-ES algorithm takes a full population as argument population = [ creator.Individual(x) for x in (numpy.random.uniform(0, 1, (MU, N))) ] for ind in population: ind.fitness.values = toolbox.evaluate(ind) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + (stats.fields if stats else []) for gen in range(NGEN): # Generate a new population population = toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Update the strategy with the evaluated individuals toolbox.update(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(population), **record) if verbose: print(logbook.stream) if verbose: print("Final population hypervolume is %f" % hypervolume(strategy.parents, [11.0, 11.0])) # import matplotlib.pyplot as plt # valid_front = numpy.array([ind.fitness.values for ind in strategy.parents if valid(ind)]) # invalid_front = numpy.array([ind.fitness.values for ind in strategy.parents if not valid(ind)]) # fig = plt.figure() # if len(valid_front) > 0: # plt.scatter(valid_front[:,0], valid_front[:,1], c="g") # if len(invalid_front) > 0: # plt.scatter(invalid_front[:,0], invalid_front[:,1], c="r") # plt.show() return strategy.parents
tic = time.perf_counter() pop = toolbox.population(n=pop_size) invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean, axis=0) stats.register("std", np.std, axis=0) stats.register("min", np.min, axis=0) stats.register("max", np.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" record = stats.compile(pop) logbook.record(gen=0, evals=len(pop), **record) print(logbook.stream) scores_deque = deque(maxlen=100) scores = [] for gen in range(1, n_generations): pop = toolbox.select(pop, k=n_elite) reward = agent.evaluate(pop[0], gamma=1.0) best_Weights['fc1_W'] = np.array([pops['fc1_W'] for pops in pop]).mean(axis=0) best_Weights['fc1_b'] = np.array([pops['fc1_b']
def find_shapelets_pso(timeseries, labels, max_len=100, min_len=1, particles=25, iterations=25, verbose=True, stop_iterations=10): candidates = generate_candidates(timeseries, labels, max_len, min_len) creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Particle", np.ndarray, fitness=creator.FitnessMax, speed=list, smin=None, smax=None, best=None) def generate(smin, smax, n): rand_cands = np.array(candidates)[np.random.choice(range(len(candidates)), size=n)] parts = [] for rand_cand in rand_cands: rand_cand = rand_cand[0] part = creator.Particle(rand_cand) part.speed = np.random.uniform(smin, smax, len(rand_cand)) part.smin = smin part.smax = smax parts.append(part) return parts def updateParticle(part, best, phi1, phi2): u1 = np.random.uniform(0, phi1, len(part)) u2 = np.random.uniform(0, phi2, len(part)) v_u1 = u1 * (part.best - part) v_u2 = u2 * (best - part) # These magic numbers are found in http://www.ijmlc.org/vol5/521-C016.pdf part.speed = 0.729*part.speed + np.minimum(np.maximum(1.49445 * (v_u1 + v_u2), part.smin), part.smax) part += part.speed def cost(shapelet): return (check_candidate(timeseries, labels, shapelet)[0], ) toolbox = base.Toolbox() toolbox.register("population", generate, smin=-0.25, smax=0.25) toolbox.register("update", updateParticle, phi1=1, phi2=1) toolbox.register("evaluate", cost) pop = toolbox.population(n=particles) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean) stats.register("std", np.std) stats.register("max", np.max) logbook = tools.Logbook() logbook.header = ["gen", "evals"] + stats.fields GEN = 10000 best = None it_wo_improvement = 0 gain_ub = information_gain_ub(labels) for g in range(GEN): it_wo_improvement += 1 for part in pop: part.fitness.values = toolbox.evaluate(part) if part.best is None or part.best.fitness < part.fitness: part.best = creator.Particle(part) part.best.fitness.values = part.fitness.values if best is None or best.fitness < part.fitness: best = creator.Particle(part) best.fitness.values = part.fitness.values it_wo_improvement = 0 for part in pop: toolbox.update(part, best) # Gather all the fitnesses in one list and print the stats logbook.record(gen=g, evals=len(pop), **stats.compile(pop)) print(logbook.stream) if it_wo_improvement == stop_iterations or best.fitness.values[0] >= gain_ub: break return best
def execute(self): print "Executing MOEA/D" logbook = tools.Logbook() logbook.header = ['gen', 'evals'] + (self.stats.fields if self.stats else []) self.evaluations_ = 0 print "POPSIZE:", self.populationSize_ self.indArray_ = [ self.toolbox.individual() for _ in range(self.n_objectives) ] # 2-D list of size populationSize * T_ self.neighbourhood_ = [[None] * self.T_] * (self.populationSize_) # List of size number of objectives. Contains best fitness. self.z_ = self.n_objectives * [None] #2-D list Of size populationSize_ x Number of objectives. Used for weight vectors. self.lambda_ = [[None for _ in range(self.n_objectives)] for i in range(self.populationSize_)] # STEP 1. Initialization self.initUniformWeight() self.initNeighbourhood() self.initIdealPoint() record = self.stats.compile(self.population) if self.stats is not None else {} logbook.record(gen=self.ngen , evals=self.evaluations_, **record) if self.verbose: print logbook.stream while self.evaluations_ < self.maxEvaluations: permutation = [None] * self.populationSize_ # Of type int self.randomPermutations(permutation, self.populationSize_) for i in xrange(self.populationSize_): n = permutation[i] type_ = int() rnd = random.random() # STEP 2.1: Mating selection based on probability if rnd < self.delta_: type_ = 1 else: type_ = 2 p = list() # Vector of type integer self.matingSelection(p, n, 2, type_) # STEP 2.2: Reproduction child = None children = [] parents = [None] * 3 candidates = list(self.population[:]) parents[0] = deepcopy(candidates[p[0]]) parents[1] = deepcopy(candidates[p[1]]) children = self.toolbox.mate(parents[0], parents[1]) # Apply mutation children = [self.toolbox.mutate(child) for child in children] # Evaluation offspring = [] for child in children: fit = self.toolbox.evaluate(child[0]) self.evaluations_ += 1 child[0].fitness.values = fit offspring.append(child[0]) # STEP 2.3 Repair # TODO: Add this as an option to repair invalid individuals? # STEP 2.4: Update z_ for child in offspring: self.updateReference(child) # STEP 2.5 Update of solutions self.updateProblem(child, n, type_) record = self.stats.compile(self.population) if self.stats is not None else {} logbook.record(gen=self.ngen, evals=self.evaluations_, **record ) if self.verbose: print logbook.stream return self.population
def main(num_Gens, size_Pops, cx, seed=None): # toolbox.register("attr_float", iniPops) # toolbox.register("individual", tools.initIterate, creator.Individuals, toolbox.attr_float) # toolbox.register("population", tools.initRepeat, list, toolbox.individual) # toolbox.register("evaluate", calBenefitandCost) # toolbox.register("mate", tools.cxOnePoint) # toolbox.register("mutate", mutModel, indpb=MutateRate) # toolbox.register("select", tools.selNSGA2) random.seed(seed) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) # stats.register("avg", numpy.mean, axis=0) # stats.register("std", numpy.std, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "min", "max" pop = toolbox.population(n=size_Pops) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in pop if not ind.fitness.valid] try: # parallel on multiprocesor or clusters using SCOOP from scoop import futures fitnesses = futures.map(toolbox.evaluate, invalid_ind) # print "parallel-fitnesses: ",fitnesses except ImportError or ImportWarning: # serial fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) # print "serial-fitnesses: ",fitnesses for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # This is just to assign the crowding distance to the individuals # no actual selection is done pop = toolbox.select(pop, int(len(pop) * SelectRate)) record = stats.compile(pop) logbook.record(gen=0, evals=len(invalid_ind), **record) print(logbook.stream) # Begin the generational process for gen in range(1, num_Gens): printInfo("###### Iteration: %d ######" % gen) # Vary the population offspring = tools.selTournamentDCD(pop, int(len(pop) * SelectRate)) offspring = [toolbox.clone(ind) for ind in offspring] for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() <= cx: toolbox.mate(ind1, ind2) toolbox.mutate(ind1) toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] try: # parallel on multiprocesor or clusters using SCOOP from scoop import futures fitnesses = futures.map(toolbox.evaluate, invalid_ind) except ImportError or ImportWarning: # serial fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) # invalid_ind = [ind for ind in offspring if not ind.fitness.valid] # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Select the next generation population pop = toolbox.select(pop + offspring, size_Pops) record = stats.compile(pop) logbook.record(gen=gen, evals=len(invalid_ind), **record) # print "\nlogbook.stream: ", logbook.stream if gen % 1 == 0: # Create plot createPlot(pop, model_Workdir, num_Gens, size_Pops, gen) # save in file outputStr = "### Generation number: %d, Population size: %d ###" % ( num_Gens, size_Pops) + LF outputStr += "### Generation_%d ###" % gen + LF outputStr += "cost\tbenefit\tscenario" + LF for indi in pop: outputStr += str(indi) + LF outfilename = model_Workdir + os.sep + "NSGAII_OUTPUT" + os.sep + "Gen_" \ + str(GenerationsNum) + "_Pop_" + str(PopulationSize) + os.sep + "Gen_" \ + str(GenerationsNum) + "_Pop_" + str(PopulationSize) + "_resultLog.txt" WriteLog(outfilename, outputStr, MODE='append') printInfo("Final population hypervolume is %f" % hypervolume(pop, [11.0, 11.0])) return pop, logbook
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__, graph=False): logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # 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) record = stats.compile(population) if stats is not None else {} logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print logbook.stream if graph: graph, pop_series = graph_gen(refmap, population, target) pbar = range(0, ngen) if verbose else trange(ngen, leave=False) for gen in pbar: # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record) if graph: update_series(graph, pop_series, population) if verbose: print logbook.stream else: desc = str(toolbox.evaluate(tools.selBest(population, 1)[0])[0]) pbar.set_description(desc) return record, logbook
def __init__(self, info): # The number of states the pendulum env is split into (and therefore the number of sub-programs to generate for each individual) self.NUM_STATES = 4 # Agent info self.env_name = info["env_name"] self.pop_size = info["pop_size"] self.max_gens = info["max_gens"] self.num_eps = info["num_eps"] self.num_steps = info["num_time_steps"] self.term_fit = info["term_fit"] self.mut_rate = info["mutation_rate"] self.tour_size = info["tournament_size"] # Primitive set self.pset = gp.PrimitiveSet("main", 3) self.pset.renameArguments(ARG0="costheta", ARG1="sintheta", ARG2="thetadot") self.pset.addPrimitive(self.IFLTE, 4) # self.pset.addPrimitive(operator.add, 2) # self.pset.addPrimitive(operator.sub, 2) # self.pset.addPrimitive(operator.mul, 2) self.pset.addPrimitive(operator.neg, 1) self.pset.addTerminal(0.0) self.pset.addTerminal(0.025) # self.pset.addTerminal(0.5) # self.pset.addTerminal(1.0) # Program generation functions creator.create("CostMin", base.Fitness, weights=(1.0, )) creator.create("Individual", gp.PrimitiveTree, fitness=creator.CostMin, pset=self.pset) self.toolbox = base.Toolbox() method = gp.genGrow if info["method"] == "grow" else gp.genFull self.toolbox.register("gen_exp", method, pset=self.pset, min_=0, max_=info["max_depth"]) self.toolbox.register("gen_program", tools.initIterate, creator.Individual, self.toolbox.gen_exp) self.toolbox.register("gen_pop", tools.initRepeat, list, self.toolbox.gen_program) # Fitness function self.toolbox.register("fit", self.fit) # Genetic operators self.toolbox.register("clone", self._clone) self.toolbox.register("select", self._tournament_sel, tournsize=self.tour_size) self.toolbox.register("mut_gen_exp", method, pset=self.pset, min_=0, max_=info["max_depth"]) self.toolbox.register("mutate", gp.mutUniform, expr=self.toolbox.mut_gen_exp, pset=self.pset) # Statistics functions self.stats = tools.Statistics( key=lambda indiv: indiv[0].fitness.values) self.stats.register("avg", np.mean) self.logbook = tools.Logbook()
def main(chrom_gen): toolbox = base.Toolbox() class ClassContainer: def __init__(self, ch: Chromosome): """ A container that generates a Chromosome object """ self.chromosome = ch creator.create("FitnessMulti", base.Fitness, weights=(1.0, 1.0)) creator.create("Individual", ClassContainer, fitness=creator.FitnessMulti) toolbox.register("attr_float", chrom_gen.generate_100cov_chromosome) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) object2D = Objective2D(chrom_gen) def evaluate_individual(indiv): return object2D.compute_objective(indiv.chromosome) toolbox.register("evaluate", evaluate_individual) toolbox.register("select", tools.selNSGA2) mutation = ChromosomeMutator100cov(chrom_gen) toolbox.register("mutate", mutation.apply_mutation) toolbox.register("mate", multipoint_cx) MU = 20 # population size (should be a multiple of 4 because we are using the selTournamentDCD) NGEN = 200 # number of generations CXPB = 0.7 online_plot = False # decide whether to show a dynamic plot with Pareto front across generations or not stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("max", numpy.max, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "pop", "max" pop = toolbox.population(n=MU) invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind1, fit in zip(invalid_ind, fitnesses): ind1.fitness.values = fit # This is just to assign the crowding distance to the individuals # no actual selection is done pop = toolbox.select(pop, len(pop)) record = stats.compile(pop) logbook.record(gen=0, pop=len(invalid_ind), **record) # print('Results: \n ============================================================= \n ', logbook.stream) ################################################################################################################ # Begin the generational process for gen in range(1, NGEN): # Vary the population offspring_pop = list() while len(offspring_pop) < len(pop): # select parent 1 parent1 = apply_tournament_selection(pop, 2) offspring1 = toolbox.clone(parent1) # select parent 2 parent2 = apply_tournament_selection(pop, 2) offspring2 = toolbox.clone(parent2) # apply crossover r = random.random() if r <= CXPB: toolbox.mate(offspring1.chromosome, offspring2.chromosome) # apply mutation toolbox.mutate(offspring1.chromosome) toolbox.mutate(offspring2.chromosome) # calculate objectives scores offspring1.fitness.values = toolbox.evaluate(offspring1) offspring2.fitness.values = toolbox.evaluate(offspring2) # add offsprings to the new population offspring_pop.append(offspring1) offspring_pop.append(offspring2) # Select the next generation population pop = toolbox.select(pop + offspring_pop, MU) # if online_plot: # frontier = numpy.array([ind.fitness.values for ind in pop]) # plt.close() # plt.scatter(frontier[:, 0], frontier[:, 1], c="r", marker='o',edgecolors='k') # plt.xlabel('Specificity') # plt.ylabel('Frequency') # plt.pause(0.01) record = stats.compile(pop) logbook.record(gen=gen, pop=len(invalid_ind), **record) # print(logbook.stream) for ind in pop: # apply corrections check_variable_parts(ind.chromosome, chrom_gen.messages) # 1. Let's first extract only the Pareto front fitnesses = toolbox.map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit ParetoSet = sortNondominated(pop, len(pop), first_front_only=True) pop = ParetoSet[0] front = numpy.array([ind.fitness.values for ind in pop]) # get the max value for each objective # Specificity max_spec = 0.0 min_spec = 1.0 max_freq = 0.0 min_freq = 1.0 for individual in pop: if individual.fitness.values[0] > max_spec: max_spec = individual.fitness.values[0] if individual.fitness.values[0] < min_spec: min_spec = individual.fitness.values[0] if individual.fitness.values[1] > max_freq: max_freq = individual.fitness.values[1] if individual.fitness.values[1] < min_freq: min_freq = individual.fitness.values[1] ############################# # search for the mid point # between the corner points mid_x = (max_spec + min_spec) / 2 mid_y = (max_freq + min_freq) / 2 mid = (mid_x, mid_y) # get the closest point to the mid_pt distance = [] for opt in front: dist = numpy.sqrt(((mid[0] - opt[0])**2) + ((mid[1] - opt[1])**2)) distance.append(dist) mid_pt = front[distance.index(min(distance))] # print('Middle point = ', mid_pt) ############################# # search for the Knee point, the closets point ot the max objectives min_dist = 100.0 for opt1 in front: dist = numpy.sqrt(((max_spec - opt1[0])**2) + ((max_freq - opt1[1])**2)) if dist < min_dist: min_dist = dist knee_pt = opt1 # print('Knee point = ', knee_pt) min_dist = 100.0 for opt1 in front: dist = numpy.sqrt(((1.0 - opt1[0])**2) + ((1.0 - opt1[1])**2)) if dist < min_dist: min_dist = dist knee_pt1 = opt1 # print('Knee point11 = ', knee_pt1) for ch in pop: if ch.fitness.values[0] == knee_pt[0] and ch.fitness.values[ 1] == knee_pt[1]: knee_solution = ch break for ch in pop: if ch.fitness.values[0] == knee_pt1[0] and ch.fitness.values[ 1] == knee_pt1[1]: knee_solution1 = ch break for ch in pop: if ch.fitness.values[0] == mid_pt[0] and ch.fitness.values[ 1] == mid_pt[1]: mid_solution = ch break ## plot the pareto front # plt.scatter(front[:,0], front[:,1], c="r", marker='o') # # print the mid_pt # plt.scatter(mid_pt[0], mid_pt[1], c='b', marker='*') # plt.scatter(mid_x, mid_y, c='black', marker='*') # # print the knee point # plt.scatter(max_spec, max_freq, c='black', marker='^') # plt.scatter(knee_pt[0], knee_pt[1], c='g', marker='^') # # print the knee11 point # plt.scatter(knee_pt1[0], knee_pt1[1], c='y', marker='+') # # plt.xlabel('Specificity') # plt.ylabel('Frequency') # # plt.show() # pareto is a dict with three elements # key : name of the point from the pareto front # value: chromosome pareto = { 'Knee_Solution': knee_solution.chromosome, 'Knee_Solution_1': knee_solution1.chromosome, 'Mid_Solution': mid_solution.chromosome } #return the three best points # the logbook to see the variation of specificity and frequency values # the execution time # the Non dominated points from the last population # return pareto, logbook, execution_time, pop return pareto #, logbook, pop
def optimize(hoc_files, compiled_mod_library, morphology_path, features, targets, stim_params, passive_results, fit_type, fit_style_data, ngen, seed, mu, storage_directory, starting_population=None): """ Perform embarrassingly parallel evolutionary optimization with NEURON Parameters ---------- hoc_files : list List of hoc files for NEURON to load compiled_mod_library : str Path to compiled .mod file library morphology_path : str Path to morphology SWC file features : list List of features to match targets : dict Dictionary with feature names as keys and elements as dicts with "mean" and "stdev" key-value pairs stim_params : :class:`StimParams` Stimulation parameters passive_results : dict Dictionary with passive parameters fit_type : str Code for fit type (for output filenames) fit_style_data : dict Dictionary of fit style parameters ngen : int Number of generations seed : int Seed for random number generator mu : int Size of each generation storage_directory : str Path to storage directory starting_population : str, optional Path to file with starting population. If `None`, a random starting population is generated. Returns ------- dict Dictionary with paths to output files """ # need to be global since cannot pass via partial functions to # parallel NEURON mapping function global utils global v_vec, i_vec, t_vec do_block_check = fit_style_data["check_depol_block"] if do_block_check: max_stim_amp = preprocess_results["max_stim_test_na"] if max_stim_amp <= stim_params["amplitude"]: print("Depol block check not necessary") do_block_check = False else: max_stim_amp = None environment = NeuronEnvironment(hoc_files, compiled_mod_library) utils = Utils() h = utils.h utils.generate_morphology(morphology_path) utils.load_cell_parameters(passive_results, fit_style_data["conditions"], fit_style_data["channels"], fit_style_data["addl_params"]) utils.insert_iclamp() utils.set_iclamp_params(stim_params["amplitude"], stim_params["delay"], stim_params["duration"]) h.tstop = stim_params["delay"] * 2.0 + stim_params["duration"] h.celsius = fit_style_data["conditions"]["celsius"] h.v_init = preprocess_results["v_baseline"] h.cvode_active(1) h.cvode.atolscale("cai", 1e-4) h.cvode.maxstep(10) v_vec, i_vec, t_vec = utils.record_values() try: neuron_parallel._runworker() print("Setting up GA") random.seed(seed) cxpb = 0.1 mtpb = 0.35 eta = 10.0 ndim = len(fit_style_data["channels"]) + len(fit_style_data["addl_params"]) creator.create("FitnessMin", base.Fitness, weights=(-1.0, )) creator.create("Individual", list, fitness=creator.FitnessMin) toolbox = base.Toolbox() toolbox.register("attr_float", uniform, BOUND_LOWER, BOUND_UPPER, ndim) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("evaluate", eval_param_set, do_block_check=do_block_check, max_stim_amp=max_stim_amp, stim_params=stim_params, features=features, targets=targets ) toolbox.register("mate", tools.cxSimulatedBinaryBounded, low=BOUND_LOWER, up=BOUND_UPPER, eta=eta) toolbox.register("mutate", tools.mutPolynomialBounded, low=BOUND_LOWER, up=BOUND_UPPER, eta=eta, indpb=mtpb) toolbox.register("variate", algorithms.varAnd) toolbox.register("select", tools.selBest) toolbox.register("map", neuron_parallel.map) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", np.min, axis=0) stats.register("max", np.max, axis=0) stats.register("best", best_sum) logbook = tools.Logbook() logbook.header = "gen", "nevals", "min", "max", "best" if starting_population is not None: print("Using a pre-defined starting population") toolbox.register("population_start", initPopulation, list, creator.Individual) pop = toolbox.population_start(starting_population) else: pop = toolbox.population(n=mu) invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit hof = tools.HallOfFame(mu) hof.update(pop) record = stats.compile(pop) logbook.record(gen=0, nevals=len(invalid_ind), **record) print(logbook.stream) print("Best so far:") print(utils.actual_parameters_from_normalized(hof[0])) for gen in range(1, ngen + 1): offspring = toolbox.variate(pop, toolbox, cxpb, 1.0) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit hof.update(offspring) pop[:] = toolbox.select(pop + offspring, mu) record = stats.compile(pop) logbook.record(gen=gen, nevals=len(invalid_ind), **record) print(logbook.stream) print("Best so far:") print(utils.actual_parameters_from_normalized(hof[0])) utils.set_normalized_parameters(hof[0]) h.finitialize() h.run() feature_errors = utils.calculate_feature_errors(t_vec.as_numpy(), v_vec.as_numpy(), i_vec.as_numpy(), features, targets) print("Error vector for best so far: " + str(feature_errors)) prefix = "{:s}_{:d}_".format(fit_type, seed) final_pop_path = os.path.join(storage_directory, prefix + "final_pop.txt") np.savetxt(final_pop_path, np.array(list(map(utils.actual_parameters_from_normalized, pop)), dtype=np.float64)) final_pop_fit_path = os.path.join(storage_directory, prefix + "final_pop_fit.txt") np.savetxt(final_pop_fit_path, np.array([ind.fitness.values for ind in pop])) final_hof_path = os.path.join(storage_directory, prefix + "final_hof.txt") np.savetxt(final_hof_path, np.array(list(map(utils.actual_parameters_from_normalized, hof)), dtype=np.float64)) final_hof_fit_path = os.path.join(storage_directory, prefix + "final_hof_fit.txt") np.savetxt(final_hof_fit_path, np.array([ind.fitness.values for ind in hof])) output = { "paths": { "final_pop": final_pop_path, "final_pop_fit": final_pop_fit_path, "final_hof": final_hof_path, "final_hof_fit_path": final_hof_fit_path, } } neuron_parallel._done() return output except: print("Exception encountered during parallel NEURON execution") MPI.COMM_WORLD.Abort() raise
def main(extended=True, verbose=True): target_set = [] species = [] stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean) stats.register("std", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) logbook = tools.Logbook() logbook.header = "gen", "species", "evals", "std", "min", "avg", "max" ngen = 300 g = 0 for i in range(len(schematas)): size = int(TARGET_SIZE / len(schematas)) target_set.extend(toolbox.target_set(schematas[i], size)) species = [toolbox.species() for _ in range(NUM_SPECIES)] species_index = list(range(NUM_SPECIES)) last_index_added = species_index[-1] # Init with random a representative for each species representatives = [random.choice(species[i]) for i in range(NUM_SPECIES)] best_fitness_history = [None] * IMPROVMENT_LENGTH if plt and extended: contribs = [[]] stag_gen = [] collab = [] while g < ngen: # Initialize a container for the next generation representatives next_repr = [None] * len(species) for (i, s), j in zip(enumerate(species), species_index): # Vary the species individuals s = algorithms.varAnd(s, toolbox, 0.6, 1.0) # Get the representatives excluding the current species r = representatives[:i] + representatives[i + 1:] for ind in s: # Evaluate and set the individual fitness ind.fitness.values = toolbox.evaluate([ind] + r, target_set) record = stats.compile(s) logbook.record(gen=g, species=j, evals=len(s), **record) if verbose: print((logbook.stream)) # Select the individuals species[i] = toolbox.select(s, len(s)) # Tournament selection next_repr[i] = toolbox.get_best(s)[0] # Best selection if plt and extended: # Book keeping of the collaborative fitness collab.append(next_repr[i].fitness.values[0]) g += 1 representatives = next_repr # Keep representatives fitness for stagnation detection best_fitness_history.pop(0) best_fitness_history.append(representatives[0].fitness.values[0]) try: diff = best_fitness_history[-1] - best_fitness_history[0] except TypeError: diff = float("inf") if plt and extended: for (i, rep), j in zip(enumerate(representatives), species_index): contribs[j].append( (toolbox.evaluateContribution(representatives, target_set, i)[0], g - 1)) if diff < IMPROVMENT_TRESHOLD: if len(species) > 1: contributions = [] for i in range(len(species)): contributions.append( toolbox.evaluateContribution(representatives, target_set, i)[0]) for i in reversed(list(range(len(species)))): if contributions[i] < EXTINCTION_TRESHOLD: species.pop(i) species_index.pop(i) representatives.pop(i) last_index_added += 1 best_fitness_history = [None] * IMPROVMENT_LENGTH species.append(toolbox.species()) species_index.append(last_index_added) representatives.append(random.choice(species[-1])) if extended and plt: stag_gen.append(g - 1) contribs.append([]) if extended: for r in representatives: # print final representatives without noise print(("".join(str(x) for x, y in zip(r, noise) if y == "*"))) if extended and plt: # Ploting of the evolution line1, = plt.plot(collab, "--", color="k") for con in contribs: try: con, g = list(zip(*con)) line2, = plt.plot(g, con, "-", color="k") except ValueError: pass axis = plt.axis("tight") for s in stag_gen: plt.plot([s, s], [0, axis[-1]], "--", color="k") plt.legend((line1, line2), ("Collaboration", "Contribution"), loc="center right") plt.xlabel("Generations") plt.ylabel("Fitness") plt.show()
def main(extended=True, verbose=True): target_set = [] stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean) stats.register("std", numpy.std) stats.register("min", numpy.min) stats.register("max", numpy.max) logbook = tools.Logbook() logbook.header = "gen", "species", "evals", "std", "min", "avg", "max" ngen = 150 g = 0 for i in range(len(schematas)): size = int(TARGET_SIZE / len(schematas)) target_set.extend(toolbox.target_set(schematas[i], size)) species = [toolbox.species() for _ in range(NUM_SPECIES)] # Init with random a representative for each species representatives = [random.choice(s) for s in species] if plt and extended: # We must save the match strength to plot them t1, t2, t3 = list(), list(), list() while g < ngen: # Initialize a container for the next generation representatives next_repr = [None] * len(species) for i, s in enumerate(species): # Vary the species individuals s = algorithms.varAnd(s, toolbox, 0.6, 1.0) # Get the representatives excluding the current species r = representatives[:i] + representatives[i + 1:] for ind in s: ind.fitness.values = toolbox.evaluate([ind] + r, target_set) record = stats.compile(s) logbook.record(gen=g, species=i, evals=len(s), **record) if verbose: print((logbook.stream)) # Select the individuals species[i] = toolbox.select(s, len(s)) # Tournament selection next_repr[i] = toolbox.get_best(s)[0] # Best selection g += 1 if plt and extended: # Compute the match strength without noise for the # representatives on the three schematas t1.append( toolbox.evaluate_nonoise( representatives, toolbox.target_set(schematas[0], 1), noise)[0]) t2.append( toolbox.evaluate_nonoise( representatives, toolbox.target_set(schematas[1], 1), noise)[0]) t3.append( toolbox.evaluate_nonoise( representatives, toolbox.target_set(schematas[2], 1), noise)[0]) representatives = next_repr if extended: for r in representatives: # print individuals without noise print(("".join(str(x) for x, y in zip(r, noise) if y == "*"))) if plt and extended: # Do the final plotting plt.plot(t1, '-', color="k", label="Target 1") plt.plot(t2, '--', color="k", label="Target 2") plt.plot(t3, ':', color="k", label="Target 3") plt.legend(loc="lower right") plt.axis([0, ngen, 0, max(max(t1), max(t2), max(t3)) + 1]) plt.xlabel("Generations") plt.ylabel("Number of matched bits") plt.show()
def main(): # """ # Reproducing GRALG optimization with mu+lambda strategy of evolution # """ #################### random.seed(64) verbose = True population = toolbox.population(n=MU) cxpb = CXPROB mutpb = MUTPROB ngen = N_GEN mu = MU lambda_ = LAMBDA halloffame = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", np.mean) stats.register("std", np.std) stats.register("min", np.min) stats.register("max", np.max) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) ################### print("Loading...") data1 = graph_nxDataset( "/home/luca/Documenti/Progetti/E-ABC_v2/eabc_v2/Datasets/IAM/Letter3/Training/", "LetterH", reader=IAMreadergraph) data2 = graph_nxDataset( "/home/luca/Documenti/Progetti/E-ABC_v2/eabc_v2/Datasets/IAM/Letter3/Validation/", "LetterH", reader=IAMreadergraph) # data1 = data1.shuffle() # data2 = data2.shuffle() #Removed not connected graph and null graph! cleanData = [] for dataset in [data1, data2]: for g, idx, label in zip(dataset.data, dataset.indices, dataset.labels): if not nx.is_empty(g): if nx.is_connected(g): cleanData.append((g, idx, label)) cleanData = np.asarray(cleanData, dtype=object) normalize('coords', cleanData[:750, 0], cleanData[750:, 0]) #Slightly different from dataset used in pygralg dataTR = graph_nxDataset([cleanData[:750, 0], cleanData[:750, 2]], "LetterH", idx=cleanData[:750, 1]) dataVS = graph_nxDataset([cleanData[750:, 0], cleanData[750:, 2]], "LetterH", idx=cleanData[750:, 1]) del data1 del cleanData print("Setup...") extract_func = randomwalk_restart.extr_strategy(max_order=6) # extract_func = breadthFirstSearch.extr_strategy(max_order=6) # subgraph_extr = Extractor(extract_func) subgraph_extr = Extractor(extract_func) expTRSet = dataTR.fresh_dpcopy() for i, x in enumerate(dataTR): k = 0 while (k < 50): for j in range(1, 6): subgraph_extr.max_order = j expTRSet.add_keyVal(dataTR.to_key(i), subgraph_extr.extract(x)) k += 6 expVSSet = dataVS.fresh_dpcopy() for i, x in enumerate(dataVS): k = 0 while (k < 50): for j in range(1, 6): subgraph_extr.max_order = j expVSSet.add_keyVal(dataVS.to_key(i), subgraph_extr.extract(x)) k += 6 # Evaluate the individuals with an invalid fitness print("Initializing population...") subgraphs = subgraph_extr.randomExtractDataset(dataTR, 1260) invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.map( functools.partial(toolbox.evaluate, granulationBucket=subgraphs, trEmbeddBucket=expTRSet, vsEmbeddBucket=expVSSet, TRindices=dataTR.indices, VSindices=dataVS.indices, TRlabels=dataTR.labels, VSlabels=dataVS.labels), invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): # Vary the population offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) #Evaluate invalid of modified individual invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map( functools.partial(toolbox.evaluate, granulationBucket=subgraphs, trEmbeddBucket=expTRSet, vsEmbeddBucket=expVSSet, TRindices=dataTR.indices, VSindices=dataVS.indices, TRlabels=dataTR.labels, VSlabels=dataVS.labels), invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(offspring) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) return population, logbook
def ea_mu_plus_lambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, cfg, stats=None, halloffame=None, verbose=True, prompt_on_exception=True): """This is the :math:`(\mu + \lambda)` evolutionary algorithm. :param population: A list of individuals. :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution operators. :param mu: The number of individuals to select for the next generation. :param lambda\_: The number of children to produce at each generation. :param cxpb: The probability that an offspring is produced by crossover. :param mutpb: The probability that an offspring is produced by mutation. :param ngen: The number of generation. :param stats: A :class:`~deap.tools.Statistics` object that is updated inplace, optional. :param halloffame: A :class:`~deap.tools.HallOfFame` object that will contain the best individuals, optional. :param verbose: Whether or not to log the statistics. :returns: The final population. First, the individuals having an invalid fitness are evaluated. Then, the evolutionary loop begins by producing *lambda_* offspring from the population, the offspring are generated by a crossover, a mutation or a reproduction proportionally to the probabilities *cxpb*, *mutpb* and 1 - (cxpb + mutpb). The offspring are then evaluated and the next generation population is selected from both the offspring **and** the population. Briefly, the operators are applied as following :: evaluate(population) for i in range(ngen): offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) evaluate(offspring) population = select(population + offspring, mu) This function expects :meth:`toolbox.mate`, :meth:`toolbox.mutate`, :meth:`toolbox.select` and :meth:`toolbox.evaluate` aliases to be registered in the toolbox. This algorithm uses the :func:`varOr` variation. """ t0 = time() population_ = population[:] logbook = tools.Logbook() logbook.header = ['gen', 'progress', 'nevals', 'speed', 'eta' ] + (stats.fields if stats else []) # 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) record = stats.compile(population) if stats is not None else {} nevals = len(invalid_ind) t1 = time() speed = nevals / (t1 - t0) performed_evals = nevals estimated_evals = (ngen + 1) * lambda_ * (cxpb + mutpb) remaining_evals = estimated_evals - performed_evals remaining = timedelta(seconds=int(remaining_evals / speed)) progress = '{:.2f}%'.format(100 / (ngen + 1)) logbook.record(gen=0, progress=progress, nevals=nevals, speed='{:.2f} ev/s'.format(speed), eta=remaining, **record) if verbose: logger.log(100, logbook.stream) # Begin the generational process for gen in xrange(1, ngen + 1): try: # Vary the population t0 = time() offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness t1 = time() invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals # every 2 generations if halloffame is not None: # and not gen % 2: halloffame.update(offspring) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) # Update the statistics with the new population nevals = len(invalid_ind) t2 = time() ev_speed = nevals / (t2 - t1) speed = nevals / (t2 - t0) performed_evals += nevals remaining_evals = estimated_evals - performed_evals remaining = timedelta(seconds=int(remaining_evals / speed)) record = stats.compile(population) if stats is not None else {} progress = '{:.2f}%'.format(100 * (gen + 1) / (ngen + 1)) logbook.record(gen=gen, progress=progress, nevals=nevals, speed='{:.2f} ev/s'.format(ev_speed), eta=remaining, **record) if verbose: logger.log(100, logbook.stream) except (Exception, KeyboardInterrupt) as e: logger.error(e) if prompt_on_exception: answer = raw_input( '\nInterruption detected. Write results so far? (y/N): ') if answer.lower() not in ('y', 'yes'): sys.exit('Ok, bye!') for individual in population: try: individual.unexpress() except Exception: # individual was already unexpressed pass break else: # Save a copy of an fully evaluated population, in case the # simulation is stopped in next generation. population_ = population[:] if halloffame and cfg.output.check_every and not gen % cfg.output.check_every: try: dump_population(halloffame, cfg, subdir='check{}'.format(gen)) except Exception: logger.warn('Could not write checkpoing for gen #%s', gen) return population_, logbook
def main(seed=None, play=0, NGEN=40, MU=4 * 10): random.seed(seed) # this has to be a multiple of 4. period. CXPB = 0.9 stats = tools.Statistics(lambda ind: ind.fitness.values[1]) # stats.register("avg", numpy.mean, axis=0) # stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" pop = toolbox.population(n=MU) #network_obj = Neterr(indim, outdim, n_hidden, np.random) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # This is just to assign the crowding distance to the individuals # no actual selection is done pop = toolbox.select(pop, len(pop)) # print(pop) record = stats.compile(pop) logbook.record(gen=0, evals=len(invalid_ind), **record) print(logbook.stream) maxi = 0 stri = '' flag = 0 # Begin the generational process # print(pop.__dir__()) for gen in range(1, NGEN): # Vary the population offspring = tools.selTournamentDCD(pop, len(pop)) offspring = [toolbox.clone(ind) for ind in offspring] if play: if play == 1: pgen = NGEN * 0.1 elif play == 2: pgen = NGEN * 0.9 if gen == int(pgen): print("gen:", gen, "doing clustering") to_bp_lis = cluster.give_cluster_head(offspring, int(MU * bp_rate)) assert (to_bp_lis[0] in offspring) print("doing bp") [ item.modify_thru_backprop(indim, outdim, network_obj.rest_setx, network_obj.rest_sety, epochs=10, learning_rate=0.1, n_par=10) for item in to_bp_lis ] for ind1, ind2 in zip(offspring[::2], offspring[1::2]): # print(ind1.fitness.values) """if not flag : ind1.modify_thru_backprop(indim, outdim, network_obj.rest_setx, network_obj.rest_sety, epochs=10, learning_rate=0.1, n_par=10) flag = 1 print("just testing") """ if random.random() <= CXPB: toolbox.mate(ind1, ind2, gen) maxi = max(maxi, ind1.node_ctr, ind2.node_ctr) toolbox.mutate(ind1) toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Select the next generation population pop = toolbox.select(pop + offspring, MU) record = stats.compile(pop) logbook.record(gen=gen, evals=len(invalid_ind), **record) anost = logbook.stream liso = [item.rstrip() for item in anost.split("\t")] mse = float(liso[3]) if (mse <= 115): print( "already achieved a decent performance(validation), breaking at gen_no.", gen) break print(anost) stri += anost + '\n' # file_ob.write(str(logbook.stream)) # print(len(pop)) # file_ob.close() #print(stri) return pop, logbook
def main(seed=None): random.seed(seed) NGEN = 250 MU = 100 CXPB = 0.9 stats = tools.Statistics(lambda ind: ind.fitness.values) # stats.register("avg", numpy.mean, axis=0) # stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" pop = toolbox.population(n=MU) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # This is just to assign the crowding distance to the individuals # no actual selection is done pop = toolbox.select(pop, len(pop)) record = stats.compile(pop) logbook.record(gen=0, evals=len(invalid_ind), **record) print((logbook.stream)) # Begin the generational process for gen in range(1, NGEN): # Vary the population offspring = tools.selTournamentDCD(pop, len(pop)) offspring = [toolbox.clone(ind) for ind in offspring] for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() <= CXPB: toolbox.mate(ind1, ind2) toolbox.mutate(ind1) toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Select the next generation population pop = toolbox.select(pop + offspring, MU) record = stats.compile(pop) logbook.record(gen=gen, evals=len(invalid_ind), **record) print((logbook.stream)) print(("Final population hypervolume is %f" % hypervolume(pop, [11.0, 11.0]))) return pop, logbook