def ea_deap(self, population, toolbox, ngen, stats=None, verbose=__debug__): history = History() toolbox.decorate("mate", history.decorator) history.update(population) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Evaluate all individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit record = stats.compile(population) if stats else {} logbook.record(gen=0, nevals=len(population), **record) if verbose: print(logbook.stream) # Begin the generational process for gen in range(1, ngen + 1): self.current_generation += 1 # Select the next generation individuals old_offspring = deepcopy(population) offspring = toolbox.select(population, len(population)) # Vary the pool of individuals new_offspring = toolbox.mate(deepcopy(offspring), toolbox) hash_models_deap(old_offspring, new_offspring, self.genome_set, self.models_set) self.update_mutation_rate() # Evaluate the individuals with an invalid fitness fitnesses = toolbox.map(toolbox.evaluate, new_offspring) for ind, fit in zip(new_offspring, fitnesses): ind.fitness.values = fit ind['age'] += 1 # Replace the current population by the offspring population[:] = new_offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=len(population), **record) if verbose: print(logbook.stream) pop_stats = self.calculate_stats(self.population) for stat, val in pop_stats.items(): global_vars.get('sacred_ex').log_scalar( f'avg_{stat}', val, self.current_generation) self.write_to_csv({k: str(v) for k, v in pop_stats.items()}, self.current_generation) self.print_to_evolution_file(self.population, self.current_generation) return population, logbook
def evolve(evaluate, cls, popsize=10): select = partial(harsh_winter, count=popsize) history = History() stats = statsa() hof = ObjectiveFunctionHallOfFame(maxsize=15) return algorithm(cls, popsize, futures.map, evaluate, select, breed, mutate, stats, history, hof)
def evolve(evaluate, Individual, popsize=10): toolbox = base.Toolbox() toolbox.register("map", futures.map) toolbox.register('select', partial(harsh_winter, count=popsize)) toolbox.register('breed', breed) toolbox.register('mutate', mutate) toolbox.register("individual", Individual) toolbox.register('evaluate', evaluate) history = History() stats = statsa() hof = ObjectiveFunctionHallOfFame(maxsize=15) return algorithm(toolbox, stats, history, hof, popsize)
def algorithm(population, select, generations) -> ObjectiveFunctionHallOfFame: hof = ObjectiveFunctionHallOfFame(maxsize=15) history = History() stats = statsa() for g in range(1, generations + 1): for ind in population: ind.set_sigma((g / generations) * 1 / 3 + (generations - g) / generations * 1 / 10) log_stuff(g, history, hof, population, stats) offspring = breed(population) mutants = mutate(population) for ind in offspring + mutants: if not ind.fitness.valid: ind.evaluate() print('.', end='') population = select(set(offspring) | set(mutants) | population) return hof
def qual_definition(model_path, init_pop_path, exp_essentiality_path, base_biomass=True, logbook=True, hall_of_fame=True, history=False, processes=None, **kwargs): """ This function treats the inputs for the genetic algorithm. :param model_path: Path to the model for which the biomass objective function is defined :param init_pop_path: Path to the initial population on which to run the algorithm. The population should be generated with the initial_population module :param exp_essentiality_path: Path to the experimental essentiality data. Two columns csv file, for each gene a 0 in the essentiality column indicates a non-essential gene, a 1 an essential one. :param base_biomass: default=True, :param logbook: default=True, generates a logbook of fitness data over generations to the path in kwargs :param hall_of_fame: default=True, generates a Hall Of Fame of the best individuals of all time to the path in kwargs :param history: default=False, NOT FUNCTIONNAL AS OF 0.3 :param processes: defaul=None, the number of cores to use :param kwargs: :return: """ # Required arguments model = _import_model(model_path) exp_ess = _import_essentiality(exp_essentiality_path) """Will have to make the import of the initial population and experimental essentiality data safer""" initial_pop = pd.read_csv(init_pop_path, index_col=0) #valid_ess = pd.read_csv(valid_essentiality_path, index_col=0) # GA parameters default_param = { 'CXPB': 0.5, 'MUTPB': 0.1, 'NGEN': 20, 'indpb': 0.005, 'distance_measure': 'mcc', 'fitness_distance': 1.0, 'fitness_size': -0.25 } if 'GA_param' in kwargs: default_param.update(kwargs.get('GA_param')) else: print('Using default GA parameters') # Non required inputs if processes is None: try: processes = multiprocessing.cpu_count() except NotImplementedError: warn("Number of cores could not be detected - assuming 1.") processes = 1 if base_biomass: if 'base_biomass_path' in kwargs: base_biomass_df = _import_base_biomass( kwargs.get('base_biomass_path')) print(base_biomass_df) base_biomass = dict( zip([ model.metabolites.get_by_id(k) for k in base_biomass_df['Metabolites'] ], [v for v in base_biomass_df['Coefficients']])) else: # Give a standard biomass reaction bb_id = { 'ala__L_c': -0.8582035429224959, 'arg__L_c': -0.1968950229490204, 'asn__L_c': -0.2046276924644766, 'asp__L_c': -0.3120212125365338, 'atp_c': -75.55223000000001, 'ctp_c': -0.16308309312316666, 'cys__L_c': -0.04349107533373362, 'datp_c': -0.02365734018153735, 'dctp_c': -0.0264672933260632, 'dgtp_c': -0.023187313048617483, 'dttp_c': -0.024331654502082398, 'gln__L_c': -0.17647268259672946, 'glu__L_c': -0.33695369012459897, 'gly_c': -0.880181177186217, 'gtp_c': -0.15908917528888614, 'his__L_c': -0.08628587541929372, 'ile__L_c': -0.3172325107365821, 'leu__L_c': -0.450016536630228, 'lys__L_c': -0.29929818581613993, 'met__L_c': -0.11698875330288233, 'phe__L_c': -0.13737116178622735, 'pro__L_c': -0.2469302131726492, 'ser__L_c': -0.33144864820741754, 'thr__L_c': -0.3337027605043413, 'trp__L_c': -0.027235586441322963, 'tyr__L_c': -0.0965789766332646, 'utp_c': -0.15004465345468998, 'val__L_c': -0.4875735097180578 } base_biomass = {} for k, v in bb_id.items(): base_biomass[model.metabolites.get_by_id(k)] = v else: base_biomass = {} # Output files outputs = {} if logbook: if 'logbook_name' in kwargs: outputs['logbook_name'] = kwargs.get('logbook_name') else: outputs['logbook_name'] = 'logbook.csv' if hall_of_fame: if 'hall_of_fame_name' in kwargs: outputs['hall_of_fame_name'] = kwargs.get('hall_of_fame_name') else: outputs['hall_of_fame_name'] = 'hall_of_fame.csv' if 'hall_of_fame_size' in kwargs: outputs['hall_of_fame_size'] = kwargs.get('hall_of_fame_size') else: outputs['hall_of_fame_size'] = 1000 if history: if 'history_name' in kwargs: outputs['history_name'] = kwargs.get('history_name') else: outputs['history_name'] = 'history.csv' print('initializing toolbox') # Initialize DEAP toolbox toolbox = base.Toolbox() creator.create("FitnessMulti", base.Fitness, weights=(1.0, -0.25)) creator.create("Individual", list, fitness=creator.FitnessMulti) toolbox.register("individual_guess", initIndividual, creator.Individual) toolbox.register("population_guess", initPopulation, list, toolbox.individual_guess, init_pop_path) toolbox.register('generate_new_individual', generate_new_individual) # Get the constants for the evaluation function toolbox.register("evaluate", eval_ind) toolbox.register('map', pebble_map) toolbox.register("mate", tools.cxOnePoint) toolbox.register("mutate", tools.mutFlipBit, indpb=default_param.get('indpb')) toolbox.register("select", tools.selTournament, tournsize=3) # Register history and Decorate the variation operators history = History() toolbox.decorate("mate", history.decorator) toolbox.decorate("mutate", history.decorator) # Run genetic algorithm print(default_param) distance = default_param.get('distance_measure') _genetic_algo(model, initial_pop, exp_ess, base_biomass, toolbox, default_param, distance, processes, outputs)
def optimization_deap_appendages(): ### PARAMATERS gaconfig_obj = codecs.open('assets/data/parametersga-appendages.json', 'r', encoding='utf-8').read() gaconfig = json.loads(gaconfig_obj) weight1 = np.float(gaconfig["weight1"]) / 10 # velocity weight2 = np.float(gaconfig["weight2"]) / 10 # comfort ratio weight windspeedrange = np.array(gaconfig["windspeedrange"]) windanglerange = np.array(gaconfig["windanglerange"]) pop_size = np.int(gaconfig["popsize"]) children_size = np.int(gaconfig["childrensize"]) max_gen = np.int(gaconfig["maxgeneration"]) mut_prob = np.int(gaconfig["mutprob"]) / 100 halloffame_number = np.int(gaconfig["halloffamenumber"]) indpb_value = np.int(gaconfig["indpb"]) / 100 eta_value = np.int(gaconfig["eta"]) gamethod = np.int(gaconfig["gamethod"]) limits_obj = codecs.open('assets/data/dimensions-appendages-limits.json', 'r', encoding='utf-8').read() limits = json.loads(limits_obj) for item in limits: item = str(item) if item != "category": globals()[item] = np.float(limits[item]) bound_low1, bound_up1 = badmin, badmax bound_low2, bound_up2 = emin, emax bound_low3, bound_up3 = ehmmin, ehmmax bound_low4, bound_up4 = emdcmin, emdcmax bound_low5, bound_up5 = hsrmin, hsrmax bound_low6, bound_up6 = imin, imax bound_low7, bound_up7 = jmin, jmax bound_low8, bound_up8 = lpgmin, lpgmax bound_low9, bound_up9 = pmin, pmax bound_low10, bound_up10 = rootcKmin, rootcKmax bound_low11, bound_up11 = rootcRmin, rootcRmax bound_low12, bound_up12 = roottcksKmin, roottcksKmax bound_low13, bound_up13 = roottcksRmin, roottcksRmax bound_low14, bound_up14 = spanKmin, spanKmax bound_low15, bound_up15 = spanRmin, spanRmin bound_low16, bound_up16 = splmin, splmax bound_low17, bound_up17 = sweepKdegmin, sweepKdegmax bound_low18, bound_up18 = sweepRdegmin, sweepRdegmax bound_low19, bound_up19 = tipcKmin, tipcKmax bound_low20, bound_up20 = tipcRmin, tipcRmax bound_low21, bound_up21 = tiptcksKmin, tiptcksKmax bound_low22, bound_up22 = tiptcksRmin, tiptcksRmax bound_low23, bound_up23 = xceamin, xceamax NDIM = 2 random.seed(a=42) savefile = "optimizationresistance" ### BUILD MODEL def uniform(low1, up1, low2, up2, low3, up3, low4, up4, low5, up5, low6, up6, low7, up7, low8, up8, low9, up9, low10, up10, low11, up11, low12, up12, low13, up13, low14, up14, low15, up15, low16, up16, low17, up17, low18, up18, low19, up19, low20, up20, low21, up21, low22, up22, low23, up23, size=None): return [ random.uniform(low1, up1), random.uniform(low2, up2), random.uniform(low3, up3), random.uniform(low4, up4), random.uniform(low5, up5), random.uniform(low6, up6), random.uniform(low7, up7), random.uniform(low8, up8), random.uniform(low9, up9), random.uniform(low10, up10), random.uniform(low11, up11), random.uniform(low12, up12), random.uniform(low13, up13), random.uniform(low14, up14), random.uniform(low15, up15), random.uniform(low16, up16), random.uniform(low17, up17), random.uniform(low18, up18), random.uniform(low19, up19), random.uniform(low20, up20), random.uniform(low21, up21), random.uniform(low22, up22), random.uniform(low23, up23) ] def evaluate(individual): bad = individual[0] esail = individual[1] ehm = individual[2] emdc = individual[3] hsr = individual[4] isail = individual[5] jsail = individual[6] lpg = individual[7] psail = individual[8] rootcK = individual[9] rootcR = individual[10] roottcksK = individual[11] roottcksR = individual[12] spanK = individual[13] spanR = individual[14] spl = individual[15] sweepKdeg = individual[16] sweepRdeg = individual[17] tipcK = individual[18] tipcR = individual[19] tiptcksK = individual[20] tiptcksR = individual[21] xcea = individual[22] dim_obj = codecs.open('assets/data/dimensions-new.json', 'r', encoding='utf-8').read() dim = json.loads(dim_obj) # bwl, disp, lcb, lcf, lwl, tc, sailset for item in dim: item = str(item) if item != "category": globals()[item] = np.float(dim[item]) dimapp_obj = codecs.open('assets/data/dimensions-appendages.json', 'r', encoding='utf-8').read() dimapp = json.loads(dimapp_obj) boa = np.float(dimapp["boa"]) fb = np.float(dimapp["fb"]) lr = np.float(dimapp["lr"]) boa = np.float(dimapp["xcea"]) fb = np.float(dimapp["mcrew"]) marcaK = np.float(dimapp["marcaK"]) marcaR = np.float(dimapp["marcaR"]) mcrew = np.float(dimapp["mcrew"]) dimensions = codecs.open('assets/data/dimensions.json', 'r', encoding='utf-8').read() dim = json.loads(dimensions) cb = np.float(dim["cb"]) cm = np.float(dim["cm"]) cp = np.float(dim["cp"]) cwp = np.float(dim["cwp"]) scb = np.float(dim["scb"]) kb = np.float(dim["kb"]) kg = np.float(dim["kg"]) itwp = np.float(dim["itwp"]) GMtrans = np.float(dim["gmt"]) bmt = np.float(dim["bmt"]) alcb_coefficient = np.float(dim["alcb_coefficient"]) awp = bwl * lwl * cwp alcb = lwl * alcb_coefficient * tc am = cm * bwl * tc loa = lwl * 1.1 boa = bwl * 1.2 #vboat = 3 #heel = 20 savefile = "optimizationvpp" results = vpp_solve(sailset, lwl, loa, bwl, tc, disp, lcb, lcf, cb, cm, cp, cwp, awp, alcb, am, boa, scb, kb, kg, itwp, GMtrans, bmt, fb, lr, xcea, mcrew, psail, esail, isail, jsail, bad, spl, lpg, spanR, tipcR, rootcR, tiptcksR, roottcksR, sweepRdeg, spanK, tipcK, rootcK, tiptcksK, roottcksK, sweepKdeg, marcaK, marcaR, ehm, emdc, hsr, savefile) f1 = results[0] f2 = results[1] return f1, f2 ''' def feasible(individual): # https://deap.readthedocs.io/en/master/tutorials/advanced/constraints.html # returns true if feasible, false otherwise # adicionar um counter para cada violacao lwl = individual[0] bwl = individual[1] cb = individual[5] tc = individual[2] cwp = individual[6] disp = lwl*bwl*tc*cb awp = bwl*lwl*cwp br = 40 # between 28 and 56 boa = bwl*1.2 loa = lwl*1.05 dispmass = disp*1025 ssv = boa**2/(br*tc*disp**(1/3)) avs = 110+(400/(ssv-10)) # angle of vanishing stability cs = boa*3.28084/(dispmass*2.20462/64)**(1/3) # capsize screening factor if (lwl/bwl) > 5 or (lwl/bwl) < 2.73: if (bwl/tc) > 19.39 or (bwl/tc) < 2.46: if (lwl/disp**(1/3)) > 8.5 or (lwl/disp**(1/3)) < 4.34: if (awp/disp**(2/3)) > 12.67 or (awp/disp**(2/3)) < 3.78: if avs > 50: #UPDATE if cs < 2: return True else: return False else: return False else: return False else: return False else: return False else: return False ''' creator.create("FitnessMulti", base.Fitness, weights=(weight1, weight2)) creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMulti) toolbox = base.Toolbox() toolbox.register( "attr_float", uniform, bound_low1, bound_up1, bound_low2, bound_up2, bound_low3, bound_up3, bound_low4, bound_up4, bound_low5, bound_up5, bound_low6, bound_up6, bound_low7, bound_up7, bound_low8, bound_up8, bound_low9, bound_up9, bound_low10, bound_up10, bound_low11, bound_up11, bound_low12, bound_up12, bound_low13, bound_up13, bound_low14, bound_up14, bound_low15, bound_up15, bound_low16, bound_up16, bound_low17, bound_up17, bound_low18, bound_up18, bound_low19, bound_up19, bound_low20, bound_up20, bound_low21, bound_up21, bound_low22, bound_up22, bound_low23, bound_up23) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("evaluate", evaluate) toolbox.register("mate", tools.cxSimulatedBinaryBounded, low=[ bound_low1, bound_low2, bound_low3, bound_low4, bound_low5, bound_low6, bound_low7, bound_low8, bound_low9, bound_low10, bound_low11, bound_low12, bound_low13, bound_low14, bound_low15, bound_low16, bound_low17, bound_low18, bound_low19, bound_low20, bound_low21, bound_low22, bound_low23 ], up=[ bound_up1, bound_up2, bound_up3, bound_up4, bound_up5, bound_up6, bound_up7, bound_up8, bound_up9, bound_up10, bound_up11, bound_up12, bound_up13, bound_up14, bound_up15, bound_up16, bound_up17, bound_up18, bound_up19, bound_up20, bound_up21, bound_up22, bound_up23 ], eta=eta_value) toolbox.register("mutate", tools.mutPolynomialBounded, low=[ bound_low1, bound_low2, bound_low3, bound_low4, bound_low5, bound_low6, bound_low7, bound_low8, bound_low9, bound_low10, bound_low11, bound_low12, bound_low13, bound_low14, bound_low15, bound_low16, bound_low17, bound_low18, bound_low19, bound_low20, bound_low21, bound_low22, bound_low23 ], up=[ bound_up1, bound_up2, bound_up3, bound_up4, bound_up5, bound_up6, bound_up7, bound_up8, bound_up9, bound_up10, bound_up11, bound_up12, bound_up13, bound_up14, bound_up15, bound_up16, bound_up17, bound_up18, bound_up19, bound_up20, bound_up21, bound_up22, bound_up23 ], eta=eta_value, indpb=indpb_value) if gamethod == 1: toolbox.register("select", tools.selNSGA2) elif gamethod == 2: toolbox.register("select", tools.selSPEA2) history = History() toolbox.decorate("mate", history.decorator) toolbox.decorate("mutate", history.decorator) #toolbox.decorate("evaluate", tools.DeltaPenalty(feasible, 99999) toolbox.pop_size = pop_size toolbox.children_size = children_size toolbox.max_gen = max_gen toolbox.mut_prob = mut_prob hof = tools.HallOfFame(halloffame_number) stats_fit = tools.Statistics(key=lambda ind: ind.fitness.values) stats_size = tools.Statistics(key=len) mstats = tools.MultiStatistics(fitness=stats_fit, size=stats_size) mstats.register("avg", np.mean, axis=0) mstats.register("std", np.std, axis=0) mstats.register("min", np.min, axis=0) mstats.register("max", np.max, axis=0) logbook = tools.Logbook() logbook.header = "gen", "evals", "fitness", "size" logbook.chapters["fitness"].header = "std", "min", "avg", "max", logbook.chapters["size"].header = "min", "avg", "max" ### RUN MODEL def run_ea(toolbox, stats=mstats, verbose=False): pop = toolbox.population(n=toolbox.pop_size) history.update(pop) pop = toolbox.select(pop, len(pop)) return algorithms.eaMuPlusLambda(pop, toolbox, mu=toolbox.pop_size, lambda_=toolbox.children_size, cxpb=1 - toolbox.mut_prob, mutpb=toolbox.mut_prob, stats=mstats, halloffame=hof, ngen=toolbox.max_gen, verbose=False) res, logbook = run_ea(toolbox, stats=mstats) fronts = tools.emo.sortLogNondominated(res, len(res)) ### PLOTS par1 = [] for i, inds in enumerate(fronts): # two set of values, Im getting only one par = [toolbox.evaluate(ind) for ind in inds] if i == 0: par1 = par flength = len(history.genealogy_history) f1, f2, index = np.zeros(flength), np.zeros(flength), np.zeros(flength) x1, x2, x3, x4, x5, x6, x7 = np.zeros(len(res)), np.zeros( len(res)), np.zeros(len(res)), np.zeros(len(res)), np.zeros( len(res)), np.zeros(len(res)), np.zeros(len(res)) for i in range(1, flength): f1[i] = np.float(evaluate(history.genealogy_history[i + 1])[0]) f2[i] = np.float(evaluate(history.genealogy_history[i + 1])[1]) index[i] = i return f1, f2, index
def eaSimple(self, population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__): history = History() toolbox.decorate("mate", history.decorator) toolbox.decorate("mutate", history.decorator) history.update(population) logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit if halloffame is not None: halloffame.update(population) record = stats.compile(population) if stats 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): self.current_generation += 1 # Select the next generation individuals old_offspring = deepcopy(population) offspring = toolbox.select(population, len(population)) # Vary the pool of individuals new_offspring = varAnd(offspring, toolbox, cxpb, mutpb) hash_models_deap(old_offspring, new_offspring, self.genome_set, self.models_set) # Evaluate the individuals with an invalid fitness invalid_ind = [ ind for ind in new_offspring if not ind.fitness.valid ] valid_ind = [ind for ind in new_offspring if ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit for ind in valid_ind: ind['age'] += 1 # Update the hall of fame with the generated individuals if halloffame is not None: halloffame.update(new_offspring) # Replace the current population by the offspring population[:] = new_offspring # Append the current generation statistics to the logbook record = stats.compile(population) if stats else {} logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print(logbook.stream) pop_stats = self.calculate_stats(self.population) for stat, val in pop_stats.items(): global_vars.get('sacred_ex').log_scalar( f'avg_{stat}', val, self.current_generation) self.write_to_csv({k: str(v) for k, v in pop_stats.items()}, self.current_generation) self.print_to_evolution_file(self.population, self.current_generation) graph = networkx.DiGraph(history.genealogy_tree) graph = graph.reverse() colors = [ toolbox.evaluate(history.genealogy_history[i])[0] for i in graph ] positions = networkx.drawing.nx_agraph.graphviz_layout(graph, prog="dot") networkx.draw_networkx_labels(graph, positions) networkx.draw(graph, positions, node_color=colors) with open(f'{self.exp_folder}/{self.exp_name}_genealogy_models.txt', "w") as text_file: text_file.write( pretty_print_population({ idx: pop['model'] for idx, pop in history.genealogy_history.items() })) plt.savefig(f'{self.exp_folder}/{self.exp_name}_genealogy.png') global_vars.get('sacred_ex').add_artifact( f'{self.exp_folder}/{self.exp_name}_genealogy.png') global_vars.get('sacred_ex').add_artifact( f'{self.exp_folder}/{self.exp_name}_genealogy_models.txt') return population, logbook
import numpy # Used for statistics from deap import algorithms from deap import base from deap import tools # ----------------------------------------------------------------------------- # Global variables #----------------------------------------------------------------------------- # Allowable characters include all uppercase letters and space # You can change these, just be consistent (e.g. in mutate operator) VALID_CHARS = string.ascii_uppercase + " " # Control whether all Messages are printed as they are evaluated VERBOSE = True history = History() #----------------------------------------------------------------------------- # Message object to use in evolutionary algorithm #----------------------------------------------------------------------------- class FitnessMinimizeSingle(base.Fitness): """ Class representing the fitness of a given individual, with a single objective that we want to minimize (weight = -1) """ weights = (-1.0, ) class Message(list):
def __call__(self, fixed_schedule_part, initial_schedule, current_time=0, initial_population=None): print("Evaluating...") toolbox.register( "evaluate", ga_functions.build_fitness(fixed_schedule_part, current_time)) toolbox.register( "attr_bool", ga_functions.build_initial(fixed_schedule_part, current_time)) # Structure initializers toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_bool) toolbox.register("population", tools.initRepeat, list, toolbox.individual) ga_functions.initial_chromosome = GAFunctions2.schedule_to_chromosome( initial_schedule, fixed_schedule_part) if initial_population is None: initial_population = [] if ga_functions.initial_chromosome is None: print("empty_init_solutions") init_solutions = [] else: init_solutions = [ creator.Individual( copy.deepcopy(ga_functions.initial_chromosome)) for _ in range(int(POPSIZE * INIT_SCHED_PERCENT)) ] pop = initial_population + toolbox.population( n=POPSIZE - len(initial_population) - len(init_solutions)) + init_solutions ## TODO: experimental change history = History() # Decorate the variation operators #toolbox.decorate("mate", history.decorator) # toolbox.decorate("mutate", history.decorator) # Create the population and populate the history #history.update(pop) #=================================================== hallOfFame = deap.tools.HallOfFame(5) stats = tools.Statistics(key=lambda x: 1 / x.fitness.values[0]) stats.register("min", numpy.min) stats.register("max", numpy.max) stats.register("avg", numpy.mean) stats.register("std", numpy.std) logbook = tools.Logbook() logbook.header = ["gen"] + stats.fields # Evaluate the entire population fitnesses = list(map(toolbox.evaluate, pop)) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit previous_raised_avr_individuals = [] # Begin the evolution res_list = [0 for _ in range(NGEN)] print(NGEN) for g in range(NGEN): if self.is_stopped(): break hallOfFame.update(pop) # logbook.record(pop=copy.deepcopy(pop)) # check if evolution process has stopped # if (check_evolution_for_stopping is True) and len(previous_raised_avr_individuals) == repeated_best_count: # length = len(previous_raised_avr_individuals) # whole_sum = sum(previous_raised_avr_individuals) # mean = whole_sum / length # sum2 = sum(abs(x - mean) for x in previous_raised_avr_individuals) # std = sum2/length # ## TODO: uncomment it later. output # # print("std: " + str(std)) # if std < 0.0001: # print(" Evolution process has stopped at " + str(g) + " iteration") # res = self._get_result() # extended_result = (res[0], res[1], res[2], res[3], g) # self._save_result(extended_result) # break # print("-- Generation %i --" % g) # Select the next generation individuals offspring = pop #toolbox.select(pop, len(pop)) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < CXPB: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values for mutant in offspring: if random.random() < SWEEPMUTPB: ga_functions.sweep_mutation(mutant) del mutant.fitness.values continue if 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 = list(map(toolbox.evaluate, invalid_ind)) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit #pop[:] = offspring # mix with the best individuals of the time sorted_pop = sorted(pop + list(hallOfFame) + offspring, key=lambda x: x.fitness.values, reverse=True) pop = sorted_pop[:Kbest:] + toolbox.select( sorted_pop[Kbest:], POPSIZE - Kbest) # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in pop] length = len(pop) mean = sum(fits) / length sum2 = sum(x * x for x in fits) std = abs(sum2 / length - mean**2)**0.5 worst = 1 / min(fits) best = 1 / max(fits) avg = 1 / mean data = stats.compile(pop) logbook.record(gen=g, **data) res_list[g] = res_list[g] + data['min'] if not is_silent: print(logbook.stream) # print("-- Generation %i --" % g) # print(" Worst %s" % str(worst)) # print(" Best %s" % str(best)) # print(" Avg %s" % str(avr)) # print(" Std %s" % str(1/std)) best = self._find_best(pop) # the last component is iteration number when evolution stopped result = (best, pop, fixed_schedule_part, current_time, g) self._save_result(result) self._save_pop(pop) if len(previous_raised_avr_individuals ) == repeated_best_count: previous_raised_avr_individuals = previous_raised_avr_individuals[ 1::] previous_raised_avr_individuals.append(1 / mean) pass # # import matplotlib.pyplot as plt # import networkx # # graph = networkx.DiGraph(history.genealogy_tree) # graph = graph.reverse() # Make the grah top-down # colors = [toolbox.evaluate(history.genealogy_history[i])[0] for i in graph] # networkx.draw(graph, node_color=colors) # plt.show() # best = self._find_best(pop) # self._save_result((best, pop, fixed_schedule_part, current_time)) ## return the best fitted individual and resulted population print("Ready") return self.get_result(), logbook