def mutateNN(ind): gen = ind.gen genotype(ind) tools.mutGaussian(ind, params["mmu"], params["msigma"], params["mi"]) phenotype(ind) ind.gen = gen return ind,
def add_noise(shapelets): """Add random noise to a random shapelet""" rand_shapelet = np.random.randint(len(shapelets)) tools.mutGaussian(shapelets[rand_shapelet], mu=0, sigma=0.1, indpb=0.15) return shapelets,
def mutateOneAb(Ab, mut_rate): numAttr = Ab.get_all_numeric() boolAttr = Ab.get_all_boolean() # print(tools.mutGaussian(numAttr,0,mut_rate,0.5)) Ab.set_all_numeric(tools.mutGaussian(numAttr, 0, mut_rate, 1)[0]) Ab.set_all_boolean(tools.mutFlipBit(boolAttr, mut_rate)[0]) return Ab
def init_simple_genetic_algorithm(self): ind_size = self.topology_factory.ind_size self.toolbox = base.Toolbox() if hasattr(creator, 'FitnessMin') is False: creator.create('FitnessMin', base.Fitness, weights=(-1.0, )) if hasattr(creator, 'Individual') is False: creator.create('Individual', list, fitness=creator.FitnessMin) ind_size = self.topology_factory.ind_size att = lambda: random.uniform(-1.0, 1.0) ind = lambda: tools.initRepeat(creator.Individual, att, n=ind_size) pop = lambda n: tools.initRepeat(list, ind, n=n) mut = lambda xs: tools.mutGaussian(xs, mu=0, sigma=1, indpb=0.1) self.toolbox.register('evaluate', self.objective_function) self.toolbox.register('mate', tools.cxTwoPoint) self.toolbox.register('mutate', mut) self.toolbox.register('select', tools.selTournament, tournsize=3) self.population = pop(n=self.nind) self.hof = tools.HallOfFame(1) self.stats = tools.Statistics(lambda ind: ind.fitness.values) self.stats.register('min', np.min)
def defaultMut(individual, indpb=0.26, stdperc=0.1): """ Each individual attribute suffers a Gaussian mutation with probability `indpb'. The standard deviations are `stdperc' times the corresponding mean. """ mu = [0 for i in range(len(individual))] sigma = [stdperc * x for x in individual] # TODO: Only return if parameters are Physical!!!! return tools.mutGaussian(individual, mu, sigma, indpb)
def mutGaussianScaled(individual, mu, sigma_scale, indp): """ Apply a Gaussian mutation, with the standard deviation for each attribute fixed as a percentage of the attribute's magnitude. :param float sigma_scale: scaling factor for standard deviation as a percent of magnitude """ sigmas = [v * sigma_scale for v in individual] return tools.mutGaussian(individual, mu, sigmas, indp)
def varOrZeno(population, toolbox, lambda_, cxpb, mutpb, progress, mu, sigma): """Part of an evolutionary algorithm applying only the variation part (crossover, mutation **or** reproduction). The modified individuals have their fitness invalidated. The individuals are cloned so returned population is independent of the input population. :param population: A list of individuals to vary. :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution operators. :param lambda\_: The number of children to produce :param cxpb: The probability of mating two individuals. :param mutpb: The probability of mutating an individual. :returns: The final population :returns: A class:`~deap.tools.Logbook` with the statistics of the evolution The variation goes as follow. On each of the *lambda_* iteration, it selects one of the three operations; crossover, mutation or reproduction. In the case of a crossover, two individuals are selected at random from the parental population :math:`P_\mathrm{p}`, those individuals are cloned using the :meth:`toolbox.clone` method and then mated using the :meth:`toolbox.mate` method. Only the first child is appended to the offspring population :math:`P_\mathrm{o}`, the second child is discarded. In the case of a mutation, one individual is selected at random from :math:`P_\mathrm{p}`, it is cloned and then mutated using using the :meth:`toolbox.mutate` method. The resulting mutant is appended to :math:`P_\mathrm{o}`. In the case of a reproduction, one individual is selected at random from :math:`P_\mathrm{p}`, cloned and appended to :math:`P_\mathrm{o}`. This variation is named *Or* beceause an offspring will never result from both operations crossover and mutation. The sum of both probabilities shall be in :math:`[0, 1]`, the reproduction probability is 1 - *cxpb* - *mutpb*. """ assert (cxpb + mutpb) <= 1.0, ( "The sum of the crossover and mutation probabilities must be smaller " "or equal to 1.0.") offspring = [] for _ in xrange(lambda_): op_choice = random.random() if op_choice < cxpb: # Apply crossover ind1, ind2 = map(toolbox.clone, random.sample(population, 2)) ind1, ind2 = toolbox.mate(ind1, ind2) del ind1.fitness.values offspring.append(ind1) elif op_choice < cxpb + mutpb: # Apply mutation ind = toolbox.clone(random.choice(population)) ind, = tools.mutGaussian(ind, mu, sigma * max(progress, 0.2), mutpb) del ind.fitness.values offspring.append(ind) else: # Apply reproduction offspring.append(random.choice(population)) return offspring
def fct_mutation_learned(ind1): # need to clip in up-direction because too large numbers create overflows # need to clip below to avoid stagnation, which happens when a top individuals # mutates bad strategy parameters ind1[-1] = np.clip(ind1[-1], -5, 3) ind1[-2] = np.clip(ind1[-2], -5, 3) sigma = 2**ind1[-1] indpb = 2**(ind1[-2] - 3) return tools.mutGaussian(individual=ind1, mu=0, sigma=sigma, indpb=indpb)
def fct_mutation_learned_per_gene(ind1): half = len(ind1) // 2 ind1[half:] = np.clip(ind1[half:], -6, 0) strategy = [] for s in ind1[half:]: strategy.append(2**s) # mutate genome with parameters from strategy. and mutate strategy with constant # sigma = np.concatenate((strategy, ([0.2] * half)), axis=None).tolist() sigma = np.concatenate((strategy, strategy), axis=None).tolist() return tools.mutGaussian(individual=ind1, mu=0, sigma=sigma, indpb=1.0)
def mutator(individual, mu=None, sigma=None, indpb=.8, seed=None): if mu is None: mu = (individual[0], individual[1]) if sigma is None: mu = ((U_upper - U_lower) * .15, (a_upper - a_lower) * .15) if seed is not None: np.random.seed(seed) random.seed(seed) # used in tools.mutGaussian() tools.mutGaussian(individual, mu, sigma, indpb) # if parameters are out of bounds, this guaranteed that they will not be any more if individual[0] < U_lower: individual[0] = U_lower + (np.random.random() * abs(U_lower - individual[0])) elif individual[0] > U_upper: individual[0] = U_upper - (np.random.random() * abs(U_upper - individual[0])) if individual[1] < a_lower: individual[1] = a_lower + (np.random.random() * abs(a_lower - individual[1])) elif individual[1] > a_upper: individual[1] = a_upper - (np.random.random() * abs(a_upper - individual[1]))
def mutation(toolbox, ind1, min_weight, max_weight): ind2 = toolbox.clone(ind1) if random.random() < 0.2: scale_factor = random.uniform(a=0.5, b=2.0) # Biased towards positive. for i in range(len(ind2)): ind2[i] = (ind2[i] - 1) * scale_factor + 1 else: sigma = random.uniform(a=0.02, b=0.2) ind2, = tools.mutGaussian(ind2, mu=0.0, sigma=sigma, indpb=0.8) for i in range(len(ind2)): ind2[i] = min(max(ind2[i], min_weight), max_weight) if ind2[i] < 0.2 and random.random() < 0.5: ind2[i] = 0.0 del ind2.fitness.values return ind2,
def get_child_reward_network( mom: Agent, dad: Agent, mut_sigma: float = 0.3, mut_p: float = 0.05) -> Tuple[List[np.ndarray], List[np.ndarray]]: """ Takes as input a pair of agents, and constructs the child's reward network. Parameters ---------- mom : ``Agent``. First parent agent. dad : ``Agent``. First parent agent. mut_sigma : ``float``, optional. Standard deviation of mutation operation on reward vectors. mut_p : ``float``, optional. Probability of mutation on reward vectors. Returns ------- childs_reward_weights : ``List[np.ndarray]``. Weights of the new agent's reward network. childs_reward_biases : ``List[np.ndarray]``. Biases of the new agent's reward network. """ # Get parents' DNA. moms_dna = reward_to_DNA(mom.reward_weights, mom.reward_biases) dads_dna = reward_to_DNA(dad.reward_weights, dad.reward_biases) # Crossover. childs_dna, _ = cxOnePoint(moms_dna, dads_dna) # Mutation. # HARDCODE: ``mu`` and grabbing first and only tuple element. childs_dna = mutGaussian(childs_dna, 0.0, mut_sigma, mut_p)[0] # HARDCODE: using ``mom``'s reward hyperparams for child. childs_reward_weights, childs_reward_biases = DNA_to_reward( childs_dna, mom.n_layers, mom.input_dim, mom.hidden_dim) return childs_reward_weights, childs_reward_biases
def f_mutate_bit(bit, p=None, mu=0., sigma=0.1, indpb=0.2): if p['type'] == 'continuous': rng = p['args'] mu = rng[0] + mu * (rng[1] - rng[0]) sigma *= rng[1] - rng[0] bit = tools.mutGaussian([bit], mu, sigma, indpb)[0][0] return min(max(bit, rng[0]), rng[1]) elif p['type'] == 'ordinal': idx = p['args'].index(bit) idx += np.random.choice([-1, 0, 1], p=[0.5 * indpb, 1. - indpb, 0.5 * indpb]) idx = min(max(idx, 0), len(p['args']) - 1) return p['args'][idx] elif p['type'] == 'categorical': if np.random.random() < indpb: return np.random.choice(p['args']) else: return bit else: raise ValueError( 'Parameter type should be categorical, ordinal or continuous')
def mutate(individual): global mutation_mu, mutation_sigma, mutation_alpha weights, shoulder_bias, hip_bias, knee_bias, neuron_parameters, inputs = individual biases = [shoulder_bias, hip_bias, knee_bias] tools.mutGaussian(weights, mutation_mu, mutation_sigma, mutation_alpha) tools.mutGaussian(biases, mutation_mu, mutation_sigma, mutation_alpha) tools.mutGaussian(inputs, mutation_mu, mutation_sigma, mutation_alpha) for i in range(len(neuron_parameters)): tools.mutGaussian(neuron_parameters[i], mutation_mu, mutation_sigma, mutation_alpha) shoulder_bias, hip_bias, knee_bias = biases temp = [ weights, shoulder_bias, hip_bias, knee_bias, neuron_parameters, inputs ] for i in range(len(individual)): individual[i] = temp[i] return individual
def customMutation(self, ind, mu, indpb): """ Parameters ---------- ind : Deap individual mu : scalar value for gaussian mean value indpb : scalar value in [0,1] for individual gene probability of mutation Returns ------- Mutated individual Description ------ Each individual gene in in is mutated with dea mutGaussian function. Gaussian mean should be null, whereas the sigma is defined as a sequence for each guassian as required by deap mutGaussian """ # mu = [ind[i] for i in range(len(ind))] sigmaQ = [10] sigma01 = [0.2 for _ in range(len(ind))] #Assuming genes [Q, 01bounded, ... ] sigma = sigmaQ + sigma01 return tools.mutGaussian(ind, mu, sigma, indpb)
def mutate(individual): global mutation_mu, mutation_sigma, mutation_alpha weights, neuron_parameters, inputs = individual tools.mutGaussian(weights, mutation_mu, mutation_sigma, mutation_alpha) tools.mutGaussian(inputs, mutation_mu, mutation_sigma, mutation_alpha) for i in range(len(weights)): if (weights[i] > 1): weights[i] = 1 if (weights[i] < -1): weights[i] = -1 for i in range(len(neuron_parameters)): tools.mutGaussian(neuron_parameters[i], mutation_mu, mutation_sigma, mutation_alpha) temp = [weights, neuron_parameters, inputs] for i in range(len(individual)): individual[i] = temp[i] return individual
def run(self): print("run") while self.g <= self.generations: self.g = self.g + 1 print("-- Generation %i --" % self.g) offspring = self.toolbox.select(self.pop, len(self.pop)) # Clone the selected individuals offspring = list(map(self.toolbox.clone, offspring)) # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): # cross two individuals with probability CXPB re_evaluate = False for vector in ['xuv', 'ir']: if random.random() < self.CXPB: self.toolbox.mate(child1[vector], child2[vector]) re_evaluate = True if re_evaluate: del child1.fitness.values del child2.fitness.values for mutant in offspring: # mutate an individual with probability MUTPB re_evaluate = False for vector in ['xuv', 'ir']: if random.random() < self.MUTPB: self.toolbox.mutate(mutant[vector]) re_evaluate = True if re_evaluate: del mutant.fitness.values for mutant in offspring: # mutate an individual with probabililty MUTPB2 re_evaluate = False for vector in ['xuv', 'ir']: if random.random() < self.MUTPB2: # tools.mutGaussian(mutant[vector], mu=0.0, sigma=0.2, indpb=0.2) tools.mutGaussian(mutant[vector], mu=0.0, sigma=0.1, indpb=0.6) re_evaluate = True if re_evaluate: del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = [self.toolbox.evaluate(inv) for inv in invalid_ind] for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit, print(" Evaluated %i individuals" % len(invalid_ind)) # The population is entirely replaced by the offspring self.pop[:] = offspring # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in self.pop] length = len(self.pop) mean = sum(fits) / length sum2 = sum(x * x for x in fits) std = abs(sum2 / length - mean**2)**0.5 print(" Min %s" % min(fits)) print(" Max %s" % max(fits)) print(" Avg %s" % mean) print(" Std %s" % std) print("-- End of (successful) evolution -- gen {}".format( str(self.g))) best_ind = tools.selBest(self.pop, 1)[0] # plot the best individual self.calc_vecs_and_mse(best_ind, plot_and_graph=True) # return the mse of final result best_ind = tools.selBest(self.pop, 1)[0] # return self.calc_vecs_and_mse(best_ind, plot_and_graph=True) phase_retrieved = self.get_phase_curve(best_ind) # trace and trace mse recons_trace, trace_mse = self.get_trace_and_rmse(best_ind) result = dict() result["field"] = phase_retrieved result["trace"] = dict() result["trace"]["reconstructed"] = recons_trace result["trace"]["mse"] = trace_mse return result
def mut_gaussian_int(parent, mu, sigma, indpb): from deap.tools import mutGaussian mutant = mutGaussian(parent, mu, sigma, indpb) for i in range(len(mutant[0])): mutant[0][i] = int(mutant[0][i]) return mutant
def evaluate(individual): """評価関数の戻り値は必ずタプルにする""" a = sum(individual) b = len(individual) return a, 1.0 / b ind1.fitness.values = evaluate(ind1) print ind1.fitness.valid print ind1.fitness #突然変異 mutant = toolbox.clone(ind1) ind2, = tools.mutGaussian(mutant, mu=0.0, sigma=0.2, indpb=0.2) del mutant.fitness.values print ind2 is mutant print mutant is ind1 #交叉 child1, child2 = [toolbox.clone(ind) for ind in (ind1, ind2)] tools.cxBlend(child1, child2, 0.5) del child1.fitness.values del child2.fitness.values print ind1, ind2 #選択 selected = tools.selBest([child1, child2], 2)
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 launch_nsga2(env, variant, size_pop=100, pb_crossover=0.6, pb_mutation=0.3, nb_generation=1000, display=False, verbose=False): global but_atteint but_generation = None # votre code contiendra donc des tests comme suit pour gérer la différence entre ces variantes: if (variant == "FIT+NS"): creator.create("FitnessMax", base.Fitness, weights=(1.0, -1.0, 1.0)) elif (variant == "FIT"): creator.create("FitnessMax", base.Fitness, weights=(1.0, -1.0)) elif (variant == "NS"): creator.create("FitnessMax", base.Fitness, weights=(1.0, )) else: print("Variante inconnue: " + variant) IND_SIZE = 192 random.seed() #create class creator.create("FitnessMax", base.Fitness, weights=(1.0, -1.0, 1.0)) creator.create("Individual", list, fitness=creator.FitnessMax, but=float, fit=float, bd=list, novelty=float) # toolbox toolbox = base.Toolbox() toolbox.register("attr_float", np.random.normal) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=IND_SIZE) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("select", tools.selNSGA2) toolbox.register("mate", tools.cxBlend, alpha=0.3) #halloffame paretofront = tools.ParetoFront() #statistics statistics = tools.Statistics(lambda ind: ind.fitness.values) statistics.register("avg", numpy.mean) statistics.register("std", numpy.std) statistics.register("min", numpy.min) statistics.register("max", numpy.max) #log logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + statistics.fields # pour plot heatmap position_record = [] # generer la population initiale pop = toolbox.population(size_pop) # simulation for ind in pop: ind.but, ind.fit, ind.bd = simulation(env, ind, display=display) position_record.append(ind.bd) # MAJ archive if (variant == "FIT+NS") or (variant == "NS"): arc = updateNovelty(pop, pop, None) # MAJ fitness for ind in pop: ind.fitness.values = list([]) if variant == "FIT+NS" or variant == "FIT": ind.fitness.values = list(ind.fitness.values) + list( [ind.but, ind.fit]) if variant == "FIT+NS" or variant == "NS": ind.fitness.values = list(ind.fitness.values) + list([ind.novelty]) # Update the hall of fame with the generated individuals paretofront.update(pop) record = statistics.compile(pop) logbook.record(gen=0, nevals=len(pop), **record) if verbose: print(logbook.stream) means = [] mins = [] # main boucle for gen in range(1, nb_generation + 1): #print("generation ",gen) if but_atteint and but_generation == None: but_generation = gen #if gen%50 == 0: #print("generation ",gen) # Select the next generation individuals offspring = toolbox.select(pop, size_pop) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) #print(np.mean(np.array([ind.fitness.values[1] for ind in offspring]))) #print(np.min(np.array([ind.fitness.values[1] for ind in offspring]))) if (variant == "NS"): means.append( np.mean(np.array([ind.fitness.values[0] for ind in offspring]))) mins.append( np.min(np.array([ind.fitness.values[0] for ind in offspring]))) else: means.append( np.mean(np.array([ind.fitness.values[1] for ind in offspring]))) mins.append( np.min(np.array([ind.fitness.values[1] for ind in offspring]))) # crossover for child1, child2 in zip(offspring[::2], offspring[1::2]): if np.random.random() < pb_crossover: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values #mutation for mutant in offspring: if np.random.random() < pb_mutation: tools.mutGaussian(mutant, mu=0.0, sigma=1, indpb=0.1) del mutant.fitness.values # simulation invalid_inds = [ind for ind in offspring if ind.fitness.valid == False] for ind in invalid_inds: ind.but, ind.fit, ind.bd = simulation(env, ind, display=display) position_record.append(ind.bd) # MAJ archive if (variant == "FIT+NS") or (variant == "NS"): arc = updateNovelty( offspring, offspring, arc, k=15) #Update the novelty criterion (including archive update) # MAJ fitness for ind in offspring: ind.fitness.values = list([]) if variant == "FIT+NS" or variant == "FIT": ind.fitness.values = list(ind.fitness.values) + list( [ind.but, ind.fit]) if variant == "FIT+NS" or variant == "NS": ind.fitness.values = list(ind.fitness.values) + list( [ind.novelty]) # Select the next generation population pop[:] = offspring + pop # Update the hall of fame with the generated individuals paretofront.update(pop) record = statistics.compile(pop) logbook.record(gen=gen, nevals=len(pop), **record) if verbose: print(logbook.stream) if but_atteint: break return pop, logbook, paretofront, position_record, but_atteint, but_generation, means, mins
def launch_nsga2(mu=50, lambda_=50, cxpb=0.6, mutpb=0.3, ngen=1000, display=False, verbose=False): ## A completer: creator et toolbox de DEAP ## # creator creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0)) creator.create("Individual", array.array, typecode="d", fitness=creator.FitnessMin, strategy=None) creator.create("Strategy", array.array, typecode="d") #toolbox toolbox = base.Toolbox() toolbox.register("individual", generateES, creator.Individual, creator.Strategy, IND_SIZE, MIN_VALUE, MAX_VALUE, MIN_STRATEGY, MAX_STRATEGY) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("mate", tools.cxESBlend, alpha=0.1) toolbox.register("mutate", tools.mutESLogNormal, c=1.0, indpb=0.1) toolbox.register("select", tools.selNSGA2, k=lambda_) toolbox.register("evaluate", benchmarks.schaffer_mo) random.seed() population = toolbox.population(n=mu) 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 []) ## A completer: évaluation des individus et mise à jour de leur 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 #====================================== # display the generation of random individuals paretofront = tools.ParetoFront() if display: plot_pop_pareto_front(population, [], "Gen: %d" % (0)) if paretofront is not None: paretofront.update(population) #print("Pareto Front: "+str(paretofront)) 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): ## A completer, génération des 'offspring' et sélection de la nouvelle population # Select the next generation individuals offspring = toolbox.select(population) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # crossover for child1, child2 in zip(offspring[::2], offspring[1::2]): if np.random.random() < cxpb: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values #mutation for mutant in offspring: if np.random.random() < mutpb: tools.mutGaussian(mutant, mu=0.0, sigma=1, indpb=0.1) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Update the hall of fame with the generated individuals if paretofront is not None: paretofront.update(offspring) if display: plot_pop_pareto_front(population, paretofront, "Gen: %d" % (gen)) # 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) population[:] = offspring + population return population, logbook, paretofront
toolbox.register("population_seed", initPopulation, pop_size=POP_SIZE, indv=toolbox.individual, num_bars=NUM_BARS) pop = toolbox.population_seed() print(pop[0].fitness.valid) print(pop[0].fitness) i1 = pop[0] def evaluate(individual): return (sum(individual), ) fitness_i1 = evaluate(i1) i1.fitness.values = fitness_i1 i2, = tools.mutGaussian(i1, mu=0.0, sigma=0.2, indpb=0.2) i3 = pop[3] i4 = pop[4] print(i3) tools.cxBlend(i3, i4, 0.5) print(i3) #very light weight wrapper, that then deals with some of the messy computation for me and forces me to stage the computation correctly
def genetic(rts, cpus): def func_X(a, b): """ length of messages transmitted from a towards b or from b towards a """ comm_load = 0 if "p" in a: for p in a["p"]: if p["id"] == b["id"]: comm_load += p["payload"] # This part consideres incoming msgs from other tasks (so that task is the successor, b->a) # if "p" in b: # for p in b["p"]: # if p["id"] == a["id"]: # comm_load += p["payload"] return comm_load def func_Y(i, rts): """ load of the communication control network that the task i produces """ comm_load = 0 other_tasks = [t for t in rts if t is not i] for j in other_tasks: comm_load += func_X(i, j) return comm_load def func_Xc(cpu_h, cpu_k): """ length of all messages (in bytes) to be transmitted between processors h and k through the network """ summ = 0 for task_h in cpu_h["tasks"]: for task_j in cpu_k["tasks"]: summ += func_X(task_h, task_j) return summ def func_Vp(cpus): """ total amount of information to be transferred over the network """ summ = 0 for cpu in cpus.values(): other_cpus = [c for c in cpus.values() if c is not cpu] for other_cpu in other_cpus: summ += func_Xc(cpu, other_cpu) return summ def func_B(rts): """ Total amount of data to be transferred between predecessor and successors throught the network """ summ = 0 for task in rts: summ += func_Y(task, rts) return summ def func_cost_p(rts, cpus): return func_Vp(cpus) / func_B(rts) # initialization n_p = 128 # number of generations n_g = 16 # population pc = 0.5 # crossover probability pm = 0.001 # mutation probability m = len(rts) # tasks n = len(cpus) # processors B = func_B(rts) # total of data to be transferred between predecessor and successor W = 70 # network bandwith in bytes/slot Dmin = min([t["d"] for t in rts]) # minimum deadline WDmin = W * Dmin # generate first chromosome chromosome1 = [] for task in rts: g = func_Y(task, rts) * int(random.uniform(0,1) * m) chromosome1.append(g) # the dict stores the cpus tasks lists chromosomes = [(chromosome1, dict())] # generate remain population for _ in range(n_g - 1): new_chromosome = [] nu = max(chromosome1) / 10 for g1 in chromosome1: g2 = g1 + random.uniform(-nu, nu) new_chromosome.append(g2) chromosomes.append((new_chromosome, dict())) # initialize the dict associated with each chromosome for _, cpus_alloc in chromosomes: for cpu_id in cpus.keys(): cpus_alloc[cpu_id] = {"tasks":[], "uf":0} # tasks assigned to this cpu # aux for reordering and other stuff chromosomes_stack = [] # do generations for _ in range(n_p): chromosomes_stack.clear() # A stack is assembled containing the tasks ordered by the value of its allele in decreasing order. for item in chromosomes: chromosome, cpus_alloc = item[0], item[1] task_stack = [] for task_id, allele in enumerate(chromosome): task_stack.append((allele, rts[task_id])) task_stack.sort(key=lambda allele: allele[0], reverse=True) # clear previous task assignation for cpu in cpus_alloc.values(): cpu["tasks"].clear() # aux -- for easy sorting cpu_stack = [cpu for cpu in cpus_alloc.values()] # partition for _, max_task in task_stack: if "cpu" in max_task: cpu_id = max_task["cpu"] cpus_alloc[cpu_id]["tasks"].append(max_task) else: # create auxiliary stack with all task j that communicate with i aux_stack = [] # add the succesors if "p" in max_task: for p in max_task["p"]: for task in rts: if task["id"] == p["id"]: aux_stack.append((func_Y(task, rts), task)) # add other tasks that communicate with the task (the task will be the succesor) #for task in [t for t in rts if t is not max_task]: # if "p" in task: # for p in task["p"]: # if p["id"] == max_task["id"]: # aux_stack.append((func_Y(task, rts), task)) cpu_a = None # order by func_y if aux_stack: aux_stack.sort(key=lambda t: t[0], reverse=True) aux_max_task = aux_stack[0] # find the cpu at which the aux_max_task is allocated for cpu in cpus_alloc.values(): if aux_max_task in cpu["tasks"]: cpu_a = cpu #if not aux_stack or cpu_a is None: if cpu_a is None: # update uf factors and allocate task to cpu with min uf for cpu in cpus_alloc.values(): cpu["uf"] = sum([t["uf"] for t in cpu["tasks"]]) cpu_stack.sort(key=lambda c: c["uf"]) cpu_stack[0]["tasks"].append(max_task) else: cpu_a["tasks"].append(max_task) # apply the cost function to the chromosomes chromosomes_stack.append((func_cost_p(rts, cpus_alloc), chromosome)) # evaluation, cost and fitness # elistist selection -- for the sake of simplicity, separate the first two chromosomes as the 'best' chromosomes_stack.sort(key=lambda c: c[0]) # order by ascending value chromosomes_stack = chromosomes_stack[2:] # apply roulette selection on the rest -- an apply crossover sum_fitness = sum([c[0] for c in chromosomes_stack]) # sum of all fitness values (cost function result) chromosomes_stack = [(c[0] / sum_fitness, c[1]) for c in chromosomes_stack] # normalization # calculate probabilities sum_prob = 0 probs = [] for fitness, c in chromosomes_stack: prob = sum_prob + fitness probs.append(prob) sum_prob += fitness # perform crossover for _ in range(int(n_g / 2)): cs = [] # selected chromosomes for s in range(2): r = random.uniform(0,1) for idx, p in enumerate(probs): if r < p: cs.append(chromosomes_stack[idx][1]) # uses radint() function for selecting a crossover point tools.cxOnePoint(cs[0], cs[1]) # mutate for c in chromosomes_stack: tools.mutGaussian(c[1], pm, pm, pm) # memory constraint verification for idx, chromosome in enumerate(chromosomes): print("Chromosome {0}".format(idx)) valid_cpu = True ch_cpus = chromosome[1] for cpuid, cpu in ch_cpus.items(): if cpus[cpuid]["capacity"] < sum([t["r"] for t in cpu["tasks"]]): valid_cpu = False if valid_cpu: print_results(rts, chromosome[1]) else: print(" -- Invalid assignation found.") # bandwidth constraint bw_ok = B <= WDmin return
def es(env, size_pop=50, lambda_=100, pb_crossover=0.6, pb_mutation=0.5, nb_generation=100, display=False, verbose=False): IND_SIZE = 171 random.seed() #create class creator.create("FitnessMax", base.Fitness, weights=(-1.0, -1.0)) creator.create("Individual", list, fitness=creator.FitnessMax) # toolbox toolbox = base.Toolbox() toolbox.register("attr_float", np.random.normal) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=IND_SIZE) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("select", tools.selNSGA2, k=lambda_) toolbox.register("mate", tools.cxBlend, alpha=0.1) #statistics statistics = tools.Statistics(lambda ind: ind.fitness.values) statistics.register("avg", numpy.mean) statistics.register("std", numpy.std) statistics.register("min", numpy.min) statistics.register("max", numpy.max) #log logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + statistics.fields #pareto paretofront = tools.ParetoFront() # generer la population initiale pop = toolbox.population(size_pop) # evaluation for ind in pop: ind.fitness.values = eval_nn(env, ind) # display if display: plot_pop_pareto_front(pop, [], "Gen: %d" % (0)) # Update the hall of fame with the generated individuals if paretofront is not None: paretofront.update(pop) record = statistics.compile(pop) logbook.record(gen=0, nevals=len(pop), **record) if verbose: print(logbook.stream) for gen in range(1, nb_generation + 1): print("generation ", gen) # Select the next generation individuals offspring = toolbox.select(pop) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # crossover for child1, child2 in zip(offspring[::2], offspring[1::2]): if np.random.random() < pb_crossover: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values #mutation for mutant in offspring: if np.random.random() < pb_mutation: tools.mutGaussian(mutant, mu=0.0, sigma=1, indpb=0.1) del mutant.fitness.values # evaluation invalid_inds = [ind for ind in offspring if ind.fitness.valid == False] for ind in invalid_inds: ind.fitness.values = eval_nn(env, ind) # remplacement pop[:] = offspring + pop # Update the pareto with the generated individuals if paretofront is not None: paretofront.update(pop) if display: plot_pop_pareto_front(pop, paretofront, "Gen: %d" % (gen)) record = statistics.compile(pop) logbook.record(gen=gen, nevals=len(pop), **record) if verbose: print(logbook.stream) return pop, logbook, paretofront
def mut(individual, low, up, mu, sigma, indpb): ''' Procedimento de mutação de um indivíduo ''' tools.mutGaussian(individual, mu, sigma, indpb) clipIndividual(individual, low, up)
def es(env, size_pop=50, pb_crossover=0.6, pb_mutation=0.3, nb_generation=100, display=False, verbose=True): from deap import base from deap import creator from deap import tools import numpy import numpy as np IND_SIZE = 61 #create class creator.create("FitnessMax", base.Fitness, weights=(1.0, )) creator.create("Individual", list, fitness=creator.FitnessMax) # toolbox toolbox = base.Toolbox() toolbox.register("attr_float", np.random.normal) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=IND_SIZE) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("select", tools.selTournament, tournsize=5) toolbox.register("mate", tools.cxBlend, alpha=0.1) #statistics halloffame = tools.HallOfFame(1) statistics = tools.Statistics(lambda ind: ind.fitness.values) statistics.register("avg", numpy.mean) statistics.register("std", numpy.std) statistics.register("min", numpy.min) statistics.register("max", numpy.max) #log logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + statistics.fields # generer la population initiale pop = toolbox.population(size_pop) # evaluation for ind in pop: ind.fitness.values = eval_nn(env, ind) # Update the hall of fame with the generated individuals halloffame.update(pop) record = statistics.compile(pop) logbook.record(gen=0, nevals=len(pop), **record) if verbose: print(logbook.stream) for gen in range(1, nb_generation + 1): print("generation ", gen) # Select the next generation individuals offspring = toolbox.select(pop, size_pop) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # crossover for child1, child2 in zip(offspring[::2], offspring[1::2]): if np.random.random() < pb_crossover: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values #mutation for mutant in offspring: if np.random.random() < pb_mutation: tools.mutGaussian(mutant, mu=0.0, sigma=1, indpb=0.1) del mutant.fitness.values # evaluation invalid_inds = [ind for ind in offspring if ind.fitness.valid == False] for ind in invalid_inds: ind.fitness.values = eval_nn(env, ind) # remplacement pop[:] = offspring # Update the hall of fame with the generated individuals halloffame.update(pop) record = statistics.compile(pop) logbook.record(gen=gen, nevals=len(pop), **record) if verbose: print(logbook.stream) return pop, logbook, halloffame
def timeMutation(timeSequence, sigma, mu, indpb): ret = tools.mutGaussian(timeSequence, mu, sigma, indpb) return ret[0][0]/2
0.25)) # Keep 25% best in population rand = tools.selRandom(pop, int(POP_SIZE * 0.5)) # randomly select 50% to crossover new = toolbox.population(n=int( POP_SIZE * 0.25)) # introduce 25% of new randomness into population # print(len(winners)) # print(len(rand)) # print(len(new)) # SELECT WINNERS winners = toolbox.clone(winners) for w in winners: del w.fitness.values mutant = toolbox.clone(w) mutant = tools.mutGaussian(mutant, mu=0.0, sigma=0.1, indpb=0.2) pop_new.append(mutant[0]) # SELECT RANDOM AND CROSSOVER rand = toolbox.clone(rand) for r in rand: del r.fitness.values rand1 = rand[:int((POP_SIZE * 0.5) / 2)] rand2 = rand[int((POP_SIZE * 0.5) / 2):] for r1, r2 in zip(rand1, rand2): child1, child2 = tools.cxUniform(r1, r2, 0.25) pop_new.append(child1) pop_new.append(child2) for n in new:
def evolution(self): start = time.time() CXPB, MUTPB = 0.3, 0.2 creator.create("FitnessMin", base.Fitness, weights=(-1.0, )) creator.create("Individual", np.ndarray, fitness=creator.FitnessMin) toolbox = base.Toolbox() toolbox.register("individual", tools.initRepeat, creator.Individual, np.random.random, self.model.numParam) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register( "evaluate", evaluate, model=self.model ) #toolbox.register("evaluate", models.objfunc(self.model.evaluate)) toolbox.register("mate", tools.cxTwoPoint) toolbox.register("mutate", tools.mutPolynomialBounded, indpb=1, eta=0, low=self.lb, up=self.ub) toolbox.register("select", tools.selTournament, tournsize=self.numParents / 20) tools.mutGaussian() print("Start evolution") start = time.time() population = toolbox.population(n=self.numParents) fitnesses = list(map(toolbox.evaluate, population)) report = np.zeros([self.numGeneration, 7]) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in population] lastScore = np.min(fits) meanScore = np.mean(fits) std = np.std(fits) lap = time.time() - start stall = 0 print(" Evaluated %i individuals", len(population)) print( 'Generation \t evaluate \t Best f(x) \t Mean f(x) \t std \t\t lap (sec) \t StallGen' ) print('%d \t\t %d \t\t %10f \t %10f \t %10f \t %10f \t %d', (0, len(population), lastScore, meanScore, std, lap, stall)) report[0, :] = np.array( [0, len(population), lastScore, meanScore, std, lap, stall]) # Begin the evolution for generation in range(self.numGeneration): start = time.time() offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring)) for child1, child2 in zip(offspring[0::2], offspring[1::2]): # cross two individuals with probability CXPB if np.random.random() < CXPB: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values for mutant in offspring: # mutate an individual with probability MUTPB if np.random.random() < MUTPB: toolbox.mutate(mutant) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # The population is entirely replaced by the offspring population[:] = offspring # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in population] bestScore = min(fits) std = np.std(fits) if bestScore < lastScore: stall = 0 lastScore = bestScore else: stall = stall + 1 lap = time.time() - start print('%d \t\t %d \t\t %10f \t %10f \t %10f \t %10f \t %d', (generation + 1, len(invalid_ind), bestScore, np.mean(fits), std, lap, stall)) report[0, :] = np.array( [0, len(invalid_ind), bestScore, meanScore, std, lap, stall]) print("-- End of (successful) evolution --") best_ind = tools.selBest(population, 1)[0] print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values)) return best_ind, best_ind.fitness.values, report