Skip to content

Commit

Permalink
Added GodenSectionSearch, RVEA and GDE3
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Blank committed Sep 30, 2020
1 parent 330bcb8 commit d25963c
Show file tree
Hide file tree
Showing 24 changed files with 453 additions and 130 deletions.
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
recursive-include pymoo *.py *.cpp
recursive-include pymoo *.py *.cpp *.pf
recursive-exclude pymoo *.so *.pyx *.pxd

include LICENSE Makefile
44 changes: 44 additions & 0 deletions pymoo/algorithms/gde3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from pymoo.algorithms.nsga2 import RankAndCrowdingSurvival
from pymoo.algorithms.so_de import DE
from pymoo.docs import parse_doc_string
from pymoo.model.population import Population
from pymoo.util.display import MultiObjectiveDisplay
from pymoo.util.dominator import get_relation


class GDE3(DE):

def __init__(self, **kwargs):
super().__init__(display=MultiObjectiveDisplay(), **kwargs)

def _next(self):

# make a step and create the offsprings
self.off = self._step()

# evaluate the offsprings
self.evaluator.eval(self.problem, self.off, algorithm=self)

survivors = []

for k in range(self.pop_size):
parent, off = self.pop[k], self.off[k]

rel = get_relation(parent, off)

if rel == 0:
survivors.extend([parent, off])
elif rel == -1:
survivors.append(off)
else:
survivors.append(parent)

survivors = Population.create(*survivors)

if len(survivors) > self.pop_size:
survivors = RankAndCrowdingSurvival().do(self.problem, survivors, self.pop_size)

self.pop = survivors


parse_doc_string(GDE3.__init__)
98 changes: 49 additions & 49 deletions pymoo/algorithms/nsga2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from pymoo.algorithms.genetic_algorithm import GeneticAlgorithm
from pymoo.docs import parse_doc_string
from pymoo.model.individual import Individual
from pymoo.model.survival import Survival
from pymoo.operators.crossover.simulated_binary_crossover import SimulatedBinaryCrossover
from pymoo.operators.mutation.polynomial_mutation import PolynomialMutation
Expand Down Expand Up @@ -60,6 +59,53 @@ def binary_tournament(pop, P, algorithm, **kwargs):
return S[:, None].astype(np.int, copy=False)


# ---------------------------------------------------------------------------------------------------------
# Survival Selection
# ---------------------------------------------------------------------------------------------------------


class RankAndCrowdingSurvival(Survival):

def __init__(self, nds=None) -> None:
super().__init__(filter_infeasible=True)
self.nds = nds if nds is not None else NonDominatedSorting()

def _do(self, problem, pop, n_survive, D=None, **kwargs):

# get the objective space values and objects
F = pop.get("F").astype(np.float, copy=False)

# the final indices of surviving individuals
survivors = []

# do the non-dominated sorting until splitting front
fronts = self.nds.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]


# =========================================================================================================
# Implementation
# =========================================================================================================
Expand All @@ -73,6 +119,7 @@ def __init__(self,
selection=TournamentSelection(func_comp=binary_tournament),
crossover=SimulatedBinaryCrossover(eta=15, prob=0.9),
mutation=PolynomialMutation(prob=None, eta=20),
survival=RankAndCrowdingSurvival(),
eliminate_duplicates=True,
n_offsprings=None,
display=MultiObjectiveDisplay(),
Expand All @@ -96,7 +143,7 @@ def __init__(self,
selection=selection,
crossover=crossover,
mutation=mutation,
survival=RankAndCrowdingSurvival(),
survival=survival,
eliminate_duplicates=eliminate_duplicates,
n_offsprings=n_offsprings,
display=display,
Expand All @@ -111,53 +158,6 @@ def _set_optimum(self, **kwargs):
self.opt = self.pop[self.pop.get("rank") == 0]


# ---------------------------------------------------------------------------------------------------------
# Survival Selection
# ---------------------------------------------------------------------------------------------------------


class RankAndCrowdingSurvival(Survival):

def __init__(self) -> None:
super().__init__(filter_infeasible=True)
self.nds = NonDominatedSorting()

def _do(self, problem, pop, n_survive, D=None, **kwargs):

# get the objective space values and objects
F = pop.get("F").astype(np.float, copy=False)

# the final indices of surviving individuals
survivors = []

# do the non-dominated sorting until splitting front
fronts = self.nds.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 calc_crowding_distance(F, filter_out_duplicates=True):
n_points, n_obj = F.shape

Expand Down
Loading

0 comments on commit d25963c

Please sign in to comment.