Genetic algorithm with "best-pool" functionality. One of many numpy
-based genetic algorithm implementations in
python
. However, this implementation includes the option to return not only the person with the best fitness -- as
is standard with genetic algorithms --, but also allows to return a pool of people whose fitness is within a user-
defined deviation from the best fitness.
Why the "best-pool" functionality? This functionality is useful when the fitness-function is a computationally cheap proxy function of the real optimisation problem. Using this proxy in combination with the "best pool" functionality allows to narrow-down the input space to be explored/investigated with the more computationally expensive function (or model).
This repository only depends on numpy
(see requirements.txt
).
The basic usage of the genetic algorithm requires the initiation of the GeneticAlgorithm
-class, which requires some
definitions of the optimisation problem at hand:
- fitness-function
- dimensionality
- variable types (
{'bool', 'int', 'float'}
) - variable boundaries
Note that the dimensionality should match the number of input arguments of the fitness-function as well as the variable types and boundaries. In case all variables have the same type, a single definition suffices.
The initiation (including the definition of a fitness-function) looks as follows:
from src.ga import GeneticAlgorithm
# define the fitness function
def fitness(x, y, z):
"""Dummy fitness function for a three-dimensional problem."""
return sum([x, y, z])
# initiate the GA-class
model = GeneticAlgorithm(
fitness, # fitness function
3, # dimensionality
'float', # variable type (all float)
[
[0, 10], # variable boundaries for `x`
[3, 5], # variable boundaries for `y`
[0, 1] # variable boundaries for `z`
]
)
After the initiation, the genetic algorithm must be executed. To do so, the exec()
-method has be called, which returns a
tuple
with three items:
- Most fit person and its fitness (
dict
); - Evolution of fitness over the generations (
dict
); - Pool of fittest people and their fitness (
numpy.ndarray
, orNone
).
Note that the evolution of fitness can contain other data of the population during its evolution, based on the
optional argument provided by the user to the exec()
-method.
Note that the pool of fittest people equals None
if the genetic algorithm is executed without its "best pool"
functionality enabled (disabled by default).
The subsequent execution of the genetic algorithm looks as follows:
from src.ga import GeneticAlgorithm
# define the fitness function
def fitness(x, y, z):
"""Dummy fitness function for a three-dimensional problem."""
return sum([x, y, z])
# initiate the GA-class
model = GeneticAlgorithm(fitness, 3, 'float', [[0, 10], [3, 5], [0, 1]])
# execute without "best pool" functionality
output_without_pool = model.exec()
# execute with "best pool" functionality
output_with_pool = model.exec(output_pool=True)
The exact output varies per execution due to the random nature of the genetic algorithm. Nevertheless, the results in
output_without_pool
will contain the following three items:
{'person': array([v01, v02, v03]), 'fitness': f0}
{'best_fitness': [..., ..., f0]}
None
The results in the output_with_pool
will look the same, except the addition of the pool with the fittest people:
{'person': array([v01, v02, v03]), 'fitness': f0}
{'best_fitness': [..., ..., f0]}
[[v11, v12, v13, f1]
[v21, v22, v23, f2]
...
[vn1, vn2, vn3, fn]]
Note that the pool may (and probably will) contain duplicates.
Note that the shown example only addresses the basic usage. However, the genetic algorithm includes more options to
fine-tune the results to the user's needs. Most of these are included in the settings
of the genetic algorithm, which
can be modified by entering the settings' key(s) as optional argument(s):
from src.ga import GeneticAlgorithm
model = GeneticAlgorithm(
lambda *args: sum(args), 3, 'float', [[0, 10], [3, 5], [0, 1]],
population_size=200, # default: 100
elite_ratio=0, # default: 0.1
)
Other optional arguments can be provided to the exec()
-method. These concern the "best pool" functionality, and
evolution progress track-record (i.e., what data to store throughout the evolution).
Gijs G. Hendrickx
0000-0001-9523-7657
(Delft University of Technology).
Contact: [email protected].
Please refer appropriately when using this repository. This repository is made as part of the research described in Hendrickx et al. (2023), which may be used as linked reference for this repository.
Hendrickx, G.G., Antolínez, J.A.A., and Herman, P.M.J. (2023). Predicting the response of complex systems for coastal management. Coastal Engineering, 182:104289. doi:10.1016/j.coastaleng.2023.104289.
This repository is licensed under Apache License 2.0
.
The genetic algorithm is included in the src
-directory:
+-- src
| +-- __init__.py
| +-- ga.py
+-- tests
| +-- __init__.py
| +-- test_ga.py
+-- .gitignore
+-- __init__.py
+-- LICENSE
+-- README.md
+-- requirements.txt
+-- setup.py