예제 #1
0
    def do(self,
           F,
           weights,
           _type="auto",
           ideal_point=None,
           utopian_point=None,
           nadir_point=None,
           **kwargs):

        _F, _weights = to_1d_array_if_possible(F), to_1d_array_if_possible(weights)

        if _type == "auto":
            if _F.ndim == 1 and _weights.ndim > 1:
                _type = "one_to_many"
            elif _F.ndim > 1 and _weights.ndim == 1:
                _type = "many_to_one"
            elif _F.ndim == 2 and _weights.ndim == 2 and _F.shape[0] == _weights.shape[0]:
                _type = "one_to_one"
            else:
                _type = "many_to_many"

        # make both at least 2d arrays
        F, weights = at_least_2d_array(F), at_least_2d_array(weights)

        # get the number of points and weights
        n_points, n_weights = F.shape[0], weights.shape[0]

        self.ideal_point = ideal_point
        if self.ideal_point is None:
            self.ideal_point = np.zeros(F.shape[1])

        self.utopian_point = utopian_point
        if self.utopian_point is None:
            self.utopian_point = self.ideal_point - self.eps

        # set the nadir point by default to value or default
        self.nadir_point = nadir_point
        if self.nadir_point is None:
            self.nadir_point = self.utopian_point + np.ones(F.shape[1])

        if _type == "one_to_one":
            D = self._do(F, weights=weights, **kwargs).flatten()

        elif _type == "one_to_many":
            F = np.repeat(F, n_weights, axis=0)
            D = self._do(F, weights=weights, **kwargs).flatten()

        elif _type == "many_to_one":
            weights = np.repeat(weights, n_points, axis=0)
            D = self._do(F, weights=weights, **kwargs).flatten()

        elif _type == "many_to_many":
            F = np.repeat(F, n_weights, axis=0)
            weights = np.tile(weights, (n_points, 1))
            D = self._do(F, weights=weights, **kwargs).reshape(n_points, n_weights)

        else:
            raise Exception("Unknown type for decomposition: %s" % _type)

        return D
예제 #2
0
파일: problem.py 프로젝트: Jiadalee/pymoo
    def _evaluate(self, x, out, *args, **kwargs):
        super()._evaluate(x, out, return_as_dictionary=True)

        F, G = at_least_2d_array(out["F"]), at_least_2d_array(out["G"])
        CV = Problem.calc_constraint_violation(G)

        out["__F__"] = F
        out["__G__"] = G
        out["__CV__"] = CV

        out["F"] = out["F"] + self.penalty * CV
        out["G"] = None
예제 #3
0
    def do(self, x, out, *args, **kwargs):
        self.problem.do(x, out, *args, **kwargs)

        if self.problem.has_constraints():

            F, G = at_least_2d_array(out["F"]), at_least_2d_array(out["G"])
            CV = Problem.calc_constraint_violation(G)

            out["__F__"] = F
            out["__G__"] = G
            out["__CV__"] = CV

            out["F"] = F + self.penalty * CV
            out["G"] = None
예제 #4
0
    def pareto_front(self,
                     *args,
                     use_cache=True,
                     exception_if_failing=True,
                     **kwargs):
        """
        Parameters
        ----------

        args : Same problem implementation need some more information to create the Pareto front. For instance
                the DTLZ problem suite generates the Pareto front by usage of the reference directions.
                We refer to the corresponding problem for more information.
        exception_if_failing : bool
                Whether to throw an exception when generating the Pareto front has failed.
        use_cache : bool
                Whether to use the cache if the Pareto front has been generated beforehand.

        Returns
        -------
        P : np.array
            The Pareto front of a given problem. It is only loaded or calculate the first time and then cached.
            For a single-objective problem only one point is returned but still in a two dimensional array.

        """
        if not use_cache or self._pareto_front is None:
            try:
                self._pareto_front = at_least_2d_array(
                    self._calc_pareto_front(*args, **kwargs))
                self._ideal_point = np.min(self._pareto_front, axis=0)
                self._nadir_point = np.max(self._pareto_front, axis=0)
            except Exception as e:
                if exception_if_failing:
                    raise e

        return self._pareto_front
