Source code for pygenalgo.operators.selection.select_operator

from math import fabs
from pygenalgo.genome.chromosome import Chromosome
from pygenalgo.operators.genetic_operator import GeneticOperator

# Public interface.
__all__ = ["SelectionOperator", "ensure_positive_fitness"]

[docs] def ensure_positive_fitness(population: list[Chromosome]) -> list[float]: """ Ensures that the fitness value of each chromosome is a positive number. This is useful because some of the selection methods require a positive fitness to operate. Also in minimization problems the fitness values are negated, therefore by using this transformation the methods that require positive values are guaranteed to work. :param population: (list) of chromosomes. :return: (list) of positive fitness values. """ # Extract all the fitness values from the chromosomes. all_fitness: list[float] = [p.fitness for p in population] # If there are negative values we perform a shift # transformation where all the values are shifted # so that the minimum fitness is going to be one. if any(fit_value < 0.0 for fit_value in all_fitness): # Compute the shift value. shift_value = fabs(min(all_fitness)) + 1.0 # Shift all fitness values so that the minimum is '1'. all_fitness = [f + shift_value for f in all_fitness] # _end_if_ return all_fitness
# _end_def_
[docs] class SelectionOperator(GeneticOperator): """ Description: Provides the base class (interface) for a Selection Operator. Note that even though the operator accepts a probability value, for the moment this operator is applied with 100% 'probability'. """ def __init__(self, selection_probability: float) -> None: """ Construct a 'SelectionOperator' object with a given probability value. :param selection_probability: (float). """ # Call the super constructor with the provided # probability value. super().__init__(selection_probability) # _end_def_
[docs] def select(self, population: list[Chromosome]) -> list[Chromosome]: """ Abstract method that "reminds" the user that if they want to create a Selection Class that inherits from here they should implement a select method. :param population: is a list, with the chromosomes, to select he parents for the next generation :return: Nothing but raising an error. """ raise NotImplementedError(f"{self.__class__.__name__}: " f"You should implement this method!")
# _end_def_ def __call__(self, *args, **kwargs) -> list[Chromosome]: """ This is only a wrapper of the "select" method. """ return self.select(*args, **kwargs)
# _end_def_ # _end_class_