Skip to content

Commit cbcc654

Browse files
committed
Support of NSGA-III
1 parent 2157cde commit cbcc654

10 files changed

Lines changed: 1582 additions & 30 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ __pycache__/
1515
# =============================================================================
1616
docs/build/
1717
.venv-docs/
18+
19+
# =============================================================================
20+
# IDE settings: JetBrains (PyCharm, IntelliJ, etc.) workspace files.
21+
# These are personal to each developer and should not be committed.
22+
# =============================================================================
23+
.idea/

README.md

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
[PyGAD](https://pypi.org/project/pygad) is an open-source easy-to-use Python 3 library for building the genetic algorithm and optimizing machine learning algorithms. It supports Keras and PyTorch. PyGAD supports optimizing both single-objective and multi-objective problems.
44

5-
> Try the [Optimization Gadget](https://optimgadget.com), a free cloud-based tool powered by PyGAD. It makes optimization easier by reducing or removing the need for coding, and it shows helpful visualizations.
5+
> Try [Vilvik](https://vilvik.com), a free cloud-based tool powered by PyGAD. It makes optimization easier by reducing or removing the need for coding, and it shows helpful visualizations.
66
77
Read the [PyGAD documentation](https://pygad.readthedocs.io/en/latest).
88

99
[![PyPI Downloads](https://pepy.tech/badge/pygad)](https://pepy.tech/project/pygad) [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/pygad.svg?label=Conda%20Downloads)](
10-
https://anaconda.org/conda-forge/PyGAD) [![PyPI version](https://badge.fury.io/py/pygad.svg)](https://badge.fury.io/py/pygad)![Docs](https://readthedocs.org/projects/pygad/badge)[![PyGAD PyTest / Python 3.13](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py313.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py313.yml) [![PyGAD PyTest / Python 3.12](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py312.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py312.yml) [![PyGAD PyTest / Python 3.11](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml) [![PyGAD PyTest / Python 3.10](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml) [![PyGAD PyTest / Python 3.9](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml) [![PyGAD PyTest / Python 3.8](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Translation](https://hosted.weblate.org/widgets/weblate/-/svg-badge.svg)](https://hosted.weblate.org/engage/weblate/) [![REUSE](https://api.reuse.software/badge/github.com/WeblateOrg/weblate)](https://api.reuse.software/info/github.com/WeblateOrg/weblate) [![Stack Overflow](https://img.shields.io/badge/stackoverflow-Ask%20questions-blue.svg)](
10+
https://anaconda.org/conda-forge/PyGAD) [![PyPI version](https://badge.fury.io/py/pygad.svg)](https://badge.fury.io/py/pygad)![Docs](https://readthedocs.org/projects/pygad/badge)[![PyGAD PyTest / Python 3.13](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main.yml) [![PyGAD PyTest / Python 3.12](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/release.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/release.yml) [![PyGAD PyTest / Python 3.11](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/scorecard.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/scorecard.yml) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Translation](https://hosted.weblate.org/widgets/weblate/-/svg-badge.svg)](https://hosted.weblate.org/engage/weblate/) [![REUSE](https://api.reuse.software/badge/github.com/WeblateOrg/weblate)](https://api.reuse.software/info/github.com/WeblateOrg/weblate) [![Stack Overflow](https://img.shields.io/badge/stackoverflow-Ask%20questions-blue.svg)](
1111
https://stackoverflow.com/questions/tagged/pygad) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ahmedfgad/GeneticAlgorithmPython/badge)](https://securityscorecards.dev/viewer/?uri=github.com/ahmedfgad/GeneticAlgorithmPython) [![DOI](https://zenodo.org/badge/DOI/10.1007/s11042-023-17167-y.svg)](https://doi.org/10.1007/s11042-023-17167-y)
1212

1313
![PYGAD-LOGO](https://user-images.githubusercontent.com/16560492/101267295-c74c0180-375f-11eb-9ad0-f8e37bd796ce.png)
@@ -18,7 +18,6 @@ The library is under active development and more features are added regularly. I
1818

1919
# Donation
2020

21-
* [Credit/Debit Card](https://donate.stripe.com/eVa5kO866elKgM0144): https://donate.stripe.com/eVa5kO866elKgM0144
2221
* [Open Collective](https://opencollective.com/pygad): [opencollective.com/pygad](https://opencollective.com/pygad)
2322
* PayPal: Use either this link: [paypal.me/ahmedfgad](https://paypal.me/ahmedfgad) or the e-mail address ahmed.f.gad@gmail.com
2423
* Interac e-Transfer: Use e-mail address ahmed.f.gad@gmail.com
@@ -45,18 +44,6 @@ pip install pygad[deep_learning]
4544

4645
To get started with PyGAD, read the documentation at [Read the Docs](https://pygad.readthedocs.io).
4746

48-
# PyGAD Source Code
49-
50-
The source code of the PyGAD modules is in the following GitHub projects:
51-
52-
- [pygad](https://github.com/ahmedfgad/GeneticAlgorithmPython): (https://github.com/ahmedfgad/GeneticAlgorithmPython)
53-
- [pygad.nn](https://github.com/ahmedfgad/NumPyANN): https://github.com/ahmedfgad/NumPyANN
54-
- [pygad.gann](https://github.com/ahmedfgad/NeuralGenetic): https://github.com/ahmedfgad/NeuralGenetic
55-
- [pygad.cnn](https://github.com/ahmedfgad/NumPyCNN): https://github.com/ahmedfgad/NumPyCNN
56-
- [pygad.gacnn](https://github.com/ahmedfgad/CNNGenetic): https://github.com/ahmedfgad/CNNGenetic
57-
- [pygad.kerasga](https://github.com/ahmedfgad/KerasGA): https://github.com/ahmedfgad/KerasGA
58-
- [pygad.torchga](https://github.com/ahmedfgad/TorchGA): https://github.com/ahmedfgad/TorchGA
59-
6047
# PyGAD Documentation
6148

6249
The PyGAD documentation is available at [Read the Docs](https://pygad.readthedocs.io) at this link: https://pygad.readthedocs.io. It explains the modules supported by PyGAD and all its classes, methods, attributes, and functions. For each module, several examples are given.
@@ -304,7 +291,4 @@ If you used PyGAD, please consider adding a citation to the following paper abou
304291

305292
* E-mail: ahmed.f.gad@gmail.com
306293
* [LinkedIn](https://www.linkedin.com/in/ahmedfgad)
307-
* [Paperspace](https://blog.paperspace.com/author/ahmed)
308-
* [KDnuggets](https://kdnuggets.com/author/ahmed-gad)
309-
* [TowardsDataScience](https://towardsdatascience.com/@ahmedfgad)
310294
* [GitHub](https://github.com/ahmedfgad)

pygad/pygad.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class GA(utils.parent_selection.ParentSelection,
99
utils.crossover.Crossover,
1010
utils.mutation.Mutation,
1111
utils.nsga2.NSGA2,
12+
utils.nsga3.NSGA3,
1213
utils.validation.Validation,
1314
utils.engine.GAEngine,
1415
helper.unique.Unique,
@@ -37,6 +38,7 @@ def __init__(self,
3738
keep_parents=-1,
3839
keep_elitism=1,
3940
K_tournament=3,
41+
nsga3_num_divisions=None,
4042
crossover_type="single_point",
4143
crossover_probability=None,
4244
mutation_type="random",
@@ -86,6 +88,7 @@ def __init__(self,
8688
parent_selection_type: Type of parent selection.
8789
keep_parents: If 0, this means no parent in the current population will be used in the next population. If -1, this means all parents in the current population will be used in the next population. If set to a value > 0, then the specified value refers to the number of parents in the current population to be used in the next population. Some parent selection operators such as rank selection, favor population diversity and therefore keeping the parents in the next generation can be beneficial. However, some other parent selection operators, such as roulette wheel selection (RWS), have higher selection pressure and keeping more than one parent in the next generation can seriously harm population diversity. This parameter has an effect only when the keep_elitism parameter is 0. Thanks to Prof. Fernando Jiménez (http://webs.um.es/fernan) for editing this sentence.
8890
K_tournament: When the value of 'parent_selection_type' is 'tournament', the 'K_tournament' parameter specifies the number of solutions from which a parent is selected randomly.
91+
nsga3_num_divisions: Only used when 'parent_selection_type' is 'nsga3' or 'tournament_nsga3'. It is the number of divisions per objective axis used to build the structured reference points (the 'p' parameter from Deb & Jain 2014). The total number of reference points is C(M + p - 1, p) where M is the number of objectives. Must be a positive integer. Defaults to None.
8992
9093
keep_elitism: Added in PyGAD 2.18.0. It can take the value 0 or a positive integer that satisfies (0 <= keep_elitism <= sol_per_pop). It defaults to 1 which means only the best solution in the current generation is kept in the next generation. If assigned 0, this means it has no effect. If assigned a positive integer K, then the best K solutions are kept in the next generation. It cannot be assigned a value greater than the value assigned to the sol_per_pop parameter. If this parameter has a value different from 0, then the keep_parents parameter will have no effect.
9194
@@ -145,6 +148,7 @@ def __init__(self,
145148
keep_parents=keep_parents,
146149
keep_elitism=keep_elitism,
147150
K_tournament=K_tournament,
151+
nsga3_num_divisions=nsga3_num_divisions,
148152
crossover_type=crossover_type,
149153
crossover_probability=crossover_probability,
150154
mutation_type=mutation_type,

pygad/utils/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pygad.utils import crossover
33
from pygad.utils import mutation
44
from pygad.utils import nsga2
5+
from pygad.utils import nsga3
56
from pygad.utils import validation
67
from pygad.utils import engine
78

pygad/utils/engine.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,13 @@ def run(self):
435435
# Know whether the problem is SOO or MOO.
436436
if type(self.last_generation_fitness[0]) in self.supported_int_float_types:
437437
# Single-objective problem.
438-
# If the problem is SOO, the parent selection type cannot be nsga2 or tournament_nsga2.
439-
if self.parent_selection_type in ['nsga2', 'tournament_nsga2']:
438+
# If the problem is SOO, the parent selection type cannot be nsga2/nsga3 or their tournament variants.
439+
if self.parent_selection_type in ['nsga2', 'tournament_nsga2', 'nsga3', 'tournament_nsga3']:
440440
raise TypeError(f"Incorrect parent selection type. The fitness function returned a single numeric fitness value which means the problem is single-objective. But the parent selection type {self.parent_selection_type} is used which only works for multi-objective optimization problems.")
441441
elif type(self.last_generation_fitness[0]) in [list, tuple, numpy.ndarray]:
442442
# Multi-objective problem.
443-
pass
443+
if self.parent_selection_type in ('nsga3', 'tournament_nsga3'):
444+
self._bootstrap_nsga3_reference_points()
444445

445446
best_solution, best_solution_fitness, best_match_idx = self.best_solution(pop_fitness=self.last_generation_fitness)
446447

0 commit comments

Comments
 (0)