Models

Genetic

Here we have the code documentation for the main classes of the genetic algorithm: individual, population, configuration and problem.

class mango.models.genetic.individual.Individual(genes=None, idx: int = 0, parents: tuple | None = None, config=None)
property genes: ndarray

Property that stores the numpy.ndarray of genes in the individual

If max_bound or min_bound are set, the genes values are clipped to the bounds. After setting the value for the genes the hash is updated.

Parameters:

value (numpy.ndarray) – the new value for the genes (used on setting up the property)

Returns:

the genes value

property idx: int

Property that stores the internal idx of the Individual. This value is just to help distinguish between individuals.

Parameters:

value (int) – the new value for the idx (used on setting up the property)

Returns:

the idx value

property config: GeneticBaseConfig

Property that stores the config object for the individual

Parameters:

value (mango.models.genetic.config.GeneticBaseConfig) – the new value for the config (used on setting up the property)

Returns:

the config value

property parents: tuple

Property that stores the parents of the individual and their idx.

During the setter the value for attribute parents_idx is updated as well as a tuple of the idx of all the parents

Parameters:

value (tuple) – the new value for the parents (used on setting up the property)

Returns:

the parents value

property encoding: str

Property that stores the encoding type for the individual

Parameters:

value (str) – the new value for the encoding (used on setting up the property)

Returns:

the encoding value

Return type:

str

property fitness: float

Property that stores the fitness value for the individual

Parameters:

value (float) – the new value for the fitness (used on setting up the property)

Returns:

the fitness value

classmethod create_random_individual(idx: int, config: GeneticBaseConfig) Individual

Class method that creates a new individual with random genes.

Parameters:
Returns:

the new individual

create_random_genes()

Method to create random genes for an individual based on the encoding type.

The genes are stored in the genes attribute

mutate(mutation_prob: float | None = None)

Method to mutate the individual based on the encoding type.

The mutation probability is used to determine if the individual will be mutated or not. An individual can have more than one gene that gets mutated. The

Parameters:

mutation_prob (float) – the probability of mutation

_mutate_binary()

Mutation method for the binary values encoding.

This mutation is a simple bit flip on the calculated gene position

_mutate_integer()

Mutation method for the integer values encoding.

This mutation is a simple random value between the min and max bounds (randint)

_mutate_real()

Mutation method for the real values encoding

This mutation is a simple random value between the min and max bounds

dominates(other)

This method should implement the logic to check if one individual dominates another one

The domination concept is mainly used in multiobjective optimization problems. A solution dominates another when the first one is equal or better in all objectives and one objective is at least better than the other solution

copy() Individual

Method to create a copy of the individual

__hash__()

Method to calculate the hash of the individual and store it in the _hash attribute

The hash is calculated based on the byte representation of the genes of the individual so that only individuals with the same genome have the hash

__eq__(other) bool

Method to compare two individuals

In order to make this comparison as fast as possible it used the pre-generated hash to compare the individuals. So the comparison is made on the genotype instead of the phenotype, as two individuals with different genotypes can have the same phenotype, so they should be considered as not equal for crossover and genetic diversity purposes.

Parameters:

other – the other individual to compare

Returns:

True if the individuals are equal, False otherwise

Return type:

bool

class mango.models.genetic.population.Population(config, evaluator)
property config

Property to store the configuration that the genetic algorithm has to use.

Getter:

Returns the configuration object.

Setter:

Sets the configuration object.

Parameters:

value (GeneticBaseConfig) – The configuration object.

property evaluator

Property to store the function or class that evaluates the fitness of an individual.

Getter:

Returns the evaluator function.

Setter:

Sets the evaluator function.

Parameters:

value (Union[callable, Problem]) – The evaluator function or class.

run()

Method to run the evolution process on the population.

This method does not have any input argument as all the information should be passed through the config class. This method does not return anything, but it can be stopped due to the exceptions that can be raised on other parts of the algorithm.

Raises:

GeneticDiversity – When the genetic diversity is too low this exception gets raised. it can be raised during the parent selection process or during the stop phase of the algorithm.

continue_running(generations: int)

Method to rerun the Genetic Algorithm from the point it stopped for more generations.

This method only works if the algorithm has previously stopped due to reaching the initial generation limit, if it is due to a GeneticDiversity exception, it will probably raise said exception again.

Parameters:

generations – Number of generations to run the Genetic Algorithm.

Raises:

