Пример #1
0
    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).do(N[k]) for k in range(len(N))]
            elif self.perf_indicator == "hv":
                hv = Hypervolume(ref_point=np.ones(c_F.shape[1]))
                delta_f = [hv.do(N[k]) for k in range(len(N))]
        else:
            delta_f = [IGD(N[k + 1]).do(N[k]) for k in range(len(N) - 1)]

        ret["delta_f"] = delta_f

        return ret
Пример #2
0
    def __init__(self, min_igd, pf) -> None:
        super().__init__()
        if pf is None:
            raise Exception(
                "You can only use IGD termination criteria if the pareto front is known!"
            )

        self.obj = IGD(pf)
        self.igd = min_igd
Пример #3
0
    def _metric(self, data):
        last, current = data[-2], data[-1]

        # this is the range between the nadir and the ideal point
        norm = current["nadir"] - current["ideal"]

        # if the range is degenerated (very close to zero) - disable normalization by dividing by one
        norm[norm < 1e-32] = 1

        # calculate the change from last to current in ideal and nadir point
        delta_ideal = calc_delta_norm(current["ideal"], last["ideal"], norm)
        delta_nadir = calc_delta_norm(current["nadir"], last["nadir"], norm)

        # get necessary data from the current population
        c_F, c_ideal, c_nadir = current["F"], current["ideal"], current[
            "nadir"]

        # normalize last and current with respect to most recent ideal and nadir
        c_N = normalize(c_F, c_ideal, c_nadir)
        l_N = normalize(last["F"], c_ideal, c_nadir)

        # calculate IGD from one to another
        delta_f = IGD(c_N).do(l_N)

        return {
            "delta_ideal": delta_ideal,
            "delta_nadir": delta_nadir,
            "delta_f": delta_f
        }
Пример #4
0
def disp_multi_objective(problem, evaluator, D):
    attrs = [('n_gen', D['n_gen'], 5),
             ('n_eval', evaluator.n_eval, 7)]

    pf = problem.pareto_front()
    if pf is not None:
        attrs.append(('igd', "%.5f" % IGD(pf).calc(D['pop'].F), 8))

    return attrs
Пример #5
0
class IGDTermination(Termination):
    def __init__(self, min_igd, pf) -> None:
        super().__init__()
        if pf is None:
            raise Exception(
                "You can only use IGD termination criteria if the pareto front is known!"
            )

        self.obj = IGD(pf)
        self.igd = min_igd

    def _do_continue(self, algorithm):
        F = algorithm.pop.get("F")
        return self.obj.calc(F) > self.igd
Пример #6
0
    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)
Пример #7
0
    def do(self, data, scope=None, benchmark=None, inplace=False, **kwargs):
        assert benchmark is not None, "The benchmark is necessary to retrieve the known optimum of a function"

        problem = benchmark.problems[data["problem"]]["obj"]
        CV, F = from_dict(data, "CV", "F")

        igd = np.inf
        pf = problem.pareto_front(**kwargs)
        if pf is not None:
            igd = IGD(pf, zero_to_one=True).do(F)

        ret = {
            "pf": pf,
            "igd": igd,
        }

        if inplace:
            for k, v in ret.items():
                data[k] = v

        return ret
Пример #8
0
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 problem.n_constr > 0:
        attrs.append(('cv (min/avg)', "%.5f / %.5f" % (np.min(CV), np.mean(CV)), 13))

    if len(feasible) > 0:
        if pf is not None:
            attrs.append(('igd', "%.5f" % IGD(pf).calc(F[feasible]), 8))
            attrs.append(('gd', "%.5f" % GD(pf).calc(F[feasible]), 8))
            if problem.n_obj == 2:
                attrs.append(('hv', "%.5f" % Hypervolume(pf=pf).calc(F[feasible]), 8))
    else:
        attrs.append(('igd', "-", 8))
        attrs.append(('gd', "-", 8))
        if problem.n_obj == 2:
            attrs.append(('hv', "-", 8))

    return attrs
Пример #9
0
    def do(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).do(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).do(front)
                    except:
                        pass

        if calc_hv:
            return rigd, rhv
        else:
            return rigd
Пример #10
0
    def calc(self, hyper_volume=True, delta=0.2, pf=None):
        """
        This method calculates the R-IGD and R-HV based off of the population that was provided
        :return: R-IGD and R-HV
        """
        translated = []
        final_PF = []

        # 1. Prescreen Procedure - NDS Filtering
        pop = self._filter()

        if pf is not None:
            solution = pf
        else:
            solution = self.problem.pareto_front()

        # solution = calc_PF(1, 10000, 2)

        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=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=solution,
                                      ref_point=self.ref_points[i],
                                      w_point=self.w_points[i])
            PF = self._trim(solution, target)
            final_PF.extend(PF)

        translated = np.array(translated)

        if np.size(translated) == 0:
            igd = -1
            volume = -1
        else:
            # IGD Computation
            from pymoo.indicators.igd import IGD
            IGD_ = IGD(final_PF)
            igd = IGD_.calc(translated)
            # HV Computation

            nadir_point = np.amax(self.w_points, axis=0)
            front = translated
            dim = self.ref_points[0].shape[0]
            if hyper_volume:
                if dim < 3:
                    try:
                        # Python
                        from pymoo.indicators.hv import HyperVolume
                        hv = HyperVolume(nadir_point)
                        volume = hv.compute(front)
                    except TypeError:
                        volume = -1

                else:
                    # cpp

                    from pymoo.cpp.hypervolume.build import hypervolume

                    volume = hypervolume.calculate(dim, len(front), front,
                                                   nadir_point)
            else:
                volume = np.nan
        return igd, volume
Пример #11
0
 def _metric(self, data):
     last, current = data[-2], data[-1]
     return IGD(current).do(last)
Пример #12
0
def test_multi_obj(problem, algorithm):
    res = minimize(problem, algorithm, ('n_gen', 300), seed=1, verbose=True)
    pf = problem.pareto_front()
    assert IGD(pf).do(res.F) < 0.05