Beispiel #1
0
    def test_survival(self):
        problem = DTLZ2(n_obj=3)

        for k in range(1, 11):

            print("TEST RVEA GEN", k)

            ref_dirs = np.loadtxt(
                path_to_test_resources('rvea', f"ref_dirs_{k}.txt"))
            F = np.loadtxt(path_to_test_resources('rvea', f"F_{k}.txt"))
            pop = Population.new(F=F)

            algorithm = RVEA(ref_dirs)
            algorithm.setup(problem, termination=('n_gen', 500))
            algorithm.n_gen = k
            algorithm.pop = pop

            survival = APDSurvival(ref_dirs)
            survivors = survival.do(problem,
                                    algorithm.pop,
                                    len(pop),
                                    algorithm=algorithm,
                                    return_indices=True)

            apd = pop[survivors].get("apd")
            correct_apd = np.loadtxt(
                path_to_test_resources('rvea', f"apd_{k}.txt"))
            np.testing.assert_allclose(apd, correct_apd)
    def _initialize(self):
        # ! get the initial population - different ways are possible

        # provide a whole population object - (individuals might be already evaluated)
        if isinstance(self.sampling, Population):
            pop = self.sampling
        else:
            pop = Population(0, individual=self.individual)
            if isinstance(self.sampling, np.ndarray):
                pop = pop.new("X", self.sampling)
            else:
                pop = self.sampling.do(self.problem,
                                       self.pop_size,
                                       pop=pop,
                                       algorithm=self)

        # repair all solutions that are not already evaluated
        if self.repair:
            I = [k for k in range(len(pop)) if pop[k].F is None]
            pop = self.repair.do(self.problem, pop[I], algorithm=self)

        # then evaluate using the objective function
        self.evaluator.eval(self.problem, pop, algorithm=self)

        # that call is a dummy survival to set attributes that are necessary for the mating selection
        if self.survival:
            pop = self.survival.do(self.problem, pop, len(pop), algorithm=self)

        self.pop = pop
Beispiel #3
0
    def do(self, problem, pop, n_offsprings, **kwargs):
        X, F, G = pop.get("X", "F", "G")
        xl, xu = problem.bounds()

        # defining a params dict for the parameters to be sent to the API
        DATA = {
            'X': numpy_to_json(X),
            'F': numpy_to_json(F),
            'xl': numpy_to_json(xl),
            'xu': numpy_to_json(xu),
        }

        if problem.has_constraints():
            DATA['G'] = numpy_to_json(G)

        DATA = {**DATA, 'n_infills': n_offsprings, **self.params}

        # sending get request and saving the response as response object
        r = requests.post(url=f"{self.url}/{self.endpoint}",
                          json=json.dumps(DATA))

        # extracting data in json format
        resp = r.json()

        if not resp["success"]:
            raise Exception(f"ERROR during remote call: {resp['error']}")

        X = np.array(resp["X"])

        return Population.new(X=X)
Beispiel #4
0
    def _initialize(self):
        # ! get the initial population - different ways are possible

        # provide a whole population object - (individuals might be already evaluated)
        if isinstance(self.sampling, Population):
            pop = self.sampling
        else:
            pop = Population(0, individual=self.individual)
            if isinstance(self.sampling, np.ndarray):
                pop = pop.new("X", self.sampling)
            else:
                pop = self.sampling.sample(self.problem,
                                           pop,
                                           self.pop_size,
                                           algorithm=self)

        # repair in case it is necessary
        if self.func_repair:
            pop = self.func_repair(self.problem, pop, algorithm=self)

        # in case the initial population was not evaluated
        if np.any(pop.collect(lambda ind: ind.F is None, as_numpy_array=True)):
            self.evaluator.eval(self.problem, pop, algorithm=self)

        # that call is a dummy survival to set attributes that are necessary for the mating selection
        if self.survival:
            pop = self.survival.do(self.problem,
                                   pop,
                                   self.pop_size,
                                   algorithm=self)

        return pop
Beispiel #5
0
    def do(self, problem, n_samples, pop=Population(), **kwargs):
        """
        Sample new points with problem information if necessary.

        Parameters
        ----------

        problem : :class:`~pymoo.model.problem.Problem`
            The problem to which points should be sampled. (lower and upper bounds, discrete, binary, ...)

        n_samples : int
            Number of samples

        pop : :class:`~pymoo.model.population.Population`
            The sampling results are stored in a population. The template of the population can be changed.
            If 'none' simply a numpy array is returned.

        Returns
        -------
        X : numpy.array
            Samples points in a two dimensional array

        """
        val = self._do(problem, n_samples, **kwargs)

        if pop is None:
            return val

        return Population.new("X", val)
