예제 #1
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
예제 #2
0
    def _next(self):

        # all the elements in the interval
        a, left, right, b = self.pop

        # the golden ratio (precomputed constant)
        R = self.R

        # if the left solution is better than the right
        if left.F[0] < right.F[0]:

            # make the right to be the new right bound and the left becomes the right
            a, b = a, right
            right = left

            # create a new left individual and evaluate
            left = Individual(X=b.X - R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(left), algorithm=self)

        # if the right solution is better than the left
        else:

            # make the left to be the new left bound and the right becomes the left
            a, b = left, b
            left = right

            # create a new right individual and evaluate
            right = Individual(X=a.X + R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(right), algorithm=self)

        # update the population with all the four individuals
        self.pop = Population.create(a, left, right, b)
예제 #3
0
    def _next(self):

        # do the mating using the total population
        Hm = Population.merge(self.pop, self.da)
        self.off = self.mating.do(self.problem,
                                  Hm,
                                  n_offsprings=self.n_offsprings,
                                  algorithm=self)

        # if the mating could not generate any new offspring (duplicate elimination might make that happen)
        if len(self.off) == 0:
            self.termination.force_termination = True
            return

        # if not the desired number of offspring could be created
        elif len(self.off) < self.n_offsprings:
            if self.verbose:
                print(
                    "WARNING: Mating could not produce the required number of (unique) offsprings!"
                )

        # evaluate the offspring
        self.evaluator.eval(self.problem, self.off, algorithm=self)

        # merge the offsprings with the current population
        self.pop = Population.merge(self.pop, self.off)

        # the do survival selection
        self.pop, self.da = self.survival.do(self.problem,
                                             self.pop,
                                             self.da,
                                             self.pop_size,
                                             algorithm=self)
예제 #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.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
예제 #5
0
    def _step(self):
        pop = self.pop
        X = pop.get("X")
        F = pop.get("F")

        #Levy Flight
        best = self.opt
        G_X = best.get("X")

        step_size = self._get_global_step_size(X)
        _X = X + np.random.rand(*X.shape) * step_size * (G_X - X)
        _X = set_to_bounds_if_outside_by_problem(self.problem, _X)

        #Evaluate
        off = Population(len(pop)).set("X", _X)
        self.evaluator.eval(self.problem, off, algorithm=self)

        # replace the worse pop with better off per index
        # this method includes replacement with less constraints violation
        # which the original paper doesn't have
        ImprovementReplacement().do(self.problem, pop, off, inplace=True)

        #Local Random Walk
        dir_vec = self._get_local_directional_vector(X)
        _X = X + dir_vec
        _X = set_to_bounds_if_outside_by_problem(self.problem, _X)
        off = Population(len(pop)).set("X", _X)
        self.evaluator.eval(self.problem, off, algorithm=self)

        #append offspring to population and then sort for elitism (survival)
        self.pop = Population.merge(pop, off)
        self.pop = self.survival.do(self.problem,
                                    self.pop,
                                    self.pop_size,
                                    algorithm=self)
예제 #6
0
    def _do(self, problem, pop, n_offsprings, parents=None, **kwargs):
        rnd = np.random.random(n_offsprings)
        n_neighbors = (rnd <= self.bias).sum()

        other = super()._do(problem, pop, n_offsprings - n_neighbors, parents,
                            **kwargs)

        N = []

        cand = TournamentSelection(comp_by_rank).do(pop,
                                                    n_neighbors,
                                                    n_parents=1)[:, 0]
        for k in cand:
            N.append(pop[k])

            n_cand_neighbors = pop[k].get("neighbors")
            rnd = np.random.permutation(
                len(n_cand_neighbors))[:self.crossover.n_parents - 1]
            [N.append(e) for e in n_cand_neighbors[rnd]]

        parents = np.reshape(np.arange(len(N)), (-1, self.crossover.n_parents))
        N = Population.create(*N)

        bias = super()._do(problem, N, n_neighbors, parents, **kwargs)

        return Population.merge(bias, other)
