Example #1
0
    def _do(self, problem, pop, n_survive, D=None, **kwargs):

        # attributes to be set after the survival
        F = pop.get("F")

        # find or usually update the new ideal point - from feasible solutions
        self.ideal_point = np.min(np.vstack(
            (self.ideal_point, F, self.ref_points)),
                                  axis=0)
        self.worst_point = np.max(np.vstack(
            (self.worst_point, F, self.ref_points)),
                                  axis=0)

        # calculate the fronts of the population
        fronts, rank = NonDominatedSorting().do(F,
                                                return_rank=True,
                                                n_stop_if_ranked=n_survive)
        non_dominated, last_front = fronts[0], fronts[-1]

        # find the extreme points for normalization
        self.extreme_points = get_extreme_points_c(
            np.vstack([F[non_dominated], self.ref_points]),
            self.ideal_point,
            extreme_points=self.extreme_points)

        # find the intercepts for normalization and do backup if gaussian elimination fails
        worst_of_population = np.max(F, axis=0)
        worst_of_front = np.max(F[non_dominated, :], axis=0)

        self.nadir_point = get_nadir_point(self.extreme_points,
                                           self.ideal_point, self.worst_point,
                                           worst_of_population, worst_of_front)

        #  consider only the population until we come to the splitting front
        I = np.concatenate(fronts)
        pop, rank, F = pop[I], rank[I], F[I]

        # update the front indices for the current population
        counter = 0
        for i in range(len(fronts)):
            for j in range(len(fronts[i])):
                fronts[i][j] = counter
                counter += 1
        last_front = fronts[-1]

        unit_ref_points = (self.ref_points - self.ideal_point) / (
            self.nadir_point - self.ideal_point)
        ref_dirs = get_ref_dirs_from_points(unit_ref_points,
                                            self.aspiration_ref_dirs,
                                            mu=self.mu)
        self.ref_dirs = denormalize(ref_dirs, self.ideal_point,
                                    self.nadir_point)

        # associate individuals to niches
        niche_of_individuals, dist_to_niche, dist_matrix = associate_to_niches(
            F, ref_dirs, self.ideal_point, self.nadir_point)
        pop.set('rank', rank, 'niche', niche_of_individuals, 'dist_to_niche',
                dist_to_niche)

        # set the optimum, first front and closest to all reference directions
        closest = np.unique(
            dist_matrix[:, np.unique(niche_of_individuals)].argmin(axis=0))
        self.opt = pop[intersect(fronts[0], closest)]

        # if we need to select individuals to survive
        if len(pop) > n_survive:

            # if there is only one front
            if len(fronts) == 1:
                n_remaining = n_survive
                until_last_front = np.array([], dtype=int)
                niche_count = np.zeros(len(ref_dirs), dtype=int)

            # if some individuals already survived
            else:
                until_last_front = np.concatenate(fronts[:-1])
                niche_count = calc_niche_count(
                    len(ref_dirs), niche_of_individuals[until_last_front])
                n_remaining = n_survive - len(until_last_front)

            S = niching(pop[last_front], n_remaining, niche_count,
                        niche_of_individuals[last_front],
                        dist_to_niche[last_front])

            survivors = np.concatenate(
                (until_last_front, last_front[S].tolist()))
            pop = pop[survivors]

        return pop
Example #2
0
    def _do(self, pop, n_survive, D=None, **kwargs):

        # attributes to be set after the survival
        X, F = pop.get("X", "F")

        # find or usually update the new ideal point - from feasible solutions
        self.ideal_point = np.min(np.vstack((self.ideal_point, F)), axis=0)
        self.worst_point = np.max(np.vstack((self.worst_point, F)), axis=0)

        # calculate the fronts of the population
        fronts, rank = NonDominatedSorting().do(F,
                                                return_rank=True,
                                                n_stop_if_ranked=n_survive)
        non_dominated, last_front = fronts[0], fronts[-1]

        # find the extreme points for normalization
        self.extreme_points = get_extreme_points_c(
            F[non_dominated, :],
            self.ideal_point,
            extreme_points=self.extreme_points)

        # find the intercepts for normalization and do backup if gaussian elimination fails
        worst_of_population = np.max(F, axis=0)
        worst_of_front = np.max(F[non_dominated, :], axis=0)

        self.nadir_point = get_nadir_point(self.extreme_points,
                                           self.ideal_point, self.worst_point,
                                           worst_of_population, worst_of_front)

        #  consider only the population until we come to the splitting front
        I = np.concatenate(fronts)
        pop, rank, X, F = pop[I], rank[I], X[I], F[I]

        # update the front indices for the current population
        counter = 0
        for i in range(len(fronts)):
            for j in range(len(fronts[i])):
                fronts[i][j] = counter
                counter += 1
        last_front = fronts[-1]

        # associate individuals to niches
        niche_of_individuals, dist_to_niche = associate_to_niches(
            F, self.ref_dirs, self.ideal_point, self.nadir_point)

        kktpm, _ = KKTPM(var_bounds_as_constraints=False).calc(X, problem)
        kktpm = kktpm[:, 0]

        pop.set('rank', rank, 'niche', niche_of_individuals, 'dist_to_niche',
                dist_to_niche, 'kktpm', kktpm)

        # if we need to select individuals to survive
        if len(pop) > n_survive:

            # if there is only one front
            if len(fronts) == 1:
                n_remaining = n_survive
                until_last_front = np.array([], dtype=np.int)
                niche_count = np.zeros(len(self.ref_dirs), dtype=np.int)

            # if some individuals already survived
            else:
                until_last_front = np.concatenate(fronts[:-1])
                niche_count = calc_niche_count(
                    len(self.ref_dirs), niche_of_individuals[until_last_front])
                n_remaining = n_survive - len(until_last_front)

            S = niching(F[last_front, :], n_remaining, niche_count,
                        niche_of_individuals[last_front], kktpm[last_front])

            survivors = np.concatenate(
                (until_last_front, last_front[S].tolist()))
            pop = pop[survivors]

        return pop
