Beispiel #1
0
def test_elementwise_crossover():

    problem = get_problem('zdt1')

    sampling = FloatRandomSampling()

    pop = sampling.do(problem, n_samples=3)

    crossover = ElementwiseCrossover(SBX(20))
    off = crossover.do(problem, pop[0], pop[1])
    assert len(off) == 2

    crossover = ElementwiseCrossover(DEX())
    off = crossover.do(problem, pop[0], pop[1], pop[2])
    assert len(off) == 1
Beispiel #2
0
    def __init__(self,
                 ref_dirs,
                 pop_size=None,
                 sampling=FloatRandomSampling(),
                 selection=TournamentSelection(func_comp=comp_by_cv_then_random),
                 crossover=SimulatedBinaryCrossover(eta=30, prob=1.0),
                 mutation=PolynomialMutation(eta=20, prob=None),
                 eliminate_duplicates=True,
                 n_offsprings=None,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        Parameters
        ----------

        ref_dirs : {ref_dirs}
        pop_size : int (default = None)
            By default the population size is set to None which means that it will be equal to the number of reference
            line. However, if desired this can be overwritten by providing a positive number.
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        n_offsprings : {n_offsprings}

        """

        self.ref_dirs = ref_dirs

        # in case of R-NSGA-3 they will be None - otherwise this will be executed
        if self.ref_dirs is not None:

            if pop_size is None:
                pop_size = len(self.ref_dirs)

            if pop_size < len(self.ref_dirs):
                print(
                    f"WARNING: pop_size={pop_size} is less than the number of reference directions ref_dirs={len(self.ref_dirs)}.\n"
                    "This might cause unwanted behavior of the algorithm. \n"
                    "Please make sure pop_size is equal or larger than the number of reference directions. ")

        if 'survival' in kwargs:
            survival = kwargs['survival']
            del kwargs['survival']
        else:
            survival = ReferenceDirectionSurvival(ref_dirs)

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         advance_after_initial_infill=True,
                         **kwargs)
Beispiel #3
0
    def __init__(self,
                 ref_dirs,
                 pop_size=None,
                 sampling=FloatRandomSampling(),
                 selection=NeighborhoodSelection(),
                 crossover=DEX(prob=0.9, CR=0.5, variant='bin'),
                 mutation=PM(eta=20),
                 display=MultiObjectiveDisplay(),
                 **kwargs):

        # set reference directions and pop_size
        self.ref_dirs = ref_dirs
        if self.ref_dirs is not None:
            if pop_size is None:
                pop_size = len(self.ref_dirs)

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         eliminate_duplicates=False,
                         display=display,
                         **kwargs)

        self.RA = None
        self.norm = None
        self.archive = None
Beispiel #4
0
 def __init__(self,
              n_points_per_iteration=100,
              sampling=FloatRandomSampling(),
              display=SingleObjectiveDisplay(),
              **kwargs):
     super().__init__(display=display, **kwargs)
     self.n_points_per_iteration = n_points_per_iteration
     self.sampling = sampling
Beispiel #5
0
    def __init__(self,
                 n_elites=200,
                 n_offsprings=700,
                 n_mutants=100,
                 bias=0.7,
                 sampling=FloatRandomSampling(),
                 survival=None,
                 display=SingleObjectiveDisplay(),
                 eliminate_duplicates=False,
                 **kwargs
                 ):
        """


        Parameters
        ----------

        n_elites : int
            Number of elite individuals

        n_offsprings : int
            Number of offsprings to be generated through mating of an elite and a non-elite individual

        n_mutants : int
            Number of mutations to be introduced each generation

        bias : float
            Bias of an offspring inheriting the allele of its elite parent

        eliminate_duplicates : bool or class
            The duplicate elimination is more important if a decoding is used. The duplicate check has to be
            performed on the decoded variable and not on the real values. Therefore, we recommend passing
            a DuplicateElimination object.
            If eliminate_duplicates is simply set to `True`, then duplicates are filtered out whenever the
            objective values are equal.

        """

        if survival is None:
            survival = EliteSurvival(n_elites, eliminate_duplicates=eliminate_duplicates)

        super().__init__(pop_size=n_elites + n_offsprings + n_mutants,
                         n_offsprings=n_offsprings,
                         sampling=sampling,
                         selection=EliteBiasedSelection(),
                         crossover=BinomialCrossover(bias, prob=1.0),
                         mutation=NoMutation(),
                         survival=survival,
                         display=display,
                         eliminate_duplicates=True,
                         advance_after_initial_infill=True,
                         **kwargs)

        self.n_elites = n_elites
        self.n_mutants = n_mutants
        self.bias = bias
        self.default_termination = SingleObjectiveDefaultTermination()
Beispiel #6
0
    def __init__(self,
                 ref_dirs,
                 alpha=2.0,
                 adapt_freq=0.1,
                 pop_size=None,
                 sampling=FloatRandomSampling(),
                 selection=RandomSelection(),
                 crossover=SimulatedBinaryCrossover(eta=30, prob=1.0),
                 mutation=PolynomialMutation(eta=20, prob=None),
                 eliminate_duplicates=True,
                 n_offsprings=None,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        Parameters
        ----------

        ref_dirs : {ref_dirs}
        adapt_freq : float
            Defines the ratio of generation when the reference directions are updated.
        pop_size : int (default = None)
            By default the population size is set to None which means that it will be equal to the number of reference
            line. However, if desired this can be overwritten by providing a positive number.
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        n_offsprings : {n_offsprings}

        """

        # set reference directions and pop_size
        self.ref_dirs = ref_dirs
        if self.ref_dirs is not None:
            if pop_size is None:
                pop_size = len(self.ref_dirs)

        # the fraction of n_max_gen when the the reference directions are adapted
        self.adapt_freq = adapt_freq

        # you can override the survival if necessary
        survival = kwargs.pop("survival", None)
        if survival is None:
            survival = APDSurvival(ref_dirs, alpha=alpha)

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         **kwargs)
Beispiel #7
0
    def _infill(self):
        pop = self.pop

        # actually do the mating given the elite selection and biased crossover
        off = self.mating.do(self.problem, pop, n_offsprings=self.n_offsprings, algorithm=self)

        # create the mutants randomly to fill the population with
        mutants = FloatRandomSampling().do(self.problem, self.n_mutants, algorithm=self)

        # evaluate all the new solutions
        return Population.merge(off, mutants)