예제 #5
0
    def evaluate(self,
                 X,
                 *args,
                 return_values_of=None,
                 return_as_dictionary=False,
                 **kwargs):

        # make sure the array is at least 2d. store if reshaping was necessary
        X, only_single_value = at_least_2d_array(X, extend_as="row", return_if_reshaped=True)
        assert X.shape[1] == self.n_var, f'Input dimension {X.shape[1]} are not equal to n_var {self.n_var}!'

        # number of function evaluations to be done
        n_evals = X.shape[0]

        # the values to be actually returned by in the end - set bu default if not providded
        ret_vals = default_return_values(self.has_constraints()) if return_values_of is None else return_values_of

        # prepare the dictionary to be filled after the evaluation
        out = dict_with_none(ret_vals)

        # do the actual evaluation for the given problem - calls in _evaluate method internally
        self.do(X, out, *args, **kwargs)

        # make sure the array is 2d before doing the shape check
        out_to_2d_ndarray(out)

        # if enabled (recommended) the output shapes are checked for inconsistencies
        if self.check_inconsistencies:
            check(self, X, out)

        # if the NaN values should be replaced
        if self.replace_nan_values_by is not None:
            replace_nan_values(out, self.replace_nan_values_by)

        # make sure F and G are in fact floats (at least try to do that, no exception will be through if it fails)
        out_to_float(out, ["F", "G"])

        if "CV" in ret_vals or "feasible" in ret_vals:
            CV = calc_constr(out["G"]) if self.has_constraints() else np.zeros([n_evals, 1])
            out["CV"] = CV
            out["feasible"] = CV <= 0

        # in case the input had only one dimension, then remove always the first dimension from each output
        if only_single_value:
            out_to_1d_ndarray(out)

        if self.callback is not None:
            self.callback(X, out)

        # now depending on what should be returned prepare the output
        if return_as_dictionary:
            return out
        else:
            if len(ret_vals) == 1:
                return out[ret_vals[0]]
            else:
                return tuple([out[e] for e in ret_vals])
예제 #6
0
파일: evaluator.py 프로젝트: mbeza/pymoo-1
def set_cv(pop, feasbility=True):
    for ind in pop:
        if ind.G is None:
            ind.CV = np.zeros(1)
        else:
            ind.CV = Problem.calc_constraint_violation(at_least_2d_array(
                ind.G))[0]

    if feasbility:
        set_feasibility(pop)
예제 #7
0
파일: problem.py 프로젝트: abfarr/moo2020
    def pareto_set(self, *args, use_cache=True, **kwargs):
        """
        Returns
        -------
        S : np.array
            Returns the pareto set for a problem. Points in the X space to be known to be optimal!
        """
        if not use_cache or self._pareto_set is None:
            self._pareto_set = at_least_2d_array(self._calc_pareto_set(*args, **kwargs))

        return self._pareto_set
예제 #8
0
    def __init__(self, pf, dist_func, axis, zero_to_one=False, ideal=None, nadir=None, norm_by_dist=False, **kwargs):

        # the pareto front if necessary to calculate the indicator
        pf = at_least_2d_array(pf, extend_as="row")
        ideal, nadir = derive_ideal_and_nadir_from_pf(pf, ideal=ideal, nadir=nadir)

        super().__init__(zero_to_one=zero_to_one, ideal=ideal, nadir=nadir, **kwargs)
        self.dist_func = dist_func
        self.axis = axis
        self.norm_by_dist = norm_by_dist
        self.pf = self.normalization.forward(pf)
예제 #9
0
def set_to_bounds_if_outside(X, xl, xu):
    _X, only_1d = at_least_2d_array(X, return_if_reshaped=True)

    if xl is not None:
        xl = np.repeat(xl[None, :], _X.shape[0], axis=0)
        _X[_X < xl] = xl[_X < xl]

    if xu is not None:
        xu = np.repeat(xu[None, :], _X.shape[0], axis=0)
        _X[_X > xu] = xu[_X > xu]

    if only_1d:
        return _X[0, :]
    else:
        return _X
예제 #10
0
def bounce_back(X, xl, xu):
    only_1d = (X.ndim == 1)
    X = at_least_2d_array(X)

    xl = np.repeat(xl[None, :], X.shape[0], axis=0)
    xu = np.repeat(xu[None, :], X.shape[0], axis=0)

    # otherwise bounds back into the feasible space
    _range = xu - xl
    X[X < xl] = (xl + np.mod((xl - X), _range))[X < xl]
    X[X > xu] = (xu - np.mod((X - xu), _range))[X > xu]

    if only_1d:
        return X[0, :]
    else:
        return X
