Source code of PyGAD, a Python 3 library for building the genetic algorithm and training machine learning algorithms (Keras & PyTorch).
PyGAD 2.18.1
keep_elitism
is used. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/132
run_completed
property to False
. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/122
run()
method self.best_solutions, self.best_solutions_fitness, self.solutions, self.solutions_fitness
: https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/123. Now, the user can have the flexibility of calling the run()
method more than once while extending the data collected after each generation. Another advantage happens when the instance is loaded and the run()
method is called, as the old fitness value are shown on the graph alongside with the new fitness values. Read more in this section: [Continue without Loosing Progress](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#continue-without-loosing-progress)crossover_type=None
.keep_elitism
. It defaults to 1 which means for each generation keep only the best solution in the next generation. If assigned 0, then it has no effect. Read more in this section: [Elitism Selection](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#elitism-selection). https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/74
last_generation_elitism
added to hold the elitism in the last generation.random_seed
added to accept a seed for the random function generators. Credit to this issue https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/70 and [Prof. Fernando Jiménez Barrionuevo](http://webs.um.es/fernan). Read more in this section: [Random Seed](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#random-seed).pygad.TorchGA
module to make sure the tensor data is moved from GPU to CPU. Thanks to Rasmus Johansson for opening this pull request: https://github.com/ahmedfgad/TorchGA/pull/2
Release Date: 8 July 2022
gene_space
parameter is given a fixed value. e.g. gene_space=[range(5), 4]. The second gene's value is static (4) which causes an exception.allow_duplicate_genes
parameter did not work when mutation is disabled (i.e. mutation_type=None
). This is by checking for duplicates after crossover directly. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/39
tournament_selection()
method as the indices of the selected parents were incorrect. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/89
save_solutions=True
.parallel_processing
in the constructor of the pygad.GA
class. Thanks to [@windowshopr](https://github.com/windowshopr) for opening the issue [#78](https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/78) at GitHub. Check the [Parallel Processing in PyGAD](https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#parallel-processing-in-pygad) section for more information and examples.Changes in PyGAD 2.16.3
previous_generation_fitness
added in the pygad.GA
class. It holds the fitness values of one generation before the fitness values saved in the last_generation_fitness
.cal_pop_fitness()
method in getting the correct indices of the previous parents. This is solved by using the previous generation's fitness saved in the new attribute previous_generation_fitness
to return the parents' fitness values. Thanks to Tobias Tischhauser (M.Sc. - [Mitarbeiter Institut EMS, Departement Technik, OST – Ostschweizer Fachhochschule, Switzerland](https://www.ost.ch/de/forschung-und-dienstleistungen/technik/systemtechnik/ems/team)) for detecting this bug.save_solutions=True
.tqdm
library to show a progress bar. https://github.com/ahmedfgad/GeneticAlgorithmPython/discussions/50
import pygad
import numpy
import tqdm
equation_inputs = [4,-2,3.5]
desired_output = 44
def fitness_func(solution, solution_idx):
output = numpy.sum(solution * equation_inputs)
fitness = 1.0 / (numpy.abs(output - desired_output) + 0.000001)
return fitness
num_generations = 10000
with tqdm.tqdm(total=num_generations) as pbar:
ga_instance = pygad.GA(num_generations=num_generations,
sol_per_pop=5,
num_parents_mating=2,
num_genes=len(equation_inputs),
fitness_func=fitness_func,
on_generation=lambda _: pbar.update(1))
ga_instance.run()
ga_instance.plot_result()
solutions
and solutions_fitness
when the save_solutions
parameter is set to True
. Now, the fitness of the last population is appended to the solutions_fitness
array. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/64
solutions
, solutions_fitness
, best_solutions
, and best_solutions_fitness
) doubled after each call of the run()
method. This is solved by resetting these variables at the beginning of the run()
method. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/62
mutation_type="adaptive"
). https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/65
A user-defined function can be passed to the mutation_type, crossover_type, and parent_selection_type parameters in the pygad.GA class to create a custom mutation, crossover, and parent selection operators. Check the User-Defined Crossover, Mutation, and Parent Selection Operators section in the documentation: https://pygad.readthedocs.io/en/latest/README_pygad_ReadTheDocs.html#user-defined-crossover-mutation-and-parent-selection-operators The example_custom_operators.py script gives an example of building and using custom functions for the 3 operators. https://github.com/ahmedfgad/GeneticAlgorithmPython/discussions/50
Fix a bug when keep_parents
is set to a positive integer. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/49
last_generation_parents_indices
holds the indices of the selected parents in the last generation.last_generation_fitness
and last_generation_parents_indices
attributes. This speeds-up the adaptive mutation.None
in the gene_space
parameter (e.g. gene_space=[[1, 2, 3], [5, 6, None]]
), then its value will be randomly generated for each solution rather than being generated once for all solutions. Previously, a value of None
in a sublist of the gene_space
parameter was identical across all solutions.gene_space
parameter itself or one of its elements has a new key called "step"
to specify the step of moving from the start to the end of the range specified by the 2 existing keys "low"
and "high"
. An example is {"low": 0, "high": 30, "step": 2}
to have only even values for the gene(s) starting from 0 to 30. For more information, check the More about the gene_space
Parameter section. https://github.com/ahmedfgad/GeneticAlgorithmPython/discussions/48
predict()
is added in both the pygad.kerasga
and pygad.torchga
modules to make predictions. This makes it easier than using custom code each time a prediction is to be made.stop_criteria
allows the user to specify one or more stop criteria to stop the evolution based on some conditions. Each criterion is passed as str
which has a stop word. The current 2 supported words are reach
and saturate
. reach
stops the run()
method if the fitness value is equal to or greater than a given fitness value. An example for reach
is "reach_40"
which stops the evolution if the fitness is >= 40. saturate
means stop the evolution if the fitness saturates for a given number of consecutive generations. An example for saturate
is "saturate_7"
which means stop the run()
method if the fitness does not change for 7 consecutive generations. Thanks to Rainer for asking about this feature: https://github.com/ahmedfgad/GeneticAlgorithmPython/discussions/44
False
, named save_solutions
is added to the constructor of the pygad.GA
class. If True
, then all solutions in each generation are appended into an attribute called solutions
which is NumPy array.plot_result()
method is renamed to plot_fitness()
. The users should migrate to the new name as the old name will be removed in the future.plot_fitness()
function in the pygad.GA
class which are font_size=14
, save_dir=None
, color="#3870FF"
, and plot_type="plot"
. Use font_size
to change the font of the plot title and labels. save_dir
accepts the directory to which the figure is saved. It defaults to None
which means do not save the figure. color
changes the color of the plot. plot_type
changes the plot type which can be either "plot"
(default), "scatter"
, or "bar"
. https://github.com/ahmedfgad/GeneticAlgorithmPython/pull/47
title
parameter in the plot_fitness()
method is "PyGAD - Generation vs. Fitness"
rather than "PyGAD - Iteration vs. Fitness"
.plot_new_solution_rate()
creates, shows, and returns a figure showing the rate of new/unique solutions explored in each generation. It accepts the same parameters as in the plot_fitness()
method. This method only works when save_solutions=True
in the pygad.GA
class's constructor.plot_genes()
creates, shows, and returns a figure to show how each gene changes per each generation. It accepts similar parameters like the plot_fitness()
method in addition to the graph_type
, fill_color
, and solutions
parameters. The graph_type
parameter can be either "plot"
(default), "boxplot"
, or "histogram"
. fill_color
accepts the fill color which works when graph_type
is either "boxplot"
or "histogram"
. solutions
can be either "all"
or "best"
to decide whether all solutions or only best solutions are used.gene_type
parameter now supports controlling the precision of float
data types. For a gene, rather than assigning just the data type like float
, assign a list
/tuple
/numpy.ndarray
with 2 elements where the first one is the type and the second one is the precision. For example, [float, 2]
forces a gene with a value like 0.1234
to be 0.12
. For more information, check the More about the gene_type
Parameter section.Some bug fixes when setting the save_best_solutions
parameter to True
. Previously, the best solution for generation i
was added into the best_solutions
attribute at generation i+1
. Now, the best_solutions
attribute is updated by each solution at its exact generation.
Some bug fixes when the gene_type
parameter is nested. Thanks to Rainer Engel for opening a discussion to report this bug: https://github.com/ahmedfgad/GeneticAlgorithmPython/discussions/43#discussioncomment-763342
Rainer Engel helped a lot in suggesting new features and suggesting enhancements in 2.14.0 to 2.14.2 releases.