Ejemplo n.º 1
0
    def do(self,
           problem,
           X,
           F=None,
           G=None,
           evaluator=None,
           hessian=False,
           return_values_of="auto"):

        # if no evaluator is provided to count function evaluations just use a plain one
        if evaluator is None:
            evaluator = Evaluator()

        # if it is not a population object yet, make one out of it
        pop = to_solution_set(X, F, G)

        # loop over each solution the approximation should be done for
        for solution in pop:
            x = solution.X

            # make sure the solution is evaluated
            if solution.F is None:
                evaluator.eval(problem, solution)

            eps = self.eps
            if eps is None:
                eps = EPS**(1 / self.jacobian.n_points)
                eps = eps * np.maximum(eps, np.abs(x))

            if not isinstance(eps, np.ndarray):
                eps = np.full(len(x), eps)

            values = ["F"]
            if problem.has_constraints():
                values.append("G")

            self.calc(problem, evaluator, solution, values, eps, hessian)

        if return_values_of == "auto":
            return_values_of = ["dF"]
            if hessian:
                return_values_of.append("ddF")
            if problem.has_constraints():
                return_values_of.append("dG")
                if hessian:
                    return_values_of.append("ddG")

        if isinstance(X, Individual):
            pop = pop[0]

        ret = tuple([pop.get(e) for e in return_values_of])

        if len(ret) == 1:
            return ret[0]
        else:
            return ret
Ejemplo n.º 2
0
def test_min_vs_loop_vs_infill():
    problem = get_problem("zdt1")
    n_gen = 30

    algorithm = NSGA2(pop_size=100)
    min_res = minimize(problem, algorithm, ('n_gen', n_gen), seed=1)

    algorithm = NSGA2(pop_size=100)
    algorithm.setup(problem, ('n_gen', n_gen), seed=1)
    while algorithm.has_next():
        algorithm.next()
    algorithm.finalize()
    loop_res = algorithm.result()

    np.testing.assert_allclose(min_res.X, loop_res.X)

    algorithm = NSGA2(pop_size=100)
    algorithm.setup(problem, ('n_gen', n_gen), seed=1)
    while algorithm.has_next():
        infills = algorithm.infill()
        Evaluator().eval(problem, infills)
        algorithm.advance(infills=infills)
    algorithm.finalize()
    infill_res = algorithm.result()

    np.testing.assert_allclose(min_res.X, infill_res.X)
Ejemplo n.º 3
0
def test_numerical_differentiation_hessian():
    np.random.seed(1)

    rosen = lambda x: (1 - x[0])**2 + 105. * (x[1] - x[0]**2)**2
    cubic = lambda x: (x**3).sum()
    sphere = lambda x: (x**2).sum()
    for func in [
            sphere,
            cubic,
            rosen,
    ]:
        problem = AutomaticDifferentiationProblem(func, n_var=5)

        X = np.random.random((1, problem.n_var))
        F, dF, ddF = problem.evaluate(X, return_values_of=["F", "dF", "ddF"])

        evaluator = Evaluator()
        _dF, _ddF = NumericalDifferentiation(eps=None).do(problem,
                                                          X,
                                                          F,
                                                          evaluator=evaluator,
                                                          hessian=True)
        print(evaluator.n_eval)
        np.testing.assert_allclose(_dF, dF, rtol=1e-5, atol=0)
        np.testing.assert_allclose(_ddF, ddF, rtol=1e-5, atol=0)
        print(func)

    print("Done")
Ejemplo n.º 4
0
def test_preevaluated():
    evaluator = Evaluator()
    pop = Population.new("X", X)
    evaluator.eval(problem, pop)

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

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

    np.testing.assert_allclose(F, pop.get("F"))
    assert evaluator.n_eval == 30
Ejemplo n.º 5
0
def test_numerical_differentiation_with_gradient():
    np.random.seed(1)

    problem = SphereWithGradientAndConstraint()

    X = np.random.random((1, problem.n_var))
    F, G, dF, ddF, dG, ddG = problem.evaluate(
        X, return_values_of=["F", "G", "dF", "ddF", "dG", "ddG"])

    evaluator = Evaluator()
    _dF, _ddF, _dG, _ddG = NumericalDifferentiation(eps=None).do(
        problem, X, F, G=G, evaluator=evaluator, hessian=True)

    print(evaluator.n_eval)
    np.testing.assert_allclose(_dF, dF, rtol=1e-5, atol=0)
    np.testing.assert_allclose(_ddF, ddF, rtol=1e-5, atol=0)
    np.testing.assert_allclose(_dG, dG, rtol=1e-5, atol=0)
    np.testing.assert_allclose(_ddG, ddG, rtol=1e-5, atol=0)

    print("Done")
Ejemplo n.º 6
0
        infill = Solution(X=x + t * p, t=t)
        self.evaluator.eval(self.problem, infill, algorithm=self, evaluate_values_of=["F"])
        _f = infill.F[0]

        self.pop = SolutionSet.merge(self.pop, infill)
        self.infill = infill

        if _f < f + self.alpha * self.t * df.T @ p or self.t <= 1e-8:
            self.termination.force_termination = True
        else:
            self.t = self.t * self.beta


