def _metric(self, data): ret = super()._metric(data) if not self.sliding_window: data = self.data[-self.metric_window_size:] # get necessary data from the current population current = data[-1] c_F, c_ideal, c_nadir = current["F"], current["ideal"], current[ "nadir"] # normalize all previous generations with respect to current ideal and nadir N = [normalize(e["F"], c_ideal, c_nadir) for e in data] # check if the movement of all points is significant if self.all_to_current: c_N = normalize(c_F, c_ideal, c_nadir) if self.perf_indicator == "igd": delta_f = [IGD(c_N).calc(N[k]) for k in range(len(N))] elif self.perf_indicator == "hv": # delta_f = [IGDPlus(c_N).calc(N[k]) for k in range(len(N))] hv = Hypervolume(ref_point=np.ones(c_F.shape[1])) delta_f = [hv.calc(N[k]) for k in range(len(N))] else: delta_f = [IGD(N[k + 1]).calc(N[k]) for k in range(len(N) - 1)] ret["delta_f"] = delta_f return ret
def run(countryname, capacity): problem = ScheduleProblem(country_name=countryname, critical_capacity=capacity, record_all=True) algorithm = NSGA2( pop_size=100, n_offsprings=100, sampling=get_sampling("int_random"), crossover=get_crossover("int_sbx", prob=0.9, eta=15), mutation=get_mutation("int_pm", eta=20), eliminate_duplicates=True ) termination = get_termination("n_gen", 100) res = minimize(problem, algorithm, termination, seed=1, pf=problem.pareto_front(use_cache=False), save_history=True, verbose=True) # create the performance indicator object with reference point (4,4) metric = Hypervolume(ref_point=np.array([1.0, 1.0])) # collect the population in each generation pop_each_gen = [a.pop for a in res.history] with open("./experiments/ga_{}_lastpop.json".format(countryname), 'w') as f: json.dump( {"df":[e.to_dict() for e in problem.last[0]],"x":problem.last[1].tolist()}, f) with open("./experiments/ga_{}_lastobj.json".format(countryname), 'w') as f: json.dump( {"deaths": problem.last_objectives[0].tolist(), "activity":problem.last_objectives[1].tolist()} , f) # Objective Space fig = plt.figure() plot = Scatter(title = "Objective Space") plot.add(res.F) plt.savefig("./experiments/ga_{}_objective.png".format(countryname)) # receive the population in each generation obj_and_feasible_each_gen = [pop[pop.get("feasible")[:,0]].get("F") for pop in pop_each_gen] # calculate for each generation the HV metric hv = [metric.calc(f) for f in obj_and_feasible_each_gen] # function evaluations at each snapshot n_evals = np.array([a.evaluator.n_eval for a in res.history]) # visualize the convergence curve fig = plt.figure() plt.plot(n_evals, hv, '-o') plt.title("Convergence") plt.xlabel("Function Evaluations") plt.ylabel("Hypervolume") plt.savefig("./experiments/ga_{}_hypervolume.png".format(countryname)) plt.show()
def run_fi_optimization(ALG, state, metrics, constraints, seeds, config, n_gens, opt_i, feas_mask, infeas_mask): """ Run one optimziation phase with feasible-infeasible method. """ # print(feas_mask, infeas_mask) pop_size = config.pop_size // 2 # Half for each population. feas_algo = NSGA2_FI( pop_size=pop_size, sampling=seeds[:pop_size] if opt_i == 0 else seeds, mutation=DistrictMutation(state, config.n_districts, config.equality_constraint), crossover=DistrictCross(), callback=partial( opt_callback, text=' Feas HV', HV=Hypervolume(ref_point=np.ones(sum(feas_mask))), pbar=tqdm(total=n_gens, position=0), hypervolume_mask=np.ones( sum(feas_mask), dtype='bool' ) # This gets only 1's because mask is already applied in FI alg. )) feas_algo.hv_history = [] feas_algo.pf_size_history = [] infeas_algo = NSGA2_FI( pop_size=pop_size, sampling=seeds[pop_size:] if opt_i == 0 else seeds, crossover=DistrictCross(), mutation=DistrictMutation(state, config.n_districts, 1.0), selection=TournamentSelection(func_comp=cv_agnostic_binary_tournament), callback=partial( opt_callback, text='InFeas HV', HV=Hypervolume(ref_point=np.ones(sum(infeas_mask))), pbar=tqdm(total=n_gens, position=1), hypervolume_mask=np.ones( sum(infeas_mask), dtype='bool' ) # This gets only 1's because mask is already applied in FI alg. )) problem = DistrictProblemFI(state, n_gens, config, used_metrics=metrics, used_constraints=constraints) result = FI_minimize(problem, feas_algo, infeas_algo, ('n_gen', n_gens), feas_mask=feas_mask, infeas_mask=infeas_mask, verbose=False, seed=0) # print('final', result.F.sum(axis=0)) return result, feas_algo.hv_history #, feas_algo.pf_size_history
def run_optimization(ALG, state, metrics, constraints, seeds, config, n_gens, opt_i): mask = [True] * len(metrics) + ([False] if config.novelty else []) print('Run optimization', len(seeds)) algorithm = ALG( pop_size=config.pop_size, sampling=seeds, crossover=DistrictCross(), mutation=DistrictMutation(state, config.n_districts, config.equality_constraint), callback=partial(opt_callback, text='HV', HV=Hypervolume(ref_point=np.ones(sum(mask))), pbar=tqdm(total=n_gens), hypervolume_mask=mask), ) algorithm.hv_history = [] algorithm.pf_size_history = [] problem = DistrictProblem(state, n_gens, config, used_metrics=metrics, used_constraints=constraints) result = minimize(problem, algorithm, ('n_gen', n_gens), seed=0, verbose=False, save_history=False) # print(algorithm.pop.get('X').shape) #result.F = result.F[:, mask] # result.X = algorithm.pop.get('X') # result.F = algorithm.pop.get('F') # print('Finished optimization', result.F.shape) return result, algorithm.hv_history #, algorithm.pf_size_history
def calc_hypervolume(Y, ref_point, obj_type=None): ''' Calculate hypervolume ''' Y = convert_minimization(Y, obj_type) return Hypervolume(ref_point=ref_point).calc(Y)
def disp_multi_objective(problem, evaluator, algorithm, pf=None): attrs = [('n_gen', algorithm.n_gen, 5), ('n_eval', evaluator.n_eval, 7)] F, CV, feasible = algorithm.pop.get("F", "CV", "feasible") feasible = np.where(feasible[:, 0])[0] if isinstance(pf, bool): if pf: pf = pareto_front_if_possible(problem) else: pf = None if problem.n_constr > 0: attrs.append(disp_cv(CV)) if len(feasible) > 0: if pf is not None: attrs.append( ('igd', format_float(IGD(pf).calc(F[feasible])), width)) attrs.append(('gd', format_float(GD(pf).calc(F[feasible])), width)) if problem.n_obj == 2: attrs.append( ('hv', format_float(Hypervolume(pf=pf).calc(F[feasible])), width)) else: attrs.append(('igd', "-", width)) attrs.append(('gd', "-", width)) if problem.n_obj == 2: attrs.append(('hv', "-", width)) return attrs
def calc_hypervolume(Y, ref_point, obj_type): ''' Calculate hypervolume ''' # convert maximization to minimization Y, ref_point = np.array(Y), np.array(ref_point) if isinstance(obj_type, str): obj_type = [obj_type] * Y.shape[1] assert isinstance(obj_type, Iterable) maxm_idx = np.array(obj_type) == 'max' Y[:, maxm_idx] = -Y[:, maxm_idx] ref_point[maxm_idx] = -ref_point[maxm_idx] # calculate return Hypervolume(ref_point=ref_point).calc(Y)
def _do(self, problem, evaluator, algorithm): super()._do(problem, evaluator, algorithm) F, CV, feasible = algorithm.pop.get("F", "CV", "feasible") feasible = np.where(feasible[:, 0])[0] if problem.n_constr > 0: self.output.append("cv (min)", CV.min()) self.output.append("cv (avg)", np.mean(CV)) if self.pareto_front_is_available: igd, gd, hv = "-", "-", "-" if len(feasible) > 0: _F = algorithm.opt.get("F") igd, gd = IGD(self.pf).calc(_F), GD(self.pf).calc(_F) if problem.n_obj == 2: hv = Hypervolume(pf=self.pf).calc(_F) self.output.extend(*[('igd', igd), ('gd', gd)]) if problem.n_obj == 2: self.output.append("hv", hv) else: self.output.append("n_nds", len(algorithm.opt), width=7) self.term.do_continue(algorithm) max_from, eps = "-", "-" if len(self.term.metrics) > 0: metric = self.term.metrics[-1] tol = self.term.tol delta_ideal, delta_nadir, delta_f = metric[ "delta_ideal"], metric["delta_nadir"], metric["delta_f"] if delta_ideal > tol: max_from = "ideal" eps = delta_ideal elif delta_nadir > tol: max_from = "nadir" eps = delta_nadir else: max_from = "f" eps = delta_f self.output.append("eps", eps) self.output.append("indicator", max_from)
def _do(self, problem, evaluator, algorithm): super()._do(problem, evaluator, algorithm) F, CV, feasible = algorithm.pop.get("F", "CV", "feasible") feasible = np.where(feasible[:, 0])[0] if problem.n_constr > 0: self.output.append("cv (min)", CV.min()) self.output.append("cv (avg)", np.mean(CV)) if self.pareto_front_is_available: igd, gd, hv = "-", "-", "-" if len(feasible) > 0: _F = algorithm.opt.get("F") igd, gd = IGD(self.pf).calc(_F), GD(self.pf).calc(_F) if problem.n_obj == 2: hv = Hypervolume(pf=self.pf).calc(_F) self.output.extend(*[('igd', igd), ('gd', gd)]) if problem.n_obj == 2: self.output.append("hv", hv) else: self.output.append("n_nds", len(algorithm.opt), width=7) self.term.do_continue(algorithm) delta_ideal, delta_nadir, delta_f, hist_delta_max = "-", "-", "-", "-" metric = self.term.metric() if metric is not None: delta_ideal = metric["delta_ideal"] delta_nadir = metric["delta_nadir"] delta_f = metric["delta_f"] hist_delta_max = metric["max_delta_all"] self.output.append("delta_ideal", delta_ideal) self.output.append("delta_nadir", delta_nadir) self.output.append("delta_f", delta_f) self.output.append("delta_max", max(delta_ideal, delta_nadir, delta_f)) self.output.append("hist_delta_max", hist_delta_max, width=13)
def _do(self, problem, evaluator, algorithm): super()._do(problem, evaluator, algorithm) F, CV, feasible = algorithm.pop.get("F", "CV", "feasible") feasible = np.where(feasible[:, 0])[0] if problem.n_constr > 0: self.output.append("cv (min)", CV.min()) self.output.append("cv (avg)", np.mean(CV)) if len(feasible) > 0: if self.pareto_front_is_available: _F = F[feasible] self.output.append("igd", IGD(self.pf).calc(_F)) self.output.append("gd", GD(self.pf).calc(_F)) if problem.n_obj == 2: self.output.append("hv", Hypervolume(pf=self.pf).calc(_F)) else: if self.pareto_front_is_available: self.output.extend(*[('igd', "-"), ('gd', "-")]) if problem.n_obj == 2: self.output.append("hv", "-")
# important methods -> ref_point problem = "zdt6" ref_point = np.array([1, 9.735527117321219]) if problem.startswith("zdt"): pf = get_problem(problem).pareto_front() # Dtlz-5 to dtlz-7 have their own files related to their pareto fronts elif problem == "dtlz5" or problem == "dtlz6" or problem == "dtlz7": pf = get_problem(problem, n_var=N_VAR,n_obj=N_OBJ).pareto_front() else: ref_dirs = get_reference_directions("das-dennis", 3, n_partitions=12) pf = get_problem(problem, n_var=N_VAR,n_obj=N_OBJ).pareto_front(ref_dirs=ref_dirs) metric = Hypervolume(pf=pf, ref_point=ref_point, normalize=True) # dtlz-1 -> [482.1632866685836,479.911835933397,471.9731868733398] # dtlz-2 -> [2.651414902010465,2.5206368624614965,2.656093434231162] # dtlz-3 -> [1784.9822112456513,1683.7871520696372,1679.1459524987113] # dtlz-4 -> [2.7493608245409247,2.665459302333755,2.691506519652278] # dtlz-5 -> [2.6184046195044153,2.3154562025982375,2.490037232873547] # dtlz-6 -> [10.460414515081052,10.523716498291654,10.571261523682367] # dtlz-7 -> [1,1,24.464595045398383] # zdt-1 -> [1, 5.687041127771669] # zdt-2 -> [1, 6.71194298397789] # zdt-3 -> [1, 6.020951819554247] # zdt-4 -> [1, 129.8511197453462] # zdt-6 -> [1, 9.735527117321219]
import numpy as np import pandas as pd import matplotlib.pyplot as plt from pymoo.factory import get_problem, get_performance_indicator, get_reference_directions, get_visualization from pymoo.performance_indicator.hv import Hypervolume import os import sys import json # important methods -> ref_point problem = "dtlz7" ref_point = np.array([1, 1, 25.5569793232092]) metric = Hypervolume(ref_point=ref_point) # dtlz-1 -> [ 471.3117071532848 , 435.8374989915892 , 472.2238634974974] # dtlz-2 -> [ 2.6494714115367466 ,2.4976230873112413 , 2.5731274054646143] # dtlz-3 -> [ 1637.6728744970585 , 1673.0108237192817 , 1808.6984346000695] # dtlz-4 -> [ 2.6253637741130307 , 2.353665286189082 , 2.4351708177608087] # dtlz-5 -> [ 2.269162767609037 , 2.2304768511412387 , 2.68580157047176] # dtlz-6 -> [ 10.59185298644897 , 10.524986132238132 , 10.632515988282993] # dtlz-7 -> [ 1, 1, 25.5569793232092 ] # zdt-1 -> [1, 6.775886488298255] # zdt-2 -> [1, 6.935060239453283] # zdt-3 -> [1, 6.955305612890139] # zdt-4 -> [1, 157.21179819263173] # zdt-6 -> [1, 9.477411646692643] # general constants NUM_EXECS = 30
cv.append(opt.get("CV").min()) # filter out only the feasible and append feas = np.where(opt.get("feasible"))[0] _F = opt.get("F")[feas] F.append(_F) ''' === Hypvervolume (HV) === ''' import matplotlib.pyplot as plt from pymoo.performance_indicator.hv import Hypervolume # MODIFY - this is problem dependend ref_point = np.array([1.0, 1.0]) # create the performance indicator object with reference point metric = Hypervolume(ref_point=ref_point, normalize=False) # calculate for each generation the HV metric hv = [metric.calc(f) for f in F] fig = plt.figure() # visualze the convergence curve plt.plot(n_evals, hv, '-o', markersize=4, linewidth=2) plt.title("Convergence") plt.xlabel("Function Evaluations") plt.ylabel("Hypervolume") # fig.savefig(LATEX_DIR + 'convergence.eps', format='eps') plt.show() from pymoo.factory import get_visualization, get_decomposition
import numpy as np import pandas as pd import matplotlib.pyplot as plt from pymoo.factory import get_problem, get_performance_indicator, get_reference_directions, get_visualization from pymoo.performance_indicator.hv import Hypervolume import os import sys # important methods -> ref_point ref_point = np.array([500.0, 500.0, 500.0]) metric = Hypervolume(ref_point=ref_point, normalize=False) problem = "dtlz1" # 1 -> [488.4435867485893 ,471.03860764532106 , 501.59485141330845 ] # 2 -> [ 2.7640053099955044, 2.5431893060817545 , 2.676556552035201] # 3 -> [ 1692.099007341335 , 1678.2523471910183 , 1812.180711990459 ] # 4 -> [ 2.80704182512513 , 2.6906135709301386 , 2.534695795120166] # 5 -> [ 2.352652061652649 , 2.504239438737515 , 2.7298272947925213] # 6 -> [ 10.548625453871612 , 10.612209406392823 , 10.634665459827534 ] # 7 -> [ 1, 1, 27.9038366074846 ] # general constants NUM_EXECS = 30 variants = [ "rand1", "rand2", "best1", "best2", "currtobest1", "pbest/P-0.05", "pbest/P-0.1", "pbest/P-0.15", "pbest/P-0.2" ] # base_path = "/home/nick/.go-de/mode/paretoFront/" + problem + "/" # data for the plot HVData = []
def calc(self, F, others=None, calc_hv=True): """ This method calculates the R-IGD and R-HV based off of the values provided. Parameters ---------- F : numpy.ndarray The objective space values others : numpy.ndarray Results from other algorithms which should be used for filtering nds solutions calc_hv : bool Whether the hv is calculate - (None if more than 3 dimensions) Returns ------- rigd : float R-IGD rhv : float R-HV if calc_hv is true and less or equal to 3 dimensions """ self.F, self.others = F, others translated = [] final_PF = [] # 1. Prescreen Procedure - NDS Filtering pop = self._filter() pf = self.pf if pf is None: pf = self.problem.pareto_front() if pf is None: raise Exception( "Please provide the Pareto front to calculate the R-Metric!" ) labels = np.argmin(cdist(pop, self.ref_points), axis=1) for i in range(len(self.ref_points)): cluster = pop[np.where(labels == i)] if len(cluster) != 0: # 2. Representative Point Identification zp = self._preprocess( cluster, self.ref_points[i], w_point=self.w_points[i] )[0] # 3. Filtering Procedure - Filter points trimmed_data = self._trim(cluster, zp, range=self.delta) # 4. Solution Translation pop_t = self._translate( zp, trimmed_data, self.ref_points[i], w_point=self.w_points[i] ) translated.extend(pop_t) # 5. R-Metric Computation target = self._preprocess( data=pf, ref_point=self.ref_points[i], w_point=self.w_points[i] ) PF = self._trim(pf, target) final_PF.extend(PF) translated = np.array(translated) final_PF = np.array(final_PF) rigd, rhv = None, None if len(translated) > 0: # IGD Computation rigd = IGD(final_PF).calc(translated) nadir_point = np.amax(self.w_points, axis=0) front = translated dim = self.ref_points[0].shape[0] if calc_hv: if dim <= 3: try: rhv = Hypervolume(ref_point=nadir_point).calc(front) except: pass if calc_hv: return rigd, rhv else: return rigd
import numpy as np import pandas as pd import matplotlib.pyplot as plt from pymoo.factory import get_problem, get_performance_indicator, get_reference_directions, get_visualization from pymoo.performance_indicator.hv import Hypervolume import os import sys # important methods -> ref_point ref_point = np.array([ 2.9699152058577947 , 4.985423795813952, 6.988314095918014]) metric = Hypervolume(ref_point=ref_point, normalize=False) problem = "wfg1" # 1 -> [488.4435867485893 ,471.03860764532106 , 501.59485141330845 ] # 2 -> [ 2.7640053099955044, 2.5431893060817545 , 2.676556552035201] # 3 -> [ 1692.099007341335 , 1678.2523471910183 , 1812.180711990459 ] # 4 -> [ 2.80704182512513 , 2.6906135709301386 , 2.534695795120166] # 5 -> [ 2.352652061652649 , 2.504239438737515 , 2.7298272947925213] # 6 -> [ 10.548625453871612 , 10.612209406392823 , 10.634665459827534 ] # 7 -> [ 1, 1, 27.9038366074846 ] # WFGS # 1 -> [ 2.9699152058577947 , 4.985423795813952, 6.988314095918014] # general constants NUM_EXECS = 30 variants = ["rand1", "rand2", "best1", "best2", "currtobest1", "pbest/P-0.05", "pbest/P-0.1", "pbest/P-0.15", "pbest/P-0.2"] # base_path = "/home/nick/.gode/mode/paretoFront/" + problem + "/" # data for the plot HVData = []
seed =1, pf = problem.pareto_front(use_cache=False), save_history=True, verbose= True) Scatter().add(res.F).show() dspace = res.pop.get("X") reynolds = dspace[:,0] pitch= dspace[:,1] depth = dspace[:,2] #print(dspace) metric = Hypervolume(ref_point=np.array([1.0, 1.0])) # collect the population in each generation pop_each_gen = [a.pop for a in res.history] # receive the population in each generation obj_and_feasible_each_gen = [pop[pop.get("feasible")[:,0]].get("F") for pop in pop_each_gen] # calculate for each generation the HV metric hv = [metric.calc(f) for f in obj_and_feasible_each_gen] # visualze the convergence curve plt.plot(np.arange(len(hv)), hv, '-o') plt.title("Convergence") plt.xlabel("Generation") plt.ylabel("Hypervolume")
# i - 1, because generation 1 has index 0 for i in generations2plot: plt.scatter(-history[i-1][:,0],-history[i-1][:,1]) ax4.set_xlabel('Total profit [US$]') ax4.set_ylabel('Natural Vegetation [hectar]') plt.plot(revenue[0],area[0], "sr") plt.legend(["initial", 500, 1000, 1500, 2000, 2500, 3000]) #plt.savefig(default_directory+"/figures/pareto_front_over_generations.png") plt.show() # Hypervolume from pymoo.performance_indicator.hv import Hypervolume # make an array of the generation numbers n_gen = np.array(range(1,len(history)+1)) # set reference point ref_point = np.array([0.0, 0.0]) # create the performance indicator object with reference point metric = Hypervolume(ref_point=ref_point, normalize=False) # calculate for each generation the HV metric hv = [metric.calc(i) for i in history] # visualze the convergence curve fig5, ax5 = plt.subplots(1) ax5.plot(n_gen, hv, '-o', markersize=4, linewidth=2) ax5.set_xlabel("Generation") ax5.set_ylabel("Hypervolume") #plt.savefig(default_directory+"/figures/hypervolume.png") plt.show()