Example #3
0
    def _do(self, pop, n_survive, D=None, **kwargs):

        # attributes to be set after the survival
        F = pop.get("F")

        # find or usually update the new ideal point - from feasible solutions
        self.ideal_point = np.min(np.vstack((self.ideal_point, F)), axis=0)
        self.worst_point = np.max(np.vstack((self.worst_point, F)), axis=0)

        # calculate the fronts of the population
        fronts, rank = NonDominatedSorting().do(F,
                                                return_rank=True,
                                                n_stop_if_ranked=n_survive)
        non_dominated, last_front = fronts[0], fronts[-1]

        # find the extreme points for normalization
        self.extreme_points = get_extreme_points_c(
            F[non_dominated, :],
            self.ideal_point,
            extreme_points=self.extreme_points)

        # find the intercepts for normalization and do backup if gaussian elimination fails
        worst_of_population = np.max(F, axis=0)
        worst_of_front = np.max(F[non_dominated, :], axis=0)

        self.nadir_point = get_nadir_point(self.extreme_points,
                                           self.ideal_point, self.worst_point,
                                           worst_of_population, worst_of_front)

        #  consider only the population until we come to the splitting front
        I = np.concatenate(fronts)
        pop, rank, F = pop[I], rank[I], F[I]

        # update the front indices for the current population
        counter = 0
        for i in range(len(fronts)):
            for j in range(len(fronts[i])):
                fronts[i][j] = counter
                counter += 1

        # normalize the whole population by the estimations made
        N = normalize(F, self.ideal_point, self.nadir_point)

        # the final indices of surviving individuals
        survivors = []

        for k, front in enumerate(fronts):

            # calculate the crowding distance of the front
            crowding_of_front = calc_asf_crowding_distance(N[front, :])

            # save rank and crowding in the individual class
            for j, i in enumerate(front):
                pop[i].set("rank", k)
                pop[i].set("crowding", crowding_of_front[j])

            # current front sorted by crowding distance if splitting
            if len(survivors) + len(front) > n_survive:
                I = randomized_argsort(crowding_of_front,
                                       order='descending',
                                       method='numpy')
                I = I[:(n_survive - len(survivors))]

            # otherwise take the whole front unsorted
            else:
                I = np.arange(len(front))

            # extend the survivors by all or selected individuals
            survivors.extend(front[I])

        return pop[survivors]
Example #4
0
    def _do(self, pop, n_survive, algorithm=None, **kwargs):

        if True:

            if self.archive is None:
                self.archive = pop
            else:
                self.archive = self.archive.merge(pop)

            # get the function values of the current archive for operations
            F = self.archive.get("F")

            # filter out all the duplicate solutions
            I = np.logical_not(default_is_duplicate(F))
            self.archive, F = self.archive[I], F[I]

            # get only the non-dominated solutions
            I = NonDominatedSorting().do(F, only_non_dominated_front=True)
            self.archive, F = self.archive[I], F[I]

            if len(self.archive) > self.n_archive:
                cd = calc_crowding_distance(F)
                self.archive = self.archive[np.argsort(cd)[::-1]
                                            [:self.n_archive]]

            # attributes to be set after the survival
            pop.merge(self.archive)

        F = pop.get("F")

        # find or usually update the new ideal point - from feasible solutions
        self.ideal_point = np.min(np.vstack((self.ideal_point, F)), axis=0)
        self.worst_point = np.max(np.vstack((self.worst_point, F)), axis=0)

        # calculate the fronts of the population
        fronts, rank = NonDominatedSorting(epsilon=1e-10).do(
            F, return_rank=True, n_stop_if_ranked=n_survive)
        non_dominated, last_front = fronts[0], fronts[-1]

        # find the extreme points for normalization
        self.extreme_points = non_dominated[get_extreme_points(
            F[non_dominated, :], self.ideal_point)]

        # find the intercepts for normalization and do backup if gaussian elimination fails
        worst_of_population = np.max(F, axis=0)
        worst_of_front = np.max(F[non_dominated, :], axis=0)

        self.nadir_point = get_nadir_point(F[self.extreme_points],
                                           self.ideal_point, self.worst_point,
                                           worst_of_population, worst_of_front)

        # associate individuals to niches
        pop.set('rank', rank)

        # if we need to select individuals to survive
        if len(pop) > n_survive:

            for i in range(len(fronts)):
                fronts[i] = np.array(
                    [j for j in fronts[i] if j not in self.extreme_points])

            survivors = np.unique(self.extreme_points).tolist()

            for k, front in enumerate(fronts):

                # current front sorted by crowding distance if splitting
                if len(survivors) + len(front) > n_survive:
                    I = selection(survivors, list(front), F,
                                  (n_survive - len(survivors)))
                    survivors.extend(I)

                # otherwise take the whole front unsorted
                else:
                    # extend the survivors by all or selected individuals
                    survivors.extend(front)

            pop = pop[survivors]

        return pop