Darwin¶
The microgp.darwin.Darwin
class is in charge of handling the whole
evolutionprocess. It contains:
- Constraints (
microgp.constraints.Constraints
) that must be the same for each individual managed by Darwin; - Population (
microgp.population.Population
) that manages the set of individuals present in the current generation; - Archive (
microgp.archive.Archive
) that manages the best individuals ever contained in the population; - Operators (
microgp.operators.Operators
) that wraps all the GenOperator (microgp.genoperator.GenOperator
), manages statistics, and operator selection; - other evolution parameters such as selection pressure, population size, number of operators to use for the first generation, maximum age of an individual, etc;
microgp.darwin
-
class
microgp.darwin.
Darwin
(constraints: microgp.constraints.Constraints, operators: microgp.operators.Operators, mu: int, lambda_: int, nu: int = None, tau: float = 2.0, strength: float = 0.5, max_age: Optional[int] = None, max_generations: Optional[int] = 42, stopping_conditions: Optional[list] = None)¶ This class manages the evolution, stores the genetic operators, the population, and the archive. You can set some evolution parameters (lambda, tau, nu, strength, mu) and a list of stopping conditions. A microgp.population.Population and a microgp.population.Archive objects are also initialized.
Parameters: - constraints (Constraints) – Constraints object that each individual managed by Darwin must have.
- operators (Operators) – operators object that contains the set of GenOperators that will manipulate the individuals.
- mu (int) – Population size.
- lambda (int) – Number of operators to pick at each generation (except when the population is empty).
- nu (int) – Number of initialization operators to pick when the population is empty. None if you want mu individuals.
- tau (float) – Selection pressure. Default value: 2.0
- strength (float) – Probability and strength of the mutation (to be passed to the mutation GenOperators).
- max_age (int) – Maximum age that an individual in the population can have. None if you don’t want to filter individuals by age.
- stopping_conditions –
Examples:
Initialize a Darwin object:
>>> mu = 10 >>> nu = 20 >>> strength = 0.2 >>> lambda_ = 7 >>> max_age = 10 >>> darwin = ugp4.Darwin( >>> constraints=library, >>> operators=operators, >>> mu=mu, >>> nu=nu, >>> lambda_=lambda_, >>> strength=strength, >>> max_age=max_age)
Evolve, print results (Population):
>>> darwin.evolve() >>> logging.bare("This is the population:") >>> for individual in darwin.population: >>> msg = 'Printing individual ' + individual.id >>> ugp4.print_individual(individual, msg=msg, plot=True) >>> ugp4.logging.bare(individual.fitness)
Print the Archive that contains the best eve individuals
>>> logging.bare("These are the best ever individuals:") >>> ugp4.print_individual(darwin.archive)
-
do_generation
() → None¶ Perform a generation of the evolution. Pick lambda (or nu) operators, clean the resulting set of individuals given by the operators, join it to population and keep the best mu individuals
-
evolve
() → None¶ Evolve the population until at least one of the stopping conditions becomes True
-
filter_offspring
(temporary_offspring: Optional[List[Optional[microgp.individual.Individual]]]) → Optional[List[Optional[microgp.individual.Individual]]]¶ Remove “None” elements and choose the best element in sublist recursively
Parameters: temporary_offspring – the list of individuals to just generated by the operator Returns: List of valid individuals
-
get_best_unpacking
(individuals: list) → Optional[microgp.individual.Individual]¶ Find the best value in the given list (recursive)
-
keep_at_most_mu
() → None¶ Keep in the population at most mu individuals removing the worst
-
update_archive
() → None¶ Insert in archive the best individuals (and remove the no more good enough individuals)
Population¶
microgp.population
-
class
microgp.population.
Population
¶ This class contains the set of individuals composing the population and manages the selection, insertion, removal of the individuals based on the age or whether their phenotype is already in the population. A non-valid individual can’t be inserted.
Examples:
- Add a set of individuals in the population
>>> darwin.population += set(list_of_individuals)
- Add a single individual in the population
>>> darwin.population += set(individual_A) >>> darwin.population += set(individual_B)
- Remove a single individual from the population
>>> darwin.population -= set(individual_A)
- Remove multiple individuals (set) from the population
>>> darwin.population = darwin.population - set(individual_A)
- Retrieve from population an individual using tournament selection Tournament selection
>>> selected_individual = darwin.tournament_selection(tau)
- Retrieve the entire set of individual contained in the population
>>> population = darwin.population.individuals
-
filter_by_age
(max_age: int = None) → None¶ Remove from the population the individuals that are too old (individual.age >= max_age)
-
static
filter_clones
() → None¶ Check whether or not there are individuals with the same (canonical) phenotype and then remove them
-
static
grow_old
(individuals: Set[microgp.individual.Individual]) → None¶ Increment the age of a set of individuals. Typically the set is {Population - Archive}
-
select
(tau: float = 2) → microgp.individual.Individual¶ Select an individual from the population calling the tournament_selection(tau) method
-
tournament_selection
(tau: float = 2) → microgp.individual.Individual¶ Run several tournaments among a few (floor(tau) or ceil(tau)) individuals and return the best one based on the fitness
Archive¶
microgp.archive
-
class
microgp.archive.
Archive
¶ This class manages the set of individuals not dominated by all other individuals currently or previously contained in the
microgp.darwin.Darwin._population
.Examples:
- Try to insert an individual in the archive:
>>> self._archive += individual
The individual will be inserted only if it is not dominated by all individual already inside the archive. If it is not dominated then the individuals that just became dominated are removed from the archive.
Operators¶
-
class
microgp.operators.
Operators
¶ This class wraps all operators, manages statistics, and GenOperator selection. The selection is made on the basis of the arity and the success and failure statistics of the operator.
Examples:
- Create and fill an Operators object to be passed to a Darwin object
>>> operators = ugp4.Operators() >>> init_op1 = ugp4.GenOperator(ugp4.create_random_individual, 0) >>> operators += init_op1 >>> mutation_op1 = ugp4.GenOperator(ugp4.remove_node_mutation, 1) >>> operators += mutation_op1 >>> crossover_op1 = ugp4.GenOperator(ugp4.switch_proc_crossover, 2) >>> operators += crossover_op1 >>> crossover_op2 = ugp4.GenOperator(ugp4.five_individuals_crossover, 5) >>> operators += crossover_op2
- Select k operators that has arity in the given range
>>> selected_operators = operators.select(max_arity=0, k=10) >>> selected_operators = operators.select(min_arity=1, max_arity=2 k=20)
-
select
(min_arity: int = 0, max_arity: int = None) → microgp.genoperator.GenOperator¶ Select a set of operators with arity in [min_arity, max_arity]
Parameters: - min_arity (int) – minimum arity of the operators that will be returned
- max_arity (int) – maximum arity of the operators that will be returned
- k (int) – number of genetic operators to return
Returns: a valid genetic operator
GenOperator¶
-
class
microgp.genoperator.
GenOperator
(function: collections.abc.Callable, arity: int)¶ Wrapper of a method that implements the algorithm manipulating or building one or more individuals. This class will also manage (in the future versions) the statistics applied to the assigned method. The method wrapped in the GenOperator must have **kwargs in its parameters.
Examples:
- Build three genetic operators passing the method and the arity
>>> init_op1 = ugp4.GenOperator(ugp4.create_random_individual, 0) >>> mutation_op1 = ugp4.GenOperator(ugp4.remove_node_mutation, 1) >>> crossover_op1 = ugp4.GenOperator(ugp4.switch_proc_crossover, 2) >>> crossover_op2 = ugp4.GenOperator(ugp4.five_individuals_crossover, 5)
- Call the method inside the genetic operator
>>> selected_crossover_genoperator(individual1, individual2) >>> selected_mutation_genoperator(individual, strength=0.7, constraints=constraints)) >>> individuals = tuple(ind1, ind2, ind3, ind4, ind5) >>> kwargs = {'param1': var1, 'param2': var2, 'param3': [a, b, c, d, e]} >>> selected_crossover_5_individuals(*individuals, kwargs)