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
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.performance_indicator.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.performance_indicator.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