GeneticDiversity – When the genetic diversity is too low this exception gets raised. it can be raised during the parent selection process or during the stop phase of the algorithm.

init_population()

Method to initialize the population in the Genetic Algorithm

The initialization of the population is done by creating a list of random individuals with size equal to the population_size parameter. The creation of the individuals is controlled by the create_random_individual class method of the Individual class.

selection()

Method to run the selection phase of the Genetic Algorithm. The selection process actually just creates the list of probabilities of a given individual to be chosen on the crossover phase. The values of said probabilities depend on the selection method chosen..

Currently, there is seven selection methods implemented: - Random (_random_selection()). - Elitism (_elitism_selection()). - Rank (_rank_selection()). - Order (_order_selection()). - Roulette (_roulette_selection()). - Tournament (_tournament_selection()) - Boltzmann (_boltzmann_selection(), not implemented yet).

The details of how each of these methods work can be found on the Selection documentation.

crossover()

Method to run the crossover phase of the Genetic Algorithm

Currently, there is eight crossover method implemented: - One-split (_one_split_crossover()). - Two-split (_two_split_crossover()). - Mask (_mask_crossover()). - Linear (_linear_crossover()). - Flat (_flat_crossover()). - Blend (_blend_crossover()). - Gaussian (_gaussian_crossover()). - Morphology (_morphology_crossover(), not implemented yet).

The details of how each of these cross over works can be found on the Crossover documentation.

mutate()

Method to run the mutation phase of the Genetic Algorithm.

The actual implementation of the mutation is done in the individual as it is heavily dependent on the encoding. The only change is when using adaptative mutation that the mutation rate has to be updated before calling the individual.

update_population()

Method to make sure that all individuals in the population have a fitness value.

replace()

Method to run the replacement phase of the Genetic Algorithm.

Currently, there is one replacement method implemented: - Random (_random_replacement()). - Offspring (_offspring_replacement()). - Elitist (_elitist_replacement()). - Elistist stochastic (_elitist_stochastic_replacement()).

The details of how each of these replacement methods work can be found on the Replacement

update_best()

Method to update the best adapted individual on the population.

The best individual gets updated based on the optimization objective of the problem.

stop()

Method to implement stop conditions based on information about the population or the genetic diversity.

Currently, the only check done is that the genetic diversity is not too low.

_random_selection()

Method to perform random selection.

In this case the probability to select any individual is equal.

_elitism_selection()

Method to perform elitism selection.

Based on the config parameter rank_size (k), the k-best individuals are selected for crossover. That means that k individuals will have the same selection probability and the rest will have zero.

This selection method could create a diversity problem on the long run if k is small compared to the population size.

_rank_selection()

Method to perform rank selection.

This method is based on the rank of the individuals on the population.

_order_selection()

Method to perform order selection

_roulette_selection()

Method to perform roulette selection.

_tournament_selection()

Method to perform tournament selection

_boltzmann_selection()

Not implemented yet

_select_parents(n: int = 2) tuple

Method to select n parents from the population based on the selection probabilities established on the selection phase.

Parameters:

n (int) – number of parents to select from the population. It defaults to two, but it has the capability to be a different number.

Returns:

a tuple with the selected parents

Return type:

tuple

_one_split_crossover()

Method to perform one-split crossover.

This method creates two children individuals from two parents. It selects a random split point and creates two children by combining the genes of the parents.

More details of this crossover can be found on the One-split crossover section of the documentation.

_two_split_crossover()

Method to perform two-split crossover.

This method creates two children individuals from two parents. It selects two random split points and creates two children by combining the genes of the parents.

More details of this crossover can be found on the Two-split crossover section of the documentation.

_mask_crossover()

Method to perform mask crossover.

This method creates two children individuals from two parents. It selects a random mask and creates two children by combining the genes of the parents. The first children is created by taking the genes of the first parent where the mask is 1 and the genes of the second parent where the mask is 0. The second children is created by taking the genes of the first parent where the mask is 0 and the genes of the second parent where the mask is 1.

More details of this crossover can be found on the Mask crossover section of the documentation.

_linear_crossover()

Method to perform the linear crossover proposed by Wright (1991).

This method creates three child individuals. The first child is calculated as the midpoint between both parents. The other two lie on the line defined by the parents are calculated as:

  • child2 = 1.5 * p1 - 0.5 * p2

  • child3 = -0.5 * p1 + 1.5 * p2

More details of this crossover can be found on the Linear crossover section of the documentation.