Beispiel #6
0
def _new_crossover_do(self, problem, pop, parents, **kwargs):
    """

        This method executes the crossover on the parents. This class wraps the implementation of the class
        that implements the crossover.

        Parameters
        ----------
        problem: class
            The problem to be solved. Provides information such as lower and upper bounds or feasibility
            conditions for custom crossovers.

        pop : Population
            The population as an object

        parents: numpy.array
            The select parents of the population for the crossover

        kwargs : dict
            Any additional data that might be necessary to perform the crossover. E.g. constants of an algorithm.

        Returns
        -------
        offsprings : Population
            The off as a matrix. n_children rows and the number of columns is equal to the variable
            length of the problem.

        """

    if self.n_parents != parents.shape[1]:
        raise ValueError(
            'Exception during crossover: Number of parents differs from defined at crossover.'
        )

    # get the design space matrix form the population and parents
    X = pop.get("X")[parents.T].copy()

    # now apply the crossover probability
    do_crossover = np.random.random(len(parents)) < self.prob

    # execute the crossover
    _X = self._do(problem, X, **kwargs)

    X[:, do_crossover, :] = _X[:, do_crossover, :]

    # flatten the array to become a 2d-array
    print(X.shape)
    if len(X.shape) > 3:
        X = X.reshape(offspring, X.shape[-2], X.shape[-1])
    else:
        X = X.reshape(-1, X.shape[-1])
    # create a population object
    off = Population.new("X", X)

    return off
Beispiel #7
0
    def _each_iteration_samoo(self, X, **kwargs):
        self.archive = self.samoo_evaluator.eval(problem=self.samoo_problem,
                                                 x=X,
                                                 archive=self.archive)
        temp_pop = Population(0, individual=Individual())
        temp_pop = temp_pop.new("X", self.archive['x'], "F", self.archive['f'],
                                "CV", self.archive['cv'], "G",
                                self.archive['g'], "feasible",
                                self.archive['feasible_index'])
        self.func_eval = self.archive['x'].shape[0]

        return temp_pop
Beispiel #8
0
    def test_preevaluated(self):
        evaluator = Evaluator()
        pop = Population.new("X", X)
        evaluator.eval(problem, pop)

        pop[range(30)].set("F", None)

        evaluator = Evaluator()
        evaluator.eval(problem, pop)

        np.testing.assert_allclose(F, pop.get("F"))
        self.assertTrue(evaluator.n_eval == 30)
Beispiel #9
0
    def solve(self, X_init, Y_init):
        '''
        Solve the real multi-objective problem from initial data.

        Parameters
        ----------
        X_init: np.array
            Initial design variables.
        Y_init: np.array
            Initial performance values.

        Returns
        -------
        X_next: np.array
            Proposed design samples to evaluate next.
        Y_prediction: tuple
            (None, None) because there is no prediction in MOO algorithms.
        '''
        # forward transformation
        X_init = self.transformation.do(X_init)

        # convert maximization to minimization
        X, Y = X_init, Y_init.copy()
        obj_type = self.real_problem.obj_type
        if isinstance(obj_type, str):
            obj_type = [obj_type] * Y.shape[1]
        assert isinstance(obj_type, Iterable)
        maxm_idx = np.array(obj_type) == 'max'
        Y[:, maxm_idx] = -Y[:, maxm_idx]

        # construct population
        pop = Population(0, individual=Individual())
        pop = pop.new('X', X)
        pop.set('F', Y)
        pop.set('CV', np.zeros([X.shape[0],
                                1]))  # assume input samples are all feasible

        off = self._solve(pop)

        X_next = off.get('X')[:self.batch_size]

        # backward transformation
        X_next = self.transformation.undo(X_next)

        return X_next, (None, None)