예제 #7
0
    def test_restricted_mating_selection(self):
        np.random.seed(200)
        selection = RestrictedMating(func_comp=comp_by_cv_dom_then_random)

        problem = C3DTLZ4(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        Hm = CA.merge(DA)
        n_pop = len(CA)

        _, rank = NonDominatedSorting().do(Hm.get('F'), return_rank=True)

        Pc = (rank[:n_pop] == 0).sum()/len(Hm)
        Pd = (rank[n_pop:] == 0).sum()/len(Hm)

        P = selection.do(Hm, len(CA))

        assert P.shape == (91, 2)
        if Pc > Pd:
            assert (P[:, 0] < n_pop).all()
        else:
            assert (P[:, 0] >= n_pop).all()
        assert (P[:, 1] >= n_pop).any()
        assert (P[:, 1] < n_pop).any()
예제 #8
0
    def test_association(self):
        problem = C1DTLZ3(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        true_assoc = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'feasible_rank0.txt'))
        true_niche = true_assoc[:, 1]
        true_id = true_assoc[:, 0]
        sorted_id = np.argsort(true_id)

        survival = CADASurvival(self.ref_dirs)
        mixed = CA.merge(off)
        survival.ideal_point = np.min(np.vstack((DA.get("F"), mixed.get("F"))), axis=0)

        fronts = NonDominatedSorting().do(mixed.get("F"), n_stop_if_ranked=len(self.ref_dirs))
        I = np.concatenate(fronts)
        niche, _ = survival._associate(mixed[I])
        sorted_I = np.argsort(I)

        assert (niche[sorted_I] == true_niche[sorted_id]).all()
예제 #9
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)
예제 #10
0
 def _update(self):
     D = self.D
     ind = Individual(X=np.copy(D["X"]),
                      F=np.copy(D["F"]),
                      G=np.copy(-D["G"]))
     pop = Population.merge(self.pop, Population.create(ind))
     set_cv(pop)
     self.pop = pop
예제 #11
0
    def _initialize(self):

        pop = Population()
        if isinstance(self.sampling, np.ndarray):
            pop.X = self.sampling
        else:
            pop.X = self.sampling.sample(self.problem, self.pop_size)
        pop.F, pop.G = self.evaluator.eval(self.problem, pop.X)
        return pop
예제 #12
0
def crossover(crossover, a, b, c=None, xl=0, xu=1, type_var=np.double, **kwargs):
    n = a.shape[0]
    _pop = Population.merge(Population().new("X", a), Population().new("X", b))
    _P = np.column_stack([np.arange(n), np.arange(n) + n])

    if c is not None:
        _pop = Population.merge(_pop, Population().new("X", c))
        _P = np.column_stack([_P, np.arange(n) + 2 * n])

    problem = get_problem_func(a.shape[1], xl, xu, type_var)(**kwargs)
    return crossover.do(problem, _pop, _P, **kwargs).get("X")
예제 #13
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
예제 #14
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)
예제 #15
0
    def _next(self, pop):

        # do the iteration for the next generation - population objective is modified inplace
        # do the mating and evaluate the offsprings
        off = Population()
        off.X = self._mating(pop)
        off.F, off.G = self.evaluator.eval(self.problem, off.X)

        # do the survival selection with the merged population
        self.survival.do(pop, off, self.pop_size, out=self.D, **self.D)

        return off
예제 #16
0
파일: moead.py 프로젝트: Huaxu007/AutoOED
    def _solve(self, pop):
        # generate direction vectors by random sampling
        ref_dirs = np.random.random((self.batch_size, self.n_obj))
        ref_dirs /= np.expand_dims(np.sum(ref_dirs, axis=1), 1)

        algo = MOEAD_algo(ref_dirs=ref_dirs, n_neighbors=len(ref_dirs), eliminate_duplicates=False)
        repair, crossover, mutation = algo.mating.repair, algo.mating.crossover, algo.mating.mutation

        if isinstance(algo.decomposition, str):
            decomp = algo.decomposition
            if decomp == 'auto':
                if self.n_obj <= 2:
                    decomp = 'tchebi'
                else:
                    decomp = 'pbi'
            decomposition = get_decomposition(decomp)
        else:
            decomposition = algo.decomposition

        ideal_point = np.min(pop.get('F'), axis=0)

        # find the optimal individual for each reference direction
        opt_pop = Population(0, individual=Individual())
        for i in range(self.batch_size):
            N = algo.neighbors[i, :]
            FV = decomposition.do(pop.get("F"), weights=ref_dirs[i], ideal_point=ideal_point)
            opt_pop = Population.merge(opt_pop, pop[np.argmin(FV)])

        all_off = Population(0, individual=Individual())
        for i in np.random.permutation(self.batch_size):
            N = algo.neighbors[i, :]

            if self.batch_size > 1:
                if np.random.random() < algo.prob_neighbor_mating:
                    parents = N[np.random.permutation(algo.n_neighbors)][:crossover.n_parents]
                else:
                    parents = np.random.permutation(algo.pop_size)[:crossover.n_parents]

                # do recombination and create an offspring
                off = crossover.do(self.real_problem, opt_pop, parents[None, :])
            else:
                off = opt_pop[N].copy()
                
            off = mutation.do(self.real_problem, off)
            off = off[np.random.randint(0, len(off))]

            # repair first in case it is necessary
            if repair:
                off = algo.repair.do(self.real_problem, off, algorithm=algo)

            all_off = Population.merge(all_off, off)
        
        return all_off