Beispiel #8
0
    def __init__(self,
                 n_offsprings=200,
                 pop_size=None,
                 rule=1.0 / 7.0,
                 phi=1.0,
                 gamma=0.85,
                 sampling=FloatRandomSampling(),
                 survival=FitnessSurvival(),
                 display=SingleObjectiveDisplay(),
                 **kwargs):
        """
        Evolutionary Strategy (ES)

        Parameters
        ----------
        n_offsprings : int
            The number of individuals created in each iteration.
        pop_size : int
            The number of individuals which are surviving from the offspring population (non-elitist)
        rule : float
            The rule (ratio) of individuals surviving. This automatically either calculated `n_offsprings` or `pop_size`.
        phi : float
            Expected rate of convergence (usually 1.0).
        gamma : float
            If not `None`, some individuals are created using the differentials with this as a length scale.
        sampling : object
            The sampling method for creating the initial population.
        """

        if pop_size is None and n_offsprings is not None:
            pop_size = int(np.math.ceil(n_offsprings * rule))
        elif n_offsprings is None and pop_size is not None:
            n_offsprings = int(np.math.fllor(n_offsprings / rule))

        assert pop_size is not None and n_offsprings is not None, "You have to at least provivde pop_size of n_offsprings."
        assert n_offsprings >= 2 * pop_size, "The number of offsprings should be at least double the population size."

        super().__init__(pop_size=pop_size,
                         n_offsprings=n_offsprings,
                         sampling=sampling,
                         survival=survival,
                         display=display,
                         advance_after_initial_infill=True,
                         **kwargs)

        self.default_termination = SingleObjectiveDefaultTermination()
        self.phi = phi
        self.gamma = gamma

        self.tau, self.taup, self.sigma_max = None, None, None
Beispiel #9
0
    def __init__(
            self,
            ref_dirs,
            sampling=FloatRandomSampling(),
            selection=RestrictedMating(func_comp=comp_by_cv_dom_then_random),
            crossover=SimulatedBinaryCrossover(n_offsprings=1,
                                               eta=30,
                                               prob=1.0),
            mutation=PolynomialMutation(eta=20, prob=None),
            eliminate_duplicates=True,
            display=MultiObjectiveDisplay(),
            **kwargs):
        """
        CTAEA

        Parameters
        ----------
        ref_dirs : {ref_dirs}
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        """

        self.ref_dirs = ref_dirs
        pop_size = len(ref_dirs)

        if 'survival' in kwargs:
            survival = kwargs['survival']
            del kwargs['survival']
        else:
            survival = CADASurvival(ref_dirs)

        # Initialize diversity archives
        self.da = None

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=pop_size,
                         display=display,
                         **kwargs)
