Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 990f1a1

Browse files
PyGAD 3.3.1
Release Date 17 February 2024 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 fitness `last_generation_fitness`. #275 2. 4 methods with names starting with `run_`. Their purpose is to keep the main loop inside the `run()` method clean. Check the [Other Methods](https://pygad.readthedocs.io/en/latest/pygad.html#other-methods) section for more information.
1 parent eae41c0 commit 990f1a1

File tree

3 files changed

+71
-41
lines changed

3 files changed

+71
-41
lines changed

‎docs/source/pygad.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,12 @@ Other Methods
610610
from inside the ``run()`` method. Supported in `PyGAD
611611
3.3.1 <https://pygad.readthedocs.io/en/latest/releases.html#pygad-3-3-1>`__.
612612

613-
1. ``run_select_parents()``: Select the parents and call the callable
614-
``on_parents()`` if defined.
613+
1. ``run_select_parents(call_on_parents=True)``: Select the parents
614+
and call the callable ``on_parents()`` if defined. If
615+
``call_on_parents`` is ``True``, then the callable
616+
``on_parents()`` is called. It must be ``False`` when the
617+
``run_select_parents()`` method is called to update the parents at
618+
the end of the ``run()`` method.
615619

616620
2. ``run_crossover()``: Apply crossover and call the callable
617621
``on_crossover()`` if defined.

‎docs/source/releases.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,25 @@ Release Date 29 January 2024
15321532
self.best_solution_generation = numpy.where(numpy.array(
15331533
self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0]
15341534
1535+
.. _pygad-331:
1536+
1537+
PyGAD 3.3.1
1538+
-----------
1539+
1540+
Release Date 17 February 2024
1541+
1542+
1. After the last generation and before the ``run()`` method completes,
1543+
update the 2 instance attributes: 1) ``last_generation_parents`` 2)
1544+
``last_generation_parents_indices``. This is to keep the list of
1545+
parents up-to-date with the latest population fitness
1546+
``last_generation_fitness``.
1547+
https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/275
1548+
1549+
2. 4 methods with names starting with ``run_``. Their purpose is to keep
1550+
the main loop inside the ``run()`` method clean. Check the `Other
1551+
Methods <https://pygad.readthedocs.io/en/latest/pygad.html#other-methods>`__
1552+
section for more information.
1553+
15351554
PyGAD Projects at GitHub
15361555
========================
15371556

‎pygad/pygad.py

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,7 +2067,8 @@ def run(self):
20672067

20682068
# Call the run_select_parents() method to update these 2 attributes according to the 'last_generation_fitness' attribute:
20692069
# 1) last_generation_parents 2) last_generation_parents_indices
2070-
self.run_select_parents()
2070+
# Set 'call_on_parents=False' to avoid calling the callable 'on_parents' because this step is not part of the cycle.
2071+
self.run_select_parents(call_on_parents=False)
20712072

