Source code for jmetal.algorithm.multiobjective.mocell

import copy
from functools import cmp_to_key
from typing import List, TypeVar

from jmetal.algorithm.singleobjective.genetic_algorithm import GeneticAlgorithm
from jmetal.config import store
from jmetal.core.operator import Crossover, Mutation, Selection
from jmetal.core.problem import Problem
from jmetal.operator.selection import BinaryTournamentSelection
from jmetal.util.archive import BoundedArchive
from jmetal.util.comparator import Comparator, MultiComparator
from jmetal.util.density_estimator import CrowdingDistance, DensityEstimator
from jmetal.util.evaluator import Evaluator
from jmetal.util.generator import Generator
from jmetal.util.neighborhood import Neighborhood
from jmetal.util.ranking import FastNonDominatedRanking, Ranking
from jmetal.util.termination_criterion import TerminationCriterion

S = TypeVar("S")
R = TypeVar("R")

"""
.. module:: MOCell
   :platform: Unix, Windows
   :synopsis: MOCell (Multi-Objective Cellular evolutionary algorithm) implementation
.. moduleauthor:: Antonio J. Nebro <antonio@lcc.uma.es>
"""


[docs] class MOCell(GeneticAlgorithm[S, R]): def __init__( self, problem: Problem, population_size: int, neighborhood: Neighborhood, archive: BoundedArchive, mutation: Mutation, crossover: Crossover, selection: Selection = BinaryTournamentSelection( MultiComparator([FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator()]) ), termination_criterion: TerminationCriterion = store.default_termination_criteria, population_generator: Generator = store.default_generator, population_evaluator: Evaluator = store.default_evaluator, dominance_comparator: Comparator = store.default_comparator, ): """ MOCEll implementation as described in: :param problem: The problem to solve. :param population_size: Size of the population. :param mutation: Mutation operator (see :py:mod:`jmetal.operator.mutation`). :param crossover: Crossover operator (see :py:mod:`jmetal.operator.crossover`). :param selection: Selection operator (see :py:mod:`jmetal.operator.selection`). """ super(MOCell, self).__init__( problem=problem, population_size=population_size, offspring_population_size=1, mutation=mutation, crossover=crossover, selection=selection, termination_criterion=termination_criterion, population_evaluator=population_evaluator, population_generator=population_generator, ) self.dominance_comparator = dominance_comparator self.neighborhood = neighborhood self.archive = archive self.current_individual = 0 self.current_neighbors = [] self.comparator = MultiComparator([FastNonDominatedRanking.get_comparator(), CrowdingDistance.get_comparator()])
[docs] def init_progress(self) -> None: super().init_progress() for solution in self.solutions: self.archive.add(copy.copy(solution))
[docs] def update_progress(self) -> None: super().update_progress() self.current_individual = (self.current_individual + 1) % self.population_size
[docs] def selection(self, population: List[S]): parents = [] self.current_neighbors = self.neighborhood.get_neighbors(self.current_individual, population) self.current_neighbors.append(self.solutions[self.current_individual]) parents.append(self.selection_operator.execute(self.current_neighbors)) if len(self.archive.solution_list) > 0: parents.append(self.selection_operator.execute(self.archive.solution_list)) else: parents.append(self.selection_operator.execute(self.current_neighbors)) return parents
[docs] def reproduction(self, mating_population: List[S]) -> List[S]: number_of_parents_to_combine = self.crossover_operator.get_number_of_parents() if len(mating_population) % number_of_parents_to_combine != 0: raise Exception("Wrong number of parents") offspring_population = self.crossover_operator.execute(mating_population) offspring_population[0] = self.mutation_operator.execute(offspring_population[0]) return [offspring_population[0]]
[docs] def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: result = self.dominance_comparator.compare(population[self.current_individual], offspring_population[0]) if result == 1: # the offspring individual dominates the current one population[self.current_individual] = offspring_population[0] self.archive.add(copy.deepcopy(offspring_population[0])) elif result == 0: # the offspring and current individuals are non-dominated new_individual = offspring_population[0] self.current_neighbors.append(new_individual) ranking: Ranking = FastNonDominatedRanking() ranking.compute_ranking(self.current_neighbors) density_estimator: DensityEstimator = CrowdingDistance() for i in range(ranking.get_number_of_subfronts()): density_estimator.compute_density_estimator(ranking.get_subfront(i)) self.current_neighbors.sort(key=cmp_to_key(self.comparator.compare)) worst_solution = self.current_neighbors[-1] self.archive.add(copy.deepcopy(new_individual)) if worst_solution != new_individual: population[self.current_individual] = new_individual return population
[docs] def result(self) -> R: return self.archive.solution_list
[docs] def get_name(self) -> str: return "MOCell"