def do(pop, n_survive): # get the objective space values and objects F = pop.get('F') # the final indices of surviving individuals survivors = [] # do the non-dominated sorting until splitting front fronts = NonDominatedSorting().do(F, n_stop_if_ranked=n_survive) for k, front in enumerate(fronts): # calculate the crowding distance of the front crowding_of_front = calc_crowding_distance(F[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]
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]