예제 #17
0
    def _exploration_move(self, center, opt=None):
        if opt is None:
            opt = center

        def step(x, delta, k):

            # copy and add delta to the new point
            X = np.copy(x)

            # normalize the delta by the bounds if they are provided by the problem
            eps = delta[k]

            # if the problem has bounds normalize the delta
            if self.problem.has_bounds():
                xl, xu = self.problem.bounds()
                eps *= (xu[k] - xl[k])

            # now add to the current solution
            X[k] = X[k] + eps

            # repair if out of bounds if necessary
            X = set_to_bounds_if_outside_by_problem(self.problem, X)

            # return the new solution as individual
            mutant = pop_from_array_or_individual(X)[0]

            return mutant

        for k in range(self.problem.n_var):

            # create the the individual and evaluate it
            mutant = step(center.X, self.explr_delta, k)
            self.evaluator.eval(self.problem, mutant, algorithm=self)
            self.pop = Population.merge(self.pop, mutant)

            if is_better(mutant, opt):
                center, opt = mutant, mutant

            else:

                # inverse the sign of the delta
                self.explr_delta[k] = -self.explr_delta[k]

                # now try the other sign if there was no improvement
                mutant = step(center.X, self.explr_delta, k)
                self.evaluator.eval(self.problem, mutant, algorithm=self)
                self.pop = Population.merge(self.pop, mutant)

                if is_better(mutant, opt):
                    center, opt = mutant, mutant

        return opt
예제 #18
0
    def eval(self,
             problem,
             pop,
             **kwargs):
        """

        This function is used to return the result of one valid evaluation.

        Parameters
        ----------
        problem : class
            The problem which is used to be evaluated
        pop : np.array or Population object
        kwargs : dict
            Additional arguments which might be necessary for the problem to evaluate.

        """

        is_individual = isinstance(pop, Individual)
        is_numpy_array = isinstance(pop, np.ndarray) and not isinstance(pop, Population)

        # make sure the object is a population
        if is_individual or is_numpy_array:
            pop = Population().create(pop)

        # find indices to be evaluated
        if self.skip_already_evaluated:
            I = [k for k in range(len(pop)) if pop[k].F is None]
        else:
            I = np.arange(len(pop))

        # update the function evaluation counter
        self.n_eval += len(I)

        # actually evaluate all solutions using the function that can be overwritten
        if len(I) > 0:
            self._eval(problem, pop[I], **kwargs)

            # set the feasibility attribute if cv exists
            for ind in pop[I]:
                cv = ind.get("CV")
                if cv is not None:
                    ind.set("feasible", cv <= 0)

        if is_individual:
            return pop[0]
        elif is_numpy_array:
            if len(pop) == 1:
                pop = pop[0]
            return tuple([pop.get(e) for e in self.evaluate_values_of])
        else:
            return pop
예제 #19
0
    def do(self, problem, pop, n_survive, return_indices=False, **kwargs):

        # make sure the population has at least one individual
        if len(pop) == 0:
            return pop

        # if the split should be done beforehand
        if self.filter_infeasible and problem.n_constr > 0:
            feasible, infeasible = split_by_feasibility(
                pop, sort_infeasbible_by_cv=True)

            # initialize the feasible and infeasible population
            feas_pop, infeas_pop = Population(), Population()

            # if there was no feasible solution was added at all - which means at least one infeasible
            if len(feasible) == 0:
                infeas_pop = self.cv_survival.do(problem, pop[infeasible],
                                                 n_survive)

            # if there are feasible solutions in the population
            else:

                # if feasible solution do exist
                if len(feasible) > 0:
                    feas_pop = self._do(problem, pop[feasible],
                                        min(len(feasible), n_survive),
                                        **kwargs)

                # calculate how many individuals are still remaining to be filled up with infeasible ones
                n_remaining = n_survive - len(feas_pop)

                # if infeasible solutions needs to be added
                if n_remaining > 0:
                    infeas_pop = self.cv_survival.do(problem, pop[infeasible],
                                                     n_remaining)

            survivors = Population.merge(feas_pop, infeas_pop)

        else:
            survivors = self._do(problem, pop, n_survive, **kwargs)

        if return_indices:
            H = {}
            for k, ind in enumerate(pop):
                H[ind] = k
            return [H[survivor] for survivor in survivors]
        else:
            return survivors
