示例#1
0
 def __init__(self, problem, epsilon=None, evaluator=None) -> None:
     super().__init__()
     self.epsilon = epsilon
     if self.epsilon is None:
         self.epsilon = np.sqrt(np.finfo(float).eps)
     self.problem = problem
     self.evaluator = evaluator if evaluator is not None else Evaluator()
示例#2
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)
示例#3
0
    def initialize(self,
                   problem,
                   termination=None,
                   seed=None,
                   pf=True,
                   evaluator=None,
                   verbose=False,
                   save_history=False,
                   **kwargs):

        # if this run should be verbose or not
        self.verbose = verbose

        # set the problem that is optimized for the current run
        self.problem = problem

        # the termination criterion to be used to stop the algorithm
        if self.termination is None:
            self.termination = termination

        # if nothing given fall back to default
        if self.termination is None:
            self.termination = self.default_termination

        # set the random seed in the algorithm object
        self.seed = seed
        if self.seed is None:
            self.seed = np.random.randint(0, 10000000)
        np.random.seed(self.seed)
        self.pf = pf

        # by default make sure an evaluator exists if nothing is passed
        if evaluator is None:
            evaluator = Evaluator()
        self.evaluator = evaluator

        # whether the history should be stored or not
        self.save_history = save_history

        # other run dependent variables that are reset
        self.n_gen = None
        self.history = []
        self.pop = None
        self.opt = None
示例#4
0
    def solve(self,
              problem,
              termination,
              seed=None,
              disp=False,
              callback=None,
              save_history=False,
              pf=None,
              **kwargs):
        """

        Solve a given problem by a given evaluator. The evaluator determines the termination condition and
        can either have a maximum budget, hypervolume or whatever. The problem can be any problem the algorithm
        is able to solve.

        Parameters
        ----------

        problem: class
            Problem to be solved by the algorithm

        termination: class
            object that evaluates and saves the number of evaluations and determines the stopping condition

        seed: int
            Random seed for this run. Before the algorithm starts this seed is set.

        disp : bool
            If it is true than information during the algorithm execution are displayed

        callback : func
            A callback function can be passed that is executed every generation. The parameters for the function
            are the algorithm itself, the number of evaluations so far and the current population.

                def callback(algorithm):
                    pass

        save_history : bool
            If true, a current snapshot of each generation is saved.

        pf : np.array
            The Pareto-front for the given problem. If provided performance metrics are printed during execution.

        Returns
        -------
        res : dict
            A dictionary that saves all the results of the algorithm. Also, the history if save_history is true.

        """

        # set the random seed for generator
        if seed is not None:
            random.seed(seed)

        # the evaluator object which is counting the evaluations
        self.evaluator = Evaluator()
        self.problem = problem
        self.termination = termination
        self.pf = pf

        self.disp = disp
        self.callback = callback
        self.save_history = save_history

        # call the algorithm to solve the problem
        pop = self._solve(problem, termination)

        # get the optimal result by filtering feasible and non-dominated
        opt = pop.copy()
        opt = opt[opt.collect(lambda ind: ind.feasible)[:, 0]]

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

            if problem.n_obj > 1:
                I = NonDominatedSorting().do(opt.get("F"),
                                             only_non_dominated_front=True)
                opt = opt[I]
                X, F, CV, G = opt.get("X", "F", "CV", "G")

            else:
                opt = opt[np.argmin(opt.get("F"))]
                X, F, CV, G = opt.X, opt.F, opt.CV, opt.G
        else:
            opt = None

        res = Result(opt, opt is None, "")
        res.algorithm, res.problem, res.pf = self, problem, pf
        res.pop = pop

        if opt is not None:
            res.X, res.F, res.CV, res.G = X, F, CV, G

        res.history = self.history

        return res
示例#5
0
 def setUpClass(cls):
     cls.ref_dirs = np.loadtxt(path_to_test_resources('ctaea', 'weights.txt'))
     cls.evaluator = Evaluator()