if __name__ == '__main__':
    import numpy as np

    problem = Sphere()

    X = np.array(np.random.random(problem.n_var))

    point = Solution(X=X)
    Evaluator(evaluate_values_of=["F", "dF"]).eval(problem, point)

    direction = - point.get("dF")[0]

    algorithm = BacktrackingLineSearch().setup(problem, point=point, direction=direction)._initialize()

    res = minimize(problem, algorithm)

    print(res.X)
Ejemplo n.º 7
0
def wolfe_line_search(problem,
                      sol,
                      direction,
                      c1=1e-4,
                      c2=0.9,
                      max_iter=10,
                      evaluator=None):
    # initialize the evaluator to be used (this will make sure evaluations are counted)
    evaluator = evaluator if evaluator is not None else Evaluator()
    evaluator.skip_already_evaluated = False

    # the function value and gradient of the initial solution
    sol.set("alpha", 0.0)
    sol_F, sol_dF = sol.F[0], sol.get("dF")[0]

    def zoom(alpha_low, alpha_high, max_iter=100):

        while True:

            _alpha = (alpha_high.get("alpha") + alpha_low.get("alpha")) / 2
            _point = Individual(X=sol.X + _alpha * direction, alpha=_alpha)
            evaluator.eval(problem, _point, evaluate_values_of=["F", "CV"])

            if _point.F[
                    0] > sol_F + c1 * _alpha * sol_dF @ direction or _point.F[
                        0] > alpha_low.F[0]:
                alpha_high = _point
            else:
                evaluator.eval(problem, _point, evaluate_values_of=["dF"])
                point_dF = _point.get("dF")[0]

                if np.abs(point_dF @ direction) <= -c2 * sol_dF @ direction:
                    return _point

                if (point_dF @ direction) * (alpha_high.get("alpha") -
                                             alpha_low.get("alpha")) >= 0:
                    alpha_high = alpha_low

                alpha_low = _point

    last = sol

    alpha = 1.0
    current = Individual(X=sol.X + alpha * direction, alpha=alpha)

    for i in range(1, max_iter + 1):

        # evaluate the solutions
        evaluator.eval(problem, current, evaluate_values_of=["F", "CV"])

        # get the values from the solution to be used to evaluate the conditions
        F, dF, _F = last.F[0], last.get("dF")[0], current.F[0]

        # if the wolfe condition is violate we have found our upper bound
        if _F > sol_F + c1 * sol_dF @ direction or (i > 1 and F >= _F):
            return zoom(last, current)

        # for the other condition we need the gradient information
        evaluator.eval(problem, current, evaluate_values_of=["dF"])
        _dF = current.get("dF")[0]

        if np.abs(_dF @ direction) <= -c2 * sol_dF @ direction:
            return current

        if _dF @ direction >= 0:
            return zoom(current, last)

        alpha = 2 * alpha
        last = current
        current = Individual(X=sol.X + alpha * direction, alpha=alpha)

    return current
Ejemplo n.º 8
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
        # !

        # no call the algorithm specific setup given the problem
        self._setup(problem, **kwargs)

        return self
Ejemplo n.º 9
0
 def _initialize_infill(self):
     self.evaluator = Evaluator(
         skip_already_evaluated=False
     ) if self.evaluate_each_ant else MockEvaluator()
     self.opt = Population()
     self.step()
Ejemplo n.º 10
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_infill(self):
        self.evaluator = Evaluator(
            skip_already_evaluated=False
        ) if self.evaluate_each_ant else MockEvaluator()
        self.opt = Population()
        self.step()

    def step(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
Ejemplo n.º 11
0
def test_evaluate_pop():
    evaluator = Evaluator()
    pop = Population.new("X", X)
    evaluator.eval(problem, pop)
    np.testing.assert_allclose(F, pop.get("F"))
    assert evaluator.n_eval == len(X)
Ejemplo n.º 12
0
def test_evaluate_individual():
    evaluator = Evaluator()
    ind = evaluator.eval(problem, Individual(X=X[0]))
    np.testing.assert_allclose(F[0], ind.get("F"))
    assert evaluator.n_eval == 1
Ejemplo n.º 13
0
def test_evaluate_array_single():
    evaluator = Evaluator(evaluate_values_of=["F", "CV"])
    _F, _CV = evaluator.eval(problem, X[0])
    np.testing.assert_allclose(F[0], _F)
    assert evaluator.n_eval == 1
Ejemplo n.º 14
0
def test_evaluate_array():
    evaluator = Evaluator(evaluate_values_of=["F", "CV"])
    _F, _CV = evaluator.eval(problem, X)
    np.testing.assert_allclose(F, _F)
    assert evaluator.n_eval == len(X)
Ejemplo n.º 15
0
def evaluator():
    return Evaluator()