예제 #20
0
파일: so_direct.py 프로젝트: abfarr/moo2020
    def _next(self):
        # the offspring population to finally evaluate and attach to the population
        off = Population()

        # find the potential optimal solution in the current population
        potential_optimal = self._potential_optimal()

        # for each of those solutions execute the division move
        for current in potential_optimal:

            # find the largest dimension the solution has not been evaluated yet
            nxl, nxu = norm_bounds(current, problem)
            k = np.argmax(nxu - nxl)

            # the delta value to be used to get left and right - this is one sixth of the range
            xl, xu = current.get("xl"), current.get("xu")

            delta = (xu[k] - xl[k]) / 6

            # print(current.X, delta, k, xl, xu)

            # create the left individual
            left_x = np.copy(current.X)
            left_x[k] = xl[k] + delta
            left = Individual(X=left_x)

            # create the right individual
            right_x = np.copy(current.X)
            right_x[k] = xu[k] - delta
            right = Individual(X=right_x)

            # update the boundaries for all the points accordingly
            for ind in [current, left, right]:
                update_bounds(ind, xl, xu, k, delta)

            # create the offspring population, evaluate and attach to current population
            _off = Population.create(left, right)
            _off.set("depth", current.get("depth") + 1)

            off = Population.merge(off, _off)

        # evaluate the offsprings
        self.evaluator.eval(self.problem, off, algorithm=self)

        # print(off.get("X"))

        # add the offsprings to the population
        self.pop = Population.merge(self.pop, off)
예제 #21
0
파일: so_de.py 프로젝트: simplecellzg/pymoo
    def _step(self):
        selection, crossover, mutation = self.mating.selection, self.mating.crossover, self.mating.mutation

        # retrieve the current population
        pop = self.pop

        # get the vectors from the population
        F, CV, feasible = pop.get("F", "CV", "feasible")
        F = parameter_less(F, CV)

        # create offsprings and add it to the data of the algorithm
        P = selection.do(pop, self.pop_size, crossover.n_parents)

        if self.var_selection == "best":
            P[:, 0] = np.argmin(F[:, 0])
        elif self.var_selection == "rand+best":
            P[np.random.random(len(pop)) < 0.3, 0] = np.argmin(F[:, 0])

        # do the first crossover which is the actual DE operation
        off = crossover.do(self.problem, pop, P, algorithm=self)

        # then do the mutation (which is actually a crossover between old and new individual)
        _pop = Population.merge(self.pop, off)
        _P = np.column_stack(
            [np.arange(len(pop)),
             np.arange(len(pop)) + len(pop)])
        off = mutation.do(self.problem, _pop, _P,
                          algorithm=self)[:len(self.pop)]

        # bounds back if something is out of bounds
        off = BounceBackOutOfBoundsRepair().do(self.problem, off)

        return off
예제 #22
0
    def _next(self):

        # make a step and create the offsprings
        self.off = self._step()

        # evaluate the offsprings
        self.evaluator.eval(self.problem, self.off, algorithm=self)

        survivors = []

        for k in range(self.pop_size):
            parent, off = self.pop[k], self.off[k]

            rel = get_relation(parent, off)

            if rel == 0:
                survivors.extend([parent, off])
            elif rel == -1:
                survivors.append(off)
            else:
                survivors.append(parent)

        survivors = Population.create(*survivors)

        if len(survivors) > self.pop_size:
            survivors = RankAndCrowdingSurvival().do(self.problem, survivors,
                                                     self.pop_size)

        self.pop = survivors
