Exemplo n.º 1
0
    def _adapt(self):
        pop = self.pop

        X, F = pop.get("X", "F")
        sbest = self.sbest
        w, c1, c2, = self.w, self.c1, self.c2

        # get the average distance from one to another for normalization
        D = norm_eucl_dist(self.problem, X, X)
        mD = D.sum(axis=1) / (len(pop) - 1)
        _min, _max = mD.min(), mD.max()

        # get the average distance to the best
        g_D = norm_eucl_dist(self.problem, sbest.get("X"), X).mean()
        f = (g_D - _min) / (_max - _min + 1e-32)

        S = np.array([
            S1_exploration(f),
            S2_exploitation(f),
            S3_convergence(f),
            S4_jumping_out(f)
        ])
        strategy = S.argmax() + 1

        delta = 0.05 + (np.random.random() * 0.05)

        if strategy == 1:
            c1 += delta
            c2 -= delta
        elif strategy == 2:
            c1 += 0.5 * delta
            c2 -= 0.5 * delta
        elif strategy == 3:
            c1 += 0.5 * delta
            c2 += 0.5 * delta
        elif strategy == 4:
            c1 -= delta
            c2 += delta

        c1 = max(1.5, min(2.5, c1))
        c2 = max(1.5, min(2.5, c2))

        if c1 + c2 > 4.0:
            c1 = 4.0 * (c1 / (c1 + c2))
            c2 = 4.0 * (c2 / (c1 + c2))

        w = 1 / (1 + 1.5 * np.exp(-2.6 * f))

        self.f = f
        self.strategy = strategy
        self.c1 = c1
        self.c2 = c2
        self.w = w
Exemplo n.º 2
0
    def _do(self, problem, pop, n_survive, out=None, algorithm=None, **kwargs):
        X, F = pop.get("X", "F")
        if F.shape[1] != 1:
            raise ValueError(
                "FitnessSurvival can only used for single objective single!")

        n_neighbors = 5

        # calculate the normalized euclidean distances from each solution to another
        D = norm_eucl_dist(problem, X, X, fill_diag_with_inf=True)

        # set the neighborhood for each individual
        for k, individual in enumerate(pop):

            # the neighbors in the current population
            neighbors = pop[D[k].argsort()[:n_neighbors]]

            # get the neighbors of the current individual and merge
            N = individual.get("neighbors")
            if N is not None:
                rec = []
                h = set()
                for n in N:
                    for entry in n.get("neighbors"):
                        if entry not in h:
                            rec.append(entry)
                            h.add(entry)

                neighbors = Population.merge(neighbors, rec)

            # keep only the closest solutions to the individual
            _D = norm_eucl_dist(problem, individual.X[None, :],
                                neighbors.get("X"))[0]

            # find only the closest neighbors
            closest = _D.argsort()[:n_neighbors]

            individual.set("crowding", _D[closest].mean())
            individual.set("neighbors", neighbors[closest])

        best = F[:, 0].argmin()
        print(F[best], pop[best].get("crowding"))

        # plt.scatter(F[:, 0], pop.get("crowding"))
        # plt.show()

        pop.set("_F", pop.get("F"))
        pop.set("F", np.column_stack([F, -pop.get("crowding")]))
        pop = RankAndCrowdingSurvival().do(problem, pop, n_survive)
        pop.set("F", pop.get("_F"))

        return pop
Exemplo n.º 3
0
    def do(self, problem, pop, n_survive, **kwargs):

        # calculate the distance from each individual to another - pre-processing for the clearing
        X = pop.get("X")
        D = norm_eucl_dist(problem, X, X)

        def func_select_by_constraint_violation(pop):
            CV = pop.get("CV")
            return CV[:, 0].argmin()

        I = select_by_clearing(pop, D, n_survive,
                               func_select_by_constraint_violation)

        return pop[I]
Exemplo n.º 4
0
    def _initialize(self):
        self.pop = self.initialization.do(self.problem,
                                          self.pop_size,
                                          algorithm=self)
        self.evaluator.eval(self.problem, self.pop, algorithm=self)

        X = self.pop.get("X")
        D = norm_eucl_dist(self.problem, X, X)
        S = select_by_clearing(self.pop, D, self.n_parallel,
                               func_select_by_objective)

        self.solvers = []
        for s in S:
            solver = self.func_create_solver(self.problem, self.pop[s].X)
            self.solvers.append(solver)
Exemplo n.º 5
0
    def do(self, problem, pop, n_survive, **kwargs):

        # sort them by cv
        sorted_by_cv = pop.get("CV")[:, 0].argsort()
        pop = pop[sorted_by_cv]

        if self.clearing:

            # calculate the distance from each individual to another - pre-processing for the clearing
            X = pop.get("X")
            D = norm_eucl_dist(problem, X, X)

            # select by clearing using the order defined before
            I = select_by_clearing(pop,
                                   D,
                                   n_survive,
                                   func_select_from_sorted,
                                   delta=self.clearing_delta)

            return pop[I]

        else:
            return pop[:n_survive]
Exemplo n.º 6
0
    def _do(self, problem, pop, n_survive, out=None, **kwargs):
        F = pop.get("F")

        if F.shape[1] != 1:
            raise ValueError(
                "FitnessSurvival can only used for single objective single!")

        # this basically sorts the population by constraint and objective value
        pop = FitnessSurvival().do(problem, pop, len(pop))

        # calculate the distance from each individual to another - pre-processing for the clearing
        X = pop.get("X")
        D = norm_eucl_dist(problem, X, X)

        # initialize the clearing strategy
        clearing = EpsilonClearing(D, self.epsilon)

        # initialize the iteration and rank i the beginning
        iter, rank = 1, 1

        # also solutions that have been found in the first iteration
        iter_one = None

        # until the number of selected individuals are less than expected survivors
        while len(clearing.selected()) < n_survive:

            # get all the remaining indices
            remaining = clearing.remaining()

            # if no individuals are left because of clearing - perform a reset
            if len(remaining) == 0 or (self.n_max_each_iter is not None
                                       and rank > self.n_max_each_iter):
                # reset and retrieve the newly available indices
                clearing.reset()
                remaining = clearing.remaining()

                # increase the iteration counter and start over from rank 1
                iter += 1
                rank = 1

                # get the individual of the first iteration - needed for niche assignment
                iter_one = np.where(
                    pop.get("iter") == 1)[0] if iter_one is None else iter_one

            # since the population is ordered by F and CV it is always the first index
            k = remaining[0]

            # set the attribute to the selected individual
            pop[k].set("iter", iter)
            pop[k].set("rank", rank)

            # in the first iteration set the niche counter for each solution equal to rank
            if iter == 1:
                pop[k].set("niche", rank)
            else:
                closest_iter_one = iter_one[D[k][iter_one].argmin()]
                niche = pop[closest_iter_one].get("niche")
                pop[k].set("niche", niche)

            clearing.select(k)
            rank += 1

        # retrieve all individuals being selected
        S = clearing.selected()

        return pop[S]