def evalDeme(deme): deme[:] = [toolbox.clone(ind) for ind in toolbox.select(deme, len(deme))] # algorithms_helper.varLambda(toolbox, deme, LAMBDA, 0.5, 0.3) algorithms.varOr(deme, toolbox, LAMBDA, 0.5, 0.3) for ind in deme: ind.fitness.values = toolbox.evaluate(ind) return deme
def run_evolution(population, ngen, file=None): cxpb, mutpb = 0.0, 1 if not file is None: file.write("\nGeneration 0\n") fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit if not file is None: file.write(str(sortmap(ind)) + ", fitness: " + "{:,}".format(fit[0]) + "\n") file.flush() population = toolbox.select(population, 1) for i in range(ngen): file.write("\nGeneration " + str(i+1) + "\n") offspring = algorithms.varOr(population, toolbox, 4, cxpb, mutpb) fitnesses = toolbox.map(toolbox.evaluate, offspring) for ind, fit in zip(offspring, fitnesses): ind.fitness.values = fit if not file is None: file.write(str(sortmap(ind)) + ", fitness: " + "{:,}".format(fit[0]) + "\n") file.flush() np = toolbox.select(offspring, 1) if np[0].fitness.values[0] <= population[0].fitness.values[0]: population = np return population
def run_ga(self, initial_pop=False, plot=False): if initial_pop != False: population = initial_pop else: population = self.toolbox.population(n=self.initial_pop_size) fitnesses = list(map(self.toolbox.evaluate, population)) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit self.all_pops.append(population) for n in tqdm(range(self.generations)): self.all_pops.append(population) offspring = algorithms.varOr(population, self.toolbox, cxpb=self.cxpb, mutpb=self.mutpb, lambda_=self.num_children) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(self.toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit new_population = population + offspring population = self.toolbox.select(new_population, k=self.num_to_select) if plot == True: self.model.plot_substrate(self.metrics.substrate) self.model.plot_substrate(self.metrics.product) plt.show()
def eaMuPlusLambda1Gen(population, toolbox, mu, lambda_, cxpb, mutpb, gen): """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 gen: The generation number. :returns: The offspring and population after 1 generation. The algorithm takes in a population and evolves it in place using the :meth:`varOr` method. It returns the optimized population and a :class:`~deap.tools.Logbook` with the statistics of the evolution (if any). The logbook will contain the generation number, the number of evaluations for each generation and the statistics if a :class:`~deap.tools.Statistics` if any. The *cxpb* and *mutpb* arguments are passed to the :func:`varAnd` function. The pseudocode goes as follow :: 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 :func:`varOr` function. The offspring are then evaluated and the next generation population is selected from both the offspring **and** the population. Finally, when *ngen* generations are done, the algorithm returns a tuple with the final population and a :class:`~deap.tools.Logbook` of the evolution. .. note:: Care must be taken when the lambda:mu ratio is 1 to 1 as a non-stochastic selection will result in no selection at all as the operator selects *lambda* individuals from a pool of *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. """ # 1 iteration of eaMuPlusLambda (deap.__version__ == '1.0') if gen != 0: # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) else: # Generation 0 offspring = population return offspring, population
def main_parallel(): Component.resetPfKeeping() Component.resetCostKeeping() manager = Manager() Component.pfkeeping = manager.dict(Component.pfkeeping) Component.costkeeping = manager.dict(Component.costkeeping) pool = Pool(processes=3) toolbox.register("map", pool.map) print "MULTIOBJECTIVE OPTIMIZATION: parallel version" start_delta_time = time.time() # optimization random.seed(64) npop = 100 ngen = 50 stats = tools.Statistics(key=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", "avg", "std", "min", "max" pop = toolbox.population(n=npop) fits = toolbox.map(toolbox.evaluate, pop) for fit,ind in zip(fits, pop): ind.fitness.values = fit nevals = npop allpop = [] for gen in range(ngen): allpop = allpop+pop record = stats.compile(pop) logbook.record(gen=gen, evals=nevals, **record) print(logbook.stream) offspring = algorithms.varOr(pop, toolbox, lambda_=npop, cxpb=0.5, mutpb=0.1) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] nevals = len(invalid_ind) fits = toolbox.map(toolbox.evaluate, invalid_ind) for fit,ind in zip(fits, invalid_ind): ind.fitness.values = fit pop = toolbox.select(offspring+pop, k=npop) front = toolbox.sort(allpop, k=int(ngen*npop), first_front_only=True) pool.close() pool.join() delta_time = time.time() - start_delta_time print 'DONE: {} s'.format(str(datetime.timedelta(seconds=delta_time))) return allpop, logbook, front
def eaMuPlusLambdaEarlyStop( population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): """ See the documentation regarding :class:`~deap.algorithms.eaMuPlusLambdaEarlyStop`. This strategy uses the `earlystop' callable in the toolbox to determine if the evolution must stop before the last generation is reached. """ 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) # Begin the generational process gen = 0 winner = toolbox.select(population, 1)[0] earlystop = toolbox.earlystop() while gen < ngen and not earlystop(winner): # 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) winner = toolbox.select(population, 1)[0] # 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) gen += 1 return population, logbook
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, halloffame=None): """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. :returns: Yields the population and the logbook 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. """ # 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 yield population, invalid_ind # Begin the generational process while True: # Vary the population offspring = 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 # Select the next generation population population[:] = toolbox.select(population + offspring, mu) # Update the statistics with the new population yield population, invalid_ind
def launch_es(mu=100, lambda_=200, cxpb=0.6, mutpb=0.3, ngen=1000, display=False, verbose=False): # Initialisation random.seed() population = toolbox.population(n=mu) populations.append(population) halloffame = 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) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Evaluate the entire population 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) # Boucle de l'algorithme évolutionniste for gen in range(1, ngen + 1): ### A completer pour implementer un ES en affichant regulièrement les resultats a l'aide de la fonction plot_results fournie ### ### Vous pourrez tester plusieurs des algorithmes implémentés dans DEAP pour générer une population d'"enfants" ### à partir de la population courante et pour sélectionner les géniteurs de la prochaine génération offspring = algorithms.varOr(population, toolbox, lambda_=100, cxpb=0.5,mutpb=0.1) fits = toolbox.map(toolbox.evaluate, offspring) for fit, ind in zip(fits, offspring): ind.fitness.values = fit population = toolbox.select(offspring + population, k=100) populations.append(population) # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(population) # 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, halloffame,populations
def main(dictionary, g1, g2, g3): global features preprocess_data(dictionary, g1, g2, g3) data = pd.read_csv('student-mat-pre.csv', delimiter = ';') cols = list(data.columns) cols.remove('G1') cols.remove('G2') cols.remove('G3') for col in cols: data[col] = (data[col] - data[col].mean()) / data[col].std(ddof=0) data.to_csv('temp') features = [] with open('temp') as f: for index, line in enumerate(f): params = line.strip().split(',') if index != 0: for i in range(len(params)): params[i] = float(params[i]) features.append(params[1:-3]) features = features[1:len(features)] tree_c = DecisionTreeClassifier(criterion='entropy') gnb_c = GaussianNB() creator.create('FitnessMax', base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax) toolbox = base.Toolbox() toolbox.register('bit', random.random) toolbox.register('individual', tools.initRepeat, creator.Individual, toolbox.bit, n=30) toolbox.register('population',tools.initRepeat, list, toolbox.individual, n=200) toolbox.register('evaluate', fitness_value) toolbox.register('mate', tools.cxUniform, indpb=0.1) toolbox.register('mutate', tools.mutFlipBit, indpb=0.05) toolbox.register('select', tools.selNSGA2) population = toolbox.population() fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = (fit,) for gen in range(100): offspring = algorithms.varOr(population, toolbox, lambda_ = 10, cxpb=0.5, mutpb=0.1) fits = toolbox.map(toolbox.evaluate, offspring) for fit, ind in zip(fits, offspring): ind.fitness.values = (fit,) population = toolbox.select(offspring+population, k=20) individual = tools.selBest(population, k=1)
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=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) # Begin the generational process for gen in tqdm(range(1, ngen + 1)): # 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 verbose: print(logbook.stream) return population, logbook
def eaMuCommaLambda1Gen(population, toolbox, mu, lambda_, cxpb, mutpb, gen): """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 gen: The generation number. :returns: The offspring and population after 1 generation. 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 **only** from the offspring. 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(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. """ # 1 iteration of eaMuCommaLambda (deap.__version__ == '1.0') assert lambda_ >= mu, ('lambda ({}) must be greater or equal to mu ' '({}).'.format(lambda_, mu)) if gen != 0: # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) else: # Generation 0 offspring = population return offspring, population
def eaMuPlusLambda_redefined(population, toolbox, MU, LAMBDA, CXPB, MUTPB, NGEN): for i in range(NGEN): # ----determine the offspring and evaluate the fitness,w offspring = algorithms.varOr(population, toolbox, LAMBDA, CXPB, MUTPB) 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 # ---- evaluate fitness values for the population invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit population = toolbox.select(offspring + population, MU) return population
def debug_eval(self): toolbox.register("evaluate", evalr2, self.y, self.basetable) toolbox.register("mate", tools.cxOnePoint) #Uniform, indpb=0.5) toolbox.register("mutate", mutRan, indpb=self.mut) toolbox.register("select", tools.selBest) population=toolbox.population() fits=toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits,population): ind.fitness.values=fit offspring=algorithms.varOr(population, toolbox, lambda_=100, cxpb=.5, mutpb=.05) #print "offspring",offspring #fits=toolbox.map(toolbox.evaluate, offspring) print offspring for ind in offspring: ind.fitness.values=toolbox.evaluate(ind) print ind print ind.fitness.values
def eaMuPlusLambda(toolbox, ngen, verbose=__debug__, include_parents_in_next_generation=True): population = toolbox.population halloffame = toolbox.hof gen = -1 current_seed = -1 for gen in range(toolbox.initial_generation, ngen): record_individuals(toolbox, population) extra = [] if halloffame.items: extra = list(map(toolbox.clone, random.sample(population, toolbox.conf.extra_from_hof))) offspring = varOr(population + extra, toolbox, toolbox.conf.lambda_, 1 - toolbox.conf.mutpb, toolbox.conf.mutpb) for ind in offspring: # just a little extra for when we later want to analyze the hof manually ind.generation = gen if include_parents_in_next_generation: for ind in population: del ind.fitness.values candidates = population + offspring else: candidates = offspring nevals, total_steps, current_seed = evaluate_candidates(candidates, toolbox) if halloffame is not None: halloffame.update(offspring) record = toolbox.stats.compile(candidates) if toolbox.stats is not None else {} population[:] = toolbox.select(candidates, toolbox.conf.mu) toolbox.logbook.record(gen=gen, nevals=nevals, steps=total_steps, **record) if verbose: print(toolbox.logbook.stream) if toolbox.checkpoint: toolbox.checkpoint(data=dict(generation=gen, halloffame=halloffame, population=population, logbook=toolbox.logbook, last_seed=current_seed, strategy=None, recorded_individuals=toolbox.recorded_individuals)) toolbox.final_checkpoint_data = dict(generation=gen, halloffame=halloffame, population=population, logbook=toolbox.logbook, last_seed=current_seed, strategy=None, recorded_individuals=toolbox.recorded_individuals) return toolbox.logbook
def debug_eval(self): toolbox.register("evaluate", evalr2, self.y, self.basetable) toolbox.register("mate", tools.cxOnePoint) # Uniform, indpb=0.5) toolbox.register("mutate", mutRan, indpb=self.mut) toolbox.register("select", tools.selBest) population = toolbox.population() fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = fit offspring = algorithms.varOr(population, toolbox, lambda_=100, cxpb=0.5, mutpb=0.05) for ind in offspring: ind.fitness.values = toolbox.evaluate(ind) print(ind) print(ind.fitness.values)
def run_evolution_strategy(X, train_y_bin, Xt, test_y_bin, train_min, train_max, cxpb, mutpb, start_population_size, size_of_offspring, number_of_epochs): creator.create("FitnessMin", base.Fitness, weights=(-1.0, )) creator.create("Individual", list, fitness=creator.FitnessMin) toolbox = base.Toolbox() toolbox.register("individual_guess", initIndividual, creator.Individual) toolbox.register("population_guess", initPopulation, list, toolbox.individual_guess) toolbox.register("mate", tools.cxSimulatedBinary, eta=1) toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.1, indpb=0.1) toolbox.decorate("mate", checkBounds(train_min, train_max)) toolbox.decorate("mutate", checkBounds(train_min, train_max)) population = toolbox.population_guess(train_min, train_max, start_population_size) hof = tools.HallOfFame(1) avg_error_on_population = [] hof_errors = [] test_errors = [] hofs = [] for i in range(number_of_epochs): indyvidual_errors = [] offspring = algorithms.varOr(population, toolbox, size_of_offspring, cxpb, mutpb) for indyvidual in offspring: indyvidual_errors.append( update_loss_of_indyvidual(indyvidual, X, train_y_bin, train_min, train_max, offspring, hof, True)) population[:] = tools.selBest(offspring, start_population_size) avg_error_on_population.append(np.mean(indyvidual_errors)) hof_rmse = update_loss_of_indyvidual(hof[0], X, train_y_bin, train_min, train_max, offspring, hof, False) hof_errors.append(hof_rmse) test_error = update_loss_of_indyvidual(hof[0], Xt, test_y_bin, train_min, train_max, offspring, hof, False) test_errors.append(test_error) hofs.append(hof[0]) print("Epoch : {} avg RMSE for population : {} hof : {}".format( i + 1, avg_error_on_population[-1], hof[0])) return hofs, hof_errors, test_errors
def evolvepara(self): #import multiprocessing #pool = multiprocessing.Pool() #toolbox.register("map", pool.map) toolbox.register("genind", self.mkeind,self.indsize) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.genind) toolbox.register("population",tools.initRepeat, list, toolbox.individual, n=self.popsize) toolbox.register("evaluate", self.evalr2) toolbox.register("mate", tools.cxOnePoint) #Uniform, indpb=0.5) toolbox.register("mutate", self.mutaRan)#, indpb=self.mut) toolbox.register("select", tools.selBest) population=toolbox.population() #print population fits=toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits,population): ind.fitness.values=fit #print fit, ind #print fit #offspring=algorithms.varOr(population, toolbox, lambda_=100, cxpb=.5, mutpb=.05) #print toolbox.map(toolbox.evaluate, offspring) avgfitnesses=[] for gen in range(self.ngen): offspring=algorithms.varOr(population, toolbox, lambda_=self.popsize, cxpb=self.cx, mutpb=self.mut) #print "offspring",offspring #fits=toolbox.map(toolbox.evaluate, offspring) for ind in offspring: ind.fitness.values=toolbox.evaluate(ind) #for fit, ind in zip(fits,population): # ind.fitness.values=fit population=toolbox.select([k for k,v in itert.groupby(sorted(offspring+population))], k=100) popfits = toolbox.map(toolbox.evaluate, population) avgfitnesses.append(np.mean(popfits)) #plot(len(avgfitnesses), list(avgfitnesses)) # print avgfitnesses print toolbox.map(toolbox.evaluate, population) return population
def evolverf(self,evalfunc="q2loo"): #toolbox.register("map", pool.map) toolbox.register("genind", self.mkeindrf,self.indsize) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.genind) toolbox.register("population",tools.initRepeat, list, toolbox.individual, n=self.popsize) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.genind) toolbox.register("population",tools.initRepeat, list, toolbox.individual, n=self.popsize) if evalfunc=="q2loo": toolbox.register("evaluate", self.evalq2loo) elif evalfunc=="r2": toolbox.register("evaluate", self.evalr2) elif evalfunc=="r2adj": toolbox.register("evaluate", self.evalr2adj) else: raise ValueError("not a valid evaluation function specified; use evalr2adj, evalr2, or q2loo") toolbox.register("mate", tools.cxOnePoint) #Uniform, indpb=0.5) toolbox.register("mutate", self.mutaRan)#, indpb=self.mut) toolbox.register("select", tools.selBest) population=toolbox.population() #print population fits=toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits,population): ind.fitness.values=fit avgfitnesses=[] for gen in range(self.ngen): offspring=algorithms.varOr(population, toolbox, lambda_=self.popsize, cxpb=self.cx, mutpb=self.mut) for ind in offspring: ind.fitness.values=toolbox.evaluate(ind) population=toolbox.select([k for k,v in itert.groupby(sorted(offspring+population))], k=100) popfits = toolbox.map(toolbox.evaluate, population) avgfitnesses.append(np.mean(popfits)) return population
def sample_from_pop(population, toolbox, lambda_, cxpb, mutpb): """Generate a set of individuals from a population. Generate a set of individuals from a population. Parameters: :param population: the population to start from :param toolbox: the DEAP framework toolbox that contains the variation operators and the evaluation function :param lambda_: number of individuals to generate :param cxpb: cross-over probability (set to 0 to test only mutation) :param mutbp: mutation probability WARNING: if cxpb>0, the population size needs to be >2 (it thus won't work to sample individuals from a single individual) """ # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) #for of in offspring: # print("Offspring: "+str(of)) # Evaluate the individuals with an invalid fitness fitnesses = toolbox.map(toolbox.evaluate, offspring) for ind, fit in zip(offspring, fitnesses): ind.fitness.values = fit[0] ind.bd = fit[1] ind.evolvability_samples=None # SD: required, otherwise, the memory usage explodes... I do not understand why yet. return offspring
def eaMuPlusLambdaTol(population, toolbox, mu, lambda_, ngen, cxpb, mutpb, tol, stats=None, halloffame=None, verbose=__debug__): global cxpb_orig, mutpb_orig """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 :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 :func:`varOr` function. 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:`varOr` function. The pseudocode goes as follow :: 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 :func:`varOr` function. The offspring are then evaluated and the next generation population is selected from both the offspring **and** the population. Finally, when *ngen* generations are done, the algorithm returns a tuple with the final population and a :class:`~deap.tools.Logbook` of the evolution. 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. """ 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) min_fit = np.array(logbook.chapters["fitness"].select("min")) # Begin the generational process flag_change = False flag_limit = False gen = 1 while gen < ngen + 1 and not (min_fit[-1] <= tol).all(): # Vary the population offspring = 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) min_fit = np.array(logbook.chapters["fitness"].select("min")) min_actual = np.array( logbook.chapters["fitness"].select("min"))[-1] min_old = np.array(logbook.chapters["fitness"].select("min"))[-2] if verbose: print(logbook.stream) if (abs(min_actual - min_old) < 0.01).all() and flag_limit is False: cxpb = cxpb - 0.01 mutpb = mutpb + 0.01 print("change") flag_change = True if cxpb < 0.4: cxpb = 0.4 mutpb = 0.5 print("limits") flag_limit = True else: cxpb = cxpb_orig mutpb = mutpb_orig print("back to orig") if flag_change is True: cxpb = cxpb_orig + 0.1 mutpb = mutpb_orig - 0.15 flag_change = False print("orig after change") flag_limit = False gen += 1 return population, logbook
def main(): # reset bookkeeping Component.resetCostKeeping() Component.resetPfKeeping() Component.resetRiskKeeping() ## use existing pf data #pfkeeping = np.load('pfkeeping.npz') #Component.pfkeeping['flexure'] = pfkeeping['flexure'] #Component.pfkeeping['shear'] = pfkeeping['shear'] #Component.pfkeeping['deck'] = pfkeeping['deck'] ## use existing cost data #costkeeping = np.load('costkeeping.npz') #Component.costkeeping['flexure'] = costkeeping['flexure'] #Component.costkeeping['shear'] = costkeeping['shear'] #Component.costkeeping['deck'] = costkeeping['deck'] manager = Manager() Component.pfkeeping = manager.dict(Component.pfkeeping) Component.costkeeping = manager.dict(Component.costkeeping) Component.riskkeeping = manager.dict(Component.riskkeeping) pool = Pool(processes=num_processes) toolbox.register("map", pool.map) print "MULTIOBJECTIVE OPTIMIZATION: parallel version" start_delta_time = time.time() # optimization random.seed(64) logbook = tools.Logbook() logbook.header = ["gen", "evals", "nfront", "mean", "tol"] pop = toolbox.population(n=NPOP) fits = toolbox.map(toolbox.evaluate, pop) for fit,ind in zip(fits, pop): ind.fitness.values = fit nevals = NPOP g = 1 distances = [] frontfitlast = np.zeros((1,2)) nevalsum = 0 evolStop = False halloffame = tools.ParetoFront() while not evolStop: offspring = algorithms.varOr(pop, toolbox, lambda_=NPOP, cxpb=0.9, mutpb=0.1) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] nevals = len(invalid_ind) nevalsum += nevals fits = toolbox.map(toolbox.evaluate, invalid_ind) for fit,ind in zip(fits, invalid_ind): ind.fitness.values = fit pop = toolbox.select(offspring+pop, k=NPOP) front = toolbox.sort(offspring+pop, k=NPOP, first_front_only=True)[0] halloffame.update(front) # check if stop evolution distance=[] frontfit = [ind.fitness.values for ind in halloffame] for obj in frontfit: vector = np.array(frontfitlast)-np.array(obj) distance.append(min(np.linalg.norm(vector, axis=1))) distances.append(np.mean(distance)) longest = 0. for point1 in frontfit: for point2 in frontfit: dist = np.linalg.norm(np.array(point1)-np.array(point2)) if dist > longest: longest = dist tol = longest/NPOP tol = np.maximum(tol, TOL) evolStop = (len(distances)>NGEN and all(np.array(distances[-NGEN:])<tol)) or g>NMAX frontfitlast = frontfit # Gather all the fitnesses in one list and print the stats record = stats.compile(pop) logbook.record(gen=g, evals=nevals,nfront=len(halloffame), mean=distances[-1], tol=tol, **stats.compile(pop)) print(logbook.stream) g+=1 pool.close() pool.join() delta_time = time.time() - start_delta_time print 'DONE: {} s'.format(str(datetime.timedelta(seconds=delta_time))) return pop, logbook, halloffame, nevalsum
def gaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): logbook = algorithms.tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Evaluate the fitness before starting 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) # Begin the generational process for gen in range(1, ngen + 1): print("_________________GA GEN: " + str(gen) + "______________________") # Invalidate fitness of whole pop to train and evaluate for ind in population: ind.GAN.gen_no = gen ind.GAN.offspring = 0 del ind.fitness.values # Train and Evaluate the individuals 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 # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [] for ind in offspring: if not ind.fitness.valid: ind.GAN.offspring = 1 invalid_ind.append(ind) 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 verbose: print(logbook.stream) return population, logbook
def myEAMuCommaLambda(population, startgen, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, logbook=None, verbose=False, id=None): assert lambda_ >= mu, "lambda must be greater or equal to mu." # 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) if logbook is None: logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) record = stats.compile(population) if stats is not None else {} logbook.record(gen=startgen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) # Begin the generational process total_time = datetime.timedelta(seconds=0) for gen in range(startgen+1, ngen): start_time = datetime.datetime.now() # 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(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) if gen % 1 == 0: # Fill the dictionary using the dict(key=value[, ...]) constructor cp = dict(population=population, generation=gen, halloffame=halloffame, logbook=logbook, rndstate=random.getstate()) if id is None: cp_name = "checkpoint_es.pkl" else: cp_name = "checkpoint_es_{}.pkl".format(id) pickle.dump(cp, open(cp_name, "wb")) gen_time = datetime.datetime.now() - start_time total_time = total_time + gen_time if total_time > datetime.timedelta(hours=4*24): print("Time limit exceeded.") break return population, logbook
def OnEvolve(self, cxpb=0.6, mutpb=0.2, lambda_=n_pop * 2, verbose=__debug__): if self.gen == 0: start_time = time.time() invalid_ind = [ ind for ind in self.population if not ind.fitness.valid ] fitnesses = self.toolbox.map(self.toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if self.halloffame is not None: self.halloffame.update(self.population) record = self.stats.compile(self.population) if self.stats else {} self.logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: elapsed_time = time.time() - start_time #print self.logbook.stream + "\t\t%0.2f sec"%(elapsed_time) #self.Log('\n'+self.logbook.stream) self.context.evo_time = elapsed_time self.gen += 1 self.selected_individuals = self.halloffame[:1] # save to file #self.Checkpoint() else: start_time = time.time() offspring = algorithms.varOr(self.population, self.toolbox, lambda_, cxpb, mutpb) invalid_ind = [ ind for ind in offspring ] # if not ind.fitness.valid] # force eval of every indv, as history is a moving widnow to eval on fitnesses = self.toolbox.map(self.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 self.halloffame is not None: self.halloffame.clear( ) # force eval of every indv, as history is a moving widnow to eval on self.halloffame.update(offspring) self.population[:] = self.toolbox.select( self.population + offspring, n_pop) # Append the current generation statistics to the logbook record = self.stats.compile(self.population) if self.stats else {} self.logbook.record(gen=self.gen, nevals=len(invalid_ind), **record) if verbose: elapsed_time = time.time() - start_time #print self.logbook.stream + "\t\t%0.2f sec"%(elapsed_time) #self.Log('\n'+self.logbook.stream) self.context.evo_time = elapsed_time self.gen += 1 self.selected_individuals = self.halloffame[:1] # save to file #self.Checkpoint() # using the selected best item #signal = self.evalLive(self.halloffame[0]) # but with pareto front we have ANY number of non dominated individuals each gen, just use them all as an ensemble model signal = stats.mode([self.evalLive(indv) for indv in self.halloffame]).mode[0] self.context.Log(str(self.gen) + ' : ' + str(self.halloffame[0])) return signal
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): div=[] #for measuring diversity resetPeaks() logbook = tools.Logbook() logbook2 = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) logbook2.header = ['gen', 'nevals'] + (stats.fields if stats else []) fitnesses = [] hofPop=toolbox.map(toolbox.evaluateHof,population) #change depending on eval func for ind, fit in zip(population, hofPop): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats is not None else {} div.append(momOfInertia(population)) logbook2.record(gen=0, nevals=len(population), **record) #Evaluate the individuals with an invalid fitness #fitnesses = [] #for i in xrange(len(population)): # fitnesses.append(toolbox.evaluate((population)[i],population)) #for ind, fit in zip(population, fitnesses): # ind.fitness.values = fit population=toolbox.evaluate(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=0, nevals=len(population), **record) if verbose: print logbook.stream bog=[] offline=[] offlinegen=[] accuracy=[] leaps=0 #stability=[0] #needed for accuracy maxt=100 #highest peak mint=0 # Begin the generational process for gen in range(1, ngen+1): #move the peaks if gen == 150 or gen ==300: print("Best individual is: %s\nwith fitness: %s" % (halloffame[0], halloffame[0].fitness)) #print population halloffame.clear() #bog=[] global peaks peaks[0]=bitFlip(peaks[0],0.1) peaks[2]=bitFlip(peaks[2],0.1) #if gen==150: # peaks[1]=80 # peaks[3]=100 #if gen==300: # peaks[1]=100 # peaks[3]=80 for x in xrange(len(population)): del population[x].fitness.values invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluateHof, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # 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 fitness of all individuals for clearing clearingFit=toolbox.map(toolbox.evaluateHof,population + offspring) for ind, fit in zip(population+offspring, clearingFit): ind.fitness.values = fit #all individuals given fitness for hof this is then used to clear #fitnesses = [] #for i in xrange(len(population+offspring)): # fitnesses.append(toolbox.evaluate((population+offspring)[i],population+offspring)) #for ind, fit in zip(population+offspring, fitnesses): # ind.fitness.values = fit tempPop=population+offspring tempPop = toolbox.evaluate(tempPop) # Select the next generation population population[:] = toolbox.select(tempPop, mu)#change temppop here if it doesnt work # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(population + offspring), **record) if verbose: print logbook.stream # Update the hall of fame with the generated individuals fitness not dependant on sharing hofPop = deepcopy(population) fitnesses=toolbox.map(toolbox.evaluateHof,hofPop) #change depending on eval func for ind, fit in zip(hofPop, fitnesses): ind.fitness.values = fit if halloffame is not None: try: a=halloffame[0].fitness.values except IndexError: a=0 halloffame.update(hofPop) b=halloffame[0].fitness.values if b>a: leaps+=1 #record stats and offline and diversity and accuracy record = stats.compile(hofPop) if stats is not None else {} div.append(momOfInertia(hofPop)) logbook2.record(gen=gen, nevals=len(hofPop), **record) offline.append(halloffame[0].fitness.values[0]) offlinegen.append(gen) accuracy.append((record["max"]-mint)/(maxt-mint)) #show graphs at final generation if gen==ngen: #open files for data off=open("offline.txt","a") bog=open("bog.txt","a") mini=open("min.txt","a") aver=open("aver.txt","a") maxi=open("max.txt","a") diver=open("div.txt","a") print leaps print "offline performance: ",sum(offline)/len(offline) print "average bog: ", sum(logbook.select("max"))/len(logbook.select("max")) #print offline off.write(str(sum(offline)/len(offline))) off.write(",") bog.write(str(sum(logbook.select("max"))/len(logbook.select("max")))) bog.write(",") diver.write(str(div)) diver.write(",") mini.write(str(logbook2.select("min"))) mini.write(",") aver.write(str(logbook2.select("avg"))) aver.write(",") maxi.write(str(logbook2.select("max"))) maxi.write(",") #accuracy plt.figure(2) plt.title("accuracy") plt.plot(offlinegen,accuracy) plt.axis([0,ngen,0,1]) plt.show() #diversity plt.figure(3) plt.title("Diversity") plt.plot(xrange(len(div)),div) plt.axis([0,len(div),0,1250]) plt.show() #min av max plt.figure(4) plt.title("min, avg, max") plt.plot(xrange(ngen+1),logbook2.select("min"),label="min") plt.plot(xrange(ngen+1),logbook2.select("avg"),label="avg") plt.plot(xrange(ngen+1),logbook2.select("max"),label="max") plt.legend(loc=8) plt.axis([0,ngen,0,maxt]) plt.show() #stability plt.figure(5) plt.title("Stability") stability=[] for i in xrange(len(accuracy)): stability.append(max(0,accuracy[i]-accuracy[i-1])) plt.plot(offlinegen,stability) plt.axis([0,ngen,0,1]) plt.show() off.close() bog.close() mini.close() aver.close() maxi.close() diver.close() return population, logbook
def evolve(self, evalfunc="q2loo"): """ 1st element returned is the original population, 2nd is is the evaluation of the firness function on the originalpopualtion, 3rd is the final population, 4th is the evalution of the fitness function on the final population. """ toolbox.register("genind", self.mkeindseed, self.indsize) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.genind) toolbox.register("population", tools.initRepeat, list, toolbox.individual, n=self.popsize) if evalfunc == "q2loo": toolbox.register("evaluate", self.evalq2loo) elif evalfunc == "q2lmo": toolbox.register("evaluate", self.evalq2lmo) elif evalfunc == "r2": toolbox.register("evaluate", self.evalr2) elif evalfunc == "r2adj": toolbox.register("evaluate", self.evalr2adj) else: raise ValueError( "not a valid evaluation function specified; use evalr2adj, evalr2, or q2loo" ) toolbox.register("mate", tools.cxOnePoint) #Uniform, indpb=0.5) toolbox.register("mutate", self.mutaRan) #, indpb=self.mut) toolbox.register("select", tools.selBest) #progress bar start! #print 'Starting... # GEN FINISHED:', origpop = toolbox.population() #self.mkeindseed.count=0 population = cp.deepcopy(origpop) fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = fit avgfitnesses = [] popfits = 0 #prb=ProgressBar(self.ngen) for gen in range(self.ngen): try: offspring = algorithms.varOr(population, toolbox, lambda_=self.popsize, cxpb=self.cx, mutpb=self.mut) for ind in offspring: ind.fitness.values = toolbox.evaluate(ind) population = toolbox.select([ k for k, v in itert.groupby(sorted(offspring + population)) ], k=100) popfits = toolbox.map(toolbox.evaluate, population) #prb.animate(gen) #prb.score=np.mean(popfits) #ProgressBar.score=property(lambda self: self.score+np.mean(popfits)) #prb.update_time(1, prb.score) except (KeyboardInterrupt, SystemExit): result = [ origpop, toolbox.map(toolbox.evaluate, origpop), population, toolbox.map(toolbox.evaluate, population) ] return result #self.pretty_print(returnobj) result = [ origpop, toolbox.map(toolbox.evaluate, origpop), population, toolbox.map(toolbox.evaluate, population) ] return self.pretty_print(result)
def novelty_ea(evaluate, params, pool=None): """Novelty Search algorithm Novelty Search algorithm. Parameters: :param evaluate: the evaluation function :param params: the dict of run parameters * params["pop_size"]: the number of parent individuals to keep from one generation to another * params["lambda"]: the number of offspring to generate, given as a multiplying coefficent on params["pop_size"] (the number of generated individuals is: params["lambda"]*params["pop_size"] * params["nb_gen"]: the number of generations to compute * params["stats"]: the statistics to use (from DEAP framework)) * params["stats_offspring"]: the statistics to use (from DEAP framework)) * params["variant"]: the different supported variants ("NS", "Fit", "NS+Fit", "NS+BDDistP", "NS+Fit+BDDistP"), add "," at the end of the variant to select in offspring only (as the ES "," variant). By default, selects within the parents and offspring. "NS" uses the novelty criterion, "Fit" the fitness criterion and "BDDistP' the distance to the parent in the behavior space. If a single criterion is used, an elitist selection scheme is used. If more than one criterion is used, NSGA-II is used (see build_toolbox_ns function) * params["cxpb"]: the crossover rate * params["mutpb"]: the mutation rate :param dump_period_bd: the period for dumping behavior descriptors :param dump_period_pop: the period for dumping the current population :param evolvability_period: period of the evolvability computation :param evolvability_nb_samples: the number of samples to generate from each individual in the population to estimate their evolvability (WARNING: it will significantly slow down a run and it is used only for statistical reasons """ print("Novelty search algorithm") alphas = params[ "alphas"] # parameter to compute the alpha shape, to estimate the distance to explored area variant = params["variant"] if ("+" in variant): emo = True else: emo = False nb_eval = 0 lambda_ = int(params["lambda"] * params["pop_size"]) toolbox = build_toolbox_ns(evaluate, params, pool) population = toolbox.population(n=params["pop_size"]) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] if (params["stats"] is not None): logbook.header += params["stats"].fields if (params["stats_offspring"] is not None): logbook.header += params["stats_offspring"].fields # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] nb_eval += len(invalid_ind) fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) # fit is a list of fitness (that is also a list) and behavior descriptor for ind, fit in zip(invalid_ind, fitnesses): ind.fit = fit[ 0] # fit is an attribute just used to store the fitness value ind.parent_bd = None ind.bd = listify(fit[1]) ind.id = generate_uuid() ind.parent_id = None for ind in population: ind.am_parent = 0 archive = updateNovelty(population, population, None, params) alpha_shape = alphashape.alphashape(archive.all_bd, alphas) isortednov = sorted(range(len(population)), key=lambda k: population[k].novelty, reverse=True) varian = params["variant"].replace(",", "") for i, ind in enumerate(population): ind.dist_to_explored_area = dist_to_shapes(ind.bd, alpha_shape) ind.rank_novelty = isortednov.index(i) ind.dist_to_parent = 0 if (emo): if (varian == "NS+Fit"): ind.fitness.values = (ind.novelty, ind.fit[0]) elif (varian == "NS+BDDistP"): ind.fitness.values = (ind.novelty, 0) elif (varian == "NS+Fit+BDDistP"): ind.fitness.values = (ind.novelty, ind.fit, 0) else: print("WARNING: unknown variant: " + variant) ind.fitness.values = ind.fit else: ind.fitness.values = ind.fit # if it is not a multi-objective experiment, the select tool from DEAP # has been configured above to take the right attribute into account # and the fitness.values is thus ignored gen = 0 # Do we look at the evolvability of individuals (WARNING: it will make runs much longer !) generate_evolvability_samples(params, population, gen, toolbox) record = params["stats"].compile( population) if params["stats"] is not None else {} record_offspring = params["stats_offspring"].compile( population) if params["stats_offspring"] is not None else {} logbook.record(gen=0, nevals=len(invalid_ind), **record, **record_offspring) if (verbosity(params)): print(logbook.stream) #generate_dumps(params, population, None, gen, pop1label="population", archive=None, logbook=None) for ind in population: ind.evolvability_samples = None # To avoid memory to inflate too much.. # Begin the generational process for gen in range(1, params["nb_gen"] + 1): if (gen == params["restart"]): print("Restart: we reinitialize the population") offspring = toolbox.population(n=lambda_) for ind in offspring: ind.bd = None ind.id = generate_uuid() ind.parent_id = None population = [] else: # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, params["cxpb"], params["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) nb_eval += len(invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fit = fit[0] ind.fitness.values = fit[0] ind.parent_bd = ind.bd ind.parent_id = ind.id ind.id = generate_uuid() ind.bd = listify(fit[1]) for ind in population: ind.am_parent = 1 for ind in offspring: ind.am_parent = 0 pq = population + offspring if (params["stop_archive_update"] == gen): params["add_strategy"] = "none" if (params["pop_for_novelty_estimation"] == 0): pop_for_novelty_estimation = [] elif (params["freeze_pop"] == -1) or (gen <= params["freeze_pop"]): pop_for_novelty_estimation = list(pq) archive = updateNovelty(pq, offspring, archive, params, pop_for_novelty_estimation) alpha_shape = alphashape.alphashape(archive.all_bd, alphas) isortednov = sorted(range(len(pq)), key=lambda k: pq[k].novelty, reverse=True) for i, ind in enumerate(pq): ind.dist_to_explored_area = dist_to_shapes(ind.bd, alpha_shape) ind.rank_novelty = isortednov.index(i) #print("Indiv #%d: novelty=%f rank=%d"%(i, ind.novelty, ind.rank_novelty)) if (ind.parent_bd is None): ind.dist_to_parent = 0 else: ind.dist_to_parent = np.linalg.norm( np.array(ind.bd) - np.array(ind.parent_bd)) if (emo): if (varian == "NS+Fit"): ind.fitness.values = (ind.novelty, ind.fit[0]) elif (varian == "NS+BDDistP"): if (ind.parent_bd is None): bddistp = 0 else: bddistp = np.linalg.norm( np.array(ind.bd) - np.array(ind.parent_bd)) ind.fitness.values = (ind.novelty, bddistp) elif (varian == "NS+Fit+BDDistP"): if (ind.parent_bd is None): bddistp = 0 else: bddistp = np.linalg.norm( np.array(ind.bd) - np.array(ind.parent_bd)) ind.fitness.values = (ind.novelty, ind.fit, bddistp) else: print("WARNING: unknown variant: " + variant) ind.fitness.values = ind.fit else: ind.fitness.values = ind.fit if ((emo) and (offspring[0].fitness.values == offspring[0].fit)): print("WARNING: EMO and the fitness is just the fitness !") if (verbosity(params)): print("Gen %d" % (gen)) else: if (gen % 100 == 0): print(" %d " % (gen), end='', flush=True) elif (gen % 10 == 0): print("+", end='', flush=True) else: print(".", end='', flush=True) # Select the next generation population if ("," in variant): population[:] = toolbox.select(offspring, params["pop_size"]) else: population[:] = toolbox.select(pq, params["pop_size"]) if (("eval_budget" in params.keys()) and (params["eval_budget"] != -1) and (nb_eval >= params["eval_budget"])): params["nb_gen"] = gen terminates = True else: terminates = False dump_data(population, gen, params, prefix="population", attrs=[ "all", "dist_to_explored_area", "dist_to_parent", "rank_novelty" ], force=terminates) dump_data(population, gen, params, prefix="bd", complementary_name="population", attrs=["bd"], force=terminates) dump_data(offspring, gen, params, prefix="bd", complementary_name="offspring", attrs=["bd"], force=terminates) dump_data(archive.get_content_as_list(), gen, params, prefix="archive", attrs=["all"], force=terminates) generate_evolvability_samples(params, population, gen, toolbox) # Update the statistics with the new population record = params["stats"].compile( population) if params["stats"] is not None else {} record_offspring = params["stats_offspring"].compile( offspring) if params["stats_offspring"] is not None else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record, **record_offspring) if (verbosity(params)): print(logbook.stream) for ind in population: ind.evolvability_samples = None if (terminates): break return population, archive, logbook, nb_eval
def eaMuCommaLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): assert lambda_ >= mu, "lambda must be greater or equal to mu." life_mean = 0 logbook = tools.Logbook() logbook.header = ['gen', 'nevals', 'life_avg' ] + (stats.fields if stats else []) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] eval = list(toolbox.map(toolbox.evaluate, invalid_ind)) fitnesses = [e[0] for e in eval] life_list = [e[1] for e in eval] life_mean = np.mean(life_list) 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), life_avg=life_mean, **record) if verbose: print(logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): # 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] eval = list(toolbox.map(toolbox.evaluate, invalid_ind)) fitnesses = [e[0] for e in eval] life_list = [e[1] for e in eval] life_mean = np.mean(life_list) 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(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), life_avg=life_mean, **record) if verbose: print(logbook.stream) return population, logbook
def evolve(self,evalfunc="q2loo"): toolbox.register("genind", self.mkeindseed, self.indsize) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.genind) toolbox.register("population",tools.initRepeat, list, toolbox.individual, n=self.popsize) if evalfunc=="q2loo": toolbox.register("evaluate", self.evalq2loo) elif evalfunc=="q2lmo": toolbox.register("evaluate", self.evalq2lmo) elif evalfunc=="r2": toolbox.register("evaluate", self.evalr2) elif evalfunc=="r2adj": toolbox.register("evaluate", self.evalr2adj) else: raise ValueError("not a valid evaluation function specified; use evalr2adj, evalr2, or q2loo") toolbox.register("mate", tools.cxOnePoint) #Uniform, indpb=0.5) toolbox.register("mutate", self.mutaRan)#, indpb=self.mut) toolbox.register("select", tools.selBest) #progress bar start! #print 'Starting... # GEN FINISHED:', origpop=toolbox.population() #self.mkeindseed.count=0 population=cp.deepcopy(origpop) fits=toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits,population): ind.fitness.values=fit avgfitnesses=[] popfits=0 prb=ProgressBar(self.ngen)#, popfits) #ProgressBar.score=0 #prb.animate()#popfits) #prb.animate(popfits) #steps=self.ngen/10 for gen in range(self.ngen): try: offspring=algorithms.varOr(population, toolbox, lambda_=self.popsize, cxpb=self.cx, mutpb=self.mut) for ind in offspring: ind.fitness.values=toolbox.evaluate(ind) population=toolbox.select([k for k,v in itert.groupby(sorted(offspring+population))], k=100) popfits = toolbox.map(toolbox.evaluate, population) prb.animate(gen) #prb.score=np.mean(popfits) #ProgressBar.score=property(lambda self: self.score+np.mean(popfits)) #prb.update_time(1, prb.score) except (KeyboardInterrupt, SystemExit): return [origpop, toolbox.map(toolbox.evaluate, origpop), population, toolbox.map(toolbox.evaluate, population)] except: return [origpop, toolbox.map(toolbox.evaluate, origpop), population, toolbox.map(toolbox.evaluate, population)] #print prb.score #new progressbar try #if gen%steps ==0: # print '\b',gen, np.round(np.mean(popfits), decimals=3), # sys.stdout.flush() #print '\b'*1, #print '\b Done!', #sys.stdout.flush() #print "Done!" return [origpop, toolbox.map(toolbox.evaluate, origpop), population, toolbox.map(toolbox.evaluate, population)] print "Done!"
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): resetPeaks() div=[] logbook = tools.Logbook() logbook2 = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) logbook2.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] hofPop=toolbox.map(fitnessCustom,population) #change depending on eval func for ind, fit in zip(population, hofPop): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats is not None else {} div.append(momOfInertia(population)) logbook2.record(gen=0, nevals=len(population), **record) fitnesses = [] for i in xrange(len(population)): fitnesses.append(toolbox.evaluate((population)[i],population)) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit record = stats.compile(population) if stats is not None else {} div.append(momOfInertia(population)) #div.append(averageHammingDistance(population)) logbook.record(gen=0, nevals=len(population), **record) if verbose: print logbook.stream offline=[] offlinegen=[] accuracy=[] leaps=0 #stability=[0] #needed for accuracy maxt=100 #highest peak mint=0 # Begin the generational process for gen in range(1, ngen+1): #move the peaks #poppy = sorted(population, key=attrgetter("fitness"),reverse=True) #print poppy[0], poppy[0].fitness.values if gen==150 or gen == 300: print("Best individual is: %s\nwith fitness: %s" % (halloffame[0], halloffame[0].fitness)) halloffame.clear() #print population #clear every time peaks move as new fitness period global peaks #peaks[0]=bitFlip(peaks[0],0.1) #peaks[2]=bitFlip(peaks[2],0.1) print population if gen==150: peaks[1]=80 peaks[3]=100 if gen==300: peaks[1]=100 peaks[3]=80 #peaks[0] = bitFlip(peaks[0],0.2) #print peaks[0] #print("Best individual is: %s\nwith fitness: %s" % (halloffame[0], halloffame[0].fitness)) for x in xrange(len(population)): del population[x].fitness.values fitnesses = []#toolbox.map(toolbox.evaluate, population+offspring) for i in xrange(len(population)): fitnesses.append(toolbox.evaluate((population)[i],population)) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Vary the population offspring = algorithms.varOr(population, toolbox, lambda_, cxpb, mutpb) fitnesses = []#toolbox.map(toolbox.evaluate, population+offspring) for i in xrange(len(population+offspring)): fitnesses.append(toolbox.evaluate((population+offspring)[i],population+offspring)) for ind, fit in zip(population+offspring, fitnesses): ind.fitness.values = fit 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(population), **record) if verbose: print logbook.stream # Update the hall of fame with the generated individuals fitness not dependant on sharing hofPop = deepcopy(population) fitnesses=toolbox.map(fitnessCustom,hofPop) #CHANGE EVAL FUNCTION HERE for ind, fit in zip(hofPop, fitnesses): ind.fitness.values = fit if halloffame is not None: try: a=halloffame[0].fitness.values except IndexError: a=0 halloffame.update(hofPop) b=halloffame[0].fitness.values if b>a: leaps+=1 #record stats and offline and diversity and accuracy record = stats.compile(hofPop) if stats is not None else {} div.append(momOfInertia(hofPop)) logbook2.record(gen=gen, nevals=len(hofPop), **record) print logbook2.stream offline.append(halloffame[0].fitness.values[0]) offlinegen.append(gen) accuracy.append((record["max"]-mint)/(maxt-mint)) #show graphs at final generation if gen==ngen: off=open("offline.txt","a") bog=open("bog.txt","a") mini=open("min.txt","a") aver=open("aver.txt","a") maxi=open("max.txt","a") diver=open("div.txt","a") print leaps print "offline performance: ",sum(offline)/len(offline) print "average bog: ", sum(logbook2.select("max"))/len(logbook2.select("max")) #print offline off.write(str(sum(offline)/len(offline))) off.write(",") bog.write(str(sum(logbook2.select("max"))/len(logbook2.select("max")))) bog.write(",") diver.write(str(div)) diver.write(",") mini.write(str(logbook2.select("min"))) mini.write(",") aver.write(str(logbook2.select("avg"))) aver.write(",") maxi.write(str(logbook2.select("max"))) maxi.write(",") #accuracy plt.figure(2) plt.title("accuracy") plt.plot(offlinegen,accuracy) plt.axis([0,ngen,0,1]) plt.show() #diversity plt.figure(3) plt.title("Diversity") plt.plot(xrange(len(div)),div) plt.axis([0,len(div),0,1250]) plt.show() #min av max plt.figure(4) plt.title("min, avg, max") plt.plot(xrange(ngen+1),logbook2.select("min"),label="min") plt.plot(xrange(ngen+1),logbook2.select("avg"),label="avg") plt.plot(xrange(ngen+1),logbook2.select("max"),label="max") plt.legend(loc=8) plt.axis([0,ngen,0,maxt]) plt.show() #stability plt.figure(5) plt.title("Stability") stability=[] for i in xrange(len(accuracy)): stability.append(max(0,accuracy[i]-accuracy[i-1])) plt.plot(offlinegen,stability) plt.axis([0,ngen,0,1]) plt.show() off.close() bog.close() mini.close() aver.close() maxi.close() diver.close() return population, logbook
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): resetPeaks() div=[] 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 {} div.append(momOfInertia(population)) logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print logbook.stream offline=[] offlinegen=[] accuracy=[] #leaps=0 #needed for accuracy maxt=100 #highest peak mint=0 # Begin the generational process for gen in range(1, ngen+1): #print peaks if gen==150 or gen ==300: halloffame.clear() global peaks #peaks[0] = bitFlip(peaks[0],0.1) #peaks[2] = bitFlip(peaks[2],0.1) print population if gen==150: peaks[1]=80 peaks[3]=100 if gen==300: peaks[1]=100 peaks[3]=80 #print peaks for x in xrange(len(population)): del population[x].fitness.values fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # 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 {} div.append(momOfInertia(population)) offline.append(halloffame[0].fitness.values[0]) offlinegen.append(gen) accuracy.append((record["max"]-mint)/(maxt-mint)) logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print logbook.stream #show graphs at final generation if gen==ngen: #print leaps #off=open("offline.txt","a") #bog=open("bog.txt","a") #mini=open("min.txt","a") #aver=open("aver.txt","a") #maxi=open("max.txt","a") #diver=open("div.txt","a") print "offline performance: ",sum(offline)/len(offline) #off.write(str(sum(offline)/len(offline))) #off.write(",") #off.write("\n") print "average bog: ", sum(logbook.select("max"))/len(logbook.select("max")) #bog.write(str(sum(logbook.select("max"))/len(logbook.select("max")))) #bog.write(",") #bog.write("\n") #accuracy plt.figure(2) plt.title("accuracy") plt.plot(offlinegen,accuracy) plt.axis([0,ngen,0,1]) plt.show() #diversity #diver.write(str(div)) #diver.write(",") plt.figure(3) plt.title("Diversity") plt.plot(xrange(len(div)),div) #plt.axis([0,len(div),0,maxt]) plt.show() #min av max #mini.write(str(logbook.select("min"))) #mini.write(",") #mini.write("\n") #aver.write(str(logbook.select("avg"))) #aver.write(",") #aver.write("\n") #maxi.write(str(logbook.select("max"))) #maxi.write(",") #maxi.write("\n") #print logbook.select("min") #print " " #print logbook.select("avg") #print " " #print logbook.select("max") plt.figure(4) plt.title("min, avg, max") plt.plot(xrange(ngen+1),logbook.select("min"),label="min") plt.plot(xrange(ngen+1),logbook.select("avg"),label="avg") plt.plot(xrange(ngen+1),logbook.select("max"),label="max") plt.legend(loc=8) plt.axis([0,ngen,0,maxt]) plt.show() #stability #plt.figure(5) #plt.title("Stability") #stability=[] #for i in xrange(len(accuracy)): # stability.append(max(0,accuracy[i]-accuracy[i-1])) #plt.plot(offlinegen,stability) #plt.axis([0,ngen,0,1]) #plt.show() #off.close() #bog.close() #mini.close() #aver.close() #maxi.close() #diver.close() return population, logbook
def ask(self): self.offspring = varOr(self.population, self.toolbox, self.configuration.lambda_, 1 - self.configuration.mutpb, self.configuration.mutpb) return self.offspring
def optimize(population, toolbox, mu, lambda_, net, X, y, X_val, y_val, X_test, y_test, rated, njobs, path_group, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): assert lambda_ >= mu, "lambda must be greater or equal to mu." # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] # fitnesses=[] # for individual in invalid_ind: # m=rbf_optim(individual, X, y, X_val, y_val, X_test, y_test) # fitnesses.append(m) ncpus = joblib.load(os.path.join(path_group, 'total_cpus.pickle')) gpu_status = joblib.load(os.path.join(path_group, 'gpu_status.pickle')) njobs = int(ncpus - gpu_status) cpu_status = njobs joblib.dump(cpu_status, os.path.join(path_group, 'cpu_status.pickle')) pool = mp.Pool(njobs) results = [ pool.apply_async(rbf_optim, args=(np.array(individual).ravel(), net, X, y, X_val, y_val, X_test, y_test, rated)) for individual in invalid_ind ] fitnesses = [p.get() for p in results] pool.close() pool.terminate() pool.join() # fitnesses = Parallel(n_jobs=njobs)(delayed(rbf_optim)(np.array(individual).ravel(), net, X, y, X_val, y_val, X_test, y_test, rated) for # individual in invalid_ind) # 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) logbook = tools.Logbook() # Gather all the fitnesses in one list and compute the stats fits = np.array([ind.fitness.values for ind in population]) maximums = np.nanmax(fits, axis=0) minimums = np.nanmin(fits, axis=0) logbook.header = ['gen', 'nevals' ] + ['Max_mae:', 'Min_mae:', 'Max_rms:', 'Min_rms:'] record = { 'Max_mae:': maximums[0], 'Min_mae:': minimums[0], 'Max_rms:': maximums[2], 'Min_rms:': minimums[2] } print('GA rbf running generation 0') print(record) logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) # Begin the generational process with elapsed_timer() as eval_elapsed: for gen in range(1, ngen + 1): # 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] ncpus = joblib.load(os.path.join(path_group, 'total_cpus.pickle')) gpu_status = joblib.load( os.path.join(path_group, 'gpu_status.pickle')) njobs = int(ncpus - gpu_status) cpu_status = njobs joblib.dump(cpu_status, os.path.join(path_group, 'cpu_status.pickle')) pool = mp.Pool(njobs) results = [ pool.apply_async(rbf_optim, args=(np.array(individual).ravel(), net, X, y, X_val, y_val, X_test, y_test, rated)) for individual in invalid_ind ] fitnesses = [p.get() for p in results] pool.close() pool.terminate() pool.join() # fitnesses = Parallel(n_jobs=njobs)( # delayed(rbf_optim)(np.array(individual).ravel(), net, X, y, X_val, y_val, X_test, y_test, rated) for # individual in invalid_ind) # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit fits = np.array([ind.fitness.values for ind in population]) maximums = np.nanmax(fits, axis=0) minimums = np.nanmin(fits, axis=0) # 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(offspring, mu) # Update the statistics with the new population record = { 'Max_mae:': maximums[0], 'Min_mae:': minimums[0], 'Max_rms:': maximums[2], 'Min_rms:': minimums[2] } print('GA rbf running generation ', str(gen)) print(record) logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) if eval_elapsed() > 1800: break return population, logbook
creator.Individual, toolbox.bit, n=num_connections) toolbox.register('population', tools.initRepeat, list, toolbox.individual, n=population_size) toolbox.register('evaluate', evaluate_fitness) toolbox.register('mate', tools.cxUniform, indpb=0.1) toolbox.register('mutate', tools.mutFlipBit, indpb=0.05) toolbox.register('select', tools.selNSGA2) population = toolbox.population() fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = fit for gen in range(num_generations): offspring = algorithms.varOr(population, toolbox, lambda_=population_size, cxpb=0.5, mutpb=0.1) fits = toolbox.map(toolbox.evaluate, offspring) for fit, ind in zip(fits, offspring): ind.fitness.values = fit population = toolbox.select(offspring + population, k=population_size) print('Generation =', gen, 'Best Fitness =', min([ind.fitness.values for ind in population]))
import knn, random from deap import algorithms, base, creator, tools def evalFitness(individual): return knn.classification_rate(features=individual), sum(individual) creator.create("FitnessMulti", base.Fitness, weights=(1.0, -1.0)) creator.create("Individual", list, fitness=creator.FitnessMulti) toolbox = base.Toolbox() toolbox.register("bit", random.randint, 0, 1) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.bit, n=13) toolbox.register("population", tools.initRepeat, list, toolbox.individual, n=100) toolbox.register("evaluate", evalFitness) toolbox.register("mate", tools.cxUniform, indpb=0.1) toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) toolbox.register("select", tools.selNSGA2) population = toolbox.population() fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = fit for gen in range(50): offspring = algorithms.varOr(population, toolbox, lambda_=100, cxpb=0.5,mutpb=0.1) fits = toolbox.map(toolbox.evaluate, offspring) for fit, ind in zip(fits, offspring): ind.fitness.values = fit population = toolbox.select(offspring + population, k=100)
def run(self, X, y, X_test, y_test, scale_y, mfs, mu, lambda_, cxpb=0.6, mutpb=0.4, ngen=300): perf = np.inf front_best = None rules = copy.deepcopy(self.rules) self.population = self.toolbox.population() param_ind = creator.Individual(self.x) self.population.pop() self.population.insert(len(self.population), param_ind) i = 0 while i < 0.5 * len(self.population): param_ind = mut_fun(self.x, 0, self.sigma, 0.8, self.lower_bound, self.upper_bound, 0.6) param_ind = creator.Individual(param_ind[0]) self.population.pop(i) self.population.insert(i, param_ind) i += 1 assert lambda_ >= mu, "lambda must be greater or equal to mu." # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in self.population if not ind.fitness.valid] rules = copy.deepcopy(self.rules) fit1 = evaluate( np.array(invalid_ind[-1]).ravel(), X, y, X_test, y_test, scale_y, self.rated, mfs, rules, self.p, self.resampling, self.num_samples, self.n_ratio) print('initial candidate error ', fit1[1]) rules = copy.deepcopy(self.rules) fitnesses = Parallel(n_jobs=self.njobs)( delayed(evaluate)(np.array(individual).ravel(), X, y, X_test, y_test, scale_y, self.rated, mfs, rules, self.p, self.resampling, self.num_samples, self.n_ratio) for individual in invalid_ind) # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if self.hof is not None: self.hof.update(self.population) self.logbook = tools.Logbook() # Gather all the fitnesses in one list and compute the stats fits = np.array([ind.fitness.values for ind in self.population]) maximums = np.nanmax(fits, axis=0) minimums = np.nanmin(fits, axis=0) self.logbook.header = ['gen', 'nevals'] + [ 'Max_sse:', 'Min_sse:', 'Max_mae:', 'Min_mae:' ] self.logger.info('Iter: %s, Max_sse: %s, Min_mae: %s', 0, *minimums) record = { 'Max_sse:': maximums[0], 'Min_sse:': minimums[0], 'Max_mae:': maximums[1], 'Min_mae:': minimums[1] } print('GA rbf running generation 0') print(record) self.logbook.record(gen=0, nevals=len(invalid_ind), **record) print(self.logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): # Vary the population rules = copy.deepcopy(self.rules) offspring = algorithms.varOr(self.population, self.toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = Parallel(n_jobs=self.njobs)(delayed(evaluate)( np.array(individual).ravel(), X, y, X_test, y_test, scale_y, self.rated, mfs, rules, self.p, self.resampling, self.num_samples, self.n_ratio) for individual in invalid_ind) # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit fits = np.array([ind.fitness.values for ind in self.population]) maximums = np.nanmax(fits, axis=0) minimums = np.nanmin(fits, axis=0) # Update the hall of fame with the generated individuals if self.hof is not None: self.hof.update(self.population) # Select the next generation population self.population[:] = self.toolbox.select(offspring, mu) # Update the statistics with the new population record = { 'Max_sse:': maximums[0], 'Min_sse:': minimums[0], 'Max_mae:': maximums[1], 'Min_mae:': minimums[1] } print('GA rbf running generation ', str(gen)) print(record) self.logbook.record(gen=gen, nevals=len(invalid_ind), **record) front = self.population for i in range(len(front)): if front[i].fitness.getValues()[0] < perf: front_best = front[i] perf = front[i].fitness.getValues()[0] self.logger.info('Iter: %s, Max_sse: %s, Min_mae: %s', str(gen), *minimums) self.fmodel = self.evaluate( np.array(front_best).ravel(), X, y, X_test, y_test, scale_y, self.rated, mfs, self.rules, self.p, self.resampling)
def main(): # reset bookkeeping System.resetBookKeeping() ## use existing bookkeeping data #bookkeeping = np.load('bookkeeping.npz') manager = Manager() System.bookkeeping = manager.dict(System.bookkeeping) pool = Pool(processes=num_processes) toolbox.register("map", pool.map) #System.bookkeeping = dict(System.bookkeeping) #toolbox.register("map", map) print "MULTIOBJECTIVE OPTIMIZATION: parallel version" start_delta_time = time.time() # optimization random.seed(64) logbook = tools.Logbook() logbook.header = ["gen", "evals", "nfront", "mean1", "mean2", "tol1", "tol2", "time"] pop = toolbox.population(n=NPOP) fits = toolbox.map(toolbox.evaluate, pop) for fit,ind in zip(fits, pop): ind.fitness.values = fit nevals = NPOP g = 1 distances1 = [] distances2 = [] frontfitlast = np.array([[1., 0.]]) nevalsum = 0 evolStop = False halloffame = tools.ParetoFront() while not evolStop: offspring = algorithms.varOr(pop, toolbox, lambda_=NPOP, cxpb=0.9, mutpb=0.1) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] nevals = len(invalid_ind) nevalsum += nevals fits = toolbox.map(toolbox.evaluate, invalid_ind) for fit,ind in zip(fits, invalid_ind): ind.fitness.values = fit pop = toolbox.select(offspring+pop, k=NPOP) front = toolbox.sort(offspring+pop, k=NPOP, first_front_only=True)[0] halloffame.update(front) ## check if stop evolution #distance=[] #frontfit = [ind.fitness.values for ind in halloffame] #for obj in frontfit: #vector = np.array(frontfitlast)-np.array(obj) #distance.append(min(np.linalg.norm(vector, axis=1))) #distances.append(np.mean(distance)) #longest = 0. #distances.append(np.mean(distance)) #vertlongest = 0. #horilongest = 0. #for point1 in frontfit: #for point2 in frontfit: ##dist = np.linalg.norm(np.array(point1)-np.array(point2)) #if dist > longest: #longest = dist #tol = longest/NPOP #tol = np.maximum(tol, TOL) #evolStop = (len(distances)>NGEN and all(np.array(distances[-NGEN:])<tol)) or g>NMAX #frontfitlast = frontfit # check if stop evolution distance1=[] distance2=[] frontfit = np.array([ind.fitness.values for ind in halloffame]) frontfit[frontfit[:,1] == 0,1] = 1. frontfitlast[frontfitlast[:,1] == 0,1] = 1. for obj in frontfit: #vector = np.array(frontfitlast)-np.array(obj) #distance.append(min(np.linalg.norm(vector, axis=1))) distance1.append(min(np.abs(np.log10(frontfitlast[:,0])-np.log10(obj[0])))) #distance2.append(min(np.abs(frontfitlast[:,1]-obj[1]))) distance2.append(min(np.abs(np.log10(frontfitlast[:,1])-np.log10(obj[1])))) distances1.append(np.mean(distance1)) distances2.append(np.mean(distance2)) longest1 = 0. longest2 = 0. for point1 in frontfit: for point2 in frontfit: dist1 = np.abs(np.log10(point1[0])-np.log10(point2[0])) #dist2 = np.abs(point1[1]-point2[1]) dist2 = np.abs(np.log10(point1[1])-np.log10(point2[1])) if dist1 > longest1: longest1 = dist1 if dist2 > longest2: longest2 = dist2 tol1 = np.maximum(longest1/NPOP,TOL1) tol2 = np.maximum(longest2/NPOP,TOL2) evolStop = (len(distances1)>NGEN and all(np.array(distances1[-NGEN:])<tol1) and all(np.array(distances2[-NGEN:])<tol2)) or g>NMAX frontfitlast = frontfit # Gather all the fitnesses in one list and print the stats delta_time = time.time() - start_delta_time logbook.record(gen=g, evals=nevals,nfront=len(halloffame), mean1=distances1[-1], mean2=distances2[-1], tol1=tol1, tol2=tol2, time=delta_time) print(logbook.stream) g+=1 pool.close() pool.join() System.bookkeeping = System.bookkeeping.copy() delta_time = time.time() - start_delta_time print 'DONE: {} s'.format(str(datetime.timedelta(seconds=delta_time))) return pop, logbook, halloffame, nevalsum
def eaMuCommaLambda(cls, population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None): ''' Method has been copied from DEAP framework in order to add some additional features (like adding verbosity and a method which collect additional data related with simulations). If you want to understand meaning of arguments please see usage of this method in "Execute" and read about algorithm attributes in class description. ''' assert lambda_ >= mu, "lambda must be greater or equal to mu." # Create new logbook cls.logbook = tools.Logbook() cls.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 # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} cls.logbook.record(gen=0, nevals=len(invalid_ind), **record) cls.listOfPopulations = [] cls.listOfPopulations.append(copy.deepcopy(population)) # Begin the generational process for gen in range(1, ngen + 1): if cls.lverbose: print("generation no:", gen) # Vary the population offspring = 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 # Select the next generation population population[:] = toolbox.select(offspring, mu) # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} cls.logbook.record(gen=gen, nevals=len(invalid_ind), **record) cls.listOfPopulations.append(copy.deepcopy(population)) # Get final population cls.finalPopulation = population
def checkpoint_eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, logbook, start_gen=0, stats=None, halloffame=None, FREQ=DEFAULT_CHECKPOINTFREQ, checkpoint=None, CPOUT=None, verbose=__debug__, timelimit=None, termination=None): """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 :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 :func:`varOr` function. 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:`varOr` function. The pseudocode goes as follow :: 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 :func:`varOr` function. The offspring are then evaluated and the next generation population is selected from both the offspring **and** the population. Finally, when *ngen* generations are done, the algorithm returns a tuple with the final population and a :class:`~deap.tools.Logbook` of the evolution. 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. """ if timelimit: terminator = TimeTerminator(limit=timelimit) else: terminator = GenerationTerminator(limit=ngen) if checkpoint: # Removed feature print "Resuming from generation", start_gen print logbook.stream else: logbook = tools.Logbook() logbook.header = ['gen', 'evals', 'memoize', "maxdepth"] + (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=start_gen, evals=len(invalid_ind), memoize=0, maxdepth=numpy.max([x.height for x in population]), **record) if verbose: print logbook.stream if len(population) == 1: population.append(population[0]) if termination == "auto": #TODO: Place somewhere better terminator = MOEATerminationDetection() # Begin the generational process gen = start_gen while not terminator.done(): # Vary the population offspring = 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 # Update termination conditions gen+=1 if termination == "auto": P = [list(y) for y in [x.fitness.values for x in halloffame[:]]] halloffame.update(offspring) Q = [list(y) for y in [x.fitness.values for x in halloffame[:]]] terminator.update(P,Q, gen-1) else: halloffame.update(offspring) terminator.update(gen=gen) # Select the next generation population population[:] = toolbox.select(population + offspring, mu) record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, evals=len(invalid_ind), memoize=toolbox.memoizecount(), maxdepth=numpy.max([x.height for x in population]), **record ) if verbose: print logbook.stream # Store checkpoint if gen is valid if CPOUT: continue # Checkpoints disabled this_checkpoint = CPOUT+"/"+str(gen)+".checkpoint" check_store_checkpoint(this_checkpoint, population, gen, halloffame, logbook, toolbox, rndstate=random.getstate(), numpystate=numpy.random.get_state(), pset=None ) if CPOUT : this_checkpoint = CPOUT+"/"+str(ngen)+".checkpoint" store_checkpoint(this_checkpoint, population, ngen, halloffame, logbook, toolbox, rndstate=random.getstate(), numpystate=numpy.random.get_state(), pset=None ) return population, logbook
def main(): ## reset bookkeeping #Component.resetCostKeeping() #Component.resetPfKeeping() #Component.resetRiskKeeping() # use existing pf data suffix = rate2suffix(icorr_mean_list) pfname = 'pfkeeping_'+suffix+'.npz' costname = 'costkeeping_'+suffix+'.npz' datapath = os.path.join(os.path.abspath('./'), 'data') pffile = os.path.join(datapath,pfname) costfile = os.path.join(datapath,costname) pfkeeping = np.load(pffile) Component.pfkeeping['flexure'] = pfkeeping['flexure'] Component.pfkeeping['shear'] = pfkeeping['shear'] Component.pfkeeping['deck'] = pfkeeping['deck'] # use existing cost data costkeeping = np.load(costfile) Component.costkeeping['flexure'] = costkeeping['flexure'] Component.costkeeping['shear'] = costkeeping['shear'] Component.costkeeping['deck'] = costkeeping['deck'] #manager = Manager() #Component.pfkeeping = manager.dict(Component.pfkeeping) #Component.costkeeping = manager.dict(Component.costkeeping) #Component.riskkeeping = manager.dict(Component.riskkeeping) #pool = Pool(processes=num_processes) #toolbox.register("map", pool.map) Component.pfkeeping = dict(Component.pfkeeping) Component.costkeeping = dict(Component.costkeeping) Component.riskkeeping = dict(Component.riskkeeping) toolbox.register("map", map) print "MULTIOBJECTIVE OPTIMIZATION: parallel version" start_delta_time = time.time() # optimization #random.seed(64) logbook = tools.Logbook() logbook.header = ["gen", "evals", "nfront", "mean1", "mean2", "tol1", "tol2", "time"] pop = toolbox.population(n=NPOP) fits = toolbox.map(toolbox.evaluate, pop) for fit,ind in zip(fits, pop): ind.fitness.values = fit nevals = NPOP g = 1 distances1 = [] distances2 = [] frontfitlast = np.array([[1., 0.]]) nevalsum = 0 evolStop = False halloffame = tools.ParetoFront() while not evolStop: offspring = algorithms.varOr(pop, toolbox, lambda_=NPOP, cxpb=0.9, mutpb=0.1) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] nevals = len(invalid_ind) nevalsum += nevals fits = toolbox.map(toolbox.evaluate, invalid_ind) for fit,ind in zip(fits, invalid_ind): ind.fitness.values = fit pop = toolbox.select(offspring+pop, k=NPOP) front = toolbox.sort(offspring+pop, k=NPOP, first_front_only=True)[0] halloffame.update(front) # check if stop evolution distance1=[] distance2=[] frontfit = np.array([ind.fitness.values for ind in halloffame]) frontfit[frontfit[:,1] == 0,1] = 1. frontfitlast[frontfitlast[:,1] == 0,1] = 1. for obj in frontfit: #vector = np.array(frontfitlast)-np.array(obj) #distance.append(min(np.linalg.norm(vector, axis=1))) distance1.append(min(np.abs(np.log10(frontfitlast[:,0])-np.log10(obj[0])))) #distance2.append(min(np.abs(frontfitlast[:,1]-obj[1]))) distance2.append(min(np.abs(np.log10(frontfitlast[:,1])-np.log10(obj[1])))) distances1.append(np.mean(distance1)) distances2.append(np.mean(distance2)) longest1 = 0. longest2 = 0. for point1 in frontfit: for point2 in frontfit: dist1 = np.abs(np.log10(point1[0])-np.log10(point2[0])) #dist2 = np.abs(point1[1]-point2[1]) dist2 = np.abs(np.log10(point1[1])-np.log10(point2[1])) if dist1 > longest1: longest1 = dist1 if dist2 > longest2: longest2 = dist2 tol1 = np.maximum(longest1/NPOP,TOL1) tol2 = np.maximum(longest2/NPOP,TOL2) evolStop = (len(distances1)>NGEN and all(np.array(distances1[-NGEN:])<tol1) and all(np.array(distances2[-NGEN:])<tol2)) or g>NMAX frontfitlast = frontfit # Gather all the fitnesses in one list and print the stats delta_time = time.time() - start_delta_time logbook.record(gen=g, evals=nevals,nfront=len(halloffame), mean1=distances1[-1], mean2=distances2[-1], tol1=tol1, tol2=tol2, time=delta_time) print(logbook.stream) g+=1 #pool.close() #pool.join() delta_time = time.time() - start_delta_time print 'DONE: {} s'.format(str(datetime.timedelta(seconds=delta_time))) return pop, logbook, halloffame, nevalsum
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 = "pop: " + str(len(population)) + " gen: " + str(ngen) pbar.set_description(desc) return record, logbook
def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): """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 :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 :func:`varOr` function. 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:`varOr` function. The pseudocode goes as follow :: 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 :func:`varOr` function. The offspring are then evaluated and the next generation population is selected from both the offspring **and** the population. Finally, when *ngen* generations are one, the algorithm returns a tuple with the final population and a :class:`~deap.tools.Logbook` of the evolution. 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. """ 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) handler = logging.StreamHandler() handler.setLevel(logging.INFO) handler.setFormatter(logging.Formatter(fmt='%(message)s')) # #old_handler = eaMuPlusLambda._log.handlers[0] # # eaMuPlusLambda._log.removeHandler(old_handler) # eaMuPlusLambda._log.addHandler(handler) logger = logging.getLogger('algorithms') logger.setLevel(logging.INFO) logger.addHandler(handler) if verbose: # print(logbook.stream) # eaMuPlusLambda._log.info(logbook.stream) logger.info(logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): try: # Vary the population offspring = 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 verbose: # print(logbook.stream) # eaMuPlusLambda._log.info(logbook.stream) logger.info(logbook.stream) except KeyboardInterrupt: # print('Interrupt evolution from the user... continue PKP!') eaMuPlusLambda._log.warning( 'Interrupt evolution from the user... continue PKP!') break return population, logbook
def main(args): run_date = time.time() # Configure Logging root = logging.getLogger() if(args.debug): root.setLevel(logging.DEBUG) else: root.setLevel(logging.INFO) if args.quiet: root.propogate = False # Set up the database. pgdb = DBUtils(config_file=DB_CONFIG_FILE) # Get the name of this agent trail for later use at = AgentTrail() at.readTrail(args.trail, DB_CONFIG_FILE) trail_name = at.getName() if not args.quiet and not args.debug and not args.script_mode: try: TOTAL_GENERATIONS = (len(args.network) * args.generations * args.repeat) widgets = ['Processed: ', progressbar.Percentage(), ' ', progressbar.Bar(marker=progressbar.RotatingMarker()), ' ', progressbar.ETA()] pbar = progressbar.ProgressBar( widgets=widgets, maxval=TOTAL_GENERATIONS).start() except: pbar = None else: pbar = None current_overall_gen = 0 for curr_network in args.network: # Query the database to get the network information. pybrain_network = pgdb.getNetworkByID(curr_network) temp_f_h, temp_f_network = tempfile.mkstemp() os.close(temp_f_h) with open(temp_f_network, "w") as f: pickle.dump(pybrain_network, f) # TODO: Need to fix this for chemistry support here. if "Chemical" in pybrain_network.name: chem_re = re.compile( "JL NN Chemical DL([0-9]+) \([0-9]+,[0-9]+,[0-9]+\) v[0-9]+") chem_dl_length = int(chem_re.findall(pybrain_network.name)[0]) network_params_len = len(pybrain_network.params) + chem_dl_length * 3 else: network_params_len = len(pybrain_network.params) # Query the database to get the trail information. (data_matrix, db_trail_name, init_rot) = pgdb.getTrailData(args.trail) # Calculate the maximum amount of food for potential later comparison. MAX_FOOD = np.bincount(np.array(data_matrix).flatten())[1] for curr_repeat in range(0, args.repeat): repeat_start_time = datetime.datetime.now() gens_stat_list = [None] * args.generations # Create an empty array to store the launches for SCOOP. launches = [] # Prepare the array for storing hall of fame. hof_array = np.zeros((args.generations, network_params_len)) toolbox = base.Toolbox() toolbox.register("map", scoop.futures.map) toolbox.register("attr_float", random.uniform, a=args.weight_min, b=args.weight_max) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=network_params_len) toolbox.register("population", tools.initRepeat, list, toolbox.individual) an_temp = AgentNetwork() an_temp.readNetworkFromFile(temp_f_network) at_temp = AgentTrail() at_temp.readTrailInstant(data_matrix, db_trail_name, init_rot) toolbox.register("evaluate", __singleMazeTask, moves=args.moves, network=pickle.dumps(an_temp), trail=pickle.dumps(at_temp)) toolbox.register("mate", tools.cxTwoPoint) if args.mutate_type == 1: toolbox.register("mutate", tools.mutFlipBit, indpb=P_BIT_MUTATE) elif args.mutate_type == 2: toolbox.register("mutate", mutUniformFloat, low=args.weight_min, up=args.weight_max, indpb=P_BIT_MUTATE) elif args.mutate_type == 3: toolbox.register("mutate", mutUniformFloat, low=args.weight_min, up=args.weight_max, indpb=0.30) elif args.mutate_type == 4: toolbox.register("mutate", mutUniformFloat, low=args.weight_min, up=args.weight_max, indpb=0.10) elif args.mutate_type == 5: toolbox.register("mutate", tools.mutGaussian, mu=0, indpb=0.05) else: print "ERROR: Please selct a valid mutate type!" sys.exit(10) if args.selection == 1: # Selection is tournment. Must use argument from user. toolbox.register("select", tools.selTournament, tournsize=args.tournament_size) elif args.selection == 2: toolbox.register("select", tools.selRoulette) elif args.selection == 3: toolbox.register("select", tools.selNSGA2) elif args.selection == 4: toolbox.register("select", tools.selSPEA2) elif args.selection == 5: toolbox.register("select", tools.selRandom) elif args.selection == 6: toolbox.register("select", tools.selBest) elif args.selection == 7: toolbox.register("select", tools.selWorst) elif args.selection == 8: toolbox.register("select", tools.selTournamentDCD) else: print "ERROR: Something is wrong with selection method!" sys.exit(10) # Start a new evolution population = toolbox.population(n=args.population) halloffame = tools.HallOfFame(maxsize=1) food_stats = tools.Statistics(key=lambda ind: ind.fitness.values[0]) move_stats = tools.Statistics(key=lambda ind: ind.fitness.values[1]) mstats = tools.MultiStatistics(food=food_stats, moves=move_stats) mstats.register("min", np.min) mstats.register("avg", np.mean) mstats.register("max", np.max) mstats.register("std", np.std) mstats.register("mode", mode) # Record the start of this run. log_time = datetime.datetime.now() # Evaluate and record the first generation here. 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 # Determine the current generations statistics. record = mstats.compile(population) if args.debug: print "DEBUG: Completed generation 1" hof_indiv = np.array(tools.selBest(population, k=1)[0]) hof_array[0] = hof_indiv # Add the hall of fame to launches. launches.append( scoop.futures.submit(__singleMazeTask, hof_indiv, args.moves, pickle.dumps(an_temp), pickle.dumps(at_temp), 1, record) ) # Keep track of the average food history. mean_food_history = [] smart_term_msg = "" # Begin the generational process for gen in range(2, args.generations + 1): # Vary the pool of individuals if args.variation in [1]: offspring = algorithms.varAnd(population, toolbox, cxpb=args.prob_crossover, mutpb=args.prob_mutate) elif args.variation in [2, 3, 4]: offspring = algorithms.varOr(population, toolbox, lambda_=args.lambda_, cxpb=args.prob_crossover, mutpb=args.prob_mutate) elif args.variation in [5]: # Take and modify the varAnd from DEAP. offspring = [toolbox.clone(ind) for ind in population] # Apply crossover and mutation on the offspring for i in range(1, len(offspring), 2): if random.random() < args.prob_crossover: 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 random.random() < args.prob_mutate: if args.mutate_type in [5]: offspring[i], = toolbox.mutate( offspring[i], sigma=np.std(offspring[i])) else: offspring[i], = toolbox.mutate( offspring[i], offspring[i]) del offspring[i].fitness.values else: print ("ERROR: Something is really wrong! " + "Reached an invalid variation type!") sys.exit(5) # 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) # Replace the current population by the offspring if args.variation in [2, 3]: population[:] = toolbox.select(offspring, args.population) elif args.variation in [4, 5]: population[:] = toolbox.select(offspring + population, args.population) else: population[:] = offspring # Determine the current generations statistics. record = mstats.compile(population) if args.debug: print "DEBUG: Completed generation {0}.".format(gen) print ( "DEBUG: Food (Min / Max / Avg / Std / Mode): " "{0} / {1} / {2} / {3} / {4}".format( record["food"]["min"], record["food"]["max"], record["food"]["avg"], record["food"]["std"], record["food"]["mode"])) print ( "DEBUG: Moves (Min / Max / Avg / Std / Mode): " "{0} / {1} / {2} / {3} / {4}".format( record["moves"]["min"], record["moves"]["max"], record["moves"]["avg"], record["moves"]["std"], record["moves"]["mode"])) hof_indiv = np.array(tools.selBest(population, k=1)[0]) hof_array[gen - 1] = hof_indiv # Add the hall of fame to launches. launches.append( scoop.futures.submit(__singleMazeTask, hof_indiv, args.moves, pickle.dumps(an_temp), pickle.dumps(at_temp), gen, record) ) # Update the mean food history. mean_food_history.append(record["food"]["avg"]) # Update the progress bar if pbar: current_overall_gen += 1 pbar.update(current_overall_gen) # Check if it is time to quit if variation is 3. Critera are # any of the following: # 1) All food has been collected. # 2) Mean has not changed for args.mean_check_length # 3) Run out of generations (happens without this if) if args.variation in [3, 4, 5] and not args.no_early_quit: if (int(record["food"]["max"]) == int(MAX_FOOD)): smart_term_msg = ("Exited at generation {0} because " "all food was consumed.").format(gen) break elif(len(mean_food_history) >= args.mean_check_length and (np.std(mean_food_history[-args.mean_check_length:]) < 0.1)): smart_term_msg = ("Exited at generation {0} because " "mean check length has been met.").format(gen) break # Evaluate the Hall of Fame individual for each generation here # in a multithreaded fashion to speed things up. for this_future in scoop.futures.as_completed(launches): result = this_future.result() gens_stat_list[result[0] - 1] = result[1] # Remove all of the None values from the gen_stat_list gens_stat_list = filter(lambda a: a is not None, gens_stat_list) # Record the statistics on this run. run_info = {} run_info["trails_id"] = args.trail run_info["networks_id"] = curr_network run_info["selection_id"] = args.selection run_info["mutate_id"] = args.mutate_type run_info["host_type_id"] = 1 # Only one host type for now. run_info["variations_id"] = args.variation run_info["run_date"] = log_time run_info["hostname"] = socket.getfqdn() run_info["generations"] = args.generations run_info["population"] = args.population run_info["moves_limit"] = args.moves run_info["sel_tourn_size"] = args.tournament_size if args.variation in [1, 5]: run_info["lambda"] = 0 else: run_info["lambda"] = args.lambda_ run_info["p_mutate"] = args.prob_mutate run_info["p_crossover"] = args.prob_crossover run_info["weight_min"] = args.weight_min run_info["weight_max"] = args.weight_max run_info["debug"] = args.debug # Version for if anything changes in python GA Algorithm run_info["algorithm_ver"] = 2 run_info["mean_check_length"] = args.mean_check_length run_info["runtime"] = (datetime.datetime.now() - repeat_start_time) if not args.disable_db: run_id = pgdb.recordRun(run_info, gens_stat_list) else: run_id = -1 if args.script_mode: if run_id > 0: print ( "Completed repeat {0} with run ID {1}. {2}".format( curr_repeat, run_id, smart_term_msg )) else: print ( "Completed repeat {0} without logging to DB. {1}".format( curr_repeat, smart_term_msg )) # Delete the temporary file os.remove(temp_f_network) # Calculate and display the total runtime if pbar: pbar.finish() total_time_s = time.time() - run_date if run_id > 0: print "Final Run ID {0} completed all runs in {1}. {2}".format( run_id, time.strftime('%H:%M:%S', time.gmtime(total_time_s)), smart_term_msg) else: print "UNLOGGED Run completed in {0}. {1}".format( time.strftime('%H:%M:%S', time.gmtime(total_time_s)), smart_term_msg)
def eaMuPlusLambda1(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): global phase global snakeList global snakeList1 global succFlag succFlag = 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, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit #print(fit, ind.fitness.values) if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=0, nevals=len(population), hof=0.0, besthofgen=0, **record) if verbose: print(logbook.stream) #print(record) k = 0.0 kk = 0 snakeList1[:] = [] # Begin the generational process for gen in range(1, ngen + 1): # 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, offspring) for ind, fit in zip(offspring, 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([]), hof=k, besthofgen=kk, **record) if record['avgbest'] > k: k = record['avgbest'] kk = gen if gen - kk > 10: return population, logbook if verbose: print(logbook.stream) return population, logbook
def ea_mu_plus_lambda(population, toolbox, checkpoint, mu, lambda_, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): if checkpoint: # A file name has been give, then load the data from the file with open(checkpoint, "rb") as cp_file: cp = pickle.load(cp_file) population = cp["population"] start_gen = cp["generation"] + 1 halloffame = cp["halloffame"] logbook = cp["logbook"] random.setstate(cp["rndstate"]) best_specimens = cp["bestspecimens"] print(logbook) else: # start a new evolution since no cp_file was given # population = toolbox.population(n=36) start_gen = 1 # halloffame = tools.HallOfFame(maxsize=1) logbook = tools.Logbook() best_specimens = [] 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) # Begin the generational process for gen in range(start_gen, ngen + 1): # clear the directory of all sim files clear_directory() # 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) # Append the best solution from this gen to the best specimens # array # best_specimens.append(tools.selBest(population, k=1)[0]) # 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) if gen % FREQ == 0: # fill the dictionary cp = dict(population=population, generation=gen, halloffame=halloffame, logbook=logbook, rndstate=random.getstate(), bestspecimens=best_specimens) with open(CHECK_POINT, "wb") as cp_file: pickle.dump(cp, cp_file) return population, logbook