def generate(self, init_ind): if self.population is not None: new_pop = tools.selNSGA2(self.population, self.population_size) for i in range(len(new_pop)): decision = np.random.rand() if decision < self.cXp: c_output = np.argmax( [self.acc_args, self.mse_args, self.id_args]) #print(c_output) elif decision < self.cXp + self.mtp: new_pop[i] = init_ind( mutation( new_pop[i], np.argmin([ self.acc_args, self.mse_args, self.id_args ]), self.ev_hypers, self.max_net, self.max_con, self.max_lay, self.no_drop, self.no_batch)) else: new_pop = [ self.init_individual(init_ind, self.no_batch, self.no_drop) for _ in range(self.population_size) ] return new_pop
def _prepare_stage2(self, w_ssv): """ Prepare NSGA-II. Mainly to assign the crowding distance for the first time. """ # individuals that have been changed due to mutation or crossover invalid_pop = [ind for ind in self.population if not ind.fitness.valid] self._compile(invalid_pop) if self.stable_states is not None: self._count_stable_state_violations(invalid_pop) self._count_num_regulators(self.population) self.stage = 2 # three objective GP FitnessMin.weights = (-1.0, -1.0, -1.0) self.toolbox.register('select', tools.selTournamentDCD) self.toolbox.register('mutate', self._mutate, expr=self.toolbox.expr_mut, pset=self.pset) # evaluate: each individual has its own best collaboration from the collaboration pool best_collaborations = list( self.toolbox.map(self.toolbox.evaluate, self.population)) for ind, best_collaboration in zip(self.population, best_collaborations): ind.fitness.values = best_collaboration.fitness.values # Just assign the crowding distance for the first time, `fitness.crowding_dist`, which is required in selDCD self.population = tools.selNSGA2(self.population, len(self.population)) self.hof_stage2.update(best_collaborations) self._update_best_collaboration_history(best_collaborations) self.best_global_fitness = max( self.population, key=lambda ind: ind.fitness).fitness.values[0]
def orderAllPopulation(population): def getKey(item): #return fitnessValuesOrdered.index([item[2], item[3]]) for i in range(len(fitnessValuesOrdered)): if item[2] == fitnessValuesOrdered[i].fitness.values[ 0] and item[3] == fitnessValuesOrdered[ i].fitness.values[1]: return i fitness = [] fitnessValues = [] for i in range(len(population)): for j in range(len(population[i])): fitnessCalc0 = functions[0](population[i][j]) fitnessCalc1 = functions[1](population[i][j]) fitness.append([i, j, fitnessCalc0, fitnessCalc1]) fitnessValues.append([fitnessCalc0, fitnessCalc1]) pop = toolbox.population(n=len(functions) * numberOfIslands) i = 0 for ind in pop: ind.fitness.values = fitnessValues[i] i = i + 1 fitnessValuesOrdered = tools.selNSGA2(pop, len(functions) * numberOfIslands) fitnessOrdered = sorted(fitness, key=getKey) return fitnessOrdered
def getNewValidAssignment(alloc, node_status, archive, **kwargs): nNodes = kwargs['nNodes'] network_creator = topologies.network_topologies[kwargs['network_creator']] nTasks = kwargs['nTasks'] task_creator = topologies.task_topologies[kwargs['task_creator']] energy_list = kwargs['energy_list_sim'] networkGraph = network_creator(energy_list=energy_list, **kwargs) taskGraph = task_creator(networkGraph, **kwargs) aliveGraph = network_creator(energy_list=energy_list, **kwargs) remove_dead_nodes(aliveGraph, energy_list, energy_only=True, **kwargs) if len(archive) > 0: valid_archive = [ x for x in archive if checkIfAllocValid(x, node_status) ] if len(valid_archive) > 0: return tools.selNSGA2(valid_archive, 1)[0] nodes = list(aliveGraph.nodes()) tasks = list(taskGraph.nodes()) new_alloc = [] for i, x in enumerate(alloc): if not (node_status[x]): #alloc invalid, change: try: valid_nodes = tasks[i].get_constrained_nodes(aliveGraph) enabled_valid_nodes = [] for valid_node in valid_nodes: if node_status[nodes.index(valid_node)]: enabled_valid_nodes.append(valid_node) except exceptions.NoValidNodeException as e: print( "Could not find a valid node for a task while adjusting faulty assignment" ) raise e if len(enabled_valid_nodes) == 0: print( "no enabled valid node while adjusting faulty assignment") raise exceptions.NoValidNodeException cur_node = nodes[x] new_node = None dist = np.inf for node in enabled_valid_nodes: new_dist = la.norm(node.pos - cur_node.pos) if new_dist < dist: dist = new_dist new_node = node if node is None: print( "No node closer than inf found while adjusting faulty assignment" ) raise exceptions.NoValidNodeException new_alloc.append(nodes.index(new_node)) else: new_alloc.append(x) if kwargs['verbose']: print(f"new valid alloc: {new_alloc}") return new_alloc
def selectPareto(pop, initialind): """ Select Pareto Optimal individuals in the population An individual is considered Pareto optimal if there exist no other individual by whom it is dominated in any of the objective functions. :param pop: list of individuals :param gv: global variables :type pop: list :type gv: class :return: list of selected individuals :rtype: list """ selectedInd = [] selectedInd = tools.selNSGA2(pop, initialind) return selectedInd
def _combined_selection_operator(self, individuals, k): """Perform NSGA2 selection on the population according to their Pareto fitness Parameters ---------- individuals: list A list of individuals to perform selection on k: int The number of individuals to return from the selection phase Returns ------- fitness: list Returns a list of individuals that were selected """ return tools.selNSGA2(individuals, int(k / 5.)) * 5
def printStatistics(population, OriginalFile, topk=1): Original = numpy.matrix(parser.read(OriginalFile)) #top_inds = population top_inds = tools.selNSGA2(population, k=topk) i = 0 for top_ind in top_inds: conf = statistics.Conf(top_ind[0], Original) accs = statistics.Accs(top_ind[0], Original) roleCnt = statistics.RoleCnt(top_ind[0]) urCnt = statistics.URCnt(top_ind[0]) rpCnt = statistics.RPCnt(top_ind[0]) print("\nTOP INDIVIDUAL: " + str(i)) print("conf: " + str(conf)) print("accs: " + str(accs)) print("roleCnt: " + str(roleCnt)) print("urCnt: " + str(urCnt)) print("rpCnt: " + str(rpCnt)) i += 1
def selNSGA2(problem, population, selectees, k): # Evaluate any new guys for individual in population+selectees: if not individual.valid: individual.evaluate() # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, population+selectees) # Combine dIndividuals = tools.selNSGA2(dIndividuals, k) # Copy from DEAP structure to JMOO structure population = [] for i,dIndividual in enumerate(dIndividuals): cells = [] for j in range(len(dIndividual)): cells.append(dIndividual[j]) population.append(jmoo_individual(problem, cells, dIndividual.fitness.values)) return population,k
def selNSGA2(problem, population, selectees, k): # Evaluate any new guys for individual in population + selectees: if not individual.valid: individual.evaluate() # Format a population data structure usable by DEAP's package dIndividuals = deap_format(problem, population + selectees) # Combine dIndividuals = tools.selNSGA2(dIndividuals, k) # Copy from DEAP structure to JMOO structure population = [] for i, dIndividual in enumerate(dIndividuals): cells = [] for j in range(len(dIndividual)): cells.append(dIndividual[j]) population.append( jmoo_individual(problem, cells, dIndividual.fitness.values)) return population, k
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 solve(self): """Method to perform NSGA-II using DEAP tools Parameters ---------- self : OptiGenAlgNsga2Deap Solver to perform NSGA-II Returns ------- multi_output : OutputMultiOpti class containing the results """ logger = self.get_logger() # Check input parameters self.check_optimization_input() # Display information try: filename = self.get_logger().handlers[0].stream.name print( "{} Starting optimization... \n\tLog file: {}\n\tNumber of generations: {}\n\tPopulation size: {}\n" .format( datetime.now().strftime("%H:%M:%S"), filename, self.nb_gen, self.size_pop, )) except (AttributeError, IndexError): print( "{} Starting optimization...\n\tNumber of generations: {}\n\tPopulation size: {}\n" .format(datetime.now().strftime("%H:%M:%S"), self.nb_gen, self.size_pop)) try: # Keep number of evalutation to create the shape shape = self.size_pop # Create the toolbox self.create_toolbox() # Add the reference output to multi_output if isinstance(self.problem.simu.parent, Output): xoutput = XOutput(init_dict=self.problem.simu.parent.as_dict()) else: xoutput = XOutput(simu=self.problem.simu.copy()) self.xoutput = xoutput # Fitness symbol fitness_symbol = [of.symbol for of in self.problem.obj_func] # Set-up output data as list to be changed into ndarray at the end of the optimization paramexplorer_value = [] xoutput.xoutput_dict["ngen"] = DataKeeper(name="Generation number", symbol="ngen") xoutput.xoutput_dict["is_valid"] = DataKeeper( name="Individual validity", symbol="is_valid") # Add datakeeper to XOutput to store additionnal values for dk in self.problem.datakeeper_list: assert dk.symbol not in xoutput.xoutput_dict xoutput.xoutput_dict[dk.symbol] = dk # Put objective functions in XOutput for obj_func in self.problem.obj_func: # obj_func is a DataKeeper instance xoutput.xoutput_dict[obj_func.symbol] = obj_func # Create the first population pop = self.toolbox.population(self.size_pop) # Evaluate the population nb_error = 0 for i in range(0, self.size_pop): time = datetime.now().strftime("%H:%M:%S") print_gen_simu(time, 0, i, self.size_pop, nb_error, pop) nb_error += evaluate(self, pop[i]) print_obj(self.problem.obj_func, pop[i]) # Check the constraints violation nb_infeasible = 0 if len(self.problem.constraint) > 0: time = datetime.now().strftime("%H:%M:%S") for indiv in pop: nb_infeasible += check_cstr(self, indiv) == False print("\r{} gen {:>5}: Finished, {:>4} errors,{:>4} infeasible.\n". format(time, 0, nb_error, nb_infeasible)) # Add pop to XOutput for indiv in pop: # Check that at every fitness values is different from inf is_valid = indiv.is_simu_valid and indiv.cstr_viol == 0 if self.is_keep_all_output: xoutput.output_list.append(indiv.output) # is_valid xoutput.xoutput_dict["is_valid"].result.append(is_valid) # Design variable values paramexplorer_value.append(list(indiv)) # Add fitness values to DataKeeper for i, symbol in enumerate(fitness_symbol): xoutput.xoutput_dict[symbol].result.append( indiv.fitness.values[i]) # ngen xoutput.xoutput_dict["ngen"].result.append(0) if self.selector == None: pop = selNSGA2(pop, self.size_pop) else: parents = self.selector(pop, self.size_pop) ############################ # LOOP FOR EACH GENERATION # ############################ for ngen in range(1, self.nb_gen): # Extracting parents using parents = tournamentDCD(pop, self.size_pop) # Copy new indivuals children = [] for indiv in parents: child = self.toolbox.individual() for i in range(len(indiv)): child[i] = deepcopy(indiv[i]) child.output = indiv.output.copy() child.fitness = deepcopy(indiv.fitness) children.append(child) for indiv1, indiv2 in zip(children[::2], children[::-2]): # Crossover is_cross = self.cross(indiv1, indiv2) # Mutation is_mutation = self.mutate(indiv1) if is_cross or is_mutation: update(indiv1) is_mutation = self.mutate(indiv2) if is_cross or is_mutation: update(indiv2) # Evaluate the children to_eval = [] for indiv in children: if indiv.fitness.valid == False: to_eval.append(indiv) shape += len(to_eval) nb_error = 0 for i in range(len(to_eval)): time = datetime.now().strftime("%H:%M:%S") print_gen_simu(time, ngen, i, self.size_pop, nb_error, to_eval) nb_error += evaluate(self, to_eval[i]) print_obj(self.problem.obj_func, to_eval[i]) # Check the constraints violation nb_infeasible = 0 if len(self.problem.constraint) > 0: time = datetime.now().strftime("%H:%M:%S") for indiv in to_eval: nb_infeasible += check_cstr(self, indiv) == False print( "\r{} gen {:>5}: Finished, {:>4} errors,{:>4} infeasible.\n". format(time, ngen, nb_error, nb_infeasible)) # Add pop to XOutput for indiv in to_eval: # Check that at every fitness values is different from inf is_valid = indiv.is_simu_valid and indiv.cstr_viol == 0 if self.is_keep_all_output: xoutput.output_list.append(indiv.output) # is_valid xoutput.xoutput_dict["is_valid"].result.append(is_valid) # Design variable values paramexplorer_value.append(list(indiv)) # Fitness values for i, symbol in enumerate(fitness_symbol): xoutput.xoutput_dict[symbol].result.append( indiv.fitness.values[i]) # ngen xoutput.xoutput_dict["ngen"].result.append(ngen) # Sorting the population according to NSGA2 if self.selector == None: pop = selNSGA2(pop + children, self.size_pop) else: pop = self.selector(pop, self.size_pop) # Change xoutput variables in ndarray paramexplorer_value = np.array(paramexplorer_value) # Storing number of simulations xoutput.nb_simu = shape # Save design variable values in ParamExplorerSet for i, param_explorer in enumerate(self.problem.design_var): if param_explorer._setter_str is None: setter = param_explorer._setter_func else: setter = param_explorer._setter_str xoutput.paramexplorer_list.append( ParamExplorerSet( name=param_explorer.name, unit=param_explorer.unit, symbol=param_explorer.symbol, setter=setter, value=paramexplorer_value[:, i].tolist(), )) # Delete toolbox so that classes created with DEAP remains after the optimization self.delete_toolbox() return xoutput except KeyboardInterrupt: # Except keybord interruption to return the results already computed logger.info("Interrupted by the user.") # Change xoutput variables in ndarray paramexplorer_value = np.array(paramexplorer_value) # Storing number of simulations xoutput.nb_simu = shape # Save design variable values in ParamExplorerSet for i, param_explorer in enumerate(self.problem.design_var): xoutput.paramexplorer_list.append( ParamExplorerSet( name=param_explorer.name, unit=param_explorer.unit, symbol=param_explorer.symbol, setter=param_explorer.setter, value=paramexplorer_value[:, i].tolist(), )) # Delete toolbox so that classes created with DEAP remains after the optimization self.delete_toolbox() return xoutput except Exception as err: logger.error("{}: {}".format(type(err).__name__, err)) raise err
def GAEEII_IVFm(data, dimensions, number_endmembers): start_time = time.time() number_rows = int(dimensions[0]) number_columns = int(dimensions[1]) number_bands = int(dimensions[2]) number_pixels = number_rows * number_columns sigma_MAX = max(number_rows, number_generations) data_proj = numpy.asarray(affine_projection(data, number_endmembers)) creator.create("max_fitness", base.Fitness, weights=(-1.0, -1.0)) creator.create("individual", list, fitness=creator.max_fitness) toolbox = base.Toolbox() toolbox.register("create_individual", generate_individual, creator, number_endmembers, number_pixels, number_rows, number_columns) toolbox.register("initialize_population", tools.initRepeat, list, toolbox.create_individual) toolbox.register("evaluate_individual", multi_fitness, data=data, data_proj=data_proj, number_endmembers=number_endmembers) toolbox.register("cross_twopoints", tools.cxTwoPoint) toolbox.register("selNSGA2", tools.selNSGA2) toolbox.register("gaussian_mutation_op", tools.mutGaussian, mu=0, sigma=0, indpb=mutation_probability) toolbox.register("gaussian_mutation", gaussian_mutation, toolbox=toolbox, number_rows=number_rows, number_columns=number_columns) toolbox.register("random_mutation", random_mutation, number_pixels=number_pixels, number_endmembers=number_endmembers, mutation_probability=mutation_probability) population = toolbox.initialize_population(n=population_size) population_fitnesses = [ toolbox.evaluate_individual(individual) for individual in population ] for individual, fitness in zip(population, population_fitnesses): individual.fitness.values = fitness hof = tools.HallOfFame(3) hof.update(population) current_generation = 0 current_sigma = sigma_MAX generations_fitness_1 = [] generations_fitness_2 = [] generations_population = [] stop_criteria = deque(maxlen=5) stop_criteria.extend([1, 2, 3, 4, 5]) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean, axis=0) stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" record = stats.compile(population) logbook.record(gen=0, evals=len(population), **record) while current_generation < number_generations and numpy.var( numpy.array(stop_criteria)) > 0.000001: toolbox.unregister("gaussian_mutation_op") toolbox.register("gaussian_mutation_op", tools.mutGaussian, mu=0, sigma=current_sigma, indpb=mutation_probability) offspring = tools.selRandom(population, k=int(population_size / 2)) offspring = list(map(toolbox.clone, offspring)) # Crossing for child_1, child_2 in zip(offspring[::2], offspring[1::2]): if random.random() < crossing_probability: toolbox.cross_twopoints(child_1, child_2) del child_1.fitness.values del child_2.fitness.values # Mutation for mutant in offspring: if random.random() < mutation_probability: toolbox.gaussian_mutation(mutant) del mutant.fitness.values # Fitness offspring_fitnesses = [ toolbox.evaluate_individual(individual) for individual in offspring ] for individual, fitness in zip(offspring, offspring_fitnesses): individual.fitness.values = fitness # In Vitro Fertilization Module ivfoffspring = list(map(toolbox.clone, population)) ivffits = [ind.fitness.values[0] for ind in ivfoffspring] fatheridx = numpy.argmax(ivffits) # fatherfit = numpy.max(ivffits) father = creator.individual(ivfoffspring[fatheridx].copy()) for ind in ivfoffspring[::2]: toolbox.random_mutation(ind) del ind.fitness.values for child1 in ivfoffspring: child2 = creator.individual(father.copy()) toolbox.cross_twopoints(child1, child2) del child1.fitness.values del child2.fitness.values ivffitnesses = [ toolbox.evaluate_individual(ind) for ind in ivfoffspring ] for ind, fit in zip(ivfoffspring, ivffitnesses): ind.fitness.values = fit popmax = max(offspring_fitnesses) for ind in ivfoffspring: if (ind.fitness.values >= popmax): population.append(ind) new_population = population + offspring # Selection selected = toolbox.selNSGA2(new_population, population_size) selected = list(map(toolbox.clone, selected)) population[:] = selected hof.update(population) record = stats.compile(population) logbook.record(gen=current_generation, evals=len(population), **record) # print(logbook.stream) # Statistics fits_1 = [ind.fitness.values[0] for ind in population] fits_2 = [ind.fitness.values[1] for ind in population] mean_1_offspring = sum(fits_1) / len(population) mean_2_offspring = sum(fits_2) / len(population) generations_fitness_1.append(numpy.log10(mean_1_offspring)) generations_fitness_2.append(numpy.log(mean_2_offspring)) stop_criteria.append(numpy.log10(mean_1_offspring)) generations_population.append(population.copy()) current_generation += 1 current_sigma = sigma_MAX / ((current_generation + 1) / 1.5) best_individual = tools.selNSGA2(population, 1)[0] # print('Result:', multi_fitness(best_individual,data, data_proj, number_endmembers)) M = data[:, best_individual] duration = time.time() - start_time return M, duration, [ generations_fitness_1, generations_fitness_2, generations_population, current_generation ]
def solve(self): """Method to perform NSGA-II using DEAP tools Parameters ---------- self : OptiGenAlgNsga2Deap Solver to perform NSGA-II Returns ------- multi_output : OutputMultiOpti class containing the results """ # Check input parameters self.check_optimization_input() try: # Create the toolbox self.create_toolbox() # Add the design variable names self.multi_output.design_var_names = list( self.problem.design_var.keys()) self.multi_output.design_var_names.sort() # Add the fitness names self.multi_output.fitness_names = list(self.problem.obj_func.keys()) self.multi_output.fitness_names.sort() # Add the reference output to multi_output self.multi_output.output_ref = self.problem.output # Create the first population pop = self.toolbox.population(self.size_pop) # Start of the evaluation of the generation time_start_gen = datetime.now().strftime("%H:%M:%S") # Evaluate the population nb_error = 0 for i in range(0, self.size_pop): nb_error += evaluate(self, pop[i]) print( "\r{} gen {:>5}: {:>5.2f}%, {:>4} errors.".format( time_start_gen, 0, (i + 1) * 100 / self.size_pop, nb_error), end="", ) # Check the constraints violation nb_infeasible = 0 if len(self.problem.constraint) > 0: for indiv in pop: nb_infeasible += check_cstr(self, indiv) == False print("\r{} gen {:>5}: 100%, {:>4} errors,{:>4} infeasible.".format( time_start_gen, 0, nb_error, nb_infeasible - nb_error)) # Add pop to OutputMultiOpt for indiv in pop: # Check that at every fitness values is different from inf is_valid = (indiv.fitness.valid and indiv.is_simu_valid and indiv.cstr_viol == 0) # Add the indiv to the multi_output self.multi_output.add_evaluation(indiv.output, is_valid, list(indiv), indiv.fitness.values, 0) if self.selector == None: pop = selNSGA2(pop, self.size_pop) else: parents = self.selector(pop, self.size_pop) ############################ # LOOP FOR EACH GENERATION # ############################ for ngen in range(1, self.nb_gen): time_start_gen = datetime.now().strftime("%H:%M:%S") # Extracting parents using parents = tournamentDCD(pop, self.size_pop) # Copy new indivuals children = [] for indiv in parents: child = self.toolbox.individual() for i in range(len(indiv)): child[i] = deepcopy(indiv[i]) child.output = Output(init_dict=indiv.output.as_dict()) child.fitness = deepcopy(indiv.fitness) children.append(child) for indiv1, indiv2 in zip(children[::2], children[::-2]): # Crossover is_cross = self.cross(indiv1, indiv2) # Mutation is_mutation = self.mutate(indiv1) if is_cross or is_mutation: update(indiv1) is_mutation = self.mutate(indiv2) if is_cross or is_mutation: update(indiv2) # Evaluate the children to_eval = [] for indiv in children: if indiv.fitness.valid == False: to_eval.append(indiv) nb_error = 0 for i in range(len(to_eval)): nb_error += evaluate(self, to_eval[i]) print( "\r{} gen {:>5}: {:>5.2f}%, {:>4} errors.".format( time_start_gen, ngen, (i + 1) * 100 / len(to_eval), nb_error), end="", ) # Check the constraints violation nb_infeasible = 0 if len(self.problem.constraint) > 0: for indiv in to_eval: nb_infeasible += check_cstr(self, indiv) == False print( "\r{} gen {:>5}: 100%, {:>4} errors,{:>4} infeasible.".format( time_start_gen, ngen, nb_error, nb_infeasible - nb_error)) # Add children to OutputMultiOpti for indiv in children: # Check that at every fitness values is different from inf is_valid = (indiv.fitness.valid and indiv.is_simu_valid and indiv.cstr_viol == 0) # Add the indiv to the multi_output self.multi_output.add_evaluation(indiv.output, is_valid, list(indiv), indiv.fitness.values, ngen) # Sorting the population according to NSGA2 if self.selector == None: pop = selNSGA2(pop + children, self.size_pop) else: pop = self.selector(pop, self.size_pop) return self.multi_output except KeyboardInterrupt: # Except keybord interruption to return the results already computed print("Interrupted by the user.") return self.multi_output
def process(self, backdoor: Backdoor) -> List[Individual]: self.output.st_timer(self.name, 'algorithm') timestamp = now() front, points = tools.ParetoFront(), [] creator.create("Fitness", base.Fitness, weights=self.weights) creator.create("Individual", Individual, fitness=creator.Fitness) self.log_info().log_delim() self.limit.set('stagnation', 0) self.output.st_timer('Evolution_init', 'init') root = creator.Individual(backdoor) count = self.sampling.get_size(backdoor) self.log_it_header(0, 'base').log_delim() estimation = self.predict(backdoor, count) best = root.set(estimation.value) root.fitness.values = (estimation.value, estimation.value_sd()) self.log_delim() self.output.ed_timer('Evolution_init') population = [root] pop = self.strategy.breed(population) offspring = [creator.Individual(ind.backdoor) for ind in pop] self.limit.set('iteration', 1) self.limit.set('time', now() - timestamp) while not self.limit.exhausted(): it = self.limit.get('iteration') self.log_it_header(it).log_delim() self.output.st_timer('Evolution_iteration_%d' % it, 'iteration') self.output.st_timer('Evolution_evaluate', 'evaluate') for individual in offspring: backdoor = individual.backdoor count = self.sampling.get_size(backdoor) estimation = self.predict(backdoor, count) if not estimation.from_cache: self.limit.increase('predictions') individual.set(estimation.value) individual.fitness.values = (estimation.value, estimation.value_sd()) self.log_delim() self.output.ed_timer('Evolution_evaluate') # update pareto front population = tools.selNSGA2(population + offspring, len(offspring)) front.update(population) for individual in front: if best > individual: best = individual self.limit.set('stagnation', -1) # restart self.output.st_timer('Evolution_next', 'next') self.limit.increase('iteration') self.limit.increase('stagnation') if self.limit.get('stagnation') >= self.stagnation_limit: self.log_delim().output.log('Front:') for point in front: self.output.log(str(point)) front = tools.ParetoFront() points.append(best) best = root self.limit.set('stagnation', 0) info = self.strategy.configure(self.limit.limits) self.output.debug(3, 1, 'configure: ' + str(info)) population = [root] pop = self.strategy.breed(population) offspring = [creator.Individual(ind.backdoor) for ind in pop] # create new log file if not self.limit.exhausted(): self.touch_log().log_info().log_delim() else: info = self.strategy.configure(self.limit.limits) self.output.debug(3, 1, 'configure: ' + str(info)) pop = self.strategy.breed(population) offspring = [creator.Individual(ind.backdoor) for ind in pop] self.output.ed_timer('Evolution_next') self.limit.set('time', now() - timestamp) self.output.ed_timer('Evolution_iteration_%d' % it) if root > best: self.log_delim().output.log('Front:') for point in front: self.output.log(str(point)) points.append(best) self.output.ed_timer(self.name) return points
def do_selection(parents, invalid_ind, nb_ind, objective, frac_pareto=0.8): """ Perform selection of new population Parameters ---------- parents : object Parent population invalid_ind : object Invalid individuals nb_ind : int Number of individuals in population objective : str Objective function Options: 'mc_risk_av_ann_co2_to_net_energy': 'ann_and_co2_to_net_energy_ref_test' 'ann_and_co2_ref_test' 'mc_risk_av_ann_and_co2' 'mc_mean_ann_and_co2' 'mc_risk_friendly_ann_and_co2' 'mc_min_std_of_ann_and_co2' 'mc_dimless_eco_em_2d_mean' 'mc_dimless_eco_em_2d_risk_av' 'mc_dimless_eco_em_2d_risk_friendly' 'mc_dimless_eco_em_2d_std' 'ann_and_co2_dimless_ref' 'mc_dimless_eco_em_3d_mean' 'mc_dimless_eco_em_3d_risk_av' 'mc_dimless_eco_em_3d_risk_friendly' 'mc_dimless_eco_em_3d_std' 'ann_and_co2_dimless_ref_3d' frac_pareto : float, optional Pareto fraction (default: 0.8) Returns ------- newoffspring : object Population object with new offspring of parent population """ pareto_fronts = tools.sortNondominated(parents, len(parents)) if len(pareto_fronts[0]) >= nb_ind * frac_pareto: if len(invalid_ind) >= (1 - frac_pareto) * nb_ind: # Dummy value of reduced parent population reduced_parents = [] if (objective == 'mc_risk_av_ann_co2_to_net_energy' or objective == 'ann_and_co2_to_net_energy_ref_test' or objective == 'ann_and_co2_ref_test' or objective == 'mc_risk_av_ann_and_co2' or objective == 'mc_mean_ann_and_co2' or objective == 'mc_risk_friendly_ann_and_co2' or objective == 'mc_min_std_of_ann_and_co2' or objective == 'mc_dimless_eco_em_2d_mean' or objective == 'mc_dimless_eco_em_2d_risk_av' or objective == 'mc_dimless_eco_em_2d_risk_friendly' or objective == 'ann_and_co2_dimless_ref' or objective == 'mc_dimless_eco_em_2d_std'): # Get best objective function values of pareto frontiers (min_ann, min_co2, idx_ann, idx_co2)\ = get_opt_pareto_values(pareto_fronts=pareto_fronts, objective=objective) if idx_ann is None or idx_co2 is None: # Could not find minimum values: Keep parents generation reduced_parents = parents else: reduced_parents.append(pareto_fronts[0][idx_ann]) reduced_parents.append(pareto_fronts[0][idx_co2]) # Cleanup indexes (reserve to prevent index "shifting") for del_index in sorted([idx_ann, idx_co2], reverse=True): del pareto_fronts[0][del_index] # Reduce pareto frontier for i in range(int(nb_ind * frac_pareto) - 2): chosen_ind = random.choice(pareto_fronts[0]) reduced_parents.append(chosen_ind) pareto_fronts[0].remove(chosen_ind) elif (objective == 'mc_dimless_eco_em_3d_mean' or objective == 'mc_dimless_eco_em_3d_risk_av' or objective == 'mc_dimless_eco_em_3d_risk_friendly' or objective == 'ann_and_co2_dimless_ref_3d' or objective == 'mc_dimless_eco_em_3d_std'): (min_ann, min_co2, max_beta_el, idx_ann, idx_co2, idx_beta_el) = \ get_opt_pareto_values(pareto_fronts=pareto_fronts, objective=objective) if idx_ann is None or idx_co2 is None or idx_beta_el is None: # Could not find minimum values: Keep parents generation reduced_parents = parents else: reduced_parents.append(pareto_fronts[0][idx_ann]) reduced_parents.append(pareto_fronts[0][idx_co2]) if idx_beta_el != idx_ann and idx_beta_el != idx_co2: reduced_parents.append(pareto_fronts[0][idx_beta_el]) val = 3 else: val = 2 list_del_idx = [] list_cand = [idx_ann, idx_co2, idx_beta_el] for elem in list_cand: if elem not in list_del_idx: list_del_idx.append(elem) # Cleanup indexes (reserve to prevent index "shifting") for del_index in sorted(list_del_idx, reverse=True): del pareto_fronts[0][del_index] # Reduce pareto frontier for i in range(int(nb_ind * frac_pareto) - val): if len(pareto_fronts[0]) > 1: # Workaround for #260 chosen_ind = random.choice(pareto_fronts[0]) reduced_parents.append(chosen_ind) pareto_fronts[0].remove(chosen_ind) else: reduced_parents = parents else: reduced_parents = parents else: reduced_parents = parents # print information about print('Current inds and fitness values:') for ind in reduced_parents + invalid_ind: print(ind) print('fitness', ind.fitness.values) print() # Select new offspring with NSGA2 algorithm newoffspring = tools.selNSGA2(reduced_parents + invalid_ind, nb_ind) return newoffspring
def analyse_population(procid, population, output_folder, X_train, X_test, y_train, y_test, features, obj_type, REG='RF', k=10): with open(output_folder + "solutions_procid_%s.txt" % procid, "a") as myfile: best_indices = tools.selNSGA2(population, k) for j in range(k): # Picking best individual best_ind = best_indices[j] if numpy.sum(best_ind) < 1: print("No features in the solution") else: indices = [i for i, x in enumerate(best_ind) if x == 1] #.write("%s, %s " % (features.iloc[indices,0].tolist(), best_ind.fitness.values)) # print("Best individual is %s, %s" % (features.iloc[indices,0].tolist(), best_ind.fitness.values)) opt_feat = features.iloc[indices, 0] XTrain = X_train[:, indices] XTest = X_test[:, indices] r2_res, rmse_test, q2_res, rmse_train, q2f3_res, lr = regressors_function( XTrain, XTest, y_train, y_test, REG=REG) wp = williams_plot(XTrain, XTest, y_train, y_test, lr, toPrint=True, toPlot=True, path=output_folder, filename=str(j) + "_" + str(procid)) q2_m, q2f1_m, q2f2_m, q2f3_m, ccc_m, CVmse_m = compute_outside_metrics( XTrain, y_train, REG=REG, nf=10) pred_test = lr.predict(XTest) pred_train = lr.predict(XTrain) rms_test = sqrt(mean_squared_error(y_test, pred_test)) rms_train = sqrt(mean_squared_error(y_train, pred_train)) with open( output_folder + 'prediction/test_prediction_solution_' + str(j) + "_nicchia_" + str(procid), 'w') as f1: writer = csv.writer(f1, delimiter='\t') writer.writerows(zip(y_test, pred_test)) f1.close() with open( output_folder + 'prediction/train_prediction_solution_' + str(j) + "_nicchia_" + str(procid), 'w') as f2: writer = csv.writer(f2, delimiter='\t') writer.writerows(zip(y_train, pred_train)) f2.close() r2_test = lr.score(XTest, y_test) r2_train = lr.score(XTrain, y_train) myfile.write( "%s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s\n" % (best_ind.fitness.values, r2_test, r2_train, q2_m, q2f1_m, q2f2_m, q2f3_m, ccc_m, wp[0], wp[1], rms_test, rms_train, features.iloc[indices, 0].tolist())) myfile.close() f = open(output_folder + "best_indices_procid_%d" % procid, 'wb') pickle.dump(best_indices, f) f.close()
def nsga2_pareto_K(KK, propvec, pDB, sen=None, ref=None, seed=None): # GP, scal = run_GP() # NDIM = 6 #MMF+ GP # print(len(propvec['COST'])) NDIM = len(propvec['COST']) # +3 # Number of parameters # Minimize both objectives (min -f(x) if maximization is needed) creator.create("FitnessMin", base.Fitness, weights=(1.0, -1.0)) # Individuals in the generation creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMin) toolbox = base.Toolbox() # parameter sequence: RON, S, HOV, SL, LFV150, PMI, CA50, IAT, KI BOUND_LOW, BOUND_UP = 0, 1 # Lower and upper variable bounds if not (cooptimizer_input.parallel_nsgaruns): pool = Pool() toolbox.register("map", pool.map) # toolbox.register("map",futures.map) toolbox.register("attr_float", uniform, BOUND_LOW, BOUND_UP, NDIM) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) # toolbox.register("evaluate",eval_MMF_gp_opt, propvec=propvec, Kinp=KK, GP = GP, scal = scal) # toolbox.register("evaluate", eval_MMF_gp, propvec=propvec, Kinp=KK, GP = GP, scal = scal)#, propvec=propvec, Kinp=KK) # toolbox.register("evaluate", eval_gp, GP = GP, scal = scal)#, propvec=propvec, Kinp=KK) toolbox.register("evaluate", eval_mo, propvec=propvec, Kinp=KK) # , ref_in = ref, sen_in = sen ) # toolbox.register("evaluate", eval_mo2, propvec=propvec, Kinp=KK)#, ref_in = ref, sen_in = sen ) # toolbox.register("evaluate", eval_mean_var, propDB=pDB, Kinp=KK) toolbox.register("mate", tools.cxSimulatedBinaryBounded, low=BOUND_LOW, up=BOUND_UP, eta=20.0) toolbox.register("mutate", tools.mutPolynomialBounded, low=BOUND_LOW, up=BOUND_UP, eta=20.0, indpb=1.0 / NDIM) toolbox.decorate("mate", scale_2()) toolbox.decorate("mutate", scale_2()) toolbox.register("select", tools.selNSGA2) # These are parameters that can be adjusted and may change # the algorithm's performance NGEN = 300 # Number of generations MU = 100 # Number of individuals CXPB = 0.75 # Cross-over probability, [0,1] stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", numpy.mean, axis=0) stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) pf = tools.ParetoFront() hof = tools.HallOfFame(100) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" pop = toolbox.population(n=MU) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit pf.update(pop) hof.update(pop) # This is just to assign the crowding distance to the individuals # no actual selection is done # print(pop) pop = toolbox.select(pop, len(pop)) record = stats.compile(pop) logbook.record(gen=0, evals=len(invalid_ind), **record) print(logbook.stream) # Begin the generational process for gen in range(1, NGEN): # Vary the population offspring = tools.selNSGA2(pop, len(pop)) offspring = tools.selTournamentDCD(pop, len(pop)) offspring = [toolbox.clone(ind) for ind in offspring] for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() <= CXPB: toolbox.mate(ind1, ind2) toolbox.mutate(ind1) toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit try: pf.update(offspring) except: print([ind.fitness.values for ind in offspring]) lll hof.update(offspring) # Select the next generation population pop = toolbox.select(pop + offspring, MU) record = stats.compile(pop) logbook.record(gen=gen, evals=len(invalid_ind), **record) print(logbook.stream) pop.sort(key=lambda x: x.fitness.values) ''' print(pop) filename = open("vals_MMF_NMEPopt_"+str(KK)+".txt", "w") #filename.write("CA50,\t IAT \t KI \t RON \t S \t HOV \t MEAN \t VAR \n") filename.write("RON \t S \t HOV \t SL \t LFV \t PMI \t COST \t CA50 \t IAT \t KI \t MMF \t GP \n") #for eval_mo: #filename.write("RON \t S \t HOV \t SL \t LFV \t PMI \t Cost \t MMFmean \t MMFvar \n") #filename.write("RON \t S \t HOV \t SL \t LFV \t PMI \t COST \t CA50 \t IAT \t KI \t MMF \t GP \n") #filename.write("RON \t S \t HOV \t SL \t LFV \t PMI \t COST \t MMF \n") low = numpy.array([6.7, 35., 2., 99.1, 0., 303.]) #OG bounds CA50, IAT, KI, RON, S,HOV up = numpy.array([23.8, 90., 10.5, 105.6, 12.2, 595.]) #OG bounds CA50, IAT, KI, RON, S,HOV front = numpy.array([ind.fitness.values for ind in pf]) fi = 0 for point in pf: #CA50 = low[0]+(up[0]-low[0])*point[0]#22 #IAT = low[1]+(up[1]-low[1])*point[1]#23 #KI = low[2]+(up[2]-low[2])*point[2]#24 #RON=low[3]+(up[3]-low[3])*point[3] #S=low[4]+(up[4]-low[4])*point[4] #HOV=low[5]+(up[5]-low[5])*point[5] this_ron = blend(point[0:22], propvec, 'RON') this_s = blend(point[0:22], propvec, 'S') this_HoV = blend(point[0:22], propvec, 'HoV') this_SL = blend(point[0:22], propvec, 'SL') #this_AFR = blend(point, propvec, 'AFR_STOICH') this_LFV150 = blend(point[0:22], propvec, 'LFV150') this_PMI = blend(point[0:22], propvec, 'PMI') cost_f = blend(point[0:22], propvec, 'COST') #MMF = front[fi,0] #NMEP = front[fi,1] merit_f = mmf_single(RON=this_ron, S=this_s, HoV=this_HoV, SL=this_SL, K=KK) RON = this_ron S = this_s HOV= this_HoV x0 = (numpy.array([23.8, 90., 10.5])+numpy.array([6.7, 35., 2.]))/2 bound_list=[(6.7,23.8),(35.,90.),(2.,10.5)] #xout, out1,out2 = fmin_tnc(f_gp, x0,approx_grad = True, bounds=bound_list, disp = 0, args = (RON,S,HOV, GP,scal,))#???????_ex?approx_grad = True, res = minimize(f_gp, x0, bounds=bound_list, args = (RON,S,HOV, GP,scal,)) mean_out = f_gp(res.x, RON,S,HOV, GP,scal) CA50=res.x[0] IAT=res.x[1] KI = res.x[2] #gp_in = numpy.array([[CA50, IAT,KI, RON,S, HOV]]).reshape(1,-1)#CA50, IAT, KI, RON, S,HOV #pred_mean, pred_std = predict_GP(GP, scal, gp_in) #for eval_mo: #a = "{} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \n".format(this_ron, this_s, this_HoV, this_SL, this_LFV150,\ # this_PMI,cost_f,merit_mean, merit_var) a = "{} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \n".format(this_ron, this_s, this_HoV, this_SL, this_LFV150,\ this_PMI,cost_f, CA50, IAT, KI, merit_f,mean_out) #a = "{} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \n".format(CA50, IAT, KI, RON, S,HOV,pred_mean[0], pred_std[0]) #a = "{} \t {} \t {} \t {} \t {} \t {} \t {} \t {} \n".format(this_ron, this_s, this_HoV, this_SL, this_LFV150,\ # this_PMI,cost_f, merit_f) filename.write(a) fi = fi+1 filename.close() ''' front = numpy.array([ind.fitness.values for ind in pf]) print("NSGA done; hof: {}".format(pf[0])) # print("K = {}; Score: {}".format(KK, -eval_mo(pf[0],propvec,KK)[0])) # print("pv RON = {}".format(propvec['NAME'])) print('paretofront:', front) return front # front[:, 1], -front[:, 0], front[:,2]
def cx_tournament(pop, prob_cx, dict_max_pv_area, dict_restr, nb_part=4, perform_checks=True, dict_sh=None, pv_min=None, pv_step=1, use_pv=False, add_pv_prop=0, prevent_boi_lhn=True, dict_heatloads=None): """ Performs crossover on individuusm, which have been selected by selNSGA2 tournament. Parameters ---------- pop : list List of individuum dicts (ind) / population prob_cx : float Probability of crossover being applied dict_max_pv_area : dict Dict holding maximum usable PV area values in m2 per building dict_restr : dict Dict holding possible energy system sizes nb_part : int Number of individuums which take part in single tournament perform_checks : bool, optional Defines, if individuums should be checked on plausibility (default: True). Canb be deactivated to increase speed (check is also performed before running evaluation) dict_sh : dict, optional Dictionary holding building node ids as keys and maximum space heating power values in Watt as dict values (default: None). If not None, used for size limitation. If None, dict_restr is used for sizing. (default: None) pv_min : float, optional Minimum possible PV area per building in m2 (default: None) pv_step : float, optional Defines discrete step of Pv sizing in m2 (default: 1). E.g. If minimum PV size is 8 m2, 9, 10, 11...up to max. rooftop area can be chosen as PV size. use_pv : bool, optional Defines, if PV can be used (default: False) add_pv_prop : float, optional Defines additional probability of PV being changed, if only thermal mutation has been applied (defauft: 0). E.g. if boiler system has been changed to CHP, there is a change of add_pv_prob that also PV is mutated. prevent_boi_lhn : bool, optional Prevent boi/eh LHN combinations (without CHP) (default: True). If True, adds CHPs to LHN systems without CHP dict_heatloads : dict, optional Dict holding building ids as keys and design heat loads in Watt as values (default: None) Returns ------- offspring : list List of individuum dicts (ind) / population """ offspring = [] for i in range(int(round(len(pop) / 2))): # Randomly select participants list_participants = np.random.choice(pop, size=nb_part) # Determine the tournament winners list_win = tools.selNSGA2(list_participants, 2) # Copy winning individuums ind1 = copy.deepcopy(list_win[0]) ind2 = copy.deepcopy(list_win[1]) # Perform crossover on individuums if random.random() < prob_cx: ind1, ind2 = do_crossover(ind1=ind1, ind2=ind2, dict_max_pv_area=dict_max_pv_area, perform_checks=perform_checks, dict_restr=dict_restr, dict_sh=dict_sh, pv_min=pv_min, pv_step=pv_step, use_pv=use_pv, add_pv_prop=add_pv_prop, prevent_boi_lhn=prevent_boi_lhn, dict_heatloads=dict_heatloads) # Delete old fitness values del ind1.fitness.values del ind2.fitness.values # Add crossovered individuums to offspring offspring.append(ind1) offspring.append(ind2) return offspring
def start(self): # copy of the population pop = list(self.population) statistics = [] generation = 0 convergence = False # This is just to assign the crowding distance to the individuals # no actual selection is done pop = tools.selNSGA2(pop, self.config.population_size) # Log the pareto front pareto = tools.sortNondominated(pop, self.config.population_size, first_front_only=True) hv = pygmo.hypervolume([[i.fitness.values[0], i.fitness.values[1]] for i in pareto[0]]) statistics.append(hv.compute(ref_point=self.ref_point)) # Begin the generational process while not convergence and generation < self.config.number_generations: # Vary the population offspring = self.toolbox.select(pop, self.config.population_size) offspring = [self.toolbox.clone(ind) for ind in offspring] # crossover and mutation for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() <= self.config.crossover_rate: self.toolbox.mate(ind1, ind2) new_type = type_crossover(ind1, ind2) ind1.i_type = new_type ind2.i_type = new_type if random.random() <= self.config.mutation_rate: self.toolbox.mutate(ind1) self.toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = self.toolbox.map(self.toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # Select the next generation population pop = self.toolbox.dominance(pop + offspring, self.config.population_size) # Log the pareto front hypervolume pareto_new = tools.sortNondominated(pop, self.config.population_size, first_front_only=True) hv = pygmo.hypervolume([[i.fitness.values[0], i.fitness.values[1]] for i in pareto_new[0]]) statistics.append(hv.compute(ref_point=self.ref_point)) # check convergence # convergence = self._check_convergence(pareto[0], pareto_new[0]) convergence = self._check_convergence_hv(statistics) pareto = pareto_new generation += 1 gc.collect() return pop, pareto[0], statistics
def crowding_distance(pop): return tools.selNSGA2(pop, len(pop))
combinedPop = pop + offspring # 将子代与父代结合成一个大种群 fitnesses = toolbox.map(toolbox.evaluate, combinedPop) # 对该大种群进行适应度计算 for ind, fitness in zip(combinedPop, fitnesses): ind.fitness.values = fitness fronts = tools.emo.sortNondominated( combinedPop, k=N_POP, first_front_only=False) # 对该大种群进行快速非支配排序 for front in fronts: tools.emo.assignCrowdingDist(front) # 计算拥挤距离 pop = [] for front in fronts: pop += front pop = toolbox.clone(pop) pop = tools.selNSGA2(pop, k=N_POP, nd='standard') # 基于拥挤度实现精英保存策略 offspring = toolbox.select(pop, N_POP) # 选择 offspring = toolbox.clone(offspring) offspring = algorithms.varAnd(offspring, toolbox, CXPB, MUTPB) # 交叉变异 bestInd = tools.selBest(pop, 1)[0] # 选择出种群中最优个体 bestFit = bestInd.fitness.values print('best solution:', bestInd) print('best fitness:', bestFit) front = tools.emo.sortNondominated( pop, len(pop))[0] # 返回的不同前沿的pareto层集合fronts中第一个front为当前最优解集 print(f"len of front:{len(front)}") # 2目标,参考点
def hyperopt_lightgbm(X: pd.DataFrame, y: pd.Series, params: Dict, config: Config): if ENSEMBLE: # global model_i # model_i = 0 free_raw_data = False else: free_raw_data = True # X_train, X_val, y_train, y_val = data_split(X, y, test_size=0.2) # train_data = lgb.Dataset(X, label=y_train) # valid_data = lgb.Dataset(X_val, label=y_val, free_raw_data=free_raw_data) # cross validation data = lgb.Dataset(X, label=y, free_raw_data=free_raw_data) data_gen = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED).split(X, y) train_data_li = [] valid_date_li = [] for train_indices, valid_indices in data_gen: train_data_li.append(data.subset(train_indices)) valid_date_li.append(data.subset(valid_indices)) space = { "learning_rate": hp.loguniform("learning_rate", np.log(0.01), np.log(0.9)), "max_depth": hp.choice("max_depth", [1, 2, 3, 4, 5, 6, 7, 8]), "num_leaves": hp.choice("num_leaves", np.linspace(10, 100, 50, dtype=int)), "feature_fraction": hp.quniform("feature_fraction", 0.5, 1.0, 0.1), "bagging_fraction": hp.quniform("bagging_fraction", 0.5, 1.0, 0.1), "bagging_freq": hp.choice("bagging_freq", np.linspace(0, 100, 10, dtype=int)), "reg_alpha": hp.uniform("reg_alpha", 0, 2), "reg_lambda": hp.uniform("reg_lambda", 0, 2), "min_child_weight": hp.uniform('min_child_weight', 0.5, 10), # "subsample": hp.quniform("subsample", 0.5, 1.0, 0.1) # "colsample_bytree": # "min_data_in_leaf": hp.choice("min_data_in_leaf", np.linspace(5, 30, 5, dtype=int)), # "is_unbalance": hp.choice("is_unbalance", [True, False]), # "scale_pos_weight": hp.loguniform('scale_pos_weight', np.log(np.sum(y == 0)/np.sum(y == 1)), 0) # if np.sum(y == 0)/(np.sum(y == 1) + 0.0001) < 1 # else hp.loguniform('scale_pos_weight', 0, np.log(np.sum(y == 0)/np.sum(y == 1))), # "scale_pos_weight": hp.quniform("feature_fraction", np.maximum(np.sum(y == 0)/np.sum(y == 1), 0.1), 1, 0.1) # if np.sum(y == 0)/(np.sum(y == 1) + 0.0001) < 1 # else hp.quniform('scale_pos_weight', 1, np.sum(y == 0)/np.sum(y == 1), (np.sum(y == 0)/np.sum(y == 1) - 1)/10), } def objective(hyperparams): model_li = [] for j in range(len(train_data_li)): model = lgb.train( { **params, **hyperparams }, train_data_li[j], 300, valid_date_li[j], early_stopping_rounds=20, verbose_eval=0, # feval=lgb_f1_score ) model_li.append(model) score = np.mean([ model.best_score["valid_0"][params["metric"]] for model in model_li ]) # in classification, less is better result_dict = {'loss': -score, 'status': STATUS_OK} if ENSEMBLE: # save the model # global model_i # model.save_model(f"model_{model_i}", num_iteration=model.best_iteration) # model_i = model_i + 1 # predicts of valid set # result_dict['predicts'] = np.round(np.mean([model.predict(data.data) for model in model_li])) result_dict['predicts'] = np.mean( [model.predict(data.data) for model in model_li], axis=0) if ENSEMBLE_OBJ == 3: # num of weak sub-models result_dict['num_trees'] = model.num_trees() return result_dict trials = Trials() best = hyperopt.fmin(fn=objective, space=space, trials=trials, algo=tpe.suggest, max_evals=10, verbose=-1, rstate=np.random.RandomState(HYPEROPT_SEED)) if ENSEMBLE: # # select top half of the classifiers according to auc # trials._dynamic_trials.sort(key=lambda data: data['result']['loss']) # best_li = [trial['misc']['vals'] # for trial in trials._dynamic_trials[0:int(len(trials._dynamic_trials)/2)]] # hyperparams_li = [] # for best in best_li: # for key in best: # best[key] = best[key][0] # hyperparams_li.append(space_eval(space, best)) # select top half of the classifiers according to NCL predicts_ens = np.mean( [trail['result']['predicts'] for trail in trials._dynamic_trials], axis=0) pop = [] i = 0 for trail in trials._dynamic_trials: hyperparams = trail['misc']['vals'] for key in hyperparams: hyperparams[key] = hyperparams[key][0] hyperparams = space_eval(space, hyperparams) # hyperparams['ensemble_i'] = i ind = creator.Individual(hyperparams) # weights1 = (y_val == 1) * np.sum(y_val == 0) / len(y_val) # weights0 = (y_val == 0) * np.sum(y_val == 1) / len(y_val) # weights = weights0 + weights1 if ENSEMBLE_OBJ == 3: ind.fitness.values = (trail['result']['loss'], -np.sum( ((trail['result']['predicts'] - predicts_ens)**2)), trail['result']['num_trees']) else: ind.fitness.values = (trail['result']['loss'], -np.sum( ((trail['result']['predicts'] - predicts_ens)**2))) pop.append(ind) i += 1 pop = tools.selNSGA2(pop, int(len(trials._dynamic_trials) / 2)) hyperparams_li = list(pop) # # ensemble selection # num_classifiers = 0 # sum_predicts = 0 # hyperparams_li = [] # dynamic_trials = trials._dynamic_trials.copy() # for i in range(len(dynamic_trials)): # num_classifiers += 1 # best_trail = min(dynamic_trials, # key=lambda data: # np.mean(np.abs(valid_data.label - # np.round((sum_predicts + data['result']['predicts']) / # num_classifiers)))) # dynamic_trials = [trail for trail in dynamic_trials if trail != best_trail] # sum_predicts += best_trail['result']['predicts'] # hyperparams = {} # for key in best_trail['misc']['vals']: # hyperparams[key] = best_trail['misc']['vals'][key][0] # hyperparams = space_eval(space, hyperparams) # hyperparams['ensemble_error'] = \ # np.mean(np.abs(valid_data.label - np.round(sum_predicts / num_classifiers))) # hyperparams['ensemble_num'] = num_classifiers # hyperparams_li.append(hyperparams) # ensemble_num = min(hyperparams_li, key=lambda data: data['ensemble_error'])['ensemble_num'] # print(f"Ensemble_num: {ensemble_num}!!!") # hyperparams_li = hyperparams_li[0:ensemble_num] return hyperparams_li else: hyperparams = space_eval(space, best) log(f"auc = {-trials.best_trial['result']['loss']:0.4f} {hyperparams}") return hyperparams
def nsga(individuals, k, temp): return tools.selNSGA2(individuals, k)
def selection_operator(individuals, k): ''' Selects road trip for next generation from current generation favoring trips with lower total distance and more cities visited. K denotes how many selection needs to be done ''' return tools.selNSGA2(i, int(k / 5.)) * 5
def evolve_once_stage2(self, collaboration_representatives, cxpb, mutpb, controlled_elitism=True, method='mismatch', w_ssv=None): """ Perform one iteration of evolution in stage 2. :param collaboration_representatives: list of list, each row includes one representative from each species (including this species itself) :param cxpb: crossover probability :param mutpb: mutation probability :param controlled_elitism: bool, whether to apply controlled elitism for NSGA-II, True by default :param method: 'mismatch' or 'distance', how to measure the difference between the model space and data space :param w_ssv: float, weight for constraint violations. If w is None, then the stable state constraints are not considered. :return: representative of this generation """ # because Lambda cannot be pickled, a representative may have not been compiled yet in parallel processing for i, reps in enumerate(collaboration_representatives ): # representatives from the ith species pset = self.primitive_sets[i] for ind in reps: if ind.compiled is None: ind.compiled = compile_with_primitives(ind, pset) self.toolbox.register( 'evaluate', self._evaluate_stage2, collaboration_representatives=collaboration_representatives, method=method, w_ssv=w_ssv) if self.gen == self.n_gen_stage1: # just switch into stage 2: do some initialization self._prepare_stage2(w_ssv) self.gen += 1 # selection: selTournamentDCD, considering both the Pareto rank and the crowding distance parents = self.toolbox.select(self.population, len(self.population)) # variation: adaptive mutation rate to escape a local minimum mutpb = min(0.8, (1 + self._n_stagnation / 50) * mutpb) offspring = algorithms.varAnd(parents, self.toolbox, cxpb, mutpb) if self._n_stagnation > 5: i = random.randint(0, len(offspring) - 1) offspring[i] = self.toolbox.individual() # measure the characteristics of varied individuals due to crossover or mutation invalid_pop = [ind for ind in offspring if not ind.fitness.valid] self._compile(invalid_pop) # set attr 'compiled' if self.stable_states is not None: self._count_stable_state_violations( invalid_pop) # set attr 'n_stable_state_violations' self._count_num_regulators(invalid_pop) # set attr 'n_regulators' # evaluate all fitness: even an individual is not varied, the representatives have been changed best_collaborations = list( self.toolbox.map(self.toolbox.evaluate, offspring)) for ind, best_collaboration in zip(offspring, best_collaborations): ind.fitness.values = best_collaboration.fitness.values self.hof_stage2.update(best_collaborations) self._update_best_collaboration_history(best_collaborations) # select N from 2N individuals assembled from parents and offspring if controlled_elitism: self.population = tools.selNSGA2ControlledElitism( self.population + offspring, len(self.population), r=0.5) else: self.population = tools.selNSGA2(self.population + offspring, len(self.population)) # log if hasattr(self, 'logbook'): record = self.mstats.compile(self.population) self.logbook.record(index=self.index, stage=self.stage, gen=self.gen, **record) self._log_to_file() bgf = max(self.population, key=lambda ind: ind.fitness).fitness.values[0] if self.best_global_fitness - bgf < 1: self._n_stagnation += 1 else: self._n_stagnation = 0 self.best_global_fitness = bgf
def get_pareto_front(dict_gen, size_used=None, nb_ind_used=None): """ Returns list of inds, which are pareto optimal. Uses NSGA2 sorting algorithm with all populations, that existed. Runtime intensive! Parameters ---------- dict_gen : dict Dict holding generation number as key and population object as value size_used : int, optional Defines size of last number of generations, which should be used in NSGA-2 sorting (default: None). If None, uses all generations. nb_ind_used : int, optional Number of pareto-optimal solutions, which should be extracted (default: None). If None, nb_ind_used is equal to size of population respectively number of individuals per population Returns ------- list_inds_pareto : list (of inds) List holding pareto optimal individuals """ last_key = max(dict_gen.keys()) list_relevant_keys = [last_key] if size_used is None: length_val = len(dict_gen) - 1 else: length_val = size_used + 0.0 new_key = last_key + 0.0 for i in range(length_val): new_key -= 1 list_relevant_keys.append(new_key) list_relevant_inds = [] for key in list_relevant_keys: curr_pop = dict_gen[key] # # Get pareto frontier results (first/best pareto frontier) # list_cur_par = tools.sortNondominated(curr_pop, len(curr_pop), # first_front_only=True)[0] # Append list_relevant_inds for curr_ind in curr_pop: list_relevant_inds.append(curr_ind) # lists_pareto_frontier = tools.sortNondominated(list_relevant_inds, # k=len_single_ind, # first_front_only=True) # list_inds_pareto = [] # # # Add all solutions of lists_pareto_frontier to single list # for list_par in lists_pareto_frontier: # for sol in list_par: # list_inds_pareto.append(sol) # # # Sort by fitness value # list_inds_pareto = sorted(list_inds_pareto, # key=lambda x: x.fitness.values[0], # reverse=False) if nb_ind_used is None: len_single_ind = len(dict_gen[0]) else: len_single_ind = int(nb_ind_used + 0) lists_pareto_frontier = tools.selNSGA2(list_relevant_inds, k=len_single_ind) # lists_pareto_frontier = tools.selBest(list_relevant_inds, # k=len_single_ind) # Sort by fitness value lists_pareto_frontier = sorted(lists_pareto_frontier, key=lambda x: x.fitness.values[0], reverse=False) return lists_pareto_frontier
def nsga2_selection(individuals: List[Any], pop_size: int) -> List[Any]: chosen = tools.selNSGA2(individuals, pop_size) return chosen
ind1 ind2.fitness.values = evalKnapsack(ind2) ind2.fitness.values ind1.fitness.values ##CROSSOVER child1, child2 = [toolbox.clone(ind) for ind in (ind1, ind2)] tools.cxUniform(child1, child2, 0.5) #tools.cxSimulatedBinary(child1, child2,0.5) #tools.cxPartialyMatched(child1, child2) del child1.fitness.values del child2.fitness.values selected = tools.selNSGA2([child1, child2], nd="standard") print(child1 in selected) # True for g in range(NGEN): # Select and clone the next generation individuals offspring = map(toolbox.clone, toolbox.select(pop, len(pop))) # Apply crossover and mutation on the offspring offspring = algorithms.varAnd(offspring, toolbox, CXPB, MUTPB) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit
def surrogate_mo(data, KK, propvec, pDB): """ This creates ncands*dim points that are randomly perturbed from the best point. #todo: candidate points plus another dimension must add to 1 (easy: we do know what the full weight vector of xbest is -- so we perturb all N values, make them sum 1 and delete last column) """ import array import cooptimizer_input from deap import algorithms from deap import base from deap import benchmarks from deap.benchmarks.tools import diversity, convergence from deap import creator from deap import tools NDIM = data.dim+1 # Number of parameters = 21 (surrogate model) # Minimize both objectives (min -f(x) if maximization is needed) # everything must be minimized creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0)) # Individuals in the generation creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMin) toolbox = base.Toolbox() # parameter sequence: RON, S, HOV, SL, LFV150, PMI, CA50, IAT, KI BOUND_LOW, BOUND_UP = 0, 1 if not(cooptimizer_input.parallel_nsgaruns): pool = Pool() toolbox.register("map", pool.map) # toolbox.register("map",futures.map) toolbox.register("attr_float", uniform, BOUND_LOW, BOUND_UP, NDIM) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) # toolbox.register("evaluate",eval_MMF_gp_opt, propvec=propvec, Kinp=KK, GP = GP, scal = scal) # toolbox.register("evaluate", eval_MMF_gp, propvec=propvec, Kinp=KK, GP = GP, scal = scal)#, propvec=propvec, Kinp=KK) # toolbox.register("evaluate", eval_gp, GP = GP, scal = scal)#, propvec=propvec, Kinp=KK) # toolbox.register("evaluate", eval_mo, propvec=propvec, Kinp=KK)#, ref_in = ref, sen_in = sen ) # toolbox.register("evaluate", eval_mo2, propvec=propvec, Kinp=KK)#, ref_in = ref, sen_in = sen ) # toolbox.register("evaluate", eval_mean_var, propDB=pDB, Kinp=KK) toolbox.register("evaluate", my_objective, propvec=propvec, Kinp=KK, data=data) toolbox.register("mate", tools.cxSimulatedBinaryBounded, low=BOUND_LOW, up=BOUND_UP, eta=20.0) toolbox.register("mutate", tools.mutPolynomialBounded, low=BOUND_LOW, up=BOUND_UP, eta=20.0, indpb=1.0/NDIM) toolbox.decorate("mate", scale_2()) toolbox.decorate("mutate", scale_2()) toolbox.register("select", tools.selNSGA2) # These are parameters that can be adjusted and may change # the algorithm's performance NGEN = 150 MU = 40 CXPB = 0.75 # Cross-over probability, [0,1] 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) pf = tools.ParetoFront() hof = tools.HallOfFame(100) logbook = tools.Logbook() logbook.header = "gen", "evals", "std", "min", "avg", "max" pop = toolbox.population(n=MU) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in pop if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit pf.update(pop) hof.update(pop) # This is just to assign the crowding distance to the individuals # no actual selection is done # print(pop) pop = toolbox.select(pop, len(pop)) record = stats.compile(pop) logbook.record(gen=0, evals=len(invalid_ind), **record) # print(logbook.stream) # Begin the generational process for gen in range(1, NGEN): # Vary the population offspring = tools.selNSGA2(pop, len(pop)) offspring = tools.selTournamentDCD(pop, len(pop)) offspring = [toolbox.clone(ind) for ind in offspring] for ind1, ind2 in zip(offspring[::2], offspring[1::2]): if random.random() <= CXPB: toolbox.mate(ind1, ind2) toolbox.mutate(ind1) toolbox.mutate(ind2) del ind1.fitness.values, ind2.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit try: pf.update(offspring) except: print([ind.fitness.values for ind in offspring]) lll hof.update(offspring) # Select the next generation population pop = toolbox.select(pop + offspring, MU) record = stats.compile(pop) logbook.record(gen=gen, evals=len(invalid_ind), **record) print(logbook.stream) pop.sort(key=lambda x: x.fitness.values) front = np.array([ind.fitness.values for ind in pf]) print("NSGA done; hof: {}".format(pf[0])) # print("K = {}; Score: {}".format(KK, -eval_mo(pf[0],propvec,KK)[0])) # print("pv RON = {}".format(propvec['NAME'])) print('paretofront:', front) # plt.scatter(front[:,0], front[:,1], marker = 'o', c= 'r',s=40) # plt.show() # plt.savefig('MO_surr.png') # kkk pf_pop = np.array([ind for ind in pf]) print(pf_pop) print(np.sum(pf_pop, axis=1)) print(pf_pop.shape) print(front.shape) # for ii in range(pf_pop.shape[0]): # o = objective_function(pf_pop[ii,:], propvec, KK) # print(o) # print(front[ii,:]) if not(cooptimizer_input.parallel_nsgaruns): pool.close() return pf_pop, front
def select_without_duplicates(individuals, k): if settings.REMOVE_DUPLICATES: individuals = remove_duplicates(individuals) return tools.selNSGA2(individuals, k)
def _pareto_selection_operator(individuals, k): return tools.selNSGA2(individuals, int(k / 5.)) * 5