示例#6
0
    def initialize(
            self,
            problem,
            pf=True,
            evaluator=None,

            # START Default minimize
            seed=None,
            verbose=False,
            save_history=False,
            return_least_infeasible=False,
            # END Default minimize

            # START Overwrite by minimize
        termination=None,
            callback=None,
            display=None,
            # END Overwrite by minimize
            **kwargs):

        # set the problem that is optimized for the current run
        self.problem = problem

        # set the provided pareto front
        self.pf = pf

        # by default make sure an evaluator exists if nothing is passed
        if evaluator is None:
            evaluator = Evaluator()
        self.evaluator = evaluator

        # !
        # START Default minimize
        # !
        # if this run should be verbose or not
        self.verbose = verbose
        # whether the least infeasible should be returned or not
        self.return_least_infeasible = return_least_infeasible
        # whether the history should be stored or not
        self.save_history = save_history

        # set the random seed in the algorithm object
        self.seed = seed
        if self.seed is None:
            self.seed = np.random.randint(0, 10000000)
        np.random.seed(self.seed)
        # !
        # END Default minimize
        # !

        # !
        # START Overwrite by minimize
        # !
        # the termination criterion to be used to stop the algorithm
        if self.termination is None:
            self.termination = termination
        # if nothing given fall back to default
        if self.termination is None:
            self.termination = self.default_termination

        if callback is not None:
            self.callback = callback
        if display is not None:
            self.display = display

        # !
        # END Overwrite by minimize
        # !

        # by default the algorithm as not terminated
        self.has_terminated = False

        # other run dependent variables that are reset
        self.n_gen = 1
        self.history = []
        self.pop = Population()
        self.opt = None
示例#7
0
    run = params[id]
    name = names[id]
    output = output + name
    if not os.path.exists(output):
        os.makedirs(output)

        print(output)

    i = 0
    for algorithm, problem, run, points, n in run:
        try:
            problem = problem()
        except TypeError:
            pass
        points = np.array(points)
        eval = Evaluator(100 * n_gen)
        start_time = time.time()
        X, F, G = algorithm.solve(problem, evaluator=eval, seed=run)
        print("--- %s seconds ---" % (time.time() - start_time))
        fname = os.path.join(output, problem.name() + "_" + str(i))
        print(fname)
        np.savetxt(fname + ".out", F)
        if id <= 5:
            metric_time = time.time()
            igd, hv = RMetric(curr_pop=F,
                              whole_pop=F,
                              ref_points=points,
                              problem=problem).calc()
            results.append(np.array([run, igd, hv]))
            print(igd, " - ", hv)
            print("--- %s seconds ---" % (time.time() - metric_time))
示例#8
0
    def solve(
        self,
        problem,
        evaluator,
        seed=1,
        return_only_feasible=True,
        return_only_non_dominated=True,
        history=None,
    ):
        """

        Solve a given problem by a given evaluator. The evaluator determines the termination condition and
        can either have a maximum budget, hypervolume or whatever. The problem can be any problem the algorithm
        is able to solve.

        Parameters
        ----------

        problem: class
            Problem to be solved by the algorithm

        evaluator: class
            object that evaluates and saves the number of evaluations and determines the stopping condition

        seed: int
            Random seed for this run. Before the algorithm starts this seed is set.

        return_only_feasible : bool
            If true, only feasible solutions are returned.

        return_only_non_dominated : bool
            If true, only the non dominated solutions are returned. Otherwise, it might be - dependend on the
            algorithm - the final population

        Returns
        -------
        X: matrix
            Design space

        F: matrix
            Objective space

        G: matrix
            Constraint space

        """

        # set the random seed for generator
        pymoo.rand.random.seed(seed)

        # just to be sure also for the others
        seed = pymoo.rand.random.randint(0, 100000)
        random.seed(seed)
        np.random.seed(seed)

        # this allows to provide only an integer instead of an evaluator object
        if not isinstance(evaluator, Evaluator):
            evaluator = Evaluator(evaluator)

        # call the algorithm to solve the problem
        X, F, G = self._solve(problem, evaluator)

        if return_only_feasible:
            if G is not None and G.shape[0] == len(F) and G.shape[1] > 0:
                cv = Problem.calc_constraint_violation(G)[:, 0]
                X = X[cv <= 0, :]
                F = F[cv <= 0, :]
                if G is not None:
                    G = G[cv <= 0, :]

        if return_only_non_dominated:
            idx_non_dom = NonDominatedRank.calc_as_fronts(F, G)[0]
            X = X[idx_non_dom, :]
            F = F[idx_non_dom, :]
            if G is not None:
                G = G[idx_non_dom, :]

        return X, F, G
示例#9
0
 def test_evaluate_array_single(self):
     evaluator = Evaluator(evaluate_values_of=["F", "CV"])
     _F, _CV = evaluator.eval(problem, X[0])
     np.testing.assert_allclose(F[0], _F)
     self.assertTrue(evaluator.n_eval == 1)
示例#10
0
 def _initialize(self):
     self.evaluator = Evaluator(
         skip_already_evaluated=False
     ) if self.evaluate_each_ant else MockEvaluator()
     self.opt = Population()
     self._next()
