Genetic¶
Here we have the code documentation for the main classes of the genetic algorithm: individual, population, configuration and problem.
- class mango_genetic.individual.Individual(genes=None, idx: int = 0, parents: tuple = None, config=None)¶
Base class representing an individual in a genetic algorithm.
An individual contains genes (genetic information), fitness value, and metadata about its parents and configuration. The class supports different encoding types (real, binary, integer) and provides methods for mutation and genetic operations.
- Parameters:
genes (numpy.ndarray, optional) – Initial genetic information as numpy array
idx (int) – Unique identifier for the individual
parents (tuple, optional) – Tuple of parent individuals
config (GeneticBaseConfig, optional) – Configuration object containing genetic algorithm parameters
- property genes: numpy.ndarray¶
Get the genetic information of the individual.
Returns the numpy array containing the individual’s genes. If bounds are set, gene values are automatically clipped to stay within the specified range.
- Returns:
Array containing the individual’s genetic information
- Return type:
numpy.ndarray
- property idx: int¶
Get the unique identifier of the individual.
Returns the internal index used to distinguish between different individuals in the population.
- Returns:
Unique identifier for the individual
- Return type:
int
- property config: GeneticBaseConfig¶
Get the configuration object for the individual.
Returns the configuration object containing genetic algorithm parameters such as encoding type, bounds, and gene length.
- Returns:
Configuration object with genetic algorithm parameters
- Return type:
- property parents: tuple¶
Get the parent individuals of this individual.
Returns a tuple containing the parent individuals. When parents are set, the parents_idx attribute is automatically updated with their indices.
- Returns:
Tuple of parent individuals
- Return type:
tuple
- property encoding: str¶
Get the encoding type for the individual’s genes.
Returns the encoding type used for the genetic representation. Supported types include ‘real’, ‘binary’, and ‘integer’.
- Returns:
Encoding type string
- Return type:
str
- property fitness: float¶
Get the fitness value of the individual.
Returns the fitness value representing how well this individual performs according to the optimization objective.
- Returns:
Fitness value of the individual
- Return type:
float
- classmethod create_random_individual(idx: int, config: GeneticBaseConfig) Individual ¶
Create a new individual with randomly generated genes.
Factory method that creates a new individual with the specified index and configuration, then generates random genes based on the encoding type.
- Parameters:
idx (int) – Unique identifier for the new individual
config (GeneticBaseConfig) – Configuration object containing genetic algorithm parameters
- Returns:
New individual with random genes
- Return type:
- Example:
>>> config = GeneticBaseConfig() >>> individual = Individual.create_random_individual(idx=0, config=config)
- create_random_genes()¶
Generate random genes for the individual based on the encoding type.
Creates random genetic information according to the individual’s encoding type and configuration bounds. The generated genes are stored in the genes attribute.
Supported encoding types: - ‘real’: Continuous values between min_bound and max_bound - ‘binary’: Binary values (0 or 1) - ‘integer’: Integer values between min_bound and max_bound (inclusive)
- mutate(mutation_prob: float = None)¶
Mutate the individual’s genes based on the encoding type.
Applies mutation to the individual’s genes with the specified probability. The mutation process continues until the probability check fails, meaning an individual can have multiple genes mutated in a single call.
- Parameters:
mutation_prob (float) – Probability of mutation (0.0 to 1.0)
- Raises:
NotImplementedError: If encoding type is not supported
- Example:
>>> individual.mutate(mutation_prob=0.1) # 10% chance of mutation
- _mutate_binary()¶
Mutate a binary-encoded gene by flipping its value.
Performs a simple bit flip mutation on a randomly selected gene position. Changes 0 to 1 or 1 to 0.
- _mutate_integer()¶
Mutate an integer-encoded gene with a random value.
Replaces a randomly selected gene with a new random integer value between the minimum and maximum bounds (inclusive).
- _mutate_real()¶
Mutate a real-encoded gene with a random value.
Replaces a randomly selected gene with a new random real value between the minimum and maximum bounds.
- dominates(other)¶
Check if this individual dominates another individual.
This method should implement the logic to determine if one individual dominates another in multi-objective optimization problems.
A solution dominates another when: - It is equal or better in all objectives - It is strictly better in at least one objective
- Parameters:
other (Individual) – The other individual to compare against
- Returns:
True if this individual dominates the other, False otherwise
- Return type:
bool
- Raises:
NotImplementedError: This method must be implemented by subclasses
- copy() Individual ¶
Create a deep copy of the individual.
Creates a new individual with the same genetic information, index, configuration, and parent information as this individual.
- Returns:
A new individual that is a copy of this one
- Return type:
- Example:
>>> original = Individual(genes=np.array([1, 2, 3]), idx=0) >>> copy = original.copy() >>> copy.genes[0] = 5 >>> print(original.genes[0]) # Still 1
- __hash__()¶
Calculate the hash of the individual based on its genetic information.
The hash is calculated from the byte representation of the individual’s genes, ensuring that only individuals with identical genetic information have the same hash. This enables efficient comparison and storage in hash-based data structures.
- Returns:
Hash value based on the individual’s genes
- Return type:
int
- __eq__(other) bool ¶
Compare two individuals for equality based on their genetic information.
Uses pre-generated hash values for fast comparison. The comparison is based on genotype (genetic information) rather than phenotype (fitness/behavior), as individuals with different genotypes should be considered distinct for genetic diversity and crossover purposes.
- Parameters:
other (Individual) – The other individual to compare against
- Returns:
True if individuals have identical genetic information, False otherwise
- Return type:
bool
- class mango_genetic.population.Population(config, evaluator)¶
Main population class for genetic algorithm operations.
Manages a population of individuals through the complete genetic algorithm lifecycle, including initialization, selection, crossover, mutation, and replacement phases. Supports various selection methods, crossover operators, and mutation strategies.
- Parameters:
config (GeneticBaseConfig) – Configuration object containing genetic algorithm parameters
evaluator (Union[callable, Problem]) – Function or class for evaluating individual fitness
- property config¶
Get the configuration object for the genetic algorithm.
Returns the configuration object containing all genetic algorithm parameters such as population size, encoding type, selection method, etc.
- Returns:
Configuration object with genetic algorithm parameters
- Return type:
- property evaluator¶
Get the fitness evaluation function or class.
Returns the function or class responsible for evaluating the fitness of individuals in the population.
- Returns:
Evaluator function or Problem class instance
- Return type:
Union[callable, Problem]
- run()¶
Run the complete genetic algorithm evolution process.
Executes the genetic algorithm for the specified number of generations, performing selection, crossover, mutation, and replacement operations in each generation. The algorithm can be stopped early due to low genetic diversity or other stop conditions.
- Raises:
- GeneticDiversity: When genetic diversity becomes too low during
parent selection or stop phase evaluation
- continue_running(generations: int)¶
Continue running the genetic algorithm for additional generations.
Extends the maximum generation limit and continues the evolution process from where it previously stopped. This method works best when the algorithm stopped due to reaching the generation limit rather than low genetic diversity.
- Parameters:
generations (int) – Number of additional generations to run
- Raises:
- GeneticDiversity: When genetic diversity becomes too low during
parent selection or stop phase evaluation
- init_population()¶
Initialize the population with random individuals.
Creates a population of random individuals with size equal to the configured population_size. Each individual is created using the Individual.create_random_individual method with the current configuration.
- selection()¶
Execute the selection phase of the genetic algorithm.
Creates selection probabilities for each individual based on the configured selection method. These probabilities determine how likely each individual is to be chosen as a parent during the crossover phase.
Supported selection methods: - Random: Equal probability for all individuals - Elitism: Only the best k individuals can be selected - Rank: Probability based on individual ranking - Order: Probability based on fitness order - Roulette: Probability proportional to fitness - Tournament: Selection through tournament competition - Boltzmann: Temperature-based selection (not implemented)
- crossover()¶
Execute the crossover phase of the genetic algorithm.
Creates offspring individuals by combining genetic information from selected parents using the configured crossover method. The crossover operation generates new individuals that inherit traits from their parents.
Supported crossover methods: - One-split: Single crossover point - Two-split: Two crossover points - Mask: Random binary mask selection - Linear: Linear combination of parents (real encoding only) - Flat: Random values within parent range (real encoding only) - Blend: Extended range crossover (real encoding only) - Gaussian: Gaussian distribution crossover (real encoding only) - Morphology: Morphological crossover (not implemented)
- mutate()¶
Execute the mutation phase of the genetic algorithm.
Applies mutation to offspring individuals based on the configured mutation strategy. The actual mutation implementation is handled by individual objects as it depends on the encoding type. For adaptive mutation, the mutation rate is updated based on population diversity before applying mutations.
- update_population()¶
Update fitness values for all individuals in the population.
Ensures that all individuals in both the main population and offspring have their fitness values calculated using the configured evaluator.
- replace()¶
Execute the replacement phase of the genetic algorithm.
Determines which individuals from the current population and offspring will survive to the next generation based on the configured replacement strategy.
Supported replacement methods: - Random: Random selection from population and offspring - Only-offspring: Replace entire population with offspring - Elitist: Keep best individuals from combined population - Elitist-stochastic: Probabilistic selection based on fitness
- update_best()¶
Update the best individual in the population.
Identifies and stores the best individual based on the optimization objective (maximization or minimization) and their fitness value.
- stop()¶
Check stop conditions for the genetic algorithm.
Evaluates whether the algorithm should stop based on population characteristics. Currently checks for low genetic diversity by examining fitness value distribution in the population.
- Returns:
bool: False (algorithm continues) or raises GeneticDiversity exception
- Raises:
GeneticDiversity: When genetic diversity becomes too low
- _random_selection()¶
Perform random selection with equal probabilities.
Sets equal selection probability for all individuals in the population, making each individual equally likely to be chosen as a parent.
- _elitism_selection()¶
Perform elitism selection based on fitness ranking.
Selects only the k-best individuals (where k is the elitism_size parameter) for crossover. The best k individuals have equal selection probability, while all others have zero probability.
Note: This method may reduce genetic diversity if k is small compared to the population size.
- _rank_selection()¶
Perform rank-based selection.
Assigns selection probabilities based on the rank of individuals in the population, with higher-ranked individuals having higher selection probability.
- _order_selection()¶
Perform order-based selection.
Assigns selection probabilities based on the order of individuals in the population, with better individuals having higher probability.
- _roulette_selection()¶
Perform roulette wheel selection.
Assigns selection probabilities proportional to fitness values, with better individuals having higher probability of selection.
- _tournament_selection()¶
Perform tournament selection.
Simulates tournaments where individuals compete against each other, with the winner being selected based on fitness. Selection probability is proportional to the number of tournament wins.
- _boltzmann_selection()¶
Perform Boltzmann selection (not implemented).
This method is not yet implemented. Boltzmann selection uses temperature-based probability distribution for selection.
- _select_parents(n: int = 2) tuple ¶
Select n parents from the population based on selection probabilities.
Selects parents using the probabilities established during the selection phase. Ensures that different parents are selected to maintain genetic diversity.
- Parameters:
n (int) – Number of parents to select (default: 2)
- Returns:
Tuple containing the selected parent individuals
- Return type:
tuple
- Raises:
GeneticDiversity: When unable to select different parents due to low diversity
- _one_split_crossover()¶
Perform one-point crossover operation.
Creates two offspring by selecting a random split point and exchanging genetic material between two parents at that point. The first offspring gets genes from parent 1 before the split and from parent 2 after the split, while the second offspring gets the opposite combination.
- _two_split_crossover()¶
Perform two-point crossover operation.
Creates two offspring by selecting two random split points and exchanging genetic material between two parents in the middle segment. The first offspring gets genes from parent 1 in the outer segments and from parent 2 in the middle segment, while the second offspring gets the opposite combination.
- _mask_crossover()¶
Perform uniform crossover using a random mask.
Creates two offspring using a random binary mask to determine which parent contributes each gene position. The first offspring gets genes from parent 1 where the mask is 1 and from parent 2 where the mask is 0. The second offspring gets the opposite combination.
- _linear_crossover()¶
Perform linear crossover as proposed by Wright (1991).
Creates three offspring individuals using linear combinations of parent genes: - First offspring: Midpoint between parents (p1 + p2) / 2 - Second offspring: 1.5 * p1 - 0.5 * p2 - Third offspring: -0.5 * p1 + 1.5 * p2
Note: This method is only applicable for real-valued encoding.
- _flat_crossover()¶
Implement Radcliffe’s flat crossover (1990).
Creates two offspring where each gene is randomly generated within the interval defined by the corresponding genes of the two parents. Each gene value is uniformly distributed between the minimum and maximum values of the parent genes at that position.
Note: This method is only applicable for real-valued encoding.
- _blend_crossover()¶
Implement Blend crossover as proposed by Eshelman and Schaffer (1993).
Creates two offspring using an extended interval around the parent genes. The blend_expansion parameter controls the expansion: 0 equals flat crossover, 0.5 equals linear crossover intervals (with random selection).
The first offspring is randomly generated in the expanded interval, while the second offspring is calculated to maintain the average of the parents.
Note: This method is only applicable for real-valued encoding.
- _gaussian_crossover()¶
Perform Gaussian crossover (UNDX) as proposed by Ono (2003).
Implements the Unimodal Normal Distribution Crossover using three parents to create offspring with Gaussian-distributed genes. The first two parents define the primary search space, while the third parent creates the secondary search space with the midpoint between the first two parents.
Note: This method is only applicable for real-valued encoding.
- _morphology_crossover()¶
Perform morphological crossover (not implemented).
This method is not yet implemented. Morphological crossover would use morphological operations to combine parent genetic information.
- _add_offspring(genes: numpy.array, *parents: tuple)¶
Add a new offspring individual to the offspring array.
Creates a new individual with the specified genes and parent information, assigns it a unique index, and adds it to the offspring population.
- Parameters:
genes (numpy.ndarray) – Genetic information for the new offspring
parents (tuple) – Parent individuals of the offspring
- _base_mutation()¶
Apply base mutation to all offspring individuals.
Applies mutation to each offspring individual using the configured mutation rate, which can be static, gene-based, or population-based.
- _adaptative_mutation()¶
Implement adaptive mutation with dynamic rate adjustment.
Adjusts the mutation rate based on the coefficient of variation of population fitness. If diversity decreases, mutation rate increases; if diversity increases, mutation rate decreases. The mutation rate is capped at 0.9 to prevent excessive mutation.
- _calculate_coefficient_variation()¶
Calculate the coefficient of variation of population fitness.
Computes the ratio of standard deviation to mean fitness, which indicates the relative variability in fitness values across the population.
- Returns:
Coefficient of variation (std/mean)
- Return type:
float
- _update_fitness(population)¶
Update fitness values for individuals in the given population.
Evaluates fitness for all individuals that don’t already have a fitness value, using the configured evaluator function or class.
- Parameters:
population (numpy.ndarray) – Array of individuals to evaluate
- _random_replacement()¶
Implement random replacement strategy.
Combines the current population with offspring and randomly selects individuals to form the next generation, maintaining the population size.
- _offspring_replacement()¶
Implement offspring-only replacement strategy.
Completely replaces the current population with the offspring, discarding all individuals from the previous generation.
- _elitist_replacement()¶
Implement elitist replacement strategy.
Selects the best individuals from the combined population and offspring to form the next generation, ensuring the best solutions are preserved.
- _elitist_stochastic_replacement()¶
Implement elitist stochastic replacement strategy.
Assigns replacement probabilities to individuals based on their fitness values, with better individuals having higher probability of survival to the next generation.
- static extract_fitness(obj)¶
Extract fitness value from an individual.
Helper method to extract the fitness value from an individual object, used for sorting and comparison operations.
- Parameters:
obj (Individual) – Individual object
- Returns:
Fitness value of the individual
- Return type:
float
- class mango_genetic.config.GeneticBaseConfig(filename)¶
Bases:
BaseConfig
Configuration class for genetic algorithm parameters.
This class extends BaseConfig to provide configuration management for genetic algorithms. It defines all the necessary parameters for population initialization, selection methods, crossover operations, mutation strategies, and replacement mechanisms.
The configuration is organized into logical groups: - main: Core algorithm parameters (population size, generations, objectives) - individual: Individual encoding and gene parameters - selection: Selection method specific parameters - crossover: Crossover operation parameters - mutation: Mutation strategy parameters
- Parameters:
filename (str) – Path to the configuration file
- __params = {'crossover': [ConfigParameter('offspring_size', <class 'int'>, 100), ConfigParameter('blend_expansion', <class 'float'>, 0.1)], 'individual': [ConfigParameter('encoding', <class 'str'>), ConfigParameter('gene_length', <class 'int'>, 0), ConfigParameter('gene_min_value', <class 'float'>), ConfigParameter('gene_max_value', <class 'float'>)], 'main': [ConfigParameter('population_size', <class 'int'>, 100), ConfigParameter('max_generations', <class 'int'>, 500), ConfigParameter('optimization_objective', <class 'str'>), ConfigParameter('selection', <class 'str'>), ConfigParameter('crossover', <class 'str'>), ConfigParameter('replacement', <class 'str'>), ConfigParameter('mutation_control', <class 'str'>, 'none'), ConfigParameter('mutation_base_rate', <class 'float'>, 0.1)], 'mutation': [ConfigParameter('generation_adaptative', <class 'int'>, 10)], 'selection': [ConfigParameter('elitism_size', <class 'int'>, 20), ConfigParameter('tournament_size', <class 'int'>, 2), ConfigParameter('rank_pressure', <class 'float'>, 2.0)]}¶
- classmethod create_config_template(output_path: str)¶
Create a configuration template file with default values.
Generates a configuration file template based on the defined parameters. Parameters with default values will use those values, while parameters without defaults will be set to empty strings.
- Parameters:
output_path (str) – Path where the template file should be created
- Returns:
None
- Raises:
IOError – If the file cannot be written
- Example:
>>> MyConfig.create_config_template("config_template.ini")
- modify_value(key, value)¶
Modify the value of a configuration parameter.
Updates the value of an existing parameter after the configuration has been loaded. The parameter must exist in the configuration.
- Parameters:
key (str) – Name of the parameter to modify
value (Any) – New value for the parameter
- Returns:
None
- Raises:
KeyError – If the parameter is not found in the configuration
- Example:
>>> config = MyConfig("config.ini", {}) >>> config.modify_value("database_port", 3306)
- class mango_genetic.problem.Problem¶
Bases:
ABC
Abstract base class for defining optimization problems in genetic algorithms.
This class provides the interface for implementing fitness functions that can be used with genetic algorithms. Subclasses must implement the calculate_fitness method to define how solutions are evaluated.
The class can be used as a callable object, making it compatible with genetic algorithm evaluators that expect function-like interfaces.
- abstract calculate_fitness(x: numpy.array) float ¶
Calculate the fitness value for a given solution.
This abstract method must be implemented by subclasses to define how solutions are evaluated. The fitness value represents how well a solution performs according to the optimization objective.
- Parameters:
x (numpy.ndarray) – Solution vector to evaluate
- Returns:
Fitness value of the solution
- Return type:
float
- Raises:
NotImplementedError: This method must be implemented by subclasses
- _abc_impl = <_abc._abc_data object>¶
There is also some other helper classes that are used by the genetic algorithm that are documented below.
Exception raised when the mango_genetic diversity of the population is too low.
Exception.add_note(note) – add a note to the exception
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
Exception raised when the configuration of the mango_genetic algorithm is not valid.
Exception.add_note(note) – add a note to the exception
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.