Source code for utilities.quality_indicator


from numba import njit
import numba
import numpy as np
import hvwfg as hv

from desdeo_tools.scalarization import SimpleASF


@njit()
[docs]def epsilon_indicator(s1: np.ndarray, s2: np.ndarray) -> float: """ Computes the additive epsilon-indicator between two solutions. Args: s1 (np.ndarray): Solution 1. Should be an one-dimensional array. s2 (np.ndarray): Solution 2. Should be an one-dimensional array. Returns: float: The maximum distance between the values in s1 and s2. """ eps = 0.0 for i in range(s1.size): value = s2[i] - s1[i] if value > eps: eps = value return eps
@njit()
[docs]def epsilon_indicator_ndims(front: np.ndarray, reference_point: np.ndarray) -> list: """ Computes the additive epsilon-indicator between reference point and current one-dimensional vector of front. Args: front (np.ndarray): The front that the current reference point is being compared to. Should be set of arrays, where the rows are the solutions and the columns are the objective dimensions. reference_point (np.ndarray): The reference point that is compared. Should be one-dimensional array. Returns: list: The list of indicator values. """ min_eps = 0.0 eps_list = np.zeros((front.shape[0]), dtype=numba.float64) for i in np.arange(front.shape[0]): value = np.max(reference_point - front[i]) if value > min_eps: eps_list[i] = value return eps_list
[docs]def preference_indicator(s1: np.ndarray, s2: np.ndarray, min_asf_value: float, ref_point: np.ndarray, delta: float) -> float: """ Computes the preference-based quality indicator. Args: s1 (np.ndarray): Solution 1. Should be an one-dimensional array. s2 (np.ndarray): Solution 2. Should be an one-dimensional array. ref_point (np.ndarray): The reference point should be same shape as front. min_asf_value (float): Minimum value of achievement scalarization of the reference_front. Used in normalization. delta (float): The spesifity delta allows to set the amplification of the indicator to be closer or farther from the reference point. Smaller delta means that all solutions are in smaller range around the reference point. Returns: float: The maximum distance between the values in s1 and s2 taking into account the reference point and spesifity. """ s2_asf = SimpleASF(np.ones_like(s2)) norm = s2_asf(s2, reference_point=ref_point) + delta - min_asf_value return epsilon_indicator(s1, s2) / norm
[docs]def hypervolume_indicator(front: np.ndarray, reference_point: np.ndarray) -> float: """ Computes the hypervolume-indicator between reference front and current approximating point. Args: front (np.ndarray): The front that is compared. Should be set of arrays, where the rows are the solutions and the columns are the objective dimensions. reference_point (np.ndarray): The reference point that the current front is being compared to. Should be 1D array. Returns: float: Measures the volume of the objective space dominated by an approximation set. """ ref = np.asarray(reference_point, dtype='double') # hv.wfg needs datatype to be double fr = np.asarray(front, dtype='double') return hv.wfg(fr, ref)
if __name__=="__main__":
[docs] po_front = np.asarray([[1.0,0],[0.5,0.5], [0,1.0], [2, -1], [0,0]])
sol1 = [4, 4] # cant be better than po front, min is zero sol = np.asarray(sol1) ref = np.asarray([0.7, 0.3]) print("eps indi value") print(epsilon_indicator(po_front[0], sol)) print(epsilon_indicator(po_front[1], sol)) print(epsilon_indicator(po_front[2], sol)) print(epsilon_indicator(po_front[3], sol)) print(epsilon_indicator(po_front[4], sol)) print("ndims") print(epsilon_indicator_ndims(po_front, sol)) print(hypervolume_indicator(po_front, sol)) print("pref") print(preference_indicator(po_front[1], sol, 0.1, ref, 0.1))