Esempio n. 1
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)]
Esempio n. 9
0
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)