Beispiel #10
0
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition=Tchebicheff2(),
                 prob_neighbor_mating=0.9,
                 sampling=FloatRandomSampling(),
                 crossover=SimulatedBinaryCrossover(prob=1.0, eta=20),
                 mutation=PolynomialMutation(prob=None, eta=20),
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """
        Parameters
        ----------
        ref_dirs
        n_neighbors
        decomposition
        prob_neighbor_mating
        display
        kwargs
        """

        self.ref_dirs = ref_dirs
        self.pc_capacity = len(ref_dirs)
        self.pc_pop = Population.new()
        self.npc_pop = Population.new()
        self.n_neighbors = min(len(ref_dirs), n_neighbors)
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomp = decomposition

        # initialise the neighborhood of subproblems based on the distances of weight vectors
        self.neighbors = np.argsort(cdist(self.ref_dirs, self.ref_dirs),
                                    axis=1,
                                    kind='quicksort')[:, :self.n_neighbors]

        self.selection = NeighborhoodSelection(self.neighbors,
                                               prob=prob_neighbor_mating)

        super().__init__(pop_size=len(ref_dirs),
                         sampling=sampling,
                         crossover=crossover,
                         mutation=mutation,
                         eliminate_duplicates=DefaultDuplicateElimination(),
                         display=display,
                         advance_after_initialization=False,
                         **kwargs)
Beispiel #11
0
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition='auto',
                 prob_neighbor_mating=0.9,
                 sampling=FloatRandomSampling(),
                 crossover=SimulatedBinaryCrossover(prob=1.0, eta=20),
                 mutation=PolynomialMutation(prob=None, eta=20),
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """
        Parameters
        ----------
        ref_dirs
        n_neighbors
        decomposition
        prob_neighbor_mating
        display
        kwargs
        """

        self.ref_dirs = ref_dirs
        self.n_neighbors = min(len(ref_dirs), n_neighbors)
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomp = decomposition

        # neighbours includes the entry by itself intentionally for the survival method
        self.neighbors = np.argsort(cdist(self.ref_dirs, self.ref_dirs),
                                    axis=1,
                                    kind='quicksort')[:, :self.n_neighbors]

        self.selection = NeighborhoodSelection(self.neighbors,
                                               prob=prob_neighbor_mating)

        super().__init__(pop_size=len(ref_dirs),
                         sampling=sampling,
                         crossover=crossover,
                         mutation=mutation,
                         eliminate_duplicates=NoDuplicateElimination(),
                         display=display,
                         advance_after_initialization=False,
                         **kwargs)

        # the mating is just performed once here - population does not need to be filled up
        self.mating.n_max_iterations = 1
Beispiel #12
0
    def __init__(self,
                 pop_size=100,
                 sampling=FloatRandomSampling(),
                 selection=TournamentSelection(func_comp=binary_tournament),
                 crossover=SBX(eta=15, prob=0.9),
                 mutation=PM(prob=None, eta=20),
                 eliminate_duplicates=True,
                 n_offsprings=None,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """
        Adapted from:
        Panichella, A. (2019). An adaptive evolutionary algorithm based on non-euclidean geometry for many-objective
        optimization. GECCO 2019 - Proceedings of the 2019 Genetic and Evolutionary Computation Conference, July, 595–603.
        https://doi.org/10.1145/3321707.3321839

        Parameters
        ----------
        pop_size : {pop_size}
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        n_offsprings : {n_offsprings}
        """

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=AGEMOEASurvival(),
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         advance_after_initial_infill=True,
                         **kwargs)
        self.default_termination = MultiObjectiveDefaultTermination()

        self.tournament_type = 'comp_by_rank_and_crowding'
Beispiel #13
0
    def __init__(self,
                 pop_size=100,
                 sampling=FloatRandomSampling(),
                 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(),
                 **kwargs):
        """

        Parameters
        ----------
        pop_size : {pop_size}
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        n_offsprings : {n_offsprings}

        """

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         advance_after_initial_infill=True,
                         **kwargs)
        self.default_termination = MultiObjectiveDefaultTermination()
        self.tournament_type = 'comp_by_dom_and_crowding'
Beispiel #14
0
    def __init__(
            self,
            pop_size=100,
            sampling=FloatRandomSampling(),
            selection=TournamentSelection(func_comp=comp_by_cv_and_fitness),
            crossover=SimulatedBinaryCrossover(prob=0.9, eta=3),
            mutation=PolynomialMutation(prob=None, eta=5),
            survival=FitnessSurvival(),
            eliminate_duplicates=True,
            n_offsprings=None,
            display=SingleObjectiveDisplay(),
            **kwargs):
        """

        Parameters
        ----------
        pop_size : {pop_size}
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}
        n_offsprings : {n_offsprings}

        """

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         **kwargs)

        self.default_termination = SingleObjectiveDefaultTermination()
