def update_PCpop(pc_pop, off): pc_objs = pc_pop.get("F") off_objs = off.get("F") n = pc_objs.shape[0] del_ind = [] for i in range(n): flag = Dominator.get_relation(off_objs[0, :], pc_objs[i, :]) if flag == 1: # off dominates pc_pop[i] del_ind.append(i) break elif flag == -1: # pc_pop[i] dominates off return pc_pop else: # flag == 0 # off and pc_pop[i] are nondominated break if len(del_ind) > 0: pc_index = np.arange(n) # Delete element at index positions given by the list 'del_ind' pc_index = np.delete(pc_index, del_ind) pc_pop = pc_pop[pc_index.tolist()] pc_pop = Population.merge(pc_pop, off) return pc_pop
def sequential_search(F, i, fronts) -> int: """ Find the front rank for the i-th individual through sequential search Parameters ---------- F: np.ndarray the objective values i: int the index of the individual fronts: list individuals in each front """ num_found_fronts = len(fronts) k = 0 # the front now checked current = F[i] while True: if num_found_fronts == 0: return 0 # solutions in the k-th front, examine in reverse order fk_indices = fronts[k] solutions = F[fk_indices[::-1]] non_dominated = True for f in solutions: relation = Dominator.get_relation(current, f) if relation == -1: non_dominated = False break if non_dominated: return k else: k += 1 if k >= num_found_fronts: # move the individual to a new front return num_found_fronts
def binary_tournament(pop, P, algorithm): if P.shape[1] != 2: raise ValueError("Only implemented for binary tournament!") tournament_type = algorithm.tournament_type S = np.full(P.shape[0], np.nan) for i in range(P.shape[0]): a, b = P[i, 0], P[i, 1] if tournament_type == 'comp_by_dom_and_crowding': rel = Dominator.get_relation(pop[a].F, pop[b].F) if rel == 1: S[i] = a elif rel == -1: S[i] = b elif tournament_type == 'comp_by_rank_and_crowding': S[i] = compare(a, pop[a].rank, b, pop[b].rank, method='smaller_is_better') else: raise Exception("Unknown tournament type.") if np.isnan(S[i]): S[i] = compare(a, pop[a].get("crowding"), b, pop[b].get("crowding"), method='larger_is_better', return_random_if_equal=True) return S[:, None].astype(np.int)
def comp_by_dom_and_crowding(pop, P, crowding, **kwargs): if P.shape[1] != 2: raise ValueError("Only implemented for binary tournament!") S = np.zeros((P.shape[0], 1), dtype=np.int) for i, p in enumerate(P): rel = Dominator.get_relation(pop.F[P[i, 0], :], pop.F[P[i, 1], :]) # first by domination if rel == 1: S[i, 0] = P[i, 0] elif rel == -1: S[i, 0] = P[i, 1] # then by crowding else: if crowding[P[i, 0]] > crowding[P[i, 1]]: S[i, 0] = P[i, 0] elif crowding[P[i, 1]] > crowding[P[i, 0]]: S[i, 0] = P[i, 1] else: S[i, 0] = P[i, random.randint(0, 2)] return S
def binary_tournament(pop, P, algorithm, **kwargs): n_tournaments, n_parents = P.shape if n_parents != 2: raise ValueError("Only implemented for binary tournament!") tournament_type = algorithm.tournament_type S = np.full(n_tournaments, np.nan) for i in range(n_tournaments): a, b = P[i, 0], P[i, 1] a_cv, a_f, b_cv, b_f, = pop[a].CV[0], pop[a].F, pop[b].CV[0], pop[b].F rank_a, cd_a = pop[a].get("rank", "crowding") rank_b, cd_b = pop[b].get("rank", "crowding") # if at least one solution is infeasible if a_cv > 0.0 or b_cv > 0.0: S[i] = compare(a, a_cv, b, b_cv, method='smaller_is_better', return_random_if_equal=True) # both solutions are feasible else: if tournament_type == 'comp_by_dom_and_crowding': rel = Dominator.get_relation(a_f, b_f) if rel == 1: S[i] = a elif rel == -1: S[i] = b elif tournament_type == 'comp_by_rank_and_crowding': S[i] = compare(a, rank_a, b, rank_b, method='smaller_is_better') else: raise Exception("Unknown tournament type.") # if rank or domination relation didn't make a decision compare by crowding if np.isnan(S[i]): S[i] = compare(a, cd_a, b, cd_b, method='larger_is_better', return_random_if_equal=True) return S[:, None].astype(int, copy=False)
def binary_tournament(pop, P, algorithm, **kwargs): if P.shape[1] != 2: raise ValueError("Only implemented for binary tournament!") tournament_type = algorithm.tournament_type S = np.full(P.shape[0], np.nan) for i in range(P.shape[0]): a, b = P[i, 0], P[i, 1] # if at least one solution is infeasible if pop[a].CV > 0.0 or pop[b].CV > 0.0: S[i] = compare( a, pop[a].CV, b, pop[b].CV, method="smaller_is_better", return_random_if_equal=True, ) # both solutions are feasible else: if tournament_type == "comp_by_dom_and_crowding": rel = Dominator.get_relation(pop[a].F, pop[b].F) if rel == 1: S[i] = a elif rel == -1: S[i] = b elif tournament_type == "comp_by_rank_and_crowding": S[i] = compare( a, pop[a].rank, b, pop[b].rank, method="smaller_is_better" ) else: raise Exception("Unknown tournament type.") # if rank or domination relation didn't make a decision compare by crowding if np.isnan(S[i]): S[i] = compare( a, pop[a].get("crowding"), b, pop[b].get("crowding"), method="larger_is_better", return_random_if_equal=True, ) return S[:, None].astype(np.int)
def binary_search(F, i, fronts): """ Find the front rank for the i-th individual through binary search. Parameters ---------- F: np.ndarray the objective values i: int the index of the individual fronts: list individuals in each front """ num_found_fronts = len(fronts) if num_found_fronts == 0: return 0 k_min = 0 # the lower bound for checking k_max = num_found_fronts # the upper bound for checking k = floor((k_max + k_min) / 2 + 0.5) # the front now checked current = F[i] while True: # solutions in the k-th front, examine in reverse order fk_indices = fronts[k - 1] solutions = F[fk_indices[::-1]] non_dominated = True for f in solutions: relation = Dominator.get_relation(current, f) if relation == -1: non_dominated = False break # binary search if non_dominated: if k == k_min + 1: return k - 1 else: k_max = k k = floor((k_max + k_min) / 2 + 0.5) else: k_min = k if k_max == k_min + 1 and k_max < num_found_fronts: return k_max - 1 elif k_min == num_found_fronts: return num_found_fronts else: k = floor((k_max + k_min) / 2 + 0.5)
def comp_by_dom_and_crowding(pop, indices, data): if len(indices) != 2: raise ValueError("Only implemented for binary tournament!") first = indices[0] second = indices[1] rel = Dominator.get_relation(pop.F[first, :], pop.F[second, :]) if rel == 1: return first elif rel == -1: return second else: if data.crowding[first] > data.crowding[second]: return first elif data.crowding[second] > data.crowding[first]: return second else: return indices[random.randint(0, 2)]
def comp_by_cv_dom_then_random(pop, P, **kwargs): S = np.full(P.shape[0], np.nan) for i in range(P.shape[0]): a, b = P[i, 0], P[i, 1] if pop[a].CV <= 0.0 and pop[b].CV <= 0.0: rel = Dominator.get_relation(pop[a].F, pop[b].F) if rel == 1: S[i] = a elif rel == -1: S[i] = b else: S[i] = np.random.choice([a, b]) elif pop[a].CV <= 0.0: S[i] = a elif pop[b].CV <= 0.0: S[i] = b else: S[i] = np.random.choice([a, b]) return S[:, None].astype(np.int)