예제 #11
0
파일: to_bound.py 프로젝트: mbeza/pymoo-1
def set_to_bounds_if_outside(X, xl, xu):
    only_1d = (X.ndim == 1)
    X = at_least_2d_array(X)

    if xl is not None:
        xl = np.repeat(xl[None, :], X.shape[0], axis=0)
        X[X < xl] = xl[X < xl]

    if xu is not None:
        xu = np.repeat(xu[None, :], X.shape[0], axis=0)
        X[X > xu] = xu[X > xu]

    if only_1d:
        return X[0, :]
    else:
        return X
예제 #12
0
def repair_out_of_bounds(problem, X):

    only_1d = (X.ndim == 1)
    X = at_least_2d_array(X)

    if problem.xl is not None:
        xl = np.repeat(problem.xl[None, :], X.shape[0], axis=0)
        X[X < xl] = xl[X < xl]

    if problem.xu is not None:
        xu = np.repeat(problem.xu[None, :], X.shape[0], axis=0)
        X[X > xu] = xu[X > xu]

    if only_1d:
        return X[0, :]
    else:
        return X
예제 #13
0
def bounds_back(problem, X):
    only_1d = (X.ndim == 1)
    X = at_least_2d_array(X)

    if problem.xl is not None and problem.xu is not None:
        xl = np.repeat(problem.xl[None, :], X.shape[0], axis=0)
        xu = np.repeat(problem.xu[None, :], X.shape[0], axis=0)

        # otherwise bounds back into the feasible space
        _range = xu - xl
        X[X < xl] = (xl + np.mod((xl - X), _range))[X < xl]
        X[X > xu] = (xu - np.mod((X - xu), _range))[X > xu]

    if only_1d:
        return X[0, :]
    else:
        return X
예제 #14
0
    def __init__(self, ref_point=None, pf=None, nds=True, norm_ref_point=True, ideal=None, nadir=None, **kwargs):
        pf = at_least_2d_array(pf, extend_as="row")
        ideal, nadir = derive_ideal_and_nadir_from_pf(pf, ideal=ideal, nadir=nadir)

        super().__init__(ideal=ideal, nadir=nadir, **kwargs)

        # whether the input should be checked for domination or not
        self.nds = nds

        # the reference point that shall be used - either derived from pf or provided
        ref_point = ref_point
        if ref_point is None:
            if pf is not None:
                ref_point = pf.max(axis=0)

        # we also have to normalize the reference point to have the same scales
        if norm_ref_point:
            ref_point = self.normalization.forward(ref_point)

        self.ref_point = ref_point
        assert self.ref_point is not None, "For Hypervolume a reference point needs to be provided!"
예제 #15
0
    def do(self, X, out, *args, **kwargs):

        # do an elementwise evaluation and return the results
        ret = self.func_eval(self.func_elementwise_eval, self, X, out, *args, **kwargs)

        # the first element decides what keys will be set
        keys = list(ret[0].keys())

        # now stack all the results for each of them together
        for key in keys:
            assert all([key in _out for _out in ret]), f"For some elements the {key} value has not been set."

            vals = []
            for elem in ret:
                val = elem[key]

                if val is not None:

                    # if it is just a float
                    if isinstance(val, list) or isinstance(val, tuple):
                        val = np.array(val)
                    elif not isinstance(val, np.ndarray):
                        val = np.full(1, val)

                    # otherwise prepare the value to be stacked with each other by extending the dimension
                    val = at_least_2d_array(val, extend_as="row")

                vals.append(val)

            # that means the key has never been set at all
            if all([val is None for val in vals]):
                out[key] = None
            else:
                out[key] = np.row_stack(vals)

        return out
예제 #16
0
def calc_pf(problem, *args, **kwargs):
    return at_least_2d_array(problem._calc_pareto_front(*args, **kwargs))
예제 #17
0
 def _forward(self, ind, **kwargs):
     assert self.attr is not None and isinstance(ind, Individual)
     return at_least_2d_array(ind.get(self.attr), extend_as="row")