Releases: ahmedfgad/GeneticAlgorithmPython
Releases · ahmedfgad/GeneticAlgorithmPython
PyGAD 3.3.1
- After the last generation and before the
run()
method completes, update the 2 instance attributes: 1)last_generation_parents
2)last_generation_parents_indices
. This is to keep the list of parents up-to-date with the latest population fitnesslast_generation_fitness
. #275 - 4 methods with names starting with
run_
. Their purpose is to keep the main loop inside therun()
method clean. Check the [Other Methods](https://pygad.readthedocs.io/en/latest/pygad.html#other-methods) section for more information.
PyGAD-3.3.0
Release Date 29 January 2024
- Solve bugs when multi-objective optimization is used. #238
- When the
stop_ciiteria
parameter is used with thereach
keyword, then multiple numeric values can be passed when solving a multi-objective problem. For example, if a problem has 3 objective functions, thenstop_criteria="reach_10_20_30"
means the GA stops if the fitness of the 3 objectives are at least 10, 20, and 30, respectively. The number values must match the number of objective functions. If a single value found (e.g.stop_criteria=reach_5
) when solving a multi-objective problem, then it is used across all the objectives. #238 - The
delay_after_gen
parameter is now deprecated and will be removed in a future release. If it is necessary to have a time delay after each generation, then assign a callback function/method to theon_generation
parameter to pause the evolution. - Parallel processing now supports calculating the fitness during adaptive mutation. #201
- The population size can be changed during runtime by changing all the parameters that would affect the size of any thing used by the GA. For more information, check the [Change Population Size during Runtime](https://pygad.readthedocs.io/en/latest/pygad_more.html#change-population-size-during-runtime) section. #234
- When a dictionary exists in the
gene_space
parameter without a step, then mutation occurs by adding a random value to the gene value. The random vaue is generated based on the 2 parametersrandom_mutation_min_val
andrandom_mutation_max_val
. For more information, check the [How Mutation Works with the gene_space Parameter?](https://pygad.readthedocs.io/en/latest/pygad_more.html#how-mutation-works-with-the-gene-space-parameter) section. #229 - Add
object
as a supported data type for int (GA.supported_int_types) and float (GA.supported_float_types). #174 - Use the
raise
clause instead of thesys.exit(-1)
to terminate the execution. #213 - Fix a bug when multi-objective optimization is used with batch fitness calculation (e.g.
fitness_batch_size
set to a non-zero number). - Fix a bug in the
pygad.py
script when finding the index of the best solution. It does not work properly with multi-objective optimization whereself.best_solutions_fitness
have multiple columns.
self.best_solution_generation = numpy.where(numpy.array(
self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0]
PyGAD-3.2.0
- A new module
pygad.utils.nsga2
is created that has theNSGA2
class that includes the functionalities of NSGA-II. The class has these methods: 1)get_non_dominated_set()
2)non_dominated_sorting()
3)crowding_distance()
4)sort_solutions_nsga2()
. Check [this section](https://pygad.readthedocs.io/en/latest/pygad_more.html#multi-objective-optimization) for an example. - Support of multi-objective optimization using Non-Dominated Sorting Genetic Algorithm II (NSGA-II) using the
NSGA2
class in thepygad.utils.nsga2
module. Just return alist
,tuple
, ornumpy.ndarray
from the fitness function and the library will consider the problem as multi-objective optimization. All the objectives are expected to be maximization. Check [this section](https://pygad.readthedocs.io/en/latest/pygad_more.html#multi-objective-optimization) for an example. - The parent selection methods and adaptive mutation are edited to support multi-objective optimization.
- Two new NSGA-II parent selection methods are supported in the
pygad.utils.parent_selection
module: 1) Tournament selection for NSGA-II 2) NSGA-II selection. - The
plot_fitness()
method in thepygad.plot
module has a new optional parameter namedlabel
to accept the label of the plots. This is only used for multi-objective problems. Otherwise, it is ignored. It defaults toNone
and accepts alist
,tuple
, ornumpy.ndarray
. The labels are used in a legend inside the plot. - The default color in the methods of the
pygad.plot
module is changed to the greenish#64f20c
color. - A new instance attribute named
pareto_fronts
added to thepygad.GA
instances that holds the pareto fronts when solving a multi-objective problem. - The
gene_type
accepts alist
,tuple
, ornumpy.ndarray
for integer data types given that the precision is set toNone
(e.g.gene_type=[float, [int, None]]
). - In the
cal_pop_fitness()
method, the fitness value is re-used ifsave_best_solutions=True
and the solution is found in thebest_solutions
attribute. These parameters also can help re-using the fitness of a solution instead of calling the fitness function:keep_elitism
,keep_parents
, andsave_solutions
. - The value
99999999999
is replaced byfloat('inf')
in the 2 methodswheel_cumulative_probs()
andstochastic_universal_selection()
inside thepygad.utils.parent_selection.ParentSelection
class. - The
plot_result()
method in thepygad.visualize.plot.Plot
class is removed. Instead, please use theplot_fitness()
if you did not upgrade yet.
PyGAD-3.1.0
Release Date 20 June 2023
- Fix a bug when the initial population has duplciate genes if a nested gene space is used.
- The
gene_space
parameter can no longer be assigned a tuple. - Fix a bug when the
gene_space
parameter has a member of typetuple
. - A new instance attribute called
gene_space_unpacked
which has the unpackedgene_space
. It is used to solve duplicates. For infinite ranges in thegene_space
, they are unpacked to a limited number of values (e.g. 100). - Bug fixes when creating the initial population using
gene_space
attribute. - When a
dict
is used with thegene_space
attribute, the new gene value was calculated by summing 2 values: 1) the value sampled from thedict
2) a random value returned from the random mutation range defined by the 2 parametersrandom_mutation_min_val
andrandom_mutation_max_val
. This might cause the gene value to exceed the range limit defined in thegene_space
. To respect thegene_space
range, this release only returns the value from thedict
without summing it to a random value. - Formatting the strings using f-string instead of the
format()
method. #189 - In the
__init__()
of thepygad.GA
class, the logged error messages are handled using atry-except
block instead of repeating thelogger.error()
command. #189 - A new class named
CustomLogger
is created in thepygad.cnn
module to create a default logger using thelogging
module assigned to thelogger
attribute. This class is extended in all other classes in the module. The constructors of these classes have a new parameter namedlogger
which defaults toNone
. If no logger is passed, then the default logger in theCustomLogger
class is used. - Except for the
pygad.nn
module, theprint()
function in all other modules are replaced by thelogging
module to log messages. - The callback functions/methods
on_fitness()
,on_parents()
,on_crossover()
, andon_mutation()
can return values. These returned values override the corresponding properties. The output ofon_fitness()
overrides the population fitness. Theon_parents()
function/method must return 2 values representing the parents and their indices. The output ofon_crossover()
overrides the crossover offspring. The output ofon_mutation()
overrides the mutation offspring. - Fix a bug when adaptive mutation is used while
fitness_batch_size
>1. #195 - When
allow_duplicate_genes=False
and a user-definedgene_space
is used, it sometimes happen that there is no room to solve the duplicates between the 2 genes by simply replacing the value of one gene by another gene. This release tries to solve such duplicates by looking for a third gene that will help in solving the duplicates. These examples explain how it works. Check [this section](https://pygad.readthedocs.io/en/latest/pygad.html#prevent-duplicates-in-gene-values) for more information. - Use probabilities to select parents using the rank parent selection method. #205
- The 2 parameters
random_mutation_min_val
andrandom_mutation_max_val
can accept iterables (list/tuple/numpy.ndarray) with length equal to the number of genes. This enables customizing the mutation range for each individual gene. #198 - The 2 parameters
init_range_low
andinit_range_high
can accept iterables (list/tuple/numpy.ndarray) with length equal to the number of genes. This enables customizing the initial range for each individual gene when creating the initial population. - The
data
parameter in thepredict()
function of thepygad.kerasga
module can be assigned a data generator. #115 #207 - The
predict()
function of thepygad.kerasga
module accepts 3 optional parameters: 1)batch_size=None
,verbose=0
, andsteps=None
. Check documentation of the [Keras Model.predict()](https://keras.io/api/models/model_training_apis) method for more information. #207 - The documentation is updated to explain how mutation works when
gene_space
is used withint
orfloat
data types. Check [this section](https://pygad.readthedocs.io/en/latest/pygad.html#limit-the-gene-value-range-using-the-gene-space-parameter). #198
PyGAD-3.0.1
Fix an issue with passing user-defined function/method for parent selection. #179
PyGAD-3.0.0
This release has a major change where the fitness function accepts a mandatory parameter referring to the instance of the pygad.GA
class.
This is the release notes:
- The structure of the library is changed and some methods defined in the
pygad.py
module are moved to thepygad.utils
,pygad.helper
, andpygad.visualize
submodules. - The
pygad.utils.parent_selection
module has a class namedParentSelection
where all the parent selection operators exist. Thepygad.GA
class extends this class. - The
pygad.utils.crossover
module has a class namedCrossover
where all the crossover operators exist. Thepygad.GA
class extends this class. - The
pygad.utils.mutation
module has a class namedMutation
where all the mutation operators exist. Thepygad.GA
class extends this class. - The
pygad.helper.unique
module has a class namedUnique
some helper methods exist to solve duplicate genes and make sure every gene is unique. Thepygad.GA
class extends this class. - The
pygad.visualize.plot
module has a class namedPlot
where all the methods that create plots exist. Thepygad.GA
class extends this class.
...
class GA(utils.parent_selection.ParentSelection,
utils.crossover.Crossover,
utils.mutation.Mutation,
helper.unique.Unique,
visualize.plot.Plot):
...
- Support of using the
logging
module to log the outputs to both the console and text file instead of using theprint()
function. This is by assigning thelogging.Logger
to the newlogger
parameter. Check the [Logging Outputs](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#logging-outputs) for more information. - A new instance attribute called
logger
to save the logger. - The function/method passed to the
fitness_func
parameter accepts a new parameter that refers to the instance of thepygad.GA
class. Check this for an example: [Use Functions and Methods to Build Fitness Function and Callbacks](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#use-functions-and-methods-to-build-fitness-and-callbacks). #163 - Update the documentation to include an example of using functions and methods to calculate the fitness and build callbacks. Check this for more details: [Use Functions and Methods to Build Fitness Function and Callbacks](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#use-functions-and-methods-to-build-fitness-and-callbacks). #92 (comment)
- Validate the value passed to the
initial_population
parameter. - Validate the type and length of the
pop_fitness
parameter of thebest_solution()
method. - Some edits in the documentation. #106
- Fix an issue when building the initial population as (some) genes have their value taken from the mutation range (defined by the parameters
random_mutation_min_val
andrandom_mutation_max_val
) instead of using the parametersinit_range_low
andinit_range_high
. - The
summary()
method returns the summary as a single-line string. Just log/print the returned string it to see it properly. - The
callback_generation
parameter is removed. Use theon_generation
parameter instead. - There was an issue when using the
parallel_processing
parameter with Keras and PyTorch. As Keras/PyTorch are not thread-safe, thepredict()
method gives incorrect and weird results when more than 1 thread is used. #145 ahmedfgad/TorchGA#5 ahmedfgad/KerasGA#6. Thanks to this [StackOverflow answer](https://stackoverflow.com/a/75606666/5426539). - Replace
numpy.float
byfloat
in the 2 parent selection operators roulette wheel and stochastic universal. #168
PyGAD-2.19.2
- Fix an issue when paralell processing was used where the elitism solutions' fitness values are not re-used. #160 (comment)
PyGAD-2.19.1
- A new
summary()
method is supported to return a Keras-like summary of the PyGAD lifecycle. - A new optional parameter called
fitness_batch_size
is supported to calculate the fitness function in batches. If it is assigned the value1
orNone
(default), then the normal flow is used where the fitness function is called for each individual solution. If thefitness_batch_size
parameter is assigned a value satisfying this condition1 < fitness_batch_size <= sol_per_pop
, then the solutions are grouped into batches of sizefitness_batch_size
and the fitness function is called once for each batch. In this case, the fitness function must return a list/tuple/numpy.ndarray with a length equal to the number of solutions passed. #136. - The
cloudpickle
library (https://github.com/cloudpipe/cloudpickle) is used instead of thepickle
library to pickle thepygad.GA
objects. This solves the issue of having to redefine the functions (e.g. fitness function). Thecloudpickle
library is added as a dependancy in therequirements.txt
file. #159 - Support of assigning methods to these parameters:
fitness_func
,crossover_type
,mutation_type
,parent_selection_type
,on_start
,on_fitness
,on_parents
,on_crossover
,on_mutation
,on_generation
, andon_stop
. #92 #138 - Validating the output of the parent selection, crossover, and mutation functions.
- The built-in parent selection operators return the parent's indices as a NumPy array.
- The outputs of the parent selection, crossover, and mutation operators must be NumPy arrays.
- Fix an issue when
allow_duplicate_genes=True
. #39 - Fix an issue creating scatter plots of the solutions' fitness.
- Sampling from a
set()
is no longer supported in Python 3.11. Instead, sampling happens from alist()
. ThanksMarco Brenna
for pointing to this issue. - The lifecycle is updated to reflect that the new population's fitness is calculated at the end of the lifecycle not at the beginning. #154 (comment)
- There was an issue when
save_solutions=True
that causes the fitness function to be called for solutions already explored and have their fitness pre-calculated. #160 - A new instance attribute named
last_generation_elitism_indices
added to hold the indices of the selected elitism. This attribute helps to re-use the fitness of the elitism instead of calling the fitness function. - Fewer calls to the
best_solution()
method which in turns saves some calls to the fitness function. - Some updates in the documentation to give more details about the
cal_pop_fitness()
method. #79 (comment)
PyGAD-2.18.3
Update conf.py