示例#11
0
class ACO(Algorithm):
    def __init__(self,
                 ant,
                 pheromones,
                 n_ants=10,
                 global_update='best',
                 local_update=True,
                 evaluate_each_ant=True,
                 display=ACODisplay(),
                 **kwargs):
        """

        Parameters
        ----------

        ant : class
            An objective defining the behavior of each ant

        pheromones : class
            The pheromone implementation storing the amount of pheromones on each edge,
            the evaporation and update.

        n_ants : int
            Number of ants to be used each iteration

        global_update : {'all', 'it-best', 'best'}

        """

        super().__init__(display=display, **kwargs)

        # make the ant always to be a function being able to call
        if not callable(ant):
            proto = deepcopy(ant)

            def new_ant():
                return deepcopy(proto)

            ant = new_ant

        self.ant = ant
        self.pheromones = pheromones
        self.n_ants = n_ants
        self.global_update = global_update
        self.local_update = local_update
        self.evaluate_each_ant = evaluate_each_ant

    def _initialize(self):
        self.evaluator = Evaluator(
            skip_already_evaluated=False
        ) if self.evaluate_each_ant else MockEvaluator()
        self.opt = Population()
        self._next()

    def _next(self):

        # initialize all ants to be used in this iteration
        ants = []
        for k in range(self.n_ants):
            ant = self.ant()
            ant.initialize(self.problem, self.pheromones)
            ants.append(ant)

        active = list(range(self.n_ants))

        while len(active) > 0:

            for k in active:
                ant = ants[k]

                if ant.has_next():
                    ant.next()

                    if self.local_update:
                        e = ant.last()
                        if e is None or e.pheromone is None:
                            raise Exception(
                                "For a local update the ant has to set the pheromones when notified."
                            )
                        else:
                            self.pheromones.set(
                                e.key,
                                self.pheromones.get(e.key) * ant.alpha +
                                e.pheromone * ant.alpha)
                            # self.pheromones.update(e.key, e.pheromone * ant.alpha)

                else:
                    ant.finalize()
                    active = [i for i in active if i != k]

        colony = Population.create(*ants)

        # this evaluation can be disabled or faked if evaluate_each_ant is false - then the finalize method of the
        # ant has to set the objective and/or constraint values accordingly
        self.evaluator.eval(self.problem, colony)
        set_cv(colony)
        set_feasibility(colony)

        # set the current best including the new colony
        opt = FitnessSurvival().do(problem, Population.merge(colony, self.opt),
                                   1)

        # do the evaporation after this iteration
        self.pheromones.evaporate()

        # select the ants to be used for the global pheromone update
        if self.global_update == "all":
            ants_to_update = colony
        elif self.global_update == "it-best":
            ants_to_update = FitnessSurvival().do(problem, colony, 1)
        elif self.global_update == "best":
            ants_to_update = self.opt
        else:
            raise Exception(
                "Unknown value for global updating the pheromones!")

        # now spread the pheromones for each ant depending on performance
        for ant in ants_to_update:
            for e in ant.path:
                if e.pheromone is None:
                    raise Exception(
                        "The ant has to set the pheromone of each entry in the path."
                    )
                else:
                    self.pheromones.update(e.key, e.pheromone * pheromones.rho)

        self.pop, self.off = colony, colony
        self.opt = opt

    def _set_optimum(self, **kwargs):
        pass
示例#12
0
    def setup(self,
              problem,

              # START Overwrite by minimize
              termination=None,
              callback=None,
              display=None,
              # END Overwrite by minimize

              # START Default minimize
              seed=None,
              verbose=False,
              save_history=False,
              return_least_infeasible=False,
              # END Default minimize

              pf=True,
              evaluator=None,
              **kwargs):

        # set the problem that is optimized for the current run
        self.problem = problem

        # set the provided pareto front
        self.pf = pf

        # by default make sure an evaluator exists if nothing is passed
        if evaluator is None:
            evaluator = Evaluator()
        self.evaluator = evaluator

        # !
        # START Default minimize
        # !
        # if this run should be verbose or not
        self.verbose = verbose
        # whether the least infeasible should be returned or not
        self.return_least_infeasible = return_least_infeasible
        # whether the history should be stored or not
        self.save_history = save_history

        # set the random seed in the algorithm object
        self.seed = seed
        if self.seed is None:
            self.seed = np.random.randint(0, 10000000)
        # set the random seed for Python and Numpy methods
        random.seed(self.seed)
        np.random.seed(self.seed)
        # !
        # END Default minimize
        # !

        # !
        # START Overwrite by minimize
        # !

        # the termination criterion to be used to stop the algorithm
        if self.termination is None:
            self.termination = termination_from_tuple(termination)
        # if nothing given fall back to default
        if self.termination is None:
            self.termination = self.default_termination

        if callback is not None:
            self.callback = callback

        if display is not None:
            self.display = display

        # !
        # END Overwrite by minimize
        # !

        return self