예제 #23
0
    def _initialize(self):

        # initialize the function parameters
        self.alpha, self.beta, self.gamma, self.delta = self.func_params(
            self.problem)

        # reset the restart history
        self.restart_history = []

        # initialize the point
        if self.x0 is None:
            if not self.problem.has_bounds():
                raise Exception(
                    "Either provide an x0 or a problem with variable bounds!")

            # initialize randomly and make sure 5% is left for creating the initial simplex
            X = np.random.random(self.problem.n_var)
            self.x0 = denormalize(X, self.problem.xl, self.problem.xu)

        # parse the initial population from array or population object
        pop = pop_from_array_or_individual(self.x0)

        # if the simplex has not the correct number of points
        if len(pop) == 1:

            # the corresponding x values
            x0 = pop[0].X

            # if lower and upper bounds are given take 5% of the range and add
            if self.problem.has_bounds():
                self.simplex_scaling = 0.05 * (self.problem.xu -
                                               self.problem.xl)

            # no bounds are given do it based on x0 - MATLAB procedure
            else:
                self.simplex_scaling = 0.05 * x0
                # some value needs to be added if x0 is zero
                self.simplex_scaling[self.simplex_scaling == 0] = 0.00025

            # initialize the simplex
            X = self.initialize_simplex(x0)

            # create a population object
            pop = pop.merge(Population().new("X", X))

            # evaluate the values that are not already evaluated
            evaluate_if_not_done_yet(self.evaluator,
                                     self.problem,
                                     pop,
                                     algorithm=self)

        elif len(pop) != self.problem.n_var + 1:

            raise Exception(
                "Provided initial population has size of %s, but should have size of %s"
                % (len(pop), self.problem.n_var + 1))

        # sort by its corresponding function values
        self.pop = pop[np.argsort(pop.get("F")[:, 0])]
        self.opt = self.pop[0]
예제 #24
0
def filter_optimum(pop, least_infeasible=False):
    # first only choose feasible solutions
    ret = pop[pop.get("feasible")[:, 0]]

    # if at least one feasible solution was found
    if len(ret) > 0:

        # then check the objective values
        F = ret.get("F")

        if F.shape[1] > 1:
            I = NonDominatedSorting().do(F, only_non_dominated_front=True)
            ret = ret[I]

        else:
            ret = ret[np.argmin(F)]

    # no feasible solution was found
    else:
        # if flag enable report the least infeasible
        if least_infeasible:
            ret = pop[np.argmin(pop.get("CV"))]
        # otherwise just return none
        else:
            ret = None

    if isinstance(ret, Individual):
        ret = Population().create(ret)

    return ret
예제 #25
0
    def _initialize(self):
        super()._initialize()
        self.alpha, self.beta, self.gamma, self.delta = self.func_params(
            self.problem)

        # the corresponding x values of the provided or best found solution
        x0 = self.x0.X

        # if lower and upper bounds are given take 5% of the range and add
        if self.problem.has_bounds():
            self.simplex_scaling = 0.05 * (self.problem.xu - self.problem.xl)

        # no bounds are given do it based on x0 - MATLAB procedure
        else:
            self.simplex_scaling = 0.05 * self.x0.X
            # some value needs to be added if x0 is zero
            self.simplex_scaling[self.simplex_scaling == 0] = 0.00025

        # initialize the simplex
        simplex = pop_from_array_or_individual(self.initialize_simplex(x0))
        self.evaluator.eval(self.problem, simplex, algorithm=self)

        # make the simplex the current the population and sort them by fitness
        pop = Population.merge(self.opt, simplex)
        self.pop = FitnessSurvival().do(self.problem, pop, len(pop))
예제 #26
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)
예제 #27
0
def sample_by_bounds(clazz, n_samples, n_var, x_min, x_max, **kwargs):
    """

    Convenience method if only the bounds are needed to create the sample points.

    Parameters
    ----------
    clazz : class
        The sampling strategy to be used.
    n_var : int
        number of variables
    n_samples : int
        number of samples
    x_min : np.array
        lower bounds
    x_max : np.array
        upper bounds
    kwargs : dict
        additional arguments

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

    """
    class P(Problem):
        def __init__(self) -> None:
            self.n_var = n_var
            self.xl = np.full(n_var, x_min)
            self.xu = np.full(n_var, x_max)

    return clazz.sample(P(), Population(), n_samples, **kwargs).get("X")
예제 #28
0
    def _next(self):

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

        else:
            F = self.pop.get("F")[:, 0].tolist()
            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
예제 #29
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)
예제 #30
0
    def do(self, problem, n_samples, pop=Population(), **kwargs):
        """
        Sample new points with problem information if necessary.

        Parameters
        ----------

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

        n_samples: int
            Number of samples

        kwargs: class
            Any additional data that might be necessary. e.g. constants of the algorithm, ...

        pop : 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 : np.array
            Samples points in a two dimensional array

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

        if pop is None:
            return val

        return pop.new("X", val)