def _initialize(self): # initialize the function parameters self.alpha, self.beta, self.gamma, self.delta = self.func_params( self.problem) # reset the restart history self.restart_history = [] # initialize the point if self.x0 is None: if not self.problem.has_bounds(): raise Exception( "Either provide an x0 or a problem with variable bounds!") # initialize randomly and make sure 5% is left for creating the initial simplex X = np.random.random(self.problem.n_var) self.x0 = denormalize(X, self.problem.xl, self.problem.xu) # parse the initial population from array or population object pop = pop_from_array_or_individual(self.x0) # if the simplex has not the correct number of points if len(pop) == 1: # the corresponding x values x0 = pop[0].X # if lower and upper bounds are given take 5% of the range and add if self.problem.has_bounds(): self.simplex_scaling = 0.05 * (self.problem.xu - self.problem.xl) # no bounds are given do it based on x0 - MATLAB procedure else: self.simplex_scaling = 0.05 * x0 # some value needs to be added if x0 is zero self.simplex_scaling[self.simplex_scaling == 0] = 0.00025 # initialize the simplex X = self.initialize_simplex(x0) # create a population object pop = pop.merge(Population().new("X", X)) # evaluate the values that are not already evaluated evaluate_if_not_done_yet(self.evaluator, self.problem, pop, algorithm=self) elif len(pop) != self.problem.n_var + 1: raise Exception( "Provided initial population has size of %s, but should have size of %s" % (len(pop), self.problem.n_var + 1)) # sort by its corresponding function values self.pop = pop[np.argsort(pop.get("F")[:, 0])] self.opt = self.pop[0]
def sample(self, problem, pop, n_samples, **kwargs): m = problem.n_var val = random.random(size=(n_samples, m)) if self.var_type == np.bool: val = random.random((n_samples, m)) val = (val < 0.5).astype(np.bool) elif self.var_type == np.int: val = np.rint( denormalize(val, problem.xl - 0.5, problem.xu + (0.5 - 1e-16))).astype(np.int) else: val = denormalize(val, problem.xl, problem.xu) return pop.new("X", val)
def _do(self, problem, n_samples, **kwargs): for _ in range(n_samples - len(self.solution)): #w = np.random.normal(loc=0, scale=0.1, size=problem.n_var).astype(np.float32) w = np.random.random(problem.n_var) w = denormalize(w, problem.xl, problem.xu) self.solution.append(w) return np.array(self.solution)
def initialize(self, problem, **kwargs): super().initialize(problem, **kwargs) xl, xu = problem.bounds() X = denormalize(0.5 * np.ones(problem.n_var), xl, xu) x0 = Individual(X=X) x0.set("xl", xl) x0.set("xu", xu) x0.set("depth", 0) self.x0 = x0
def predict(res, X): # if it is only one dimensional convert it if X.ndim == 1: X = X[:, None] Y = np.full((X.shape[0], len(res['surrogates'])), np.inf) # denormalize if normalized before if res['normalize_X']: X = normalize(X, res['X_min'], res['X_max']) # for each target value to predict there exists a model for m, model in enumerate(res['surrogates']): Y[:, m] = model.predict(X) # denormalize target if done while fitting if res['normalize_Y']: Y = denormalize(Y, res['Y_min'], res['Y_max']) return Y
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
def _do(self, problem, n_samples, **kwargs): val = np.random.random((n_samples, problem.n_var)) return denormalize(val, problem.xl, problem.xu)
def denormalize(self, x): return denormalize(x, self._xl, self._xu)
def random_by_bounds(n_var, xl, xu, n_samples=1): val = np.random.random((n_samples, n_var)) return denormalize(val, xl, xu)