def __init__(self, nth_gen, n_plots=4) -> None: super().__init__() self.nth_gen = nth_gen self.term = MultiObjectiveSpaceToleranceTermination( renormalize=True, all_to_current=True, hist_of_metrics=True, n_hist=None) self.hist = [] self.n_hist = n_plots
class MultiObjectiveDisplay(Display): def __init__(self, **kwargs): super().__init__(**kwargs) self.term = MultiObjectiveSpaceToleranceTermination() 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, zero_to_one=True).do(_F), GD( self.pf, zero_to_one=True).do(_F) if problem.n_obj == 2: hv = Hypervolume(pf=self.pf, zero_to_one=True).do(_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)
class MultiObjectiveDisplay(Display): def __init__(self, **kwargs): super().__init__(**kwargs) self.term = MultiObjectiveSpaceToleranceTermination() 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 __init__(self, x_tol=1e-8, cv_tol=1e-6, f_tol=0.0025, nth_gen=5, n_last=30, **kwargs) -> None: super().__init__( DesignSpaceToleranceTermination(tol=x_tol, n_last=n_last), ConstraintViolationToleranceTermination(tol=cv_tol, n_last=n_last), MultiObjectiveSpaceToleranceTermination(tol=f_tol, n_last=n_last, nth_gen=nth_gen), **kwargs)
def __init__(self, x_tol=1e-6, cv_tol=1e-6, f_tol=0.0025, nth_gen=5, n_last=30, **kwargs) -> None: super().__init__( cv_tol, x_tol, MultiObjectiveSpaceToleranceTermination(tol=f_tol, n_last=n_last, nth_gen=nth_gen), nth_gen, n_last, **kwargs)
def get_termination_for_variables(max_iterations: int = 25): """ Returns the termination criteria for the blackbox optimization problem """ # tol: the tolerance in the objective space on average # n_last: it considers the maximum of the last n elements in a sliding window as a worst case # nth_gen: the termination criterion is computed every n generations # n_max_gen: if the algorithm never converges, stop after n generations termination = MultiObjectiveSpaceToleranceTermination( tol=0.0025, n_last=30, nth_gen=5, n_max_gen=max_iterations, n_max_evals=None) return termination
from pymoo.algorithms.nsga2 import NSGA2 from pymoo.factory import get_problem from pymoo.operators.crossover.simulated_binary_crossover import SimulatedBinaryCrossover from pymoo.operators.mutation.polynomial_mutation import PolynomialMutation from pymoo.optimize import minimize from pymoo.util.termination.f_tol import MultiObjectiveSpaceToleranceTermination from pymoo.visualization.scatter import Scatter problem = get_problem("welded_beam") algorithm = NSGA2( pop_size=200, crossover=SimulatedBinaryCrossover(eta=20, prob=0.9), mutation=PolynomialMutation(prob=0.25, eta=40), ) termination = MultiObjectiveSpaceToleranceTermination(n_last=60) res = minimize(problem, algorithm, pf=False, seed=10, verbose=True) print(res.algorithm.n_gen) Scatter().add(res.F, s=20).add(problem.pareto_front(), plot_type="line", color="black").show()
def __init__(self, **kwargs): super().__init__(**kwargs) self.term = MultiObjectiveSpaceToleranceTermination()
class RunningMetric(Callback): def __init__(self, nth_gen, n_plots=4) -> None: super().__init__() self.nth_gen = nth_gen self.term = MultiObjectiveSpaceToleranceTermination( renormalize=True, all_to_current=True, hist_of_metrics=True, n_hist=None) self.hist = [] self.n_hist = n_plots def notify(self, algorithm): self.term.do_continue(algorithm) t = algorithm.n_gen def press(event): if event.key == 'q': algorithm.termination.force_termination = True fig = plt.figure() fig.canvas.mpl_connect('key_press_event', press) if t > 0 and t % self.nth_gen == 0: for k, f in self.hist: plt.plot(np.arange(len(f)), f, label="t=%s" % k, alpha=0.6, linewidth=3) _delta_f = self.term.metric()["delta_f"] plt.plot(np.arange(len(_delta_f)), _delta_f, label="t=%s (*)" % t, alpha=0.9, linewidth=3) _delta_ideal = [ m['delta_ideal'] > 0.005 for m in self.term.hist_metrics ] _delta_nadir = [ m['delta_nadir'] > 0.005 for m in self.term.hist_metrics ] for k in range(len(_delta_ideal)): if _delta_ideal[k] or _delta_nadir[k]: plt.plot([k, k], [0, _delta_f[k]], color="black", linewidth=0.5, alpha=0.5) plt.plot([k], [_delta_f[k]], "o", color="black", alpha=0.5, markersize=2) self.hist.append((t, _delta_f)) if self.n_hist is not None: self.hist = self.hist[-(self.n_hist - 1):] plt.yscale("symlog") plt.legend() plt.xlabel("Generation") plt.ylabel("$\Delta \, f$", rotation=0) plt.draw() plt.waitforbuttonpress() fig.clf() plt.close(fig)
from pymoo.algorithms.nsga2 import NSGA2 from pymoo.factory import get_problem from pymoo.optimize import minimize from pymoo.util.termination.f_tol import MultiObjectiveSpaceToleranceTermination from pymoo.visualization.scatter import Scatter problem = get_problem("zdt3") algorithm = NSGA2(pop_size=100) termination = MultiObjectiveSpaceToleranceTermination(tol=0.0025, n_last=30, nth_gen=5, n_max_gen=None, n_max_evals=None) res = minimize(problem, algorithm, termination, pf=True, seed=1, verbose=False) print("Generations", res.algorithm.n_gen) plot = Scatter(title="ZDT3") plot.add(problem.pareto_front(use_cache=False, flatten=False), plot_type="line", color="black") plot.add(res.F, color="red", alpha=0.8, s=20) plot.show()