def crossoverAndMutation(problem, individuals): # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, individuals) # Crossover for ind1, ind2 in zip(dIndividuals[::2], dIndividuals[1::2]): if random.random() <= 0.9: #crossover rate tools.cxUniform(ind1, ind2, indpb=1.0 / len(problem.decisions)) # Mutation for ind in dIndividuals: tools.mutPolynomialBounded(ind, eta=1.0, low=[dec.low for dec in problem.decisions], up=[dec.up for dec in problem.decisions], indpb=0.1) del ind.fitness.values # Update beginning population data structure for individual, dIndividual in zip(individuals, dIndividuals): for i in range(len(individual.decisionValues)): individual.decisionValues[i] = dIndividual[i] individual.fitness = None return individuals, 0
def mutate(self, indiv): """ Mutate the individual design variables with different strategies according to the variables types : - interval : Polynomial Bounded mutation or user defined - set : Resampling the variable according to its initialization function - pyleecan : Resampling the variable according to its initialization function Parameters ---------- solver : Solver solver to perform the genetic algorithm with DEAP indiv : individual (e.g. OptiGenAlgIndivDeap) individual to mutate Returns ------- is_mutation : boolean True if at least one mutation occured """ is_mutation = False for k in range(len(indiv.keys)): if self.p_mutate < random.random(): # Perform mutation is_mutation = True if self.mutator == None: if ( indiv.design_var[indiv.keys[k]].type_var == "interval" ): # Interval variable # Using polynomial bounded mutation as in Deb and al., "A Fast and Elitist Multiobjective Genetic Algorithm: NSGA-II" if isinstance(indiv[k], Iterable): indiv[k] = mutPolynomialBounded( indiv[k], 20, *indiv.design_var[indiv.keys[k]].space, 1 )[0] else: # Function takes list in argument and returns list indiv[k] = mutPolynomialBounded( [indiv[k]], 20, *indiv.design_var[indiv.keys[k]].space, 1 )[0][0] else: indiv[k] = indiv.design_var[indiv.keys[k]].function( indiv.design_var[indiv.keys[k]].space ) else: # User defined mutator if ( indiv.design_var[indiv.keys[k]].type_var == "interval" ): # Interval variable indiv[k] = self.mutator(indiv[k]) else: # TODO Allow to redefine mutators for pyleecan types or set indiv[k] = indiv.design_var[indiv.keys[k]].function( indiv.design_var[indiv.keys[k]].space ) return is_mutation
def mutate(self, indpb): allele, = mutPolynomialBounded(self.allele, indpb=self.indpb, eta=self.mteta, low=-0.5 * self.flexibility, up=0.5 * self.flexibility) self.allele[:] = [round(n, self.precision) for n in allele]
def mutate(self, individual, probability): if self.method == 'Polynomial': return tools.mutPolynomialBounded(individual, eta=20.0, low=0.0, up=1.0, indpb=1 / len(individual))[0] elif self.method == 'Shuffle': return tools.mutShuffleIndexes(individual, probability)[0]
def mutate(self, indpb): if random.random() < 0.5: allele, = mutPolynomialBounded( self.allele, indpb=self.indpb, eta=self.mteta, low=-0.5 * self.flexibility, up=0.5 * self.flexibility, ) self.allele[:] = [round(n, self.precision) for n in allele] else: self.allele = [self.random_angle() for i in xrange(self.max_bonds)]
def my_mutation(self,LL,UU,individual): t=self.t typeOfInput=len(t) individual_ = [] for i in range(typeOfInput): if t[i] =='float': ind1=tools.mutPolynomialBounded([individual[i]], low=LL[i], up=UU[i], eta=20.0,indpb=1.0/len(self.t)) individual_.append(ind1[0][0]) elif t[i] =='int' or t[i]== 'bool': ind2=tools.mutUniformInt([individual[i]], low=LL[i], up=UU[i], indpb= 0.9) individual_.append(ind2[0][0]) return individual_
def crossoverAndMutation(problem, individuals): # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, individuals) # Crossover for ind1, ind2 in zip(dIndividuals[::2], dIndividuals[1::2]): if random.random() <= 0.9: #crossover rate tools.cxUniform(ind1, ind2, indpb=1.0/len(problem.decisions)) # Mutation for ind in dIndividuals: tools.mutPolynomialBounded(ind, eta = 1.0, low=[dec.low for dec in problem.decisions], up=[dec.up for dec in problem.decisions], indpb=0.1 ) del ind.fitness.values # Update beginning population data structure for individual,dIndividual in zip(individuals, dIndividuals): for i in range(len(individual.decisionValues)): individual.decisionValues[i] = dIndividual[i] individual.fitness = None return individuals,0
def mutation(individual, indpb, eta): """Mutates an individual using polynomial bounded mutation. :individual: the individual to mutate :indpb: the probability for a mutation to occur :returns: the (altered) individual """ gen = tools.mutPolynomialBounded( individual.get_values(), eta, # eta_m 1.0 == high spread; 4.0 low spread 0.0, # lower bound 1.0, # upper bound indpb) individual.set_values(gen[0]) return (individual, )
def init_algorithm(self, params): toolbox = base.Toolbox() ind_size = self.problem.ind_size ngen = params['generations'] nind = params['num_individuals'] cxpb, mutpb, lb, ub, mu, lam = 0.7, 0.2, -1.0, 1.0, nind, nind if hasattr(creator, 'FitnessMin') is False: creator.create('FitnessMin', base.Fitness, weights=(-1.0, )) if hasattr(creator, 'Individual') is False: kw0 = {'typecode': 'd', 'fitness': creator.FitnessMin} creator.create('Individual', array.array, **kw0) atr = lambda: [random.uniform(lb, ub) for _ in range(ind_size)] ind = lambda: tools.initIterate(creator.Individual, atr) population = [ind() for _ in range(nind)] kw1 = {'low': lb, 'up': ub, 'eta': 20.0, 'indpb': 1.0 / ind_size} mut = lambda xs: tools.mutPolynomialBounded(xs, **kw1) kw2 = {'low': lb, 'up': ub, 'eta': 20.0} crs = lambda i1, i2: tools.cxSimulatedBinaryBounded(i1, i2, **kw2) sel = lambda p, n: tools.selTournament(p, n, tournsize=3) toolbox.register('evaluate', self.problem.objective_function) toolbox.register('mate', crs) toolbox.register('mutate', mut) toolbox.register('select', sel) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register('min', np.min) self.hof = tools.HallOfFame(5) args = (population, toolbox, mu, lam, cxpb, mutpb, ngen) kw3 = {'stats': stats, 'halloffame': self.hof, 'verbose': True} self.algorithm = lambda: algorithms.eaMuPlusLambda(*args, **kw3)
def mutation_main(individual, indpb, column_names, heating_unit_names_share, cooling_unit_names_share, column_names_buildings_heating, column_names_buildings_cooling, district_heating_network, district_cooling_network): # create dict of individual with his/her name individual_with_name_dict = dict(zip(column_names, individual)) if district_heating_network: # MUTATE BUILDINGS CONNECTED buildings_heating = [ individual_with_name_dict[column] for column in column_names_buildings_heating ] # apply mutations buildings_heating_mutated = tools.mutFlipBit(buildings_heating, indpb)[0] # take back to the individual for column, mutated_value in zip(column_names_buildings_heating, buildings_heating_mutated): individual_with_name_dict[column] = mutated_value # MUTATE SUPPLY SYSTEM UNITS SHARE heating_units_share = [ individual_with_name_dict[column] for column in heating_unit_names_share ] NDIM = len(heating_unit_names_share) # apply mutations heating_units_share_mutated = tools.mutPolynomialBounded( heating_units_share, eta=20.0, low=0.0, up=1.0, indpb=1.0 / NDIM)[0] # takeback to teh individual for column, mutated_value in zip(heating_unit_names_share, heating_units_share_mutated): individual_with_name_dict[column] = mutated_value if district_cooling_network: # MUTATE BUILDINGS CONNECTED buildings_cooling = [ individual_with_name_dict[column] for column in column_names_buildings_cooling ] # apply mutations buildings_cooling_mutated = tools.mutFlipBit(buildings_cooling, indpb)[0] # take back to teh individual for column, mutated_value in zip(column_names_buildings_cooling, buildings_cooling_mutated): individual_with_name_dict[column] = mutated_value # MUTATE SUPPLY SYSTEM UNITS SHARE cooling_units_share = [ individual_with_name_dict[column] for column in cooling_unit_names_share ] NDIM = len(cooling_units_share) # apply mutations cooling_units_share_mutated = tools.mutPolynomialBounded( cooling_units_share, eta=20.0, low=0.0, up=1.0, indpb=1.0 / NDIM)[0] # takeback to teh individual for column, mutated_value in zip(cooling_unit_names_share, cooling_units_share_mutated): individual_with_name_dict[column] = mutated_value # now validate individual individual_with_name_dict = validation_main( individual_with_name_dict, column_names_buildings_heating, column_names_buildings_cooling, district_heating_network, district_cooling_network) # now pass all the values mutated to the original individual for i, column in enumerate(column_names): individual[i] = individual_with_name_dict[column] return individual, # add the, because deap needs this
def nsga2_1iter(self, current_pop): """ Run one iteration of the NSGA-II optimizer. Based on the crossover and mutation probabilities, the offsprings are created and evaluated. Based on the fitness of these offsprings and of the current population, a new population is created. Parameters ---------- current_pop : list The initial population. Returns ------- new_pop : list The updated population. """ # create offspring, clone of current population offspring = [deepcopy(ind) for ind in current_pop] # perform crossover for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() < self.run_dict['cx prob']: # apply crossover operator # in place editing of individuals tools.cxSimulatedBinaryBounded(ind1, ind2, self.run_dict['eta'], self.space_obj.l_b, self.space_obj.u_b) # set the fitness to an empty tuple of modified individuals del ind1.fitness.values del ind2.fitness.values # perform mutation for mutant in offspring: if random.random() < self.run_dict['mut prob']: # apply mutation operator # in place editing of individuals tools.mutPolynomialBounded(mutant, self.run_dict['eta'], self.space_obj.l_b, self.space_obj.u_b, self.run_dict['mut prob']) # set fitness to empty tuple of modified individuals del mutant.fitness.values # evaluate the modified individuals n_eval = 0 invalid_indices = [] invalid_fit_individuals = [] for i, ind in enumerate(offspring): if not ind.fitness.valid: invalid_indices.append(i) invalid_fit_individuals.append(ind) if len(invalid_fit_individuals) > 0: # create samples to evaluate individuals_to_eval, unc_samples = self.define_samples_to_eval( invalid_fit_individuals) # evaluate samples fitnesses = self.evaluate_samples(individuals_to_eval) n_eval += len(individuals_to_eval) # assign fitness to the orginal samples list individuals_to_assign = self.assign_fitness_to_population( invalid_fit_individuals, fitnesses, unc_samples) # construct offspring list for i, ind in zip(invalid_indices, individuals_to_assign): offspring[i] = deepcopy(ind) # select next population using the NSGA-II operator new_pop = tools.selNSGA2(current_pop + offspring, len(current_pop)) # update the population and fitness files self.append_points_to_file(new_pop, 'population') fitness_values = [x.fitness.values for x in new_pop] self.append_points_to_file(fitness_values, 'fitness') # update the STATUS file ite, evals = self.parse_status() self.write_status('%8i%8i' % (ite + 1, evals + n_eval)) return new_pop
def init_algorithm(self, params): if params['algorithm_class'] not in ['simple', 'multiobjective']: raise ValueError('Non-existent algorithm class.') toolbox = base.Toolbox() ngen = params['generations'] nind = params['num_individuals'] cxpb = 0.5 if params['algorithm_class'] == 'simple' else 0.9 lb, ub = -1.0, 1.0 ind_size = self.problem.ind_size if nind % 4 != 0: raise ValueError('Number of individuals must be multiple of four') if hasattr(creator, 'FitnessMin') is False: creator.create('FitnessMin', base.Fitness, weights=(-1.0, -1.0)) if hasattr(creator, 'Individual') is False: creator.create('Individual', array.array, typecode='d', fitness=creator.FitnessMin) atr = lambda: [random.uniform(lb, ub) for _ in range(ind_size)] ind = lambda: tools.initIterate(creator.Individual, atr) population = [ind() for _ in range(nind)] if params['algorithm_class'] == 'simple': self.hof = tools.HallOfFame(1) mut = lambda xs: tools.mutGaussian(xs, mu=0, sigma=1, indpb=0.1) crs = tools.cxTwoPoint sel = lambda p, n: tools.selTournament(p, n, tournsize=3) else: self.hof = tools.ParetoFront() mut = lambda xs: tools.mutPolynomialBounded( xs, low=lb, up=ub, eta=20.0, indpb=1.0 / ind_size) crs = lambda ind1, ind2: tools.cxSimulatedBinaryBounded( ind1, ind2, low=lb, up=ub, eta=20.0) sel = tools.selNSGA2 toolbox.register('evaluate', self.problem.objective_function) toolbox.register('mate', crs) toolbox.register('mutate', mut) toolbox.register('select', sel) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register('avg', np.mean, axis=0) stats.register('std', np.std, axis=0) stats.register('min', np.min, axis=0) stats.register('max', np.max, axis=0) args = (population, toolbox) kwargs = {'cxpb': cxpb, 'ngen': ngen, 'stats': stats} kwargs['halloffame'] = self.hof if params['algorithm_class'] == 'simple': kwargs['mutpb'] = 0.2 kwargs['verbose'] = True self.algorithm = lambda: algorithms.eaSimple(*args, **kwargs) else: self.algorithm = lambda: self.multiobjective(*args, **kwargs)
def __init__(self, params: AlgorithmParameters): """Initialize the genetic algorithm that will solve the control synthesis problem. The params dictionary has the following items num_control_params The number of control parameters used in a solution. generations The number of iterations of the genetic algorithm to run. """ assert len(params.lower_bounds) == len(params.upper_bounds) self.ind_size = len(params.lower_bounds) ngen = params.generations nind = params.num_individuals cxpb, mutpb, mu, lam = params.crossover_prob, params.mutation_prob, nind, nind # Here we are creating two new types. The FitnessMin type and the Individual type. # FitnessMin inherits from deap.base.Fitness and has a new weights attribute that is # a tuple. For single objective optimization, the weights attribute has one element # for multi-objective optimization it will have multiple elements. A negative weight # indicates this is a minimization problem. if hasattr(creator, 'FitnessMin') is False: creator.create('FitnessMin', base.Fitness, weights=(-1.0, )) # The individual type inherits from array.array (could use list) and it needs a # fitness attribute to know how to calculate the fitness of the individual. # Arrays store only one type of data. This is set by the tyepcode paramter. 'd' is for double. if hasattr(creator, 'Individual') is False: kw0 = {'typecode': 'd', 'fitness': creator.FitnessMin} creator.create('Individual', array.array, **kw0) # Creates the initial lists of individuals. atr = lambda: [ random.uniform(lb, ub) for lb, ub in zip(params.lower_bounds, params.upper_bounds) ] ind = lambda: creator.Individual(atr()) population = [ind() for _ in range(nind)] # The toolbox is a container to store partial functions. In particular we want the evaluate, mate, mutate, # and select genetic algorithm functions defined here. toolbox = base.Toolbox() kw1 = { 'low': params.lower_bounds, 'up': params.upper_bounds, 'eta': 20.0, 'indpb': 1.0 / self.ind_size } mut = lambda xs: tools.mutPolynomialBounded(xs, **kw1) kw2 = { 'low': params.lower_bounds, 'up': params.upper_bounds, 'eta': 20.0 } crs = lambda i1, i2: tools.cxSimulatedBinaryBounded(i1, i2, **kw2) sel = lambda p, n: tools.selTournament(p, n, tournsize=3) toolbox.register('evaluate', params.cost_function) toolbox.register('mate', crs) toolbox.register('mutate', mut) toolbox.register('select', sel) # DEAP provides objects taht will record algorithm statisitics and keep trak of the best solutions. stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register('min', np.min) self.hof = tools.HallOfFame(5) # Setting up the DEAP library for the genetic algorithm comes down to creating and # executing an algorithm function. There are a number of pre-build algorithms that # can be used rather than coding your own. The eaMuPlusLambda algorithm requires # the parameters that have been generated above. args = (population, toolbox, mu, lam, cxpb, mutpb, ngen) kw3 = {'stats': stats, 'halloffame': self.hof, 'verbose': True} self.algorithm = lambda: algorithms.eaMuPlusLambda(*args, **kw3)
def decoy_mutPoly(individual): individual, = tools.mutPolynomialBounded(individual, 0, 0.4, 0.95, 0.4) individual[0] = clamp(individual[0], MIN_SUPPORT_THRESHOLD, MAX_SUPPORT_THRESHOLD) individual[1] = clamp(individual[1], MIN_CONF_THRESHOLD, MAX_CONF_THRESHOLD) return individual,
def deepmutation(self): self.chaneOrder() returned = mutPolynomialBounded(self.gen[1], 20, 0, 1, 0.5) self.gen[1] = returned[0]
def crossoverAndMutation(problem, individuals): from copy import copy new_individuals = individuals if CULLING is True: count = 0 new_crop = [] # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, individuals) while True: count += 1 if count > 10 or len(dIndividuals) == 1 or len(new_crop) == len(individuals): break # Crossover for ind1, ind2 in zip(dIndividuals[::2], dIndividuals[1::2]): if random.random() <= 0.9: #crossover rate tools.cxUniform(ind1, ind2, indpb=1.0/len(problem.decisions)) # Mutation for ind in dIndividuals: temp = [] tools.mutPolynomialBounded(ind, eta = 1.0, low=[dec.low for dec in problem.decisions], up=[dec.up for dec in problem.decisions], indpb=0.1 ) del ind.fitness.values temp = problem.evaluate(ind) if temp[0] > jmoo_properties.CULLING_PD and temp[1] < jmoo_properties.CULLING_PF: import numpy as np test = np.array(ind).tolist() # print "IND: ", ind # print "TEST: ", test if len(new_crop) != len(individuals): new_crop = helper_list(new_crop, test) # print ">> ", problem.evaluate(ind) print "NEW CROP: ", len(new_crop) for x in new_crop: if x in dIndividuals: dIndividuals.remove(x) else: dIndividuals.remove(random.choice(dIndividuals)) for _ in xrange(1): print ">> ", problem.evaluate(x), x dIndividuals.extend(new_crop) print "Length : ", len(dIndividuals) # Update beginning population data structure for individual,dIndividual in zip(individuals, dIndividuals): for i in range(len(individual.decisionValues)): individual.decisionValues[i] = dIndividual[i] individual.fitness = None return individuals, len(individuals) * (count - 1) else: # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, individuals) new_dIndividuals = [] # print "Number of Individuals: ", len(dIndividuals) # Crossover for ind1, ind2 in zip(dIndividuals[::2], dIndividuals[1::2]): if random.random() <= 1: #crossover rate # print ".", ind1, ind2 = tools.cxUniform(ind1, ind2, indpb=1.0/len(problem.decisions)) new_dIndividuals.append(ind1) new_dIndividuals.append(ind2) else: new_dIndividuals.append(ind1) new_dIndividuals.append(ind2) # Mutation for ind in new_dIndividuals: # print "+", tools.mutPolynomialBounded(ind, eta = 1.0, low=[dec.low for dec in problem.decisions], up=[dec.up for dec in problem.decisions], indpb=0.1 ) del ind.fitness.values # Update beginning population data structure for individual, dIndividual in zip(new_individuals, new_dIndividuals): for i in range(len(individual.decisionValues)): individual.decisionValues[i] = dIndividual[i] individual.fitness = None return new_individuals,0