Source code for pygenalgo.operators.migration.meta_migration

from pygenalgo.utils.auxiliary import SubPopulation
from pygenalgo.operators.migration.random_migration import RandomMigration
from pygenalgo.operators.migration.migration_operator import MigrationOperator
from pygenalgo.operators.migration.clockwise_migration import ClockwiseMigration


[docs] class MetaMigration(MigrationOperator): """ Description: Meta-migrator, performs the migration between the subpopulations by applying randomly all other migrators (one at a time), with equal probability. NOTE: In the future the equal probabilities can be amended. """ def __init__(self, migration_probability: float = 0.95) -> None: """ Construct a 'MetaMigration' object with a predefined probability value. :param migration_probability: (float). """ # Call the super constructor with the provided probability value. super().__init__(migration_probability) # NOTE: In here the migration probabilities for each policy are set to 1.0. self._items = (RandomMigration(1.0), ClockwiseMigration(1.0)) # _end_def_
[docs] def migrate(self, islands: list[SubPopulation]) -> None: """ Perform the migration operation on the list of SubPopulations. :param islands: list[SubPopulation]. :return: None. """ # Perform the migration only if we have more than one # active populations and the migration probability is # higher than a uniformly random value. if len(islands) > 1 and self.is_operator_applicable(): # Get the number of migrators. n_operators = len(self.items) # Select randomly with equal probability a method and call # its migrate method. self.items[self.rng.integers(n_operators, dtype=int)].migrate(islands) # Increase the migration counter. self.inc_counter()
# _end_def_ @property def all_counters(self) -> dict: """ Accessor (getter) of the application counter from all the internal migrators. This is mostly to verify that everything is working as expected. :return: a dictionary with the counter calls for all migrator methods. """ return {mig_op.__class__.__name__: mig_op.counter for mig_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_