20722073
# Save the fitness value of the best solution.
20732074
_, best_solution_fitness, _ = self.best_solution(
@@ -2093,7 +2094,7 @@ def run(self):
20932094
# sys.exit(-1)
20942095
raise ex
20952096

2096-
def run_select_parents(self):
2097+
def run_select_parents(self, call_on_parents=True):
20972098
"""
20982099
This method must be only callled from inside the run() method. It is not meant for use by the user.
20992100
Generally, any method with a name starting with 'run_' is meant to be only called by PyGAD from inside the 'run()' method.
@@ -2103,6 +2104,11 @@ def run_select_parents(self):
21032104
1) last_generation_parents: A NumPy array of the selected parents.
21042105
2) last_generation_parents_indices: A 1D NumPy array of the indices of the selected parents.
21052106
2107+
Parameters
2108+
----------
2109+
call_on_parents : bool, optional
2110+
If True, then the callable 'on_parents()' is called. The default is True.
2111+
21062112
Returns
21072113
-------
21082114
None.
@@ -2133,46 +2139,47 @@ def run_select_parents(self):
21332139
elif len(self.last_generation_parents_indices) != self.num_parents_mating:
21342140
raise ValueError(f"The iterable holding the selected parents indices is expected to have ({self.num_parents_mating}) values but ({len(self.last_generation_parents_indices)}) found.")
21352141

2136-
if not (self.on_parents is None):
2137-
on_parents_output = self.on_parents(self,
2138-
self.last_generation_parents)
2139-
2140-
if on_parents_output is None:
2141-
pass
2142-
elif type(on_parents_output) in [list, tuple, numpy.ndarray]:
2143-
if len(on_parents_output) == 2:
2144-
on_parents_selected_parents, on_parents_selected_parents_indices = on_parents_output
2145-
else:
2146-
raise ValueError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray of length 2 but {type(on_parents_output)} of length {len(on_parents_output)} found.")
2147-
2148-
# Validate the parents.
2149-
if on_parents_selected_parents is None:
2150-
raise ValueError("The returned outputs of on_parents() cannot be None but the first output is None.")
2151-
else:
2152-
if type(on_parents_selected_parents) in [tuple, list, numpy.ndarray]:
2153-
on_parents_selected_parents = numpy.array(on_parents_selected_parents)
2154-
if on_parents_selected_parents.shape == self.last_generation_parents.shape:
2155-
self.last_generation_parents = on_parents_selected_parents
2156-
else:
2157-
raise ValueError(f"Size mismatch between the parents retrned by on_parents() {on_parents_selected_parents.shape} and the expected parents shape {self.last_generation_parents.shape}.")
2142+
if call_on_parents:
2143+
if not (self.on_parents is None):
2144+
on_parents_output = self.on_parents(self,
2145+
self.last_generation_parents)
2146+
2147+
if on_parents_output is None:
2148+
pass
2149+
elif type(on_parents_output) in [list, tuple, numpy.ndarray]:
2150+
if len(on_parents_output) == 2:
2151+
on_parents_selected_parents, on_parents_selected_parents_indices = on_parents_output
21582152
else:
2159-
raise ValueError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray but the first output type is {type(on_parents_selected_parents)}.")
2160-
2161-
# Validate the parents indices.
2162-
if on_parents_selected_parents_indices is None:
2163-
raise ValueError("The returned outputs of on_parents() cannot be None but the second output is None.")
2164-
else:
2165-
if type(on_parents_selected_parents_indices) in [tuple, list, numpy.ndarray, range]:
2166-
on_parents_selected_parents_indices = numpy.array(on_parents_selected_parents_indices)
2167-
if on_parents_selected_parents_indices.shape == self.last_generation_parents_indices.shape:
2168-
self.last_generation_parents_indices = on_parents_selected_parents_indices
2153+
raise ValueError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray of length 2 but {type(on_parents_output)} of length {len(on_parents_output)} found.")
2154+
2155+
# Validate the parents.
2156+
if on_parents_selected_parents is None:
2157+
raise ValueError("The returned outputs of on_parents() cannot be None but the first output is None.")
2158+
else:
2159+
if type(on_parents_selected_parents) in [tuple, list, numpy.ndarray]:
2160+
on_parents_selected_parents = numpy.array(on_parents_selected_parents)
2161+
if on_parents_selected_parents.shape == self.last_generation_parents.shape:
2162+
self.last_generation_parents = on_parents_selected_parents
2163+
else:
2164+
raise ValueError(f"Size mismatch between the parents retrned by on_parents() {on_parents_selected_parents.shape} and the expected parents shape {self.last_generation_parents.shape}.")
21692165
else:
2170-
raise ValueError(f"Size mismatch between the parents indices returned by on_parents() {on_parents_selected_parents_indices.shape} and the expected crossover output {self.last_generation_parents_indices.shape}.")
2166+
raise ValueError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray but the first output type is {type(on_parents_selected_parents)}.")
2167+
2168+
# Validate the parents indices.
2169+
if on_parents_selected_parents_indices is None:
2170+
raise ValueError("The returned outputs of on_parents() cannot be None but the second output is None.")
21712171
else:
2172-
raise ValueError(f"The output of on_parents() is expected to be tuple/list/range/numpy.ndarray but the second output type is {type(on_parents_selected_parents_indices)}.")
2173-
2174-
else:
2175-
raise TypeError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray but {type(on_parents_output)} found.")
2172+
if type(on_parents_selected_parents_indices) in [tuple, list, numpy.ndarray, range]:
2173+
on_parents_selected_parents_indices = numpy.array(on_parents_selected_parents_indices)
2174+
if on_parents_selected_parents_indices.shape == self.last_generation_parents_indices.shape:
2175+
self.last_generation_parents_indices = on_parents_selected_parents_indices
2176+
else:
2177+
raise ValueError(f"Size mismatch between the parents indices returned by on_parents() {on_parents_selected_parents_indices.shape} and the expected crossover output {self.last_generation_parents_indices.shape}.")
2178+
else:
2179+
raise ValueError(f"The output of on_parents() is expected to be tuple/list/range/numpy.ndarray but the second output type is {type(on_parents_selected_parents_indices)}.")
2180+
2181+
else:
2182+
raise TypeError(f"The output of on_parents() is expected to be tuple/list/numpy.ndarray but {type(on_parents_output)} found.")
21762183

21772184
def run_crossover(self):
21782185
"""

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /