def update_A(self, new_solution): X = new_solution.get('X') hashX = new_solution.get('hashX') F = new_solution.get('F') rank = np.zeros(len(self.A_X)) if hashX not in self.A_hashX: flag = True for j in range(len(self.A_X)): better_idv = find_better_idv(F, self.A_F[j]) if better_idv == 1: rank[j] += 1 if self.A_hashX[j] not in self.DS: self.DS.append(self.A_hashX[j]) elif better_idv == 2: flag = False if hashX not in self.DS: self.DS.append(hashX) break if flag: self.A_X.append(np.array(X)) self.A_hashX.append(np.array(hashX)) self.A_F.append(np.array(F)) rank = np.append(rank, 0) self.A_X = np.array(self.A_X)[rank == 0].tolist() self.A_hashX = np.array(self.A_hashX)[rank == 0].tolist() self.A_F = np.array(self.A_F)[rank == 0].tolist()
def update(self, idv): X = idv.X hash_ = idv.hash_ F = idv.F l = len(self.X) r = np.zeros(l, dtype=np.int8) if hash_ not in self.hash_: flag = True for i, F_ in enumerate(self.F): better_idv = find_better_idv(f0_0=F[0], f0_1=F[1], f1_0=F_[0], f1_1=F_[1]) if better_idv == 0: r[i] += 1 self.DS.add(self.hash_[i]) elif better_idv == 1: flag = False self.DS.add(hash_) break if flag: self.X.append(X) self.hash_.append(hash_) self.F.append(F) r = np.append(r, 0) self.X = np.array(self.X)[r == 0].tolist() self.hash_ = np.array(self.hash_)[r == 0].tolist() self.F = np.array(self.F)[r == 0].tolist()
for gen in gens: f = open(path_ + '/' + gen, 'rb') ea = p.load(f) f.close() n_gens = int(gen[4:-2]) arch = [''.join(idv) for idv in ea] metrics = [[data[x]['MMACs'], data[x]['test_acc']] for x in arch] metrics = np.array(metrics) metrics[:, 0] = np.round((metrics[:, 0] - mi_ma['MMACs']['min']) / (mi_ma['MMACs']['max'] - mi_ma['MMACs']['min']), 6) metrics[:, 1] = np.round(1 - metrics[:, 1], 4) l = len(metrics) r = np.zeros(l) for i in range(l): if r[i] == 0: for j in range(i + 1, l): better_idv = find_better_idv(f0_0=metrics[i][0], f0_1=metrics[i][1], f1_0=metrics[j][0], f1_1=metrics[j][1]) if better_idv == 0: r[j] += 1 elif better_idv == 1: r[i] += 1 break pf_test_ = metrics[r == 0] pf_test_ = np.unique(pf_test_, axis=0) path__ = path + '/' + result + '/' + folder + f'/pf1_eval/pf_and_evaluated_gen_{n_gens}.p' p.dump([pf_test_, n_evals[n_gens]], open(path__, 'wb')) print('done')
def local_search_on_X(self, P, X, ls_on_knee_solutions=False): P_hashX = P.get('hashX') len_soln = len(P_hashX[0]) S = P.new() S = S.merge(X) # Using for local search on knee solutions first, last = 0, 0 if ls_on_knee_solutions: first, last = len(S) - 2, len(S) - 1 m_searches = len_soln if BENCHMARK_NAME == 'MacroNAS-CIFAR-10' or BENCHMARK_NAME == 'MacroNAS-CIFAR-100': ops = ['I', '1', '2'] else: ops = ['0', '1', '2', '3', '4'] for i in range(len(S)): # Avoid stuck because don't find any better architecture tmp_m_searches = 100 tmp_n_searches = 0 checked = [S[i].get('hashX')] n_searches = 0 while (n_searches < m_searches) and (tmp_n_searches < tmp_m_searches): tmp_n_searches += 1 o = S[i].copy() # --> neighboring solution if BENCHMARK_NAME == 'NAS-Bench-101': ''' Local search on edges ''' matrix_1D, ops_INT = split_to_matrix1D_and_opsINT( o.get('X')) ops_STRING = encoding_ops(ops_INT) while True: idxs = np.random.choice(range(len(matrix_1D)), size=self.n_vars, replace=False) matrix_1D_new = matrix_1D.copy() matrix_1D_new[idxs] = 1 - matrix_1D[idxs] matrix_2D_new = encoding_matrix(matrix_1D_new) modelspec = api.ModelSpec(matrix=matrix_2D_new, ops=ops_STRING) if BENCHMARK_API.is_valid(modelspec): o_hashX = BENCHMARK_API.get_module_hash(modelspec) o_X = combine_matrix1D_and_opsINT( matrix_1D_new, ops_INT) break else: idxs = np.random.choice(range(len(o.get('X'))), size=self.n_vars, replace=False) o_X = o.get('X').copy() for idx in idxs: allowed_ops = ops.copy() allowed_ops.remove(o.get('X')[idx]) new_op = np.random.choice(allowed_ops) o_X[idx] = new_op o_hashX = convert_to_hashX(o_X, BENCHMARK_NAME) if (o_hashX not in checked) and (o_hashX not in P_hashX) and ( o_hashX not in self.DS): checked.append(o_hashX) n_searches += 1 o_F, twice = self.evaluate( o_X, using_surrogate_model=self.using_surrogate_model) if i == first and LOCAL_SEARCH_ON_KNEE_SOLUTIONS: better_idv = find_better_idv(o_F, S[i].get('F'), 'first') elif i == last and LOCAL_SEARCH_ON_KNEE_SOLUTIONS: better_idv = find_better_idv(o_F, S[i].get('F'), 'last') else: better_idv = find_better_idv(o_F, S[i].get('F')) if better_idv == 1: # --> neighboring solutions is better S[i].set('X', o_X) S[i].set('hashX', o_hashX) S[i].set('F', o_F) if not self.using_surrogate_model: self.update_A(S[i]) else: if twice: self.update_A(S[i]) else: self.training_data.append(S[i]) self.update_fake_A(S[i]) else: # --> no one is better || current solution is better o.set('X', o_X) o.set('hashX', o_hashX) o.set('F', o_F) if not self.using_surrogate_model: self.update_A(o) else: if twice: self.update_A(o) else: self.training_data.append(o) self.update_fake_A(o) return S
def _improving(self, pop, pareto_set, pos_potential_sols, pos_front_0, **kwargs): n_evals = 0 pop_HASH_ = pop.get('hashX') l = len(pop[0].X) potential_sols = pareto_set[pos_potential_sols].copy() first, last = len(potential_sols) - 2, len(potential_sols) - 1 m_searchs = l _m_searchs = 100 for i in range(len(potential_sols)): # Avoid stuck because do not find any better architectures _n_searchs = 0 HASH_ = [potential_sols[i].hashX] n_searchs = 0 while (n_searchs < m_searchs) and (_n_searchs < _m_searchs): _n_searchs += 1 o = potential_sols[i].copy() # --> neighboring solution if kwargs['problem'].name == '101': ''' Local search on edges ''' matrix_1D, ops_INT = split_to_matrix1D_and_opsINT( o.get('X')) ops_STRING = encoding_ops(ops_INT) while True: idxs = np.random.choice(range(len(matrix_1D)), size=self.n_points, replace=False) matrix_1D_new = matrix_1D.copy() matrix_1D_new[idxs] = 1 - matrix_1D[idxs] matrix_2D_new = encoding_matrix(matrix_1D_new) modelspec = api.ModelSpec(matrix=matrix_2D_new, ops=ops_STRING) if BENCHMARK_API.is_valid(modelspec): hash_ = BENCHMARK_API.get_module_hash(modelspec) x = combine_matrix1D_and_opsINT( matrix_1D_new, ops_INT) break else: n_points = self.n_points idx = np.random.choice(range(len(o.X)), size=n_points, replace=False) x = o.X.copy() for idx_ in idx: allowed_ops = kwargs['problem'].opt.copy() allowed_ops.remove(x[idx_]) new_op = np.random.choice(allowed_ops) x[idx_] = new_op hash_ = encode_to_hash(x, kwargs['problem']) if valid_(hash_, off=HASH_, pop=pop_HASH_, **kwargs): HASH_.append(hash_) n_searchs += 1 F, doTwiceEvaluate = kwargs['algorithm'].evaluate( x, kwargs['algorithm'].using_surrogate_model) n_evals += 1 if i == first: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1], pos=0) elif i == last: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1], pos=-1) else: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1]) if better_idv == 0: # --> the neighbor is better potential_sols[i].set('X', x) potential_sols[i].set('hashX', hash_) potential_sols[i].set('F', F) if not kwargs['algorithm'].using_surrogate_model: kwargs['algorithm'].elitist_archive.update( potential_sols[i]) else: if doTwiceEvaluate: kwargs['algorithm'].elitist_archive.update( potential_sols[i]) else: kwargs['algorithm'].elitist_archive_tmp.update( potential_sols[i]) kwargs['algorithm'].training_set.append( potential_sols[i]) else: # --> no one is better || the current is better o.set('X', x) o.set('hashX', hash_) o.set('F', F) if not kwargs['algorithm'].using_surrogate_model: kwargs['algorithm'].elitist_archive.update(o) else: if doTwiceEvaluate: kwargs['algorithm'].elitist_archive.update(o) else: kwargs['algorithm'].elitist_archive_tmp.update( o) kwargs['algorithm'].training_set.append(o) pareto_set[pos_potential_sols] = potential_sols pop[pos_front_0] = pareto_set return pop
def _improving_1(self, pop, pareto_set, pos_potential_sols, pos_front_0, **kwargs): pop_HASH_ = pop.get('hashX') l = len(pop[0].X) potential_sols = pareto_set[pos_potential_sols].copy() first, last = len(potential_sols) - 2, len(potential_sols) - 1 m_searchs = l _m_searchs = 100 for i in range(len(potential_sols)): # Avoid stuck because do not find any better architectures _n_searchs = 0 HASH_ = [potential_sols[i].hashX] n_searchs = 0 while (n_searchs < m_searchs) and (_n_searchs < _m_searchs): _n_searchs += 1 o = potential_sols[i].copy() # --> neighboring solution n_points = self.n_points idx = np.random.choice(range(len(o.X)), size=n_points, replace=False) x = o.X.copy() for idx_ in idx: allowed_ops = kwargs['problem'].opt.copy() allowed_ops.remove(x[idx_]) new_op = np.random.choice(allowed_ops) x[idx_] = new_op hash_ = encode_to_hash(x, kwargs['problem']) if valid_(hash_, off=HASH_, pop=pop_HASH_, **kwargs): HASH_.append(hash_) n_searchs += 1 F, doTwiceEvaluate = kwargs['algorithm'].evaluate( x, kwargs['algorithm'].using_surrogate_model) if i == first: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1], pos=0) elif i == last: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1], pos=-1) else: better_idv = find_better_idv(F[0], F[1], potential_sols[i].F[0], potential_sols[i].F[1]) if better_idv == 0: # --> the neighbor is better potential_sols[i].set('X', x) potential_sols[i].set('hashX', hash_) potential_sols[i].set('F', F) if not kwargs['algorithm'].using_surrogate_model: kwargs['algorithm'].elitist_archive.update( potential_sols[i]) else: if doTwiceEvaluate: kwargs['algorithm'].elitist_archive.update( potential_sols[i]) else: kwargs['algorithm'].elitist_archive_tmp.update( potential_sols[i]) kwargs['algorithm'].training_set.append( potential_sols[i]) else: # --> no one is better || the current is better o.set('X', x) o.set('hashX', hash_) o.set('F', F) if not kwargs['algorithm'].using_surrogate_model: kwargs['algorithm'].elitist_archive.update(o) else: if doTwiceEvaluate: kwargs['algorithm'].elitist_archive.update(o) else: kwargs['algorithm'].elitist_archive_tmp.update( o) kwargs['algorithm'].training_set.append(o) pareto_set[pos_potential_sols] = potential_sols pop[pos_front_0] = pareto_set return pop
def update_elitist_archive(new_idv_X_lst, new_idv_hashX_lst, new_idv_F_lst, elitist_archive_X, elitist_archive_hashX, elitist_archive_F, isDominated_hashX, first=False): """ Update elitist archive and get the dominated individuals :param new_idv_X_lst: List of Individuals need to checked (X) :param new_idv_hashX_lst: List of Individuals need to checked (hashX) :param new_idv_F_lst: List of Individuals need to checked (F) :param elitist_archive_X: Current Elitist Archive (X) :param elitist_archive_hashX: Current Elitist Archive (hashX) :param elitist_archive_F: Current Elitist Archive (F) :param isDominated_hashX: Current List of Dominated Individuals :param first: Using to check type of current Elitist Archive is 'list' or not? :returns: current_elitist_archive_X, current_elitist_archive_X, current_elitist_archive_X, current_elitist_archive_hashX, current_elitist_archive_F, isDominated_hashX """ if first: current_elitist_archive_X = elitist_archive_X.copy() current_elitist_archive_hashX = elitist_archive_hashX.copy() current_elitist_archive_F = elitist_archive_F.copy() else: current_elitist_archive_X = elitist_archive_X.copy().tolist() current_elitist_archive_hashX = elitist_archive_hashX.copy().tolist() current_elitist_archive_F = elitist_archive_F.copy().tolist() rank = np.zeros(len(current_elitist_archive_X)) current_isDominated_hashX = isDominated_hashX for i in range( len(new_idv_X_lst)): # Duyet cac phan tu trong list can check if new_idv_hashX_lst[i] not in current_elitist_archive_hashX: flag = True # Check xem co bi dominated khong? for j in range( len(current_elitist_archive_X )): # Duyet cac phan tu trong elitist archive hien tai better_idv = find_better_idv( new_idv_F_lst[i], current_elitist_archive_F[j] ) # Kiem tra xem tot hon hay khong? if better_idv == 1: rank[j] += 1 if current_elitist_archive_hashX[ j] not in current_isDominated_hashX: current_isDominated_hashX.append( current_elitist_archive_hashX[j]) elif better_idv == 2: flag = False if new_idv_hashX_lst[i] not in current_isDominated_hashX: current_isDominated_hashX.append(new_idv_hashX_lst[i]) break if flag: current_elitist_archive_X.append(np.array(new_idv_X_lst[i])) current_elitist_archive_hashX.append( np.array(new_idv_hashX_lst[i])) current_elitist_archive_F.append(np.array(new_idv_F_lst[i])) rank = np.append(rank, 0) current_elitist_archive_X = np.array(current_elitist_archive_X)[rank == 0] current_elitist_archive_hashX = np.array(current_elitist_archive_hashX)[ rank == 0] current_elitist_archive_F = np.array(current_elitist_archive_F)[rank == 0] return current_elitist_archive_X, \ current_elitist_archive_hashX, \ current_elitist_archive_F, \ current_isDominated_hashX
def finalize(self): # Get the non-dominated front (elitist archive) non_dominated_front_val_per = np.array(self.E_Archive.F) non_dominated_front_val_per = np.unique(non_dominated_front_val_per, axis=0) # Get the pareto front based on 'test_per' ('val_per' at the current) F = np.array([evaluate(X) for X in self.E_Archive.X]) F = np.unique(F, axis=0) l = len(F) r = np.zeros(l, dtype=np.int8) for i, F_ in enumerate(F): if r[i] == 0: for j in range(i + 1, l): better_idv = find_better_idv(f0_0=F_[0], f0_1=F_[1], f1_0=F[j][0], f1_1=F[j][1]) if better_idv == 0: r[j] += 1 elif better_idv == 1: r[i] += 1 break non_dominated_front_test_per = F[r == 0] p.dump(non_dominated_front_val_per, open(self.path + '/pareto_front_validation.p', 'wb')) p.dump(non_dominated_front_test_per, open(self.path + '/pareto_front_testing.p', 'wb')) p.dump(self.reference_point_val_per, open(f'{self.path}/reference_point_validation.p', 'wb')) p.dump(self.reference_point_test_per, open(f'{self.path}/reference_point_testing.p', 'wb')) # visualize IGD p.dump([self.n_evals_history, self.IGD_val_per_history], open(f'{self.path}/n_evals_and_IGD_validation.p', 'wb')) p.dump([self.n_evals_history, self.IGD_test_per_history], open(f'{self.path}/n_evals_and_IGD_testing.p', 'wb')) plt.plot(self.n_evals_history, self.IGD_val_per_history) plt.xlabel('No.Evaluations') plt.ylabel(f'IGD (val PER {EPOCH})') plt.grid() plt.savefig(f'{self.path}/IGD_and_no_evaluations_validation') plt.clf() plt.plot(self.n_evals_history, self.IGD_test_per_history) plt.xlabel('No.Evaluations') plt.ylabel('IGD (test PER)') plt.grid() plt.savefig(f'{self.path}/IGD_and_no_evaluations_testing') plt.clf() # visualize elitist archive plt.scatter(TRUE_PF_VAL_PER[:, 0], TRUE_PF_VAL_PER[:, 1], facecolors='none', edgecolors='blue', s=40, label=f'True PF (val PER {EPOCH})') plt.scatter(non_dominated_front_val_per[:, 0], non_dominated_front_val_per[:, 1], c='red', s=15, label=f'Approximate PF (val PER {EPOCH})') plt.xlabel('#Evals (normalize)') plt.ylabel('Validation PER (normalize)') plt.legend() plt.grid() plt.savefig(f'{self.path}/pf_val_per') plt.clf() plt.scatter(TRUE_PF_TEST_PER[:, 0], TRUE_PF_TEST_PER[:, 1], facecolors='none', edgecolors='blue', s=40, label='True PF (test PER)') plt.scatter(non_dominated_front_test_per[:, 0], non_dominated_front_test_per[:, 1], c='red', s=15, label='Approximate PF (test PER)') plt.xlabel('#Evals (normalize)') plt.ylabel('Testing PER (normalize)') plt.legend() plt.grid() plt.savefig(f'{self.path}/pf_test_per') plt.clf()
def do_each_gen(self, first=False): if self.using_surrogate_model: self.alpha = np.mean(self.F_history) if not first: E_Archive_1_X = np.array(self.E_Archive_1.X) E_Archive_1_hash_ = np.array(self.E_Archive_1.hash_) l_E_Archive_1 = len(E_Archive_1_X) tmp_set = Population(l_E_Archive_1) tmp_set.set('X', E_Archive_1_X) tmp_set.set('hash_', E_Archive_1_hash_) for i, X in enumerate(E_Archive_1_X): if checking_valid(E_Archive_1_hash_[i], DS=self.E_Archive.DS, EA_hash_=self.E_Archive.hash_): F, _ = self.evaluate(X) tmp_set[i].set('F', F) self.E_Archive_1.update(tmp_set[i]) if self.update_model and self.n_gens % self.updating_model_each_n_gens == 0: self.y_pred = np.array(self.y_pred) self.y = np.array(self.y) error = 1 / len(self.y) * np.sum((self.y - self.y_pred)**2) print('error:', error) if error <= 1e-3: self.update_model = False else: self.y_pred, self.y = [], [] data = np.array(self.training_set) self.training_set = [] X = [] Y = [] checked_hash_ = [] for i in range(len(data)): hash_ = get_hash_(data[i].X) if checking_valid(hash_, checked=checked_hash_, DS=self.E_Archive.DS, EA_hash_=self.E_Archive.hash_): checked_hash_.append(hash_) F, _ = self.evaluate(data[i].X) data[i].set('F', F) self.E_Archive.update(data[i]) X.append(data[i].X) Y.append(F[1]) for i, F in enumerate(self.E_Archive.F): X.append(self.E_Archive.X[i]) Y.append(F[1]) X = np.array(X) Y = np.array(Y) self.surrogate_model.fit(x=X, y=Y, verbose=False) # Get the non-dominated front (elitist archive) non_dominated_front_val_per = np.array(self.E_Archive.F) non_dominated_front_val_per = np.unique(non_dominated_front_val_per, axis=0) # Get the pareto front based on 'test_per' ('val_per' at the current) F = np.array([evaluate(X) for X in self.E_Archive.X]) F = np.unique(F, axis=0) l = len(F) r = np.zeros(l, dtype=np.int8) for i, F_ in enumerate(F): if r[i] == 0: for j in range(i + 1, l): better_idv = find_better_idv(f0_0=F_[0], f0_1=F_[1], f1_0=F[j][0], f1_1=F[j][1]) if better_idv == 0: r[j] += 1 elif better_idv == 1: r[i] += 1 break non_dominated_front_test_per = F[r == 0] # Updating reference point (using for calculating the Hypervolume metric) self.reference_point_val_per[0] = max( self.reference_point_val_per[0], max(non_dominated_front_val_per[:, 0])) self.reference_point_val_per[1] = max( self.reference_point_val_per[1], max(non_dominated_front_val_per[:, 1])) self.reference_point_test_per[0] = max( self.reference_point_test_per[0], max(non_dominated_front_test_per[:, 0])) self.reference_point_test_per[1] = max( self.reference_point_test_per[1], max(non_dominated_front_test_per[:, 1])) # Calculate the IGD metric IGD_val_per = calculating_IGD(approx_pf=non_dominated_front_val_per, true_pf=TRUE_PF_VAL_PER) IGD_test_per = calculating_IGD(approx_pf=non_dominated_front_test_per, true_pf=TRUE_PF_TEST_PER) if len(self.n_evals_history) == 0: self.IGD_val_per_history.append(IGD_val_per) self.IGD_test_per_history.append(IGD_test_per) self.n_evals_history.append(self.n_evals) else: if self.n_evals == self.n_evals_history[-1]: self.IGD_val_per_history[-1] = IGD_val_per self.IGD_test_per_history[-1] = IGD_test_per else: self.IGD_val_per_history.append(IGD_val_per) self.IGD_test_per_history.append(IGD_test_per) self.n_evals_history.append(self.n_evals) if self.IGD_val_per_history[ -1] == 0 and not self.isStoppingConditionsSatisfied: self.isStoppingConditionsSatisfied = True self.converging_point = self.n_evals # Saving the results p.dump( [non_dominated_front_val_per, self.n_evals], open(f'{self.path}/pf_and_n_evals_validation/gen_{self.n_gens}.p', 'wb')) p.dump([non_dominated_front_test_per, self.n_evals], open(f'{self.path}/pf_and_n_evals_testing/gen_{self.n_gens}.p', 'wb')) p.dump(self.E_Archive, open(f'{self.path}/elitist_archive/gen_{self.n_gens}.p', 'wb'))
def improving(self, P, PS, idx_potential_solutions, idx_front_0): P_hash_ = P.get('hash_') l = len(P[0].X) potential_solutions = PS[idx_potential_solutions].copy() n_potential_solutions = len(potential_solutions) first, last = n_potential_solutions - 2, n_potential_solutions - 1 m_searchs = l _m_searchs = 100 for i in range(n_potential_solutions): # Avoid stuck because do not find any better architectures _n_searchs = 0 neighbor_hash_ = [potential_solutions[i].hash_] n_searchs = 0 while (n_searchs < m_searchs) and (_n_searchs < _m_searchs): _n_searchs += 1 neighbor = potential_solutions[i].copy( ) # --> neighboring solution n_points = self.n_points idx = np.random.choice(range(len(neighbor.X)), size=n_points, replace=False) X = neighbor.X.copy() for idx_ in idx: if idx_ in IDX_MAIN_OPS: valid_ops = MAIN_OPS.copy() else: valid_ops = SKIP_OPS.copy() valid_ops.remove(X[idx_]) X[idx_] = np.random.choice(valid_ops) hash_ = get_hash_(X) if checking_valid(hash_, neighbor=neighbor_hash_, pop=P_hash_, DS=self.E_Archive.DS): neighbor_hash_.append(hash_) n_searchs += 1 F, doEvaluateTwice = self.evaluate( X, self.using_surrogate_model) if i == first: better_idv = find_better_idv( F[0], F[1], potential_solutions[i].F[0], potential_solutions[i].F[1], pos=0) elif i == last: better_idv = find_better_idv( F[0], F[1], potential_solutions[i].F[0], potential_solutions[i].F[1], pos=-1) else: better_idv = find_better_idv( F[0], F[1], potential_solutions[i].F[0], potential_solutions[i].F[1]) if better_idv == 0: # --> the neighbor is better potential_solutions[i].set('X', X) potential_solutions[i].set('hash_', hash_) potential_solutions[i].set('F', F) if not self.using_surrogate_model: self.E_Archive.update(potential_solutions[i]) else: if doEvaluateTwice: self.E_Archive.update(potential_solutions[i]) else: self.E_Archive_1.update(potential_solutions[i]) self.training_set.append( potential_solutions[i]) else: # --> no one is better || the current is better neighbor.set('X', X) neighbor.set('hash_', hash_) neighbor.set('F', F) if not self.using_surrogate_model: self.E_Archive.update(neighbor) else: if doEvaluateTwice: self.E_Archive.update(neighbor) else: self.E_Archive_1.update(neighbor) self.training_set.append(neighbor) PS[idx_potential_solutions] = potential_solutions P[idx_front_0] = PS return P