示例#13
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")

X = np.random.random((300, problem.n_var))

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

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

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)
示例#14
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))
示例#15
0
 def test_evaluate_individual(self):
     evaluator = Evaluator()
     ind = evaluator.eval(problem, Individual(X=X[0]))
     np.testing.assert_allclose(F[0], ind.get("F"))
     self.assertTrue(evaluator.n_eval == 1)
示例#16
0
def minimize(fun,
             xl=None,
             xu=None,
             termination=('n_eval', 10000),
             n_var=None,
             fun_args={},
             method='auto',
             method_args={},
             seed=None,
             callback=None,
             disp=True):
    """

    Minimization of function of one or more variables, objectives and constraints.

    This is used as a convenience function to execute several algorithms with default settings which turned
    out to work for a test problems. However, evolutionary computations utilizes the idea of customizing a
    meta-algorithm. Customizing the algorithm using the object oriented interface is recommended to improve the
    convergence.

    Parameters
    ----------

    fun : callable
        A function that gets X which is a 2d array as input. Each row represents a solution to evaluate
        and each column a variable. The function needs to return also the same number of rows and each column
        is one objective to optimize. In case of constraints, a second 2d array can be returned.

    xl : numpy.array or number
        The lower boundaries of variables as a 1d array

    xu : numpy.array or number
        The upper boundaries of variables as a 1d array

    n_var : int
        If xl or xu is only a number, this is used to create the boundary numpy arrays. Other it remains unused.

    termination : tuple
        The termination criterium that is used to stop the algorithm when the result is satisfying.

    fun_args : dict
        Additional arguments if necessary to evaluate the solutions (constants, random seed, ...)


    method : string
        Algorithm that is used to solve the problem.

    callback : callable, optional
        Called after each iteration, as ``callback(D)``, where ``D`` is a dictionary with
        algorithm information, such as the current design, objective and constraint space.

    disp : bool
        Whether to display each generation the current result or not.

    Returns
    -------
    res : Result
        The optimization result represented as a ``Result`` object.


    """

    problem = None

    if isinstance(fun, Problem):
        problem = fun

    elif callable(fun):

        if xl is None or xu is None:
            raise Exception(
                "Please provide lower and upper bounds for the problem.")
        if isinstance(xl, (int, float)):
            xl = xl * np.ones(n_var)
        if isinstance(xu, (int, float)):
            xu = xu * np.ones(n_var)

        # determine through a test evaluation details about the problem
        n_var = xl.shape[0]
        n_obj = -1
        n_constr = 0

        res = fun(xl[None, :], **fun_args)

        if isinstance(res, tuple):
            # if there are constraints it is a tuple of length two
            if len(res) > 1:
                n_constr = res[1].shape[1]
            n_obj = res[0].shape[1]
        else:
            n_obj = res.shape[1]

        # create an optimization problem given the function properties
        class OptimizationProblem(Problem):
            def __init__(self):
                Problem.__init__(self)
                self.n_var = n_var
                self.n_constr = n_constr
                self.n_obj = n_obj
                self.func = self._evaluate
                self.xl = xl
                self.xu = xu

            def _evaluate(self, x, f, g=None):
                if g is None:
                    f[:, :] = fun(x, **fun_args)
                else:
                    f[:, :], g[:, :] = fun(x, **fun_args)

        problem = OptimizationProblem()

    else:
        raise Exception(
            "fun arguments needs to be either a function or an object of the class problem."
        )

    # create an evaluator defined by the termination criterium
    termination_criterium, termination_val = termination
    if termination_criterium == 'n_eval':
        evaluator = Evaluator(termination_val)
    else:
        raise Exception('Unknown Termination criterium: %s' %
                        termination_criterium)

    return minimize_(problem,
                     evaluator,
                     method=method,
                     method_args=method_args,
                     seed=seed,
                     callback=callback,
                     disp=disp)
示例#17
0
 def fun(x, n):
     ind = Individual(X=np.copy(x))
     Evaluator().eval(problem, ind)
     global pop
     pop = Population.merge(pop, ind)
     return ind.F[0]
示例#18
0
 def test_evaluate_array(self):
     evaluator = Evaluator(evaluate_values_of=["F", "CV"])
     _F, _CV = evaluator.eval(problem, X)
     np.testing.assert_allclose(F, _F)
     self.assertTrue(evaluator.n_eval == len(X))