def creation_tools(toolbox, model, translator, creator, weights, alpha, mu, sigma, indpb, tournsize, nb_threads, **kwargs): """ Function creating operators for the continous ga Warning the deap creator has to be instanciated with the class Individual created (call function creation deap classes first) Parameters: model (python callable) evaluation function translator (Continuous_DNA instance): translator for interfacing genotype and phenotype creator (Deap creator): creator with classes Individual ans FitnessMax weights (tuple): weights of the metrics of the python callable alpha (Float): cross over parameter for allowing childs to step out of the parents' interval mu (Float): expectancy of the mutation sigma (Float): variance of the mutation indpb (float between 0 and 1): probability of mutating one gene tournsize (Integer): size of the tournament for selection nb_threads (Integer): number of process to run in parallel **kwargs: extra arguments for the model """ # generation operation: relies on the function generate_random of the translator toolbox.register("individual", generate, translator=translator, creator=creator) # a population is a repetition of individuals toolbox.register("population", tools.initRepeat, list, toolbox.individual) #funtion that retruns the fitness from an individual toolbox.register("evaluate", evaluate, model=model, translator=translator, weights=weights, **kwargs) #mate function decorated for logs of parents toolbox.register("mate", decorator_cross(tools.cxBlend), alpha=alpha) #mutation function decorated for logging on which individual the mutation was done toolbox.register("mutate", decorator_mut(tools.mutGaussian), mu=mu, sigma=sigma, indpb=indpb) #selection operator decorated for changing logs toolbox.register("select", decorator_selection(tools.selTournament), tournsize=tournsize) #Multiprocessing if the user specified multiple threads if nb_threads > 1: pool = multiprocessing.Pool(processes=nb_threads) toolbox.register("map", pool.map)
def create_tools(toolbox, model, creator, min_index, max_index, length_init, rm_mutpb, add_mutpb, tourn_size, length_max, **kwargs): """ Function creating operators Arguments: toolbox (deap toolbox instance): base.toolbox model (python callable) evaluation function creator (Deap creator): creator with classes Individual ans FitnessMax min_index (Integer): min index that can be found in the list max_index (Integer): max index that can be found in the list length_init (Integer): Length of the generated individuals rm_mutpb (Float between 0 and 1): probability for geometric law to remove n genes add_mutpb (Float between 0 and 1): probability for geometric law to add n genes tourn_size (Integer): size of the tournament length_max (Integer): maximum length of an individual """ toolbox.register("individual", generate_individual, creator=creator, min_index=min_index, max_index=max_index, length=length_init) toolbox.register("population", tools.initRepeat, list, toolbox.individual) #deap basic funtion to cross a population toolbox.register("evaluate", evaluate, model=model, **kwargs) #We decorate the operators so as to create the visualization the parameters given here are the parameters of the operators # they can be changed in the parameters of the function toolbox.register("mate", decorator_cross(cross_over)) toolbox.register("mutate", decorator_mut(mutation), min_index=min_index, max_index=max_index, rm_mutpb=rm_mutpb, add_mutpb=add_mutpb) toolbox.register("select", decorator_selection(tools.selTournament), tournsize=tourn_size) toolbox.register("trimmering", trimmering, length_max=length_max)
def run_constrained_hybrid_ga(model, weights, hparams, NGEN=40, nb_indiv=80, nb_threads=1, cxpb=0.7, mutpb=0.4, discrete_cx=tools.cxTwoPoint, discrete_cx_kwargs={}, continuous_cx=tools.cxBlend, continuous_cx_kwargs={"alpha": 0.1}, discrete_mut=tools.mutFlipBit, discrete_mut_kwargs={"indpb": 0.05}, continuous_mut=tools.mutGaussian, continuous_mut_kwargs={ "mu": 0., "sigma": 0.1, "indpb": 0.05 }, selection_op=tools.selTournament, selection_kwargs={"tournsize": 3}, stric_interval=False, log_file=None, recover_file=None, gray_code=True, constraints=[], **kwargs): if recover_file: with open(recover_file, 'rb') as pickle_file: hparams = pickle.load(pickle_file) translator = HybridDNA(hparams, stric_interval=stric_interval, gray_code=gray_code) pops = pickle.load(pickle_file) creator.create("FitnessHidden", FitnessReg, weights=weights) creator.create("FitnessMax", ConstrainedFitness, base_fit=creator.FitnessHidden) #weight is the weights given to the different fitnesses (incase you have a multiobjective optimization to make) creator.create("Individual", list, fitness=creator.FitnessMax, parents=None, mutated=None, id=None, age=0) #toolbox object from deap: allows to define functions in one line for operations on the individual toolbox = base.Toolbox() toolbox.register("individual", generate, translator=translator, creator=creator) toolbox.register("population", tools.initRepeat, list, toolbox.individual) #funtion that retruns the fitness from an individual #the output is a tuple to match the format of the weights given just above in fitnessMax definition #deap basic funtion to cross a population toolbox.register("evaluate", evaluate, model=model, translator=translator, weights=weights, **kwargs) toolbox.register("mate", decorator_cross(hybrid_cx), discrete_cx=discrete_cx, discrete_cx_kwargs=discrete_cx_kwargs, continuous_cx=continuous_cx, continuous_cx_kwargs=continuous_cx_kwargs) toolbox.register("mutate", decorator_mut(hybrid_mut), discrete_mut=discrete_mut, discrete_mut_kwargs=discrete_mut_kwargs, continuous_mut=continuous_mut, continuous_mut_kwargs=continuous_mut_kwargs) toolbox.register("select", decorator_selection(selection_op), **selection_kwargs) population = recover_last_gen(pops, creator, translator) #nb_indiv=len(population) #Performing selection and cross and mutation to create the new generation population = toolbox.select([ indiv for indiv in population if translator.is_dna_viable(indiv) ], k=nb_indiv) population = algorithms.varAnd(population, toolbox, cxpb=cxpb, mutpb=mutpb) else: translator = HybridDNA(hparams, stric_interval=stric_interval, gray_code=gray_code) creator.create("FitnessHidden", FitnessReg, weights=weights) creator.create("FitnessMax", ConstrainedFitness, base_fit=creator.FitnessHidden) #weight is the weights given to the different fitnesses (incase you have a multiobjective optimization to make) creator.create("Individual", list, fitness=creator.FitnessMax, parents=None, mutated=None, id=None, age=0) #toolbox object from deap: allows to define functions in one line for operations on the individual toolbox = base.Toolbox() toolbox.register("individual", generate, translator=translator, creator=creator) toolbox.register("population", tools.initRepeat, list, toolbox.individual) #funtion that retruns the fitness from an individual #the output is a tuple to match the format of the weights given just above in fitnessMax definition #deap basic funtion to cross a population toolbox.register("evaluate", evaluate, model=model, translator=translator, weights=weights, **kwargs) toolbox.register("mate", decorator_cross(hybrid_cx), discrete_cx=discrete_cx, discrete_cx_kwargs=discrete_cx_kwargs, continuous_cx=continuous_cx, continuous_cx_kwargs=continuous_cx_kwargs) toolbox.register("mutate", decorator_mut(hybrid_mut), discrete_mut=discrete_mut, discrete_mut_kwargs=discrete_mut_kwargs, continuous_mut=continuous_mut, continuous_mut_kwargs=continuous_mut_kwargs) toolbox.register("select", decorator_selection(selection_op), **selection_kwargs) #we are now creating the population population = toolbox.population(n=nb_indiv) pops = [] init_integer = len(pops) if nb_threads > 1: pool = multiprocessing.Pool(processes=nb_threads) toolbox.register("map", pool.map) #We are running the genetical algorithm for gen in range(init_integer, NGEN): print('Generation: ' + str(gen + 1)) #creating ids if needed for l, ind in enumerate(population): ind.age += 1 if ind.mutated != None or ind.parents != None or gen == 0: ind.id = str(gen + 1) + "." + str(l) #Evaluation of the individuals fits = toolbox.map(toolbox.evaluate, population) for fit, ind in zip(fits, population): ind.fitness.values = fit for ind in population: if translator.is_dna_viable(ind): phen = translator.dna_to_phen(ind) ind.fitness.constraints = [ const(phen, ind.fitness.values) for const in constraints ] else: ind.fitness.constraints = [False for _ in constraints] # Printing the best individual top1 = tools.selBest(population, k=1) print(translator.dna_to_phen(top1[0])) print(top1[0].fitness.values) #Registering the information in the pickle file pops.append([{ "phen": translator.dna_to_phen(indiv), "fits": indiv.fitness.values, "age": indiv.age, "id": indiv.id, "parents": indiv.parents, "mutated": indiv.mutated, "constraints": ind.fitness.constraints } for indiv in population if translator.is_dna_viable(indiv)]) #Selection of the individuals population = toolbox.select( [indiv for indiv in population if translator.is_dna_viable(indiv)], k=len(population)) population = algorithms.varAnd(population, toolbox, cxpb=cxpb, mutpb=mutpb) if log_file: with open(log_file, 'wb') as pickle_file: pickle.dump(hparams, pickle_file, protocol=pickle.HIGHEST_PROTOCOL) pickle.dump(pops, pickle_file, protocol=pickle.HIGHEST_PROTOCOL) return pops
def creation_tools(toolbox, model, translator, creator, weights, discrete_cx, discrete_cx_kwargs, continuous_cx, continuous_cx_kwargs, discrete_mut, discrete_mut_kwargs, continuous_mut, continuous_mut_kwargs, selection_op, selection_kwargs, nb_threads, **kwargs): """ Function creating operators for the continous ga Warning the deap creator has to be instanciated with the class Individual created (call function creation deap classes first) Parameters: model (python callable) evaluation function translator (Continuous_DNA instance): translator for interfacing genotype and phenotype creator (Deap creator): creator with classes Individual ans FitnessMax weights (tuple): weights of the metrics of the python callable discrete_cx (python callable): discrete cross over operation discrete_cx_kwargs (python dictionnary): kwargs for the dicrete cross over continuous_cx (python callable): continuous cross over continuous_cx_kwargs (python dictionnary): kwargs for the continuous cross over discrete_mut (python callable): discrete mutation operator discrete_mut_kwargs (python dictionnary): kwargs for discrete mutation continuous_mut (python callable): continuous mutation operator continuous_mut_kwargs (python dictionnary): kwargs for continuous mutation selection_op (python callable): selection operator selection_kwargs (python dictionnary): kwargs for the selection nb_threads (Integer): number of process to run in parallel **kwargs: extra arguments for the model """ # generation operation: relies on the function generate_random of the translator toolbox.register("individual", generate, translator=translator, creator=creator) # a population is a repetition of individuals toolbox.register("population", tools.initRepeat, list, toolbox.individual) #funtion that retruns the fitness from an individual toolbox.register("evaluate", evaluate, model=model, translator=translator, weights=weights, **kwargs) #mate function decorated for logs, mixing continuous and discrete operators toolbox.register("mate", decorator_cross(hybrid_cx), discrete_cx=discrete_cx, discrete_cx_kwargs=discrete_cx_kwargs, continuous_cx=continuous_cx, continuous_cx_kwargs=continuous_cx_kwargs) #mutation function decorated for logging on which individual the mutation was done toolbox.register("mutate", decorator_mut(hybrid_mut), discrete_mut=discrete_mut, discrete_mut_kwargs=discrete_mut_kwargs, continuous_mut=continuous_mut, continuous_mut_kwargs=continuous_mut_kwargs) #selection operator decorated for changing logs toolbox.register("select", decorator_selection(selection_op), **selection_kwargs) #Multiprocessing if the user specified multiple threads if nb_threads > 1: pool = multiprocessing.Pool(processes=nb_threads) toolbox.register("map", pool.map)