_flat_crossover()

This method implements Radcliffe’s flat crossover (1990).

It creates two child individuals with each gene created randomly inside the interval defined by the parents.

More details of this crossover can be found on the Flat crossover section of the documentation.

_blend_crossover()

This method implements the Blend crossover proposed by Eshelman and Schaffer (1993).

The alpha parameter defined for the crossover is defined as blend_expansion parameter. With a value of 0 it is equal to a Radcliffe’s flat crossover while a value of 0.5 is equal to Wright’s linear crossover intervals (but the values are randomly selected).

The main difference with Wrights linear crossover is that only two childs are created instead of two.

More details of this crossover can be found on the Blend crossover section of the documentation.

_gaussian_crossover()

Method to perform the Gaussian crossover, also known as Unimodal Normal Distribution Crossover or UNDX, proposed by Ono (2003).

This method is only implemented for real encoding.

More details of this crossover can be found on the Gaussian crossover section of the documentation.

_morphology_crossover()

This method is not yet implemented

_add_offspring(genes: array, *parents: tuple)

Method to add an offspring to the offspring array

Parameters:
  • genes (numpy.array) – Genes of the offspring

  • parents (tuple) – Parents of the offspring

_base_mutation()

This is the based mutation applied for the base mutation rate or the ones calculated based on gene length or population size.

_adaptative_mutation()

Method to implement adaptative mutation operator.

For the update of the mutation rate we use the coefficient of variation of the fitness of the population.

_calculate_coefficient_variation()

Method to calculate the coefficient of variation of the fitness of the population.

_update_fitness(population)

Internal method to update the fitness of a gioven population or subpopulation of the GA.

_random_replacement()

Method to implement a random replacement operator.

In this case the offspring is added to the population and then a random selection is done to select the individuals that will pass to the next generation.

_offspring_replacement()

The population gets completely substituted by the offspring.

_elitist_replacement()

The best adapted individuals on the population are the ones that pass to the next generation

_elitist_stochastic_replacement()

Method to implement an elitist stochastic replacement operator.

In this case each individual has a replacement probability based on their fitness.

static extract_fitness(obj)

Helper static method to extract the fitness of an individual.

class mango.models.genetic.config.GeneticBaseConfig(filename)

Bases: BaseConfig

__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)

The create_config_template function creates a configuration file with default values for each parameter. If the parameter has a default value, it will be used, otherwise an empty string will be used.

Parameters:

output_file – specify the output path for the template of the config file

Doc-author:

baobab soluciones

modify_value(key, value)

The modify value allows to modify the value of a parameter after it has been loaded

Parameters:

key – the name of the parameter we want to extract

Returns:

The value of the parameter

Doc-author:

baobab soluciones

class mango.models.genetic.problem.Problem

Bases: ABC

Metaclass to implement an abstract problem class for genetic algorithms.

The problem class is used to define the fitness function for the genetic algorithm.

abstract calculate_fitness(x: array) float

Calculate the fitness of a given solution.

This method has to be implemented on the subclasses

Parameters:

x (numpy.array) – Solution to calculate the fitness of.

Returns:

Fitness of the solution.

Return type:

float

_abc_impl = <_abc_data object>

There is also some other helper classes that are used by the genetic algorithm that are documented below.

class mango.models.genetic.shared.exceptions.GeneticDiversity

Exception raised when the genetic diversity of the population is too low.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class mango.models.genetic.shared.exceptions.ConfigurationError

Exception raised when the configuration of the genetic algorithm is not valid.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

Neural Networks components

Activations

mango.models.activations.sigmoid(x: float, factor: float = 1) float

Sigmoid funtion with a factor to control the slope

Parameters:
  • x (float) – the input value

  • factor (float, optional) – the factor to control the slope, defaults to 1

Returns:

the sigmoid value

Return type:

float

mango.models.activations.tanh(x: float, factor: float = 1) float

Tanh funtion with a factor to control the slope

Parameters:
  • x (float) – the input value

  • factor (float, optional) – the factor to control the slope, defaults to 1

Returns:

the tanh value

Neural networks

mango.models.neural_networks.calculate_network_output(x: array, weights: array, layers: int, input_nodes: int, hidden_nodes: List[int], output_nodes: int) array

The calculate_network_output function takes in a set of inputs, weights, and nodes. It then calculates the output of the network by multiplying each input with its corresponding weight and adding it to a bias term for that layer. The function then passes this value through an activation function (sigmoid) and returns the result.

