Source code for pygenalgo.operators.selection.meta_selector

from pygenalgo.genome.chromosome import Chromosome
from pygenalgo.operators.genetic_operator import increase_counter
from pygenalgo.operators.selection.select_operator import SelectionOperator

from pygenalgo.operators.selection.random_selector import RandomSelector
from pygenalgo.operators.selection.tournament_selector import TournamentSelector
from pygenalgo.operators.selection.linear_rank_selector import LinearRankSelector
from pygenalgo.operators.selection.roulette_wheel_selector import RouletteWheelSelector


[docs] class MetaSelector(SelectionOperator): """ Description: Meta-selector, selects the chromosomes for the new population by applying randomly the predefined selectors (one at a time), with equal probability. NOTE: In the future the equal probabilities can be amended. """ def __init__(self, select_probability: float = 1.0) -> None: """ Construct a 'MetaSelector' object with a predefined probability value. :param select_probability: (float). """ # Call the super constructor with the provided probability value. super().__init__(select_probability) # NOTE: In here the selection probabilities for each operator are # set to 1.0. self._items = (RandomSelector(1.0), LinearRankSelector(1.0), RouletteWheelSelector(1.0), TournamentSelector(1.0)) # _end_def_
[docs] @increase_counter def select(self, population: list[Chromosome]) -> list[Chromosome]: """ Select the individuals, from the input population, that will be passed on to the next genetic operations of crossover and mutation to form the new population of solutions. :param population: a list of chromosomes to select the parents from. :return: the selected parents population (as list of chromosomes). """ # Get the number of available selectors. n_operators: int = len(self.items) # Select randomly a method, with equal probability # (but this can be changed). return self.items[self.rng.integers(n_operators, dtype=int)].select(population)
# _end_def_ @property def all_counters(self) -> dict: """ Accessor (getter) of the application counter from all the internal selectors. This is mostly to verify that everything is working as expected. :return: a dictionary with the counter calls for all selector methods. """ return {sel_op.__class__.__name__: sel_op.counter for sel_op in self.items} # _end_def_
[docs] def reset_counter(self) -> None: """ Sets ALL the counters to 'zero'. We have to override the super().reset_counter() method, because we have to call explicitly the reset_counter on all the internal operators. :return: None. """ # First call the super() to reset the self internal counter. super().reset_counter() # Here call explicitly the reset on each of the internal mutators. for op in self.items: op.reset_counter()
# _end_def_ # _end_class_