Beispiel #10
0
    def _next(self):

        if self.pop is None or len(self.pop) == 0:
            X = next(self.es)

        else:
            F = self.pop.get("F")[:, 0].tolist()
            #
            # if self.problem.n_constr > 0:
            #     G = self.pop.get("G").tolist()
            #     self.al.set_coefficients(F, G)
            #
            #     x = self.es.gi_frame.f_locals["es"].ask(1, sigma_fac=0)[0]
            #     ind = Individual(X=x)
            #     self.evaluator.eval(self.problem, ind, algorithm=self)
            #     self.al.update(ind.F[0], ind.G)
            #
            #     F = F + sum(self.al(G))

            if not self.send_array_to_yield:
                F = F[0]

            try:
                X = self.es.send(F)
            except StopIteration:
                X = None
                self.termination.force_termination = True

        if X is not None:
            X = np.array(X)
            self.send_array_to_yield = X.ndim > 1
            X = np.atleast_2d(X)

            # evaluate the population
            self.pop = Population.new("X", X)
            self.evaluator.eval(self.problem, self.pop, algorithm=self)

            # set infeasible individual's objective values to np.nan - then CMAES can handle it
            for ind in self.pop:
                if not ind.feasible[0]:
                    ind.F[0] = np.nan
Beispiel #11
0
def pop_from_sampling(problem, sampling, n_initial_samples, pop=None):
    # the population type can be different - (different type of individuals)
    if pop is None:
        pop = Population()

    # provide a whole population object - (individuals might be already evaluated)
    if isinstance(sampling, Population):
        pop = sampling

    else:
        # if just an X array create a pop
        if isinstance(sampling, np.ndarray):
            pop = pop.new("X", sampling)

        elif isinstance(sampling, Sampling):
            # use the sampling
            pop = sampling.do(problem, n_initial_samples, pop=pop)

        else:
            return None

    return pop
Beispiel #12
0
    def do(self, problem, n_samples, **kwargs):

        # provide a whole population object - (individuals might be already evaluated)
        if isinstance(self.sampling, Population):
            pop = self.sampling

        else:
            if isinstance(self.sampling, np.ndarray):
                pop = Population.new(X=self.sampling)
            else:
                pop = self.sampling.do(problem, n_samples, **kwargs)

        # repair all solutions that are not already evaluated
        not_eval_yet = [k for k in range(len(pop)) if pop[k].F is None]
        if len(not_eval_yet) > 0:
            pop[not_eval_yet] = self.repair.do(problem, pop[not_eval_yet],
                                               **kwargs)

        # filter duplicate in the population
        pop = self.eliminate_duplicates.do(pop)

        return pop
Beispiel #13
0
    def do(self, problem, n_samples, **kwargs):

        # provide a whole population object - (individuals might be already evaluated)
        if isinstance(self.sampling, Population):
            pop = self.sampling

        else:
            pop = Population(0, individual=self.individual)
            if isinstance(self.sampling, np.ndarray):
                pop = pop.new("X", self.sampling)
            else:
                pop = self.sampling.do(problem, n_samples, pop=pop, **kwargs)

        # repair all solutions that are not already evaluated
        if self.repair:
            I = [k for k in range(len(pop)) if pop[k].F is None]
            pop = self.repair.do(problem, pop[I], **kwargs)

        if self.eliminate_duplicates is not None:
            pop = self.eliminate_duplicates.do(pop)

        return pop
Beispiel #14
0
    def _do(self, problem, pop, n_offsprings, parents=None, **kwargs):
        if parents is None:
            raise Exception("For levy flights please provide the parents!")

        X, F = pop.get("X", "F")
        xl, xu = problem.bounds()

        a, b, c = parents.T

        # the direction to be used for improvement
        direction = (X[b] - X[c])

        # get random levy values to be used for the step size
        levy = self.levy.do(size=(len(parents), 1))
        # levy = np.random.normal(0, 1, size=(len(parents), problem.n_var))

        _X = X[a] + (xu - xl) / self.alpha * levy * direction

        _X = ToBoundOutOfBoundsRepair().do(problem, _X)
        # _X = InversePenaltyOutOfBoundsRepair().do(problem, _X, P=X[a])

        return Population.new(X=_X, index=a)
Beispiel #15
0
 def test_evaluate_pop(self):
     evaluator = Evaluator()
     pop = Population.new("X", X)
     evaluator.eval(problem, pop)
     np.testing.assert_allclose(F, pop.get("F"))
     self.assertTrue(evaluator.n_eval == len(X))
Beispiel #16
0
import numpy as np

from pymoo.algorithms.nsga2 import NSGA2
from pymoo.factory import get_problem
from pymoo.model.evaluator import Evaluator
from pymoo.model.population import Population
from pymoo.optimize import minimize

problem = get_problem("zdt2")

# create initial data and set to the population object
X = np.random.random((300, problem.n_var))
pop = Population.new("X", X)
Evaluator().eval(problem, pop)

algorithm = NSGA2(pop_size=100, sampling=pop)

minimize(problem,
         algorithm,
         ('n_gen', 10),
         seed=1,
         verbose=True)