def EA_Main(locator, building_names, extraCosts, extraCO2, extraPrim, solarFeat, ntwFeat, gv, genCP=0): """ Evolutionary algorithm to optimize the district energy system's design Parameters ---------- locator : string paths to folders finances / CO2 / Prim : float costs [CHF] / emissions [kg CO2-eq] / primary energy needs [MJ oil] previously calculated solarFeat : class solarFeatures includes data from solar files ntwFeat : class ntwFeatures includes data from the ntw optimization genCP : int generation to start the EA from (eg if there was a crash of the code) Returns ------- """ t0 = time.clock() # get number of buildings nBuildings = len(building_names) # set-up toolbox of DEAp library in python (containing the evolutionary algotirhtm creator, toolbox = calc_ea_setup(nBuildings, gv) # define objective function and register into toolbox def evalConfig(ind): (costs, CO2, prim) = eI.evalInd( ind, building_names, locator, extraCosts, extraCO2, extraPrim, solarFeat, ntwFeat, gv ) return (costs, CO2, prim) toolbox.register("evaluate", evalConfig) ntwList = ["1" * nBuildings] epsInd = [] invalid_ind = [] # Evolutionary strategy if genCP is 0: # create population pop = toolbox.population(n=gv.initialInd) # Check network for ind in pop: eI.checkNtw(ind, ntwList, locator, gv) # Evaluate the initial population print "Evaluate initial population" fitnesses = map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit print ind.fitness.values, "fit" # Save initial population print "Save Initial population \n" os.chdir(locator.pathMasterRes) with open("CheckPointInitial", "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=0, networkList=ntwList, epsIndicator=[], testedPop=[]) CPpickle.dump(cp) else: print "Recover from CP " + str(genCP) + "\n" os.chdir(locator.pathMasterRes) with open("CheckPoint" + str(genCP), "rb") as CPread: CPunpick = Unpickler(CPread) cp = CPunpick.load() pop = cp["population"] ntwList = cp["networkList"] epsInd = cp["epsIndicator"] PROBA, SIGMAP = gv.PROBA, gv.SIGMAP # Evolution starts ! g = genCP stopCrit = False # Threshold for the Epsilon indictor, Not used while g < gv.NGEN and not stopCrit and (time.clock() - t0) < gv.maxTime: g += 1 print "Generation", g offspring = list(pop) # Apply crossover and mutation on the pop print "CrossOver" for ind1, ind2 in zip(pop[::2], pop[1::2]): child1, child2 = cx.cxUniform(ind1, ind2, PROBA, gv) offspring += [child1, child2] # First half of the EA: create new un-collerated configurations if g < gv.NGEN / 2: for mutant in pop: print "Mutation Flip" offspring.append(mut.mutFlip(mutant, PROBA, gv)) print "Mutation Shuffle" offspring.append(mut.mutShuffle(mutant, PROBA, gv)) print "Mutation GU \n" offspring.append(mut.mutGU(mutant, PROBA, gv)) # Third quarter of the EA: keep the good individuals but modify the shares uniformly elif g < gv.NGEN * 3 / 4: for mutant in pop: print "Mutation Uniform" offspring.append(mut.mutUniformCap(mutant, gv)) # Last quarter: keep the very good individuals and modify the shares with Gauss distribution else: for mutant in pop: print "Mutation Gauss" offspring.append(mut.mutGaussCap(mutant, SIGMAP, gv)) # Evaluate the individuals with an invalid fitness # NB: every generation leads to the reevaluation of 4n / 2n / 2n individuals # (n being the number of individuals in the previous generation) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] print "Update Network list \n" for ind in invalid_ind: eI.checkNtw(ind, ntwList, locator, gv) print "Re-evaluate the population" fitnesses = map(toolbox.evaluate, invalid_ind) print "......................................." for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit print ind.fitness.values, "new fit" print "....................................... \n" # Select the Pareto Optimal individuals print "Pareto Selection" selection = sel.selectPareto(offspring) # Compute the epsilon criteria [and check the stopping criteria] epsInd.append(eI.epsIndicator(pop, selection)) # if len(epsInd) >1: # eta = (epsInd[-1] - epsInd[-2]) / epsInd[-2] # if eta < gv.epsMargin: # stopCrit = True # The population is entirely replaced by the best individuals print "Replace the population \n" pop[:] = selection print "....................................... \n GENERATION ", g for ind in pop: print ind.fitness.values, "selected fit" print "....................................... \n" # Create Checkpoint if necessary if g % gv.fCheckPoint == 0: os.chdir(locator.pathMasterRes) print "Create CheckPoint", g, "\n" with open("CheckPoint" + str(g), "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=g, networkList=ntwList, epsIndicator=epsInd, testedPop=invalid_ind) CPpickle.dump(cp) if g == gv.NGEN: print "Final Generation reached" else: print "Stopping criteria reached" # Saving the final results print "Save final results. " + str(len(pop)) + " individuals in final population" print "Epsilon indicator", epsInd, "\n" os.chdir(locator.pathMasterRes) with open("CheckPointFinal", "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=g, networkList=ntwList, epsIndicator=epsInd, testedPop=invalid_ind) CPpickle.dump(cp) print "Master Work Complete \n" return pop, epsInd
def normalize_epsIndicator(pathX, generation): """ Calculates the normalized epsilon indicator For all generations, the populations are normalized with regards to the min / max over ALL generations Parameters ---------- pathMasterRes : string path to folder where checkpoints are stored generation : int generation up to which data are extracted pathNtwRes : string path to ntw result folder Returns ------- epsAll : list normalized epsilon indicator from the beginning of the EA to generation """ epsAll = [] allPop = [] allPopNorm = [] # Load the populations i = 1 while i < generation+1: pop, eps, testedPop = sFn.readCheckPoint(pathX, i, storeData = 0) i+=1 allPop.append(pop) # Find the max and min maxCosts =0 minCosts =0 maxCO2 =0 minCO2 =0 maxPrim =0 minPrim =0 for i in range(generation): popScaned = allPop[i] for ind in popScaned: if ind.fitness.values[0] < minCosts: minCosts = ind.fitness.values[0] if ind.fitness.values[0] > maxCosts: maxCosts = ind.fitness.values[0] if ind.fitness.values[1] < minCO2: minCO2 = ind.fitness.values[1] if ind.fitness.values[1] > maxCO2: maxCO2 = ind.fitness.values[1] if ind.fitness.values[2] < minPrim: minPrim = ind.fitness.values[2] if ind.fitness.values[2] > maxPrim: maxPrim = ind.fitness.values[2] # Normalize for k in range(generation): popScaned = allPop[k] popNorm = toolbox.clone(popScaned) for i in range( len( popScaned ) ): ind = popScaned[i] NormCost = (ind.fitness.values[0] - minCosts) / (maxCosts - minCosts) NormCO2 = (ind.fitness.values[1] - minCO2) / (maxCO2 - minCO2) NormPrim = (ind.fitness.values[2] - minPrim) / (maxPrim - minPrim) popNorm[i].fitness.values = (NormCost, NormCO2, NormPrim) allPopNorm.append(popNorm) # Compute the eps indicator for i in range(generation-1): frontOld = allPopNorm[i] frontNew = allPopNorm[i+1] epsAll.append(eI.epsIndicator(frontOld, frontNew)) return epsAll
def EA_Main(locator, building_names, extraCosts, extraCO2, extraPrim, solarFeat, ntwFeat, gv, genCP=0): """ Evolutionary algorithm to optimize the district energy system's design Parameters ---------- locator : string paths to folders finances / CO2 / Prim : float costs [CHF] / emissions [kg CO2-eq] / primary energy needs [MJ oil] previously calculated solarFeat : class solarFeatures includes data from solar files ntwFeat : class ntwFeatures includes data from the ntw optimization genCP : int generation to start the EA from (eg if there was a crash of the code) Returns ------- """ t0 = time.clock() # get number of buildings nBuildings = len(building_names) # set-up toolbox of DEAp library in python (containing the evolutionary algotirhtm creator, toolbox = calc_ea_setup(nBuildings, gv) # define objective function and register into toolbox def evalConfig(ind): (costs, CO2, prim) = eI.evalInd(ind, building_names, locator, extraCosts, extraCO2, extraPrim, solarFeat, ntwFeat, gv) return (costs, CO2, prim) toolbox.register("evaluate", evalConfig) ntwList = ["1" * nBuildings] epsInd = [] invalid_ind = [] # Evolutionary strategy if genCP is 0: # create population pop = toolbox.population(n=gv.initialInd) # Check network for ind in pop: eI.checkNtw(ind, ntwList, locator, gv) # Evaluate the initial population print "Evaluate initial population" fitnesses = map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit print ind.fitness.values, "fit" # Save initial population print "Save Initial population \n" os.chdir(locator.pathMasterRes) with open("CheckPointInitial", "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=0, networkList=ntwList, epsIndicator=[], testedPop=[]) CPpickle.dump(cp) else: print "Recover from CP " + str(genCP) + "\n" os.chdir(locator.pathMasterRes) with open("CheckPoint" + str(genCP), "rb") as CPread: CPunpick = Unpickler(CPread) cp = CPunpick.load() pop = cp["population"] ntwList = cp["networkList"] epsInd = cp["epsIndicator"] PROBA, SIGMAP = gv.PROBA, gv.SIGMAP # Evolution starts ! g = genCP stopCrit = False # Threshold for the Epsilon indictor, Not used while g < gv.NGEN and not stopCrit and (time.clock() - t0) < gv.maxTime: g += 1 print "Generation", g offspring = list(pop) # Apply crossover and mutation on the pop print "CrossOver" for ind1, ind2 in zip(pop[::2], pop[1::2]): child1, child2 = cx.cxUniform(ind1, ind2, PROBA, gv) offspring += [child1, child2] # First half of the EA: create new un-collerated configurations if g < gv.NGEN / 2: for mutant in pop: print "Mutation Flip" offspring.append(mut.mutFlip(mutant, PROBA, gv)) print "Mutation Shuffle" offspring.append(mut.mutShuffle(mutant, PROBA, gv)) print "Mutation GU \n" offspring.append(mut.mutGU(mutant, PROBA, gv)) # Third quarter of the EA: keep the good individuals but modify the shares uniformly elif g < gv.NGEN * 3 / 4: for mutant in pop: print "Mutation Uniform" offspring.append(mut.mutUniformCap(mutant, gv)) # Last quarter: keep the very good individuals and modify the shares with Gauss distribution else: for mutant in pop: print "Mutation Gauss" offspring.append(mut.mutGaussCap(mutant, SIGMAP, gv)) # Evaluate the individuals with an invalid fitness # NB: every generation leads to the reevaluation of 4n / 2n / 2n individuals # (n being the number of individuals in the previous generation) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] print "Update Network list \n" for ind in invalid_ind: eI.checkNtw(ind, ntwList, locator, gv) print "Re-evaluate the population" fitnesses = map(toolbox.evaluate, invalid_ind) print "......................................." for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit print ind.fitness.values, "new fit" print "....................................... \n" # Select the Pareto Optimal individuals print "Pareto Selection" selection = sel.selectPareto(offspring) # Compute the epsilon criteria [and check the stopping criteria] epsInd.append(eI.epsIndicator(pop, selection)) #if len(epsInd) >1: # eta = (epsInd[-1] - epsInd[-2]) / epsInd[-2] # if eta < gv.epsMargin: # stopCrit = True # The population is entirely replaced by the best individuals print "Replace the population \n" pop[:] = selection print "....................................... \n GENERATION ", g for ind in pop: print ind.fitness.values, "selected fit" print "....................................... \n" # Create Checkpoint if necessary if g % gv.fCheckPoint == 0: os.chdir(locator.pathMasterRes) print "Create CheckPoint", g, "\n" with open("CheckPoint" + str(g), "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=g, networkList=ntwList, epsIndicator=epsInd, testedPop=invalid_ind) CPpickle.dump(cp) if g == gv.NGEN: print "Final Generation reached" else: print "Stopping criteria reached" # Saving the final results print "Save final results. " + str( len(pop)) + " individuals in final population" print "Epsilon indicator", epsInd, "\n" os.chdir(locator.pathMasterRes) with open("CheckPointFinal", "wb") as CPwrite: CPpickle = Pickler(CPwrite) cp = dict(population=pop, generation=g, networkList=ntwList, epsIndicator=epsInd, testedPop=invalid_ind) CPpickle.dump(cp) print "Master Work Complete \n" return pop, epsInd