Skip to content

Commit 9ac7527

Browse files
authored
Merge pull request #334 from ahmedfgad/github-actions
PyGAD 3.5.0
2 parents 83f0bed + 19250a9 commit 9ac7527

File tree

5 files changed

+40
-80
lines changed

5 files changed

+40
-80
lines changed

docs/md/releases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ Release Date 08 July 2025
606606
15. More examples are created.
607607
16. Edited the `sort_solutions_nsga2()` method in the `pygad/utils/nsga2.py` script to accept an optional parameter called `find_best_solution` when calling this method just to find the best solution.
608608
17. Fixed a bug while applying the non-dominated sorting in the `get_non_dominated_set()` method inside the `pygad/utils/nsga2.py` script. It was swapping the non-dominated and dominated sets. In other words, it used the non-dominated set as if it is the dominated set and vice versa. All the calls to this method were edited accordingly. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/320.
609+
18. Fix a bug retrieving in the `best_solution()` method when retrieving the best solution for multi-objective problems. https://github.com/ahmedfgad/GeneticAlgorithmPython/pull/331
609610

610611
# PyGAD Projects at GitHub
611612

docs/source/pygad_more.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,14 +530,23 @@ assigning a larger value for the ``sample_size`` parameter.
530530
PyGAD does not yet handle the **dependencies** among the genes in the
531531
``gene_constraint`` parameter.
532532
533-
For example, gene 0 might depend on gene 1. To efficiently enforce
534-
the constraints, the constraint for gene 1 must be enforced first (if
535-
not ``None``) then the constraint for gene 0.
533+
This is an example where gene 0 depends on gene 1. To efficiently
534+
enforce the constraints, the constraint for gene 1 must be enforced
535+
first (if not ``None``) then the constraint for gene 0.
536+
537+
.. code:: python
538+
539+
gene_constraint=
540+
[
541+
lambda solution,values: [val for val in values if val<solution[1]],
542+
lambda solution,values: [val for val in values if val>10]
543+
]
536544
537545
PyGAD applies constraints sequentially, starting from the first gene
538546
to the last. To ensure correct behavior when genes depend on each
539547
other, structure your GA problem so that if gene X depends on gene Y,
540548
then gene Y appears earlier in the chromosome (solution) than gene X.
549+
As a result, its gene constraint will be earlier in the list.
541550
542551
Full Example
543552
------------

docs/source/releases.rst

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ Release Date 07 January 2025
15931593
8. Refactoring the ``pygad/helper/unique.py`` script to remove
15941594
duplicate codes and reformatting the docstrings.
15951595

1596-
9. The plot_pareto_front_curve() method added to the
1596+
9. The ``plot_pareto_front_curve()`` method added to the
15971597
pygad.visualize.plot.Plot class to visualize the Pareto front for
15981598
multi-objective problems. It only supports 2 objectives.
15991599
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/279
@@ -1630,11 +1630,12 @@ Release Date 07 January 2025
16301630
PyGAD 3.5.0
16311631
-----------
16321632

1633-
Release Date 07 July 2025
1633+
Release Date 08 July 2025
16341634

16351635
1. Fix a bug when minus sign (-) is used inside the ``stop_criteria``
16361636
parameter for multi-objective problems.
16371637
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/314
1638+
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/323
16381639

16391640
2. Fix a bug when the ``stop_criteria`` parameter is passed as an
16401641
iterable (e.g. list) for multi-objective problems (e.g.
@@ -1726,6 +1727,7 @@ Release Date 07 July 2025
17261727
called to ensure the candidate value is valid. Check the `Gene
17271728
Constraint <https://pygad.readthedocs.io/en/latest/pygad_more.html#gene-constraint>`__
17281729
section for more information.
1730+
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/119
17291731

17301732
11. A new parameter called ``sample_size`` is added. To select a gene
17311733
value that respects a constraint, this variable defines the size of
@@ -1755,6 +1757,23 @@ Release Date 07 July 2025
17551757

17561758
15. More examples are created.
17571759

1760+
16. Edited the ``sort_solutions_nsga2()`` method in the
1761+
``pygad/utils/nsga2.py`` script to accept an optional parameter
1762+
called ``find_best_solution`` when calling this method just to find
1763+
the best solution.
1764+
1765+
17. Fixed a bug while applying the non-dominated sorting in the
1766+
``get_non_dominated_set()`` method inside the
1767+
``pygad/utils/nsga2.py`` script. It was swapping the non-dominated
1768+
and dominated sets. In other words, it used the non-dominated set as
1769+
if it is the dominated set and vice versa. All the calls to this
1770+
method were edited accordingly.
1771+
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/320.
1772+
1773+
18. Fix a bug retrieving in the ``best_solution()`` method when
1774+
retrieving the best solution for multi-objective problems.
1775+
https://github.com/ahmedfgad/GeneticAlgorithmPython/pull/331
1776+
17581777
PyGAD Projects at GitHub
17591778
========================
17601779

example_multi_objective.py

Lines changed: 0 additions & 65 deletions
This file was deleted.

pygad/pygad.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,17 +2237,13 @@ def best_solution(self, pop_fitness=None):
22372237
pop_fitness == numpy.max(pop_fitness))[0][0]
22382238
elif pop_fitness_arr.ndim == 2:
22392239
# Multi-objective optimization.
2240-
# Sort by all objectives in descending order.
2241-
# The first objective is the most important, then the second, etc.
2242-
sorted_indices = numpy.lexsort([ -pop_fitness_arr[:,i] for i in reversed(range(pop_fitness_arr.shape[1])) ])
2243-
best_match_idx = sorted_indices[0]
2244-
maximum_fitness_value = pop_fitness_arr[best_match_idx]
2245-
2246-
best_match_list = numpy.where(
2247-
pop_fitness == maximum_fitness_value)
2248-
2249-
best_match_idx = best_match_list[0][0] # Get the first index of the best match.
2240+
# Use NSGA-2 to sort the solutions using the fitness.
2241+
# Set find_best_solution=True to avoid overriding the pareto_fronts instance attribute.
2242+
best_match_list = self.sort_solutions_nsga2(fitness=pop_fitness,
2243+
find_best_solution=True)
22502244

2245+
# Get the first index of the best match.
2246+
best_match_idx = best_match_list[0]
22512247

22522248
best_solution = self.population[best_match_idx, :].copy()
22532249
best_solution_fitness = pop_fitness[best_match_idx]

0 commit comments

Comments
 (0)