Parameters:
  • x (np.array) – the input data

  • weights (np.array) – the weights of each layer

  • layers (int) – the number of layers of the network

  • input_nodes (int) – the number of input nodes

  • hidden_nodes (list) – the list with the number of nodes in each layer

  • output_nodes (int) – the number of output nodes

Returns:

the result of the network for a given set of inputs

Return type:

np.array

Optimization

Pyomo

The following functions are tools made to work with optimization models created with the pyomo library.

mango.models.pyomo.is_feasible(status)

Return True if the status is optimal or maxTimeLimit

Parameters:

status – a status (string or pyomo object)

Returns:

True if the status is optimal or maxTimeLimit

mango.models.pyomo.safe_value(x)

Safely apply pyomo value to a variable.

pyomo value generate an error if the variable has not been used. This function will return 0 instead.

Parameters:

x – a pyomo variable

Returns:

value of the variable

mango.models.pyomo.var_to_sdict(variable, clean=False, rounding=2)

Transform a pyomo variable into a python dict

Parameters:
  • variable – a pyomo variable.

  • clean – if true, only return non-zero values.

  • rounding – number of decimal to round.

Returns:

a SuperDict containing the indices and values of the variable.

mango.models.pyomo.var_to_table(variable, keys, clean=False, rounding=2)

Generate a table from a pyomo variable.

Parameters:
  • variable – a pyomo variable.

  • keys – the names of the keys of the variable.

  • clean – if true, only return non-zero values.

  • rounding – number of decimal to round.

Returns:

a table [{Index_1:i1, Index_2:i2, Value:v}…]

mango.models.pyomo.get_status(result)

Return the status of the solution from the result object

Parameters:

result – a pyomo result object

Returns:

the status

mango.models.pyomo.get_gap(result)

Return the relative gap of the solution.

Parameters:

result – a pyomo result object

Returns:

the gap

mango.models.pyomo.write_cbc_warmstart_file(filename, instance, opt)

This function write a file to be passed to cbc solver as a warmstart file. This function is necessary because of a bug of cbc that does not allow reading warmstart files on windows with absolute path. :param filename: path to the file :param instance: model instance (created with create_instance) :param opt: solver instance (created with solver factory) :return:

mango.models.pyomo.variables_to_excel(model_solution, path, file_name='variables.xlsx', clean=True, rounding=6)

Save all the values of the variables in an Excel file.

Parameters:
  • model_solution – the pyomo solution.

  • path – path of the directory where to save the file

  • clean – discard variables with values of 0.

Returns:

nothing

mango.models.pyomo.variables_to_json(model_solution, path, file_name='variables.json', clean=True)

Save all the values of the variables in an json file.

Parameters:
  • model_solution – the pyomo solution.

  • path – path of the directory where to save the file

  • clean – discard variables with values of 0.

Returns:

nothing

mango.models.pyomo.instance_from_excel(instance, path, file_name='variables.xlsx')

The function reads instance from excel.

Parameters:
  • instance – model instance

  • path – the path of the file to be loaded

Returns:

model instance

mango.models.pyomo.instance_from_json(instance, path, file_name='variables.json', **kwargs)

The function reads instance from json.

Parameters:
  • instance – model instance

  • path – the path of the file to be loaded

Returns:

model instance

mango.models.pyomo.instance_from_dict(instance, data)

The function loads the instance based on data from dict with tables.

Parameters:
  • instance – model instance

  • data – data for instance

Returns:

model instance

mango.models.pyomo.load_variable(instance, var_name, value)

The function loads the values to indicated variable.

Parameters:
  • instance – model instance

  • var_name – name of the variable to which values will be assign

  • value – values to be assigned to variable

mango.models.pyomo.model_data_to_excel(model_data, path, file_name='model_data.xlsx')

Save a pyomo instance to excel.

Parameters:
  • model_data – dict with model data for pyomo model.

  • path – path of the directory where to save the file

  • clean – discard variables with values of 0.

Returns:

nothing

mango.models.pyomo.solver_result_to_json(result, path)

Save the result object in a json file.

Parameters:
  • result – result object from pyomo

  • path – path of the file

Returns:

nothing

mango.models.pyomo.solver_result_from_json(path, **kwargs)

Load a result object from pyomo

Parameters:
  • path – path of the file

  • kwargs – kwargs for load_json

Returns:

the result object