You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -62,13 +62,7 @@ It is OK to set the value of any of the 2 parameters `init_range_low` and `init_
62
62
63
63
If the 2 parameters `mutation_type` and `crossover_type` are `None`, this disables any type of evolution the genetic algorithm can make. As a result, the genetic algorithm cannot find a better solution that the best solution in the initial population.
64
64
65
-
The parameters are validated within the constructor. If at least a parameter is not correct, an exception is thrown.
66
-
67
-
## Plotting Methods in `pygad.GA` Class
68
-
69
-
-`plot_fitness()`: Shows how the fitness evolves by generation.
70
-
-`plot_genes()`: Shows how the gene value changes for each generation.
71
-
-`plot_new_solution_rate()`: Shows the number of new solutions explored in each solution.
65
+
The parameters are validated by calling the `validate_parameters()` method of the `utils.validation.Validation` class within the constructor. If at least a parameter is not correct, an exception is thrown and the `valid_parameters` attribute is set to `False`.
72
66
73
67
## Class Attributes
74
68
@@ -115,215 +109,20 @@ Note that the attributes with names starting with `last_generation_` are updated
115
109
-`select_parents()`: Refers to a method that selects the parents based on the parent selection type specified in the `parent_selection_type` attribute.
116
110
-`adaptive_mutation_population_fitness()`: Returns the average fitness value used in the adaptive mutation to filter the solutions.
117
111
-`summary()`: Prints a Keras-like summary of the PyGAD lifecycle. This helps to have an overview of the architecture. Supported in [PyGAD 2.19.0](https://pygad.readthedocs.io/en/latest/releases.html#pygad-2-19-0). Check the [Print Lifecycle Summary](https://pygad.readthedocs.io/en/latest/pygad_more.html#print-lifecycle-summary) section for more details and examples.
118
-
- 4 methods with names starting with `run_`. Their purpose is to keep the main loop inside the `run()` method clean. The details inside the loop are moved to 4 individual methods. Generally, any method with a name starting with `run_` is meant to be called by PyGAD from inside the `run()` method. Supported in [PyGAD 3.3.1](https://pygad.readthedocs.io/en/latest/releases.html#pygad-3-3-1).
119
-
1.`run_select_parents(call_on_parents=True)`: Select the parents and call the callable `on_parents()` if defined. If `call_on_parents` is `True`, then the callable `on_parents()` is called. It must be `False` when the `run_select_parents()` method is called to update the parents at the end of the `run()` method.
120
-
2.`run_crossover()`: Apply crossover and call the callable `on_crossover()` if defined.
121
-
3.`run_mutation()`: Apply mutation and call the callable `on_mutation()` if defined.
122
-
4.`run_update_population()`: Update the `population` attribute after completing the processes of crossover and mutation.
112
+
- 5 methods with names starting with `run_`. Their purpose is to keep the main loop inside the `run()` method clean. The details inside the loop are moved to 4 individual methods. Generally, any method with a name starting with `run_` is meant to be called by PyGAD from inside the `run()` method. Supported in [PyGAD 3.3.1](https://pygad.readthedocs.io/en/latest/releases.html#pygad-3-3-1).
113
+
1.`run_loop_head()`: The code before the loop starts.
114
+
2.`run_select_parents(call_on_parents=True)`: Select the parents and call the callable `on_parents()` if defined. If `call_on_parents` is `True`, then the callable `on_parents()` is called. It must be `False` when the `run_select_parents()` method is called to update the parents at the end of the `run()` method.
115
+
3.`run_crossover()`: Apply crossover and call the callable `on_crossover()` if defined.
116
+
4.`run_mutation()`: Apply mutation and call the callable `on_mutation()` if defined.
117
+
5.`run_update_population()`: Update the `population` attribute after completing the processes of crossover and mutation.
123
118
124
119
There are many methods that are not designed for user usage. Some of them are listed above but this is not a comprehensive list. The [release history](https://pygad.readthedocs.io/en/latest/releases.html) section usually covers them. Moreover, you can check the [PyGAD GitHub repository](https://github.com/ahmedfgad/GeneticAlgorithmPython) to find more.
125
120
126
121
The next sections discuss the methods available in the `pygad.GA` class.
127
122
128
-
## `initialize_population()`
129
-
130
-
It creates an initial population randomly as a NumPy array. The array is saved in the instance attribute named `population`.
131
-
132
-
Accepts the following parameters:
133
-
134
-
-`low`: The lower value of the random range from which the gene values in the initial population are selected. It defaults to -4. Available in PyGAD 1.0.20 and higher.
135
-
-`high`: The upper value of the random range from which the gene values in the initial population are selected. It defaults to -4. Available in PyGAD 1.0.20.
136
-
137
-
This method assigns the values of the following 3 instance attributes:
138
-
139
-
1.`pop_size`: Size of the population.
140
-
2.`population`: Initially, it holds the initial population and later updated after each generation.
141
-
3.`initial_population`: Keeping the initial population.
142
-
143
-
## `cal_pop_fitness()`
144
-
145
-
The `cal_pop_fitness()` method calculates and returns the fitness values of the solutions in the current population.
146
-
147
-
This function is optimized to save time by making fewer calls the fitness function. It follows this process:
148
-
149
-
1. If the `save_solutions` parameter is set to `True`, then it checks if the solution is already explored and saved in the `solutions` instance attribute. If so, then it just retrieves its fitness from the `solutions_fitness` instance attribute without calling the fitness function.
150
-
2. If `save_solutions` is set to `False` or if it is `True` but the solution was not explored yet, then the `cal_pop_fitness()` method checks if the `keep_elitism` parameter is set to a positive integer. If so, then it checks if the solution is saved into the `last_generation_elitism` instance attribute. If so, then it retrieves its fitness from the `previous_generation_fitness` instance attribute.
151
-
3. If neither of the above 3 conditions apply (1. `save_solutions` is set to `False` or 2. if it is `True` but the solution was not explored yet or 3. `keep_elitism` is set to zero), then the `cal_pop_fitness()` method checks if the `keep_parents` parameter is set to `-1` or a positive integer. If so, then it checks if the solution is saved into the `last_generation_parents` instance attribute. If so, then it retrieves its fitness from the `previous_generation_fitness` instance attribute.
152
-
4. If neither of the above 4 conditions apply, then we have to call the fitness function to calculate the fitness for the solution. This is by calling the function assigned to the `fitness_func` parameter.
153
-
154
-
This function takes into consideration:
155
-
156
-
1. The `parallel_processing` parameter to check whether parallel processing is in effect.
157
-
2. The `fitness_batch_size` parameter to check if the fitness should be calculated in batches of solutions.
158
-
159
-
It returns a vector of the solutions' fitness values.
160
-
161
-
## `run()`
162
-
163
-
Runs the genetic algorithm. This is the main method in which the genetic algorithm is evolved through some generations. It accepts no parameters as it uses the instance to access all of its requirements.
164
-
165
-
For each generation, the fitness values of all solutions within the population are calculated according to the `cal_pop_fitness()` method which internally just calls the function assigned to the `fitness_func` parameter in the `pygad.GA` class constructor for each solution.
166
-
167
-
According to the fitness values of all solutions, the parents are selected using the `select_parents()` method. This method behaviour is determined according to the parent selection type in the `parent_selection_type` parameter in the `pygad.GA` class constructor
168
-
169
-
Based on the selected parents, offspring are generated by applying the crossover and mutation operations using the `crossover()` and `mutation()` methods. The behaviour of such 2 methods is defined according to the `crossover_type` and `mutation_type` parameters in the `pygad.GA` class constructor.
170
-
171
-
After the generation completes, the following takes place:
172
-
173
-
- The `population` attribute is updated by the new population.
174
-
- The `generations_completed` attribute is assigned by the number of the last completed generation.
175
-
- If there is a callback function assigned to the `on_generation` attribute, then it will be called.
176
-
177
-
After the `run()` method completes, the following takes place:
178
-
179
-
- The `best_solution_generation` is assigned the generation number at which the best fitness value is reached.
180
-
- The `run_completed` attribute is set to `True`.
181
-
182
-
## Parent Selection Methods
183
-
184
-
The `ParentSelection` class in the `pygad.utils.parent_selection` module has several methods for selecting the parents that will mate to produce the offspring. All of such methods accept the same parameters which are:
185
-
186
-
*`fitness`: The fitness values of the solutions in the current population.
187
-
*`num_parents`: The number of parents to be selected.
188
-
189
-
All of such methods return an array of the selected parents.
190
-
191
-
The next subsections list the supported methods for parent selection.
192
-
193
-
### `steady_state_selection()`
194
-
195
-
Selects the parents using the steady-state selection technique.
196
-
197
-
### `rank_selection()`
198
-
199
-
Selects the parents using the rank selection technique.
200
-
201
-
### `random_selection()`
202
-
203
-
Selects the parents randomly.
204
-
205
-
### `tournament_selection()`
206
-
207
-
Selects the parents using the tournament selection technique.
208
-
209
-
### `roulette_wheel_selection()`
210
-
211
-
Selects the parents using the roulette wheel selection technique.
212
-
213
-
### `stochastic_universal_selection()`
214
-
215
-
Selects the parents using the stochastic universal selection technique.
216
-
217
-
### `nsga2_selection()`
218
-
219
-
Selects the parents for the NSGA-II algorithm to solve multi-objective optimization problems. It selects the parents by ranking them based on non-dominated sorting and crowding distance.
220
-
221
-
### `tournament_selection_nsga2()`
222
-
223
-
Selects the parents for the NSGA-II algorithm to solve multi-objective optimization problems. It selects the parents using the tournament selection technique applied based on non-dominated sorting and crowding distance.
224
-
225
-
## Crossover Methods
226
-
227
-
The `Crossover` class in the `pygad.utils.crossover` module supports several methods for applying crossover between the selected parents. All of these methods accept the same parameters which are:
228
-
229
-
*`parents`: The parents to mate for producing the offspring.
230
-
*`offspring_size`: The size of the offspring to produce.
231
-
232
-
All of such methods return an array of the produced offspring.
233
-
234
-
The next subsections list the supported methods for crossover.
235
-
236
-
### `single_point_crossover()`
237
-
238
-
Applies the single-point crossover. It selects a point randomly at which crossover takes place between the pairs of parents.
239
-
240
-
### `two_points_crossover()`
241
-
242
-
Applies the 2 points crossover. It selects the 2 points randomly at which crossover takes place between the pairs of parents.
243
-
244
-
### `uniform_crossover()`
245
-
246
-
Applies the uniform crossover. For each gene, a parent out of the 2 mating parents is selected randomly and the gene is copied from it.
247
-
248
-
### `scattered_crossover()`
249
-
250
-
Applies the scattered crossover. It randomly selects the gene from one of the 2 parents.
251
-
252
-
## Mutation Methods
253
-
254
-
The `Mutation` class in the `pygad.utils.mutation` module supports several methods for applying mutation. All of these methods accept the same parameter which is:
255
-
256
-
*`offspring`: The offspring to mutate.
257
-
258
-
All of such methods return an array of the mutated offspring.
259
-
260
-
The next subsections list the supported methods for mutation.
261
-
262
-
### `random_mutation()`
263
-
264
-
Applies the random mutation which changes the values of some genes randomly. The number of genes is specified according to either the `mutation_num_genes` or the `mutation_percent_genes` attributes.
265
-
266
-
For each gene, a random value is selected according to the range specified by the 2 attributes `random_mutation_min_val` and `random_mutation_max_val`. The random value is added to the selected gene.
267
-
268
-
### `swap_mutation()`
269
-
270
-
Applies the swap mutation which interchanges the values of 2 randomly selected genes.
271
-
272
-
### `inversion_mutation()`
273
-
274
-
Applies the inversion mutation which selects a subset of genes and inverts them.
275
-
276
-
### `scramble_mutation()`
277
-
278
-
Applies the scramble mutation which selects a subset of genes and shuffles their order randomly.
279
-
280
-
### `adaptive_mutation()`
281
-
282
-
Applies the adaptive mutation which selects the number/percentage of genes to mutate based on the solution's fitness. If the fitness is high (i.e. solution quality is high), then small number/percentage of genes is mutated compared to a solution with a low fitness.
283
-
284
-
## `best_solution()`
285
-
286
-
Returns information about the best solution found by the genetic algorithm.
287
-
288
-
It accepts the following parameters:
289
-
290
-
*`pop_fitness=None`: An optional parameter that accepts a list of the fitness values of the solutions in the population. If `None`, then the `cal_pop_fitness()` method is called to calculate the fitness values of the population.
291
-
292
-
It returns the following:
293
-
294
-
*`best_solution`: Best solution in the current population.
295
-
296
-
*`best_solution_fitness`: Fitness value of the best solution.
297
-
298
-
*`best_match_idx`: Index of the best solution in the current population.
299
-
300
-
## `plot_fitness()`
301
-
302
-
Previously named `plot_result()`, this method creates, shows, and returns a figure that summarizes how the fitness value evolves by generation.
303
-
304
-
It works only after completing at least 1 generation. If no generation is completed (at least 1), an exception is raised.
305
-
306
-
## `plot_new_solution_rate()`
307
-
308
-
The `plot_new_solution_rate()` method creates, shows, and returns a figure that shows the number of new solutions explored in each generation. This method works only when `save_solutions=True` in the constructor of the `pygad.GA` class.
309
-
310
-
It works only after completing at least 1 generation. If no generation is completed (at least 1), an exception is raised.
311
-
312
-
## `plot_genes()`
313
-
314
-
The `plot_genes()` method creates, shows, and returns a figure that describes each gene. It has different options to create the figures which helps to:
315
-
316
-
1. Explore the gene value for each generation by creating a normal plot.
317
-
2. Create a histogram for each gene.
318
-
3. Create a boxplot.
319
-
320
-
This is controlled by the `graph_type` parameter.
321
-
322
-
It works only after completing at least 1 generation. If no generation is completed (at least 1), an exception is raised.
323
-
324
123
## `save()`
325
124
326
-
Saves the genetic algorithm instance
125
+
The `save()` method in the `pygad.GA` class saves the genetic algorithm instance as a pickled object.
327
126
328
127
Accepts the following parameter:
329
128
@@ -343,6 +142,33 @@ Accepts the following parameter:
343
142
344
143
Returns the genetic algorithm instance.
345
144
145
+
# Extended Classes
146
+
147
+
To make the library modular and structured, different scripts are created where each script has one or more classes. Each class has its own objective.
148
+
149
+
This is the list of scripts and classes within them where the `pygad.GA` class extends:
150
+
151
+
1.`utils/engine.py`:
152
+
1.`utils.engine.GAEngine`:
153
+
2.`utils/validation.py`
154
+
1.`utils.validation.Validation`
155
+
3.`utils/parent_selection.py`
156
+
1.`utils.parent_selection.ParentSelection`
157
+
4.`utils/crossover.py`
158
+
1.`utils.crossover.Crossover`
159
+
5.`utils/mutation.py`
160
+
1.`utils.mutation.Mutation`
161
+
6.`utils/nsga2.py`
162
+
1.`utils.nsga2.NSGA2`
163
+
7.`helper/unique.py`
164
+
1.`helper.unique.Unique`
165
+
8.`helper/misc.py`
166
+
1.`helper.misc.Helper`
167
+
9.`visualize/plot.py`
168
+
1.`visualize.plot.Plot`
169
+
170
+
Since the `pygad.GA` class extends such classes, the attributes and methods inside them can be retrieved by instances of the `pygad.GA` class.
171
+
346
172
# Steps to Use `pygad`
347
173
348
174
To use the `pygad` module, here is a summary of the required steps:
Copy file name to clipboardExpand all lines: docs/md/releases.md
+17-11Lines changed: 17 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -552,7 +552,13 @@ Release Date 29 January 2024
552
552
Release Date 17 February 2024
553
553
554
554
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`. https://github.com/ahmedfgad/GeneticAlgorithmPython/issues/275
555
-
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.
555
+
2. 5 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.
556
+
1.`run_loop_head()`: The code before the loop starts.
557
+
2.`run_select_parents()`: The parent selection-related code.
558
+
3.`run_crossover()`: The crossover-related code.
559
+
4.`run_mutation()`: The mutation-related code.
560
+
5.`run_update_population()`: Update the `population` instance attribute after completing the processes of crossover and mutation.
561
+
556
562
557
563
## PyGAD 3.4.0
558
564
@@ -616,16 +622,16 @@ Release Date 08 July 2025
616
622
4. The `summary()` method was moved to `Helper` class in the `pygad/helper/misc.py` script.
617
623
5. The validation code in the `__init__()` method of the `pygad.GA` class is moved to the new `validate_parameters()` method in the new `Validation` class in the new `pygad/utils/validation.py` script. Moreover, the `validate_multi_stop_criteria()` method is also moved to the same class.
618
624
6. The GA main workflow is moved into the new `GAEngine` class in the new `pygad/utils/engine.py` script. Specifically, these methods are moved from the `pygad.GA` class to the new `GAEngine` class:
619
-
1. run()
620
-
2. run_loop_head()
621
-
3. run_select_parents()
622
-
4. run_crossover()
623
-
5. run_mutation()
624
-
6. run_update_population()
625
-
7. initialize_population()
626
-
8. cal_pop_fitness()
627
-
9. best_solution()
628
-
10. round_genes()
625
+
1. `run()`
626
+
1. `run_loop_head()`
627
+
2. `run_select_parents()`
628
+
3. `run_crossover()`
629
+
4. `run_mutation()`
630
+
5. `run_update_population()`
631
+
2. `initialize_population()`
632
+
3. `cal_pop_fitness()`
633
+
4. `best_solution()`
634
+
5. `round_genes()`
629
635
7. The `pygad.GA` class now extends the two new classes `utils.validation.Validation` and `utils.engine.GAEngine`.
630
636
8. The version of the `pygad.utils` submodule is upgraded from `1.3.0` to `1.4.0`.
631
637
9. The version of the `pygad.helper` submodule is upgraded from `1.2.0` to `1.3.0`.
0 commit comments