Source code for jmetal.algorithm.multiobjective.mocell

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

from jmetal.algorithm.singleobjective.genetic_algorithm import GeneticAlgorithm
from jmetal.config import store
from jmetal.core.operator import Mutation, Crossover, Selection
from jmetal.core.problem import Problem
from jmetal.operator import BinaryTournamentSelection
from jmetal.util.archive import BoundedArchive
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.comparator import Comparator, MultiComparator
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) 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(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(new_individual) if worst_solution != new_individual: population[self.current_individual] = new_individual return population
[docs] def get_result(self) -> R: return self.archive.solution_list
[docs] def get_name(self) -> str: return 'MOCell'