lightweight_genetic_algorithm package¶
Submodules¶
lightweight_genetic_algorithm.algorithm module¶
- class lightweight_genetic_algorithm.algorithm.GeneticAlgorithm(fitness_function, gene_ranges, fitness_function_args=(), number_of_genes=None, crossover_method='Either Or', mutation_mode=None, mutation_rate=None, measure=None, r0=None, D0=None, use_multiprocessing=False, ncpus=None, verbosity=1, selection_method='Diversity Enhanced', output_directory=None)[source]¶
Bases:
object
A class to represent a Genetic Algorithm.
This class provides methods to perform optimization using genetic algorithms for both numerical and categorical parameters.
- Parameters:
fitness_function (callable) – A function that calculates the fitness score of an individual.
gene_ranges (list) – A list specifying the possible values or ranges for each gene. For numerical genes, it is a list of tuples specifying the (min, max) range for each gene. For categorical genes, it is a simple list of possible categories.
fitness_function_args (tuple, optional) – Additional arguments to pass to the fitness_function (default is ()).
number_of_genes (int, optional) – The number of genes in each individual. If genes are numerical, it defaults to the length of gene_ranges. Must be specified if genes are categorical.
crossover_method (str, optional) – The method used for crossover. Options are “Between”, “Midpoint”, “Either Or”, or “None”. Default is “Either Or”.
mutation_mode (list of str, optional) – The mode used for mutation for each gene. Available options are: “additive”, “multiplicative”, “random”, “categorical”. Default is [“additive”]*number_of_genes for numerical genes and [“categorical”]*number_of_genes for categorical genes.
mutation_rate (float, optional) – The rate of mutation for each gene. Default is 1.0 / number_of_genes.
measure (str or callable, optional) – Defines the distance measure between two individuals for diversity. Options are “Hamming”, “Euclidean”, “Dynamic”, or a custom function. Default depends on gene type: “Hamming” for categorical genes, “Euclidean” for numerical genes.
r0 (float, optional) – The characteristic distance beyond which there is no diversity penalty (default is 1/10 of the average spread of initial population). Only used for diversity enhanced selection.
D0 (float, optional) – The maximum diversity penalty for identical individuals (default is 1.0). Only used for diversity enhanced selection.
use_multiprocessing (bool, optional) – Whether to use multiprocessing for fitness evaluations (default is False).
ncpus (int, optional) – The number of processes to use for multiprocessing (default is the number of CPUs minus one).
verbosity (int, optional) – The verbosity level. 0 = silent, 1 = normal output, 2 = detailed output (default is 1).
selection_method (str, optional) – The method used for selecting the best individuals for the next generation. Options are “Diversity Enhanced” or “Fitness Proportionate” (default is “Diversity Enhanced”).
output_directory (str, optional) –
The directory to save output files (default is None). If specified, the algorithm saves the genes of the selected survivors in each generation to a file “<datetime>_survivors.npy” in the output directory. The average fitness and best fitness at each generation are saved to “<datetime>_fitness.txt”. A log file is saved to “log.txt” containing the output of the algorithm printed to the console.
The “<datetime>_survivors.npy” file can be loaded using numpy.load(file, allow_pickle=True) to access the gene values of the individuals in each generation. The loaded array has shape (n_generations+1, population_size, number_of_genes) since the initial population is also saved.
- fitness_function¶
The fitness function used to evaluate individuals.
- Type:
callable
- fitness_function_args¶
Additional arguments for the fitness function.
- Type:
tuple
- gene_ranges¶
The ranges or categories for each gene.
- Type:
list
- number_of_genes¶
The number of genes in each individual.
- Type:
int
- is_discrete¶
Indicates whether the genes are categorical.
- Type:
bool
- mutation_mode¶
Mutation modes for each gene.
- Type:
list of str
- mutation_rate¶
Mutation rate for each gene.
- Type:
float
- survivor_selection¶
The survivor selection strategy.
- Type:
- use_multiprocessing¶
Indicates whether multiprocessing is used.
- Type:
bool
- ncpus¶
Number of CPUs used if multiprocessing.
- Type:
int
- pool¶
The multiprocessing Pool object if multiprocessing is used.
- Type:
multiprocessing.Pool or None
- verbosity¶
Verbosity level.
- Type:
int
- output_directory¶
Directory for output files.
- Type:
str
- fitness_file¶
Path to the file where fitness values are saved (if output_directory is specified).
- Type:
str
- survivors_file¶
Path to the file where survivor gene values are saved (if output_directory is specified).
- Type:
str
- run(n_generations, population_size, init_genes=None, fitness_threshold=None, verbosity=1)[source]¶
Runs the genetic algorithm and returns the population at each generation.
- run_light(n_generations, population_size, init_genes=None, fitness_threshold=None, verbosity=1)[source]¶
Runs the genetic algorithm and returns the gene values at each generation.
- create_initial_population(n, init_gene_values=None)[source]¶
Creates the initial population of individuals.
- Parameters:
n (int) – The number of individuals in the population.
init_gene_values (list, optional) – Initial gene values to seed the population. If None, the population is initialized randomly.
- Returns:
The initial population of individuals.
- Return type:
list of Individual
- evaluate_fitness(genes)[source]¶
Evaluates the fitness of a set of genes using the fitness function.
- Parameters:
genes (list) – The genes to evaluate.
- Returns:
The fitness value of the genes.
- Return type:
float
- log(message, level=1)[source]¶
Logs a message to the console and, if specified, to the output directory log file.
- Parameters:
message (str) – The message to log.
level (int, optional) – The level of verbosity required to print the message (default is 1).
- run(n_generations, population_size, init_genes=None, fitness_threshold=None, verbosity=1)[source]¶
Runs the genetic algorithm for a specified number of generations.
- Parameters:
n_generations (int) – The number of generations to run the genetic algorithm.
population_size (int) – The number of individuals in the population.
init_genes (list, optional) – Initial gene values to seed the population. If None, the population is initialized randomly.
fitness_threshold (float, optional) – The fitness threshold to stop the algorithm early. If None, the algorithm runs for n_generations.
verbosity (int, optional) – The verbosity level for printing messages. 0 = silent, 1 = normal output, 2 = detailed output (default is 1).
- Returns:
A list containing the population at each generation. Each population is a list of Individual objects.
- Return type:
list of list of Individual
- run_light(n_generations, population_size, init_genes=None, fitness_threshold=None, verbosity=1)[source]¶
Runs the genetic algorithm and returns only the gene values.
- Parameters:
n_generations (int) – The number of generations to run the genetic algorithm.
population_size (int) – The number of individuals in the population.
init_genes (list, optional) – Initial gene values to seed the population. If None, the population is initialized randomly.
fitness_threshold (float, optional) – The fitness threshold to stop the algorithm early. If None, the algorithm runs for n_generations.
verbosity (int, optional) – The verbosity level for printing messages. 0 = silent, 1 = normal output, 2 = detailed output (default is 1).
- Returns:
A list containing the gene values of the population at each generation.
- Return type:
list of list
lightweight_genetic_algorithm.crossover module¶
- class lightweight_genetic_algorithm.crossover.Crossover[source]¶
Bases:
object
This is a base class for all crossover methods. Crossover methods take the lists of genes of the parents as input.
- class lightweight_genetic_algorithm.crossover.CrossoverBetween[source]¶
Bases:
Crossover
Implements a ‘between’ crossover method where each child’s gene is a random value between the corresponding genes of the two parents.
Each gene in the child is generated by uniformly sampling a value between the values of the corresponding genes in the parents.
Note
The genes must have a ‘crossover_methods’ attribute that includes ‘between’.
The genes must have ‘value’, ‘low’, and ‘high’ attributes.
- crossover(parent1_genes, parent2_genes)[source]¶
Perform ‘between’ crossover between two parents.
- Parameters:
parent1_genes (List[NumericGene]) – The genes from the first parent.
parent2_genes (List[NumericGene]) – The genes from the second parent.
- Returns:
The child genes resulting from crossover.
- Return type:
List[NumericGene]
- Raises:
ValueError – If the ‘between’ crossover method is not compatible with the gene type.
- class lightweight_genetic_algorithm.crossover.CrossoverEitherOr[source]¶
Bases:
Crossover
Implements an ‘either or’ crossover method where each child’s gene is randomly chosen to be either the corresponding gene from the first parent or from the second parent, with equal probability.
Note
The genes must have a ‘crossover_methods’ attribute that includes ‘either or’.
- crossover(parent1_genes, parent2_genes)[source]¶
Perform ‘either or’ crossover between two parents.
- Parameters:
- Returns:
The child genes resulting from crossover. Each gene is chosen randomly from either parent.
- Return type:
List[Gene]
- Raises:
ValueError – If the ‘either or’ crossover method is not compatible with the gene type.
Notes
The returned genes are copies of the parent genes. This prevents unintended side effects if genes are mutable.
- class lightweight_genetic_algorithm.crossover.CrossoverMidpoint[source]¶
Bases:
Crossover
Implements a ‘midpoint’ crossover method where each child’s gene is the average (midpoint) of the corresponding genes of the two parents.
Note
The genes must have a ‘crossover_methods’ attribute that includes ‘midpoint’.
The genes must have ‘value’, ‘low’, and ‘high’ attributes.
- crossover(parent1_genes, parent2_genes)[source]¶
Perform ‘midpoint’ crossover between two parents.
- Parameters:
parent1_genes (List[NumericGene]) – The genes from the first parent.
parent2_genes (List[NumericGene]) – The genes from the second parent.
- Returns:
The child genes resulting from crossover.
- Return type:
List[NumericGene]
- Raises:
ValueError – If the ‘midpoint’ crossover method is not compatible with the gene type.
lightweight_genetic_algorithm.mutation module¶
- class lightweight_genetic_algorithm.mutation.Mutation(mutation_modes, mutation_probability, param_ranges)[source]¶
Bases:
object
A class used to represent mutations in a genetic algorithm.
The Mutation class provides methods to mutate genes or individuals based on specified mutation modes and probabilities.
- mutation_modes¶
List of mutation modes for each gene.
- Type:
list of str
- mutation_probability¶
Probability of mutating each gene.
- Type:
float
- param_ranges¶
List of parameter ranges for each gene.
- Type:
list of tuple
- is_categorical¶
Indicates if the genes are categorical.
- Type:
bool
- additive(gene, param_range)[source]¶
Applies an additive mutation to a gene.
The gene’s value is adjusted by adding a random value drawn from a normal distribution.
- multiplicative(gene, param_range=None)[source]¶
Applies a multiplicative mutation to a gene.
The gene’s value is adjusted by multiplying it by a random factor drawn from a normal distribution centered at 1.
- mutate_genes(genes, force_mutate=False)[source]¶
Mutates a list of genes based on the mutation probability and modes.
- mutate_individual(individual, force_mutate=False)[source]¶
Mutates an individual by mutating its genes.
- Parameters:
individual (Individual) – The Individual object to mutate.
force_mutate (bool, optional) – If True, ensures at least one gene is mutated.
- Returns:
A new Individual object with mutated genes.
- Return type:
- Raises:
TypeError – If the input is not an instance of Individual.
lightweight_genetic_algorithm.population module¶
- class lightweight_genetic_algorithm.population.CategoricalGene(categories, value=None)[source]¶
Bases:
Gene
A categorical gene that can take any value from a set of categories.
- Parameters:
categories (list) – The allowed categories for the gene.
value (object, optional) – The value of the gene. Must be one of the allowed categories. If not provided, the gene will be initialized with a random value.
- categories¶
The allowed categories for the gene.
- Type:
list
- value¶
The current value of the gene.
- Type:
object
- Raises:
ValueError – If the provided value is not in the allowed categories.
- copy()[source]¶
Creates and returns a copy of the gene.
- Returns:
A new instance of CategoricalGene with the same categories and value.
- Return type:
- crossover_methods = ['either or']¶
- mutation_methods = ['categorical']¶
- class lightweight_genetic_algorithm.population.Gene[source]¶
Bases:
ABC
Abstract base class for a gene.
Each subclass defines a gene in a specific genotype space.
- mutation_methods¶
The mutation methods that can be applied to the gene.
- Type:
list of str
- mutation_methods = []¶
- class lightweight_genetic_algorithm.population.Individual(genes, fitness_function, fitness_function_args, fitness=None)[source]¶
Bases:
object
Represents an individual in the population, defined by its genes.
- Parameters:
genes (list of Gene) – The genes that define the individual.
fitness_function (callable) – The fitness function used to calculate the fitness of the individual. The function should take a list of gene values as its first argument and return a scalar value.
fitness_function_args (tuple) – Additional arguments for the fitness function.
fitness (float, optional) – The fitness of the individual. If not provided, the fitness function will be evaluated. This allows avoiding redundant evaluations of the fitness function.
- genes¶
An array containing the genes of the individual.
- Type:
numpy.ndarray
- genes_values¶
An array containing the values of the genes.
- Type:
numpy.ndarray
- fitness_function¶
The fitness function used to calculate the fitness of the individual.
- Type:
callable
- fitness_function_args¶
Additional arguments for the fitness function.
- Type:
tuple
- fitness¶
The fitness of the individual.
- Type:
float
- Raises:
ValueError – If the fitness function evaluation fails, indicating incompatibility with the individual’s genes.
- copy()[source]¶
Creates and returns a copy of the individual.
- Returns:
A new Individual instance with the same genes and fitness.
- Return type:
- get_fitness_function()[source]¶
Returns the fitness function used by the individual.
- Returns:
The fitness function.
- Return type:
callable
- class lightweight_genetic_algorithm.population.NumericGene(gene_range, value=None)[source]¶
Bases:
Gene
A numeric gene represented by a real number within a range.
- Parameters:
gene_range (tuple of float) – The range (low, high) of the gene values.
value (float, optional) – The value of the gene. If not provided, the gene will be initialized with a random value.
- low¶
The lower bound of the gene values.
- Type:
float
- high¶
The upper bound of the gene values.
- Type:
float
- value¶
The current value of the gene.
- Type:
float
- copy()[source]¶
Creates and returns a copy of the gene.
- Returns:
A new instance of NumericGene with the same range and value.
- Return type:
- crossover_methods = ['between', 'midpoint', 'either or']¶
- get_gene_range()[source]¶
Returns the gene range.
- Returns:
A tuple (low, high) representing the gene range.
- Return type:
tuple of float
- mutation_methods = ['additive', 'multiplicative', 'random']¶
lightweight_genetic_algorithm.selection module¶
- class lightweight_genetic_algorithm.selection.DiversityEnhancedSurvivorSelection(measure, r0=None, D0=None)[source]¶
Bases:
SurvivorSelection
Diversity-enhanced survivor selection strategy.
This class implements a survivor selection method that considers both the fitness and the diversity of individuals. It aims to maintain diversity in the population by penalizing individuals that are too similar to already selected survivors.
- Parameters:
measure (callable or {'euclidean', 'hamming', 'dynamic'}) – A function to measure the distance or dissimilarity between two individuals. If a string is provided, it must be one of the predefined measures: - ‘euclidean’: Sum of squared differences (Euclidean distance squared). - ‘hamming’: Hamming distance normalized by the length of the vectors. - ‘dynamic’: Dynamic distance considering relative differences.
r0 (float, optional) – The characteristic distance beyond which there is no diversity penalty. Default is 1.0.
D0 (float, optional) – The maximum diversity penalty for identical individuals. Default is 1.0.
- r0¶
Characteristic distance for diversity calculation.
- Type:
float
- D0¶
Maximum diversity penalty.
- Type:
float
- measure¶
Function to compute the distance between two individuals.
- Type:
callable
- compute_diversity(individual, survivor)[source]¶
Compute the diversity penalty between an individual and a selected survivor.
The penalty decreases exponentially with the squared distance between the individual and the survivor.
- Parameters:
individual (object) – An individual from the population. Must have a method get_gene_values() that returns a numpy array of gene values.
survivor (object) – A survivor individual already selected. Must have a method get_gene_values() that returns a numpy array of gene values.
- Returns:
The diversity penalty for the individual.
- Return type:
float
- select_survivors(population, surviving_population_size)[source]¶
Select survivors from the population based on fitness and diversity.
The method iteratively selects the best individual (based on adjusted fitness), adds it to the list of survivors, and updates the fitness of the remaining individuals by subtracting the diversity penalty with respect to the newly added survivor.
- Parameters:
population (list) – A list of individuals in the current population. Each individual must have a fitness attribute and a get_gene_values() method.
surviving_population_size (int) – The number of individuals to select as survivors.
- Returns:
A list of selected individuals of length surviving_population_size.
- Return type:
list
Notes
The method modifies the input population list by removing selected survivors.
- class lightweight_genetic_algorithm.selection.FitnessProportionalSurvivorSelection[source]¶
Bases:
SurvivorSelection
Fitness-proportional survivor selection strategy.
This class implements a survivor selection method where individuals are selected based solely on their fitness values. Individuals with higher fitness have a higher chance of being selected.
- select_survivors(population, surviving_population_size)[source]¶
Select survivors from the population based on fitness.
- Parameters:
population (list) – A list of individuals in the current population. Each individual must have a fitness attribute.
surviving_population_size (int) – The number of individuals to select as survivors.
- Returns:
A list of selected individuals of length surviving_population_size.
- Return type:
list
- class lightweight_genetic_algorithm.selection.SurvivorSelection[source]¶
Bases:
object
Base class for survivor selection methods in evolutionary algorithms.
This abstract class defines the interface for survivor selection strategies. Subclasses should implement the select_survivors method to specify how survivors are selected from a population.
- select_survivors(population, surviving_population_size)[source]¶
Select survivors from the population.
- Parameters:
population (list) – A list of individuals in the current population.
surviving_population_size (int) – The number of individuals to select as survivors.
- Returns:
A list of selected individuals of length surviving_population_size.
- Return type:
list
- Raises:
NotImplementedError – If the method is not implemented in the subclass.
Module contents¶
The lightweight_genetic_algorithm package An intuitive, flexible and efficient implementation of a genetic algorithm in Python