Beispiel #15
0
    def __init__(self,
                 pop_size=100,
                 sampling=FloatRandomSampling(),
                 selection=DES("rand"),
                 crossover=DEX(CR=0.7),
                 mutation=PM(eta=20),
                 survival=NichingSurvival(0.1, 0.01, 5, 4),
                 eliminate_duplicates=True,
                 n_offsprings=None,
                 display=SingleObjectiveDisplay(),
                 **kwargs):

        super().__init__(pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         display=display,
                         **kwargs)

        self.default_termination = SingleObjectiveDefaultTermination()
Beispiel #16
0
    def __init__(
            self,
            ref_points,
            pop_per_ref_point,
            mu=0.05,
            sampling=FloatRandomSampling(),
            selection=TournamentSelection(func_comp=comp_by_cv_then_random),
            crossover=SimulatedBinaryCrossover(eta=30, prob=1.0),
            mutation=PolynomialMutation(eta=20, prob=None),
            eliminate_duplicates=True,
            n_offsprings=None,
            **kwargs):
        """

        Parameters
        ----------

        ref_points : {ref_points}
        pop_per_ref_point : int
            Size of the population used for each reference point.

        mu : float
            Defines the scaling of the reference lines used during survival selection. Increasing mu will result
            having solutions with a larger spread.

        Other Parameters
        -------

        n_offsprings : {n_offsprings}
        sampling : {sampling}
        selection : {selection}
        crossover : {crossover}
        mutation : {mutation}
        eliminate_duplicates : {eliminate_duplicates}

        """

        # number of objectives the reference lines have
        n_obj = ref_points.shape[1]

        # add the aspiration point lines
        aspiration_ref_dirs = UniformReferenceDirectionFactory(
            n_dim=n_obj, n_points=pop_per_ref_point).do()

        survival = AspirationPointSurvival(ref_points,
                                           aspiration_ref_dirs,
                                           mu=mu)
        pop_size = ref_points.shape[0] * aspiration_ref_dirs.shape[
            0] + aspiration_ref_dirs.shape[1]
        ref_dirs = None

        super().__init__(ref_dirs,
                         pop_size=pop_size,
                         sampling=sampling,
                         selection=selection,
                         crossover=crossover,
                         mutation=mutation,
                         survival=survival,
                         eliminate_duplicates=eliminate_duplicates,
                         n_offsprings=n_offsprings,
                         **kwargs)
Beispiel #17
0
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition=Tchebicheff(),
                 prob_neighbor_mating=0.9,
                 rate_update_weight=0.05,
                 rate_evol=0.8,
                 wag=20,
                 archive_size_multiplier=1.5,
                 use_new_ref_dirs_initialization=True,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        MOEAD-AWA Algorithm.

        Parameters
        ----------
        ref_dirs
        n_neighbors
        decomposition
        prob_neighbor_mating
        rate_update_weight
        rate_evol
        wag
        archive_size_multiplier
        use_new_ref_dirs_initialization
        display
        kwargs
        """

        self.n_neighbors = n_neighbors
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomp = decomposition

        self.rate_update_weight = rate_update_weight
        self.rate_evol = rate_evol
        self.wag = wag

        self.EP = None
        self.nEP = np.ceil(len(ref_dirs) * archive_size_multiplier)

        set_if_none(kwargs, 'pop_size', len(ref_dirs))
        set_if_none(kwargs, 'sampling', FloatRandomSampling())
        set_if_none(kwargs, 'crossover', SBX(prob=1.0, eta=20))
        set_if_none(kwargs, 'mutation', PM(prob=None, eta=20))
        set_if_none(kwargs, 'survival', None)
        set_if_none(kwargs, 'selection', None)

        super().__init__(display=display, **kwargs)

        # initialized when problem is known
        self.ref_dirs = ref_dirs
        if use_new_ref_dirs_initialization:
            self.ref_dirs = 1.0 / (self.ref_dirs + 1e-6)
            self.ref_dirs = self.ref_dirs / np.sum(self.ref_dirs, axis=1)[:,
                                                                          None]

        if self.ref_dirs.shape[0] < self.n_neighbors:
            print("Setting number of neighbours to population size: %s" %
                  self.ref_dirs.shape[0])
            self.n_neighbors = self.ref_dirs.shape[0]

        self.nds = NonDominatedSorting()

        # compute neighbors of reference directions using euclidean distance
        self._update_neighbors()