diff --git a/cgp/ea/mu_plus_lambda.py b/cgp/ea/mu_plus_lambda.py index 913f2ac3..a9977375 100644 --- a/cgp/ea/mu_plus_lambda.py +++ b/cgp/ea/mu_plus_lambda.py @@ -26,7 +26,6 @@ def __init__( n_processes: int = 1, local_search: Optional[Callable[[IndividualBase], None]] = None, k_local_search: Optional[int] = None, - reorder_genome: bool = False, hurdle_percentile: List = [0.0], ): """Init function @@ -50,13 +49,6 @@ def __init__( k_local_search : int Number of individuals in the whole population (parents + offsprings) to apply local search to. - reorder_genome : bool, optional - Whether genome reordering should be applied. - Reorder shuffles the genotype of an individual without changing its phenotype, - thereby contributing to neutral drift through the genotypic search space. - If True, reorder is applied to each parents genome at every generation - before creating offsprings. - Defaults to True. hurdle_percentile : List[float], optional Specifies which percentile of individuals passes the respective hurdle, i.e., which individuals are evaluated on the next objective @@ -75,7 +67,6 @@ def __init__( self.n_processes = n_processes self.local_search = local_search self.k_local_search = k_local_search - self.reorder_genome = reorder_genome self.hurdle_percentile = hurdle_percentile self.process_pool: Optional["mp.pool.Pool"] @@ -127,7 +118,7 @@ def step( Modified population with new parents. """ - if self.reorder_genome: + if pop.reorder_genome_bool: pop.reorder_genome() offsprings = self._create_new_offspring_generation(pop) diff --git a/cgp/population.py b/cgp/population.py index 2fa221f7..c5ad0598 100755 --- a/cgp/population.py +++ b/cgp/population.py @@ -17,6 +17,7 @@ def __init__( seed: int = 1234, genome_params: Optional[Union[dict, List[dict]]] = None, individual_init: Optional[Callable[[IndividualBase], IndividualBase]] = None, + reorder_genome_bool: bool = True, ) -> None: """Init function. @@ -32,6 +33,13 @@ def __init__( individual_init: callable, optional If not None, called for each individual of the initial parent population, for example, to set the dna of parents. Defaults to None. + reorder_genome_bool : bool, optional + Whether genome reordering should be applied. + Reorder shuffles the genotype of an individual without changing its phenotype, + thereby contributing to neutral drift through the genotypic search space. + If True, reorder is applied to each parents genome at every generation + in the evolutionary algorithm before creating offsprings. + Defaults to True. """ self.n_parents = n_parents # number of individuals in parent population @@ -52,6 +60,27 @@ def __init__( self._generate_random_parent_population(individual_init) + self.reorder_genome_bool = reorder_genome_bool + + # check if the reorder default is incompatible and in case set it to False + if isinstance(genome_params, dict): + if ("n_rows" in genome_params and genome_params["n_rows"] != 1) or ( + "levels_back" in genome_params + and "n_columns" in genome_params + and genome_params["levels_back"] != genome_params["n_columns"] + ): + + self.reorder_genome_bool = False + + elif isinstance(self._genome_params, list): + for genome_param in self._genome_params: + if ("n_rows" in genome_param and genome_param["n_rows"] != 1) or ( + "levels_back" in genome_param + and "n_columns" in genome_param + and genome_param["levels_back"] != genome_param["n_columns"] + ): + self.reorder_genome_bool = False + @property def champion(self) -> IndividualBase: """Return parent with the highest fitness. @@ -133,5 +162,6 @@ def reorder_genome(self) -> None: --------- None """ + assert self.reorder_genome_bool for parent in self.parents: parent.reorder_genome(self.rng) diff --git a/examples/example_reorder.py b/examples/example_reorder.py index 6842d3a6..7d4616da 100644 --- a/examples/example_reorder.py +++ b/examples/example_reorder.py @@ -74,7 +74,7 @@ def objective(individual): # evolutionary algorithms without (default) and with genome reordering. -population_params = {"n_parents": 1, "seed": 818821} +population_params = {"n_parents": 1, "reorder_genome_bool": True, "seed": 818821} genome_params = { "n_inputs": 1, @@ -90,7 +90,6 @@ def objective(individual): "n_offsprings": 4, "mutation_rate": 0.03, "n_processes": 2, - "reorder_genome": True, } evolve_params = {"max_generations": int(args["--max-generations"]), "termination_fitness": 0.0}