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
Copy file name to clipboardExpand all lines: docs/source/releases.md
+9-1Lines changed: 9 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -690,4 +690,12 @@ Release Date ..., 2026
690
690
22. Two new example folders under `/examples`: `examples/benchmarks/` has one runnable example per benchmark (classic, ZDT, DTLZ, knapsack, and TSP), and `examples/quality_indicators/` has one runnable example per quality indicator (hypervolume, IGD, GD, and spacing).
691
691
23.`plot_pareto_front_curve()` now also supports 3 objectives (3D scatter). M >= 4 still raises and points to the new high-dimensional plots.
692
692
24. Seven new plot methods on `pygad.GA`. The first three work on the final population (no extra flag needed): `plot_pareto_front_pcp()` (parallel coordinates, any M >= 2), `plot_pareto_front_scatter_matrix()` (M-by-M pairwise scatter, best for M >= 4), and `plot_pareto_front_heatmap()` (solutions-by-objectives heatmap). The other four require `save_solutions=True`: `plot_fitness_band()` (per-generation min / mean / max with a shaded band), `plot_non_dominated_hypervolume()` (hypervolume of the non-dominated set per generation), `plot_population_diversity()` (mean pairwise distance per generation), and `plot_pareto_front_evolution()` (non-dominated set overlaid every k generations).
693
-
25. Fix a latent divide-by-zero in `NSGA3.normalise_fitness()`. The safeguard for near-zero denominators used to collapse to `0` for tiny negative values (the realistic case under PyGAD-max), which silently produced wrong normalised values. The safeguard now keeps the negative sign.
693
+
25. Fix a latent divide-by-zero in `NSGA3.nsga3_normalize_fitness()`. The safeguard for near-zero denominators used to collapse to `0` for tiny negative values (the realistic case under PyGAD-max), which silently produced wrong normalized values. The safeguard now keeps the negative sign.
694
+
26. Refactor the NSGA classes to keep each script focused. A new module `pygad/utils/nsga.py` hosts the `NSGA` mixin with `non_dominated_sorting()` and `get_non_dominated_set()`, which are shared between NSGA-II and NSGA-III. `nsga2.py` now only carries NSGA-II specific code (`crowding_distance`, `sort_solutions_nsga2`). `nsga3.py` now only carries the NSGA-III algorithm primitives. The `nsga3_selection()` and `tournament_selection_nsga3()` methods have moved to `pygad/utils/parent_selection.py` next to their NSGA-II counterparts. The engine-time helpers `_bootstrap_nsga3_reference_points()`, `_nsga3_grow_population()`, `_nsga3_generate_extra_random_solutions()`, and `_nsga3_generate_single_random_gene()` now live in `pygad/utils/engine.py`.
695
+
27. Rename NSGA-III novel names to start with `nsga3_` so the algorithm-specific surface is easy to spot. Algorithm primitives become `nsga3_generate_reference_points`, `nsga3_compute_ideal_point`, `nsga3_find_extreme_points`, `nsga3_compute_intercepts`, `nsga3_normalize_fitness`, `nsga3_associate_to_reference_points`, and `nsga3_niching_select`. Module-level helpers gain the same prefix (`_nsga3_pick_target_reference_point`, `_nsga3_pick_candidate_at_reference`, `_nsga3_enumerate_compositions`, `_nsga3_validate_multi_objective_fitness`, `_nsga3_accumulate_fronts`). The constants are renamed `NSGA3_ASF_EPSILON` and `NSGA3_INTERCEPT_NEAR_ZERO`. Names that already had NSGA-II parallels (`tournament_selection_nsga3`, `pareto_fronts`, `non_dominated_sorting`) keep their original spelling.
696
+
28. Spell every name and docstring in American English (`normalize`, `maximize`, `behavior`, `color`, `optimization`, ...) so the library stays consistent.
697
+
29. Expand abbreviated names introduced by the NSGA-III refactor: `fl_indices` to `critical_front_indices`, `fl_assoc` to `critical_front_associations`, `fl_dist` to `critical_front_distances`, `st_indices` to `selection_pool_indices`, `st_fitness` to `selection_pool_fitness`, `accepted_assoc` to `accepted_associations`, `K` to `num_to_select` (in `nsga3_niching_select`).
698
+
30. The NSGA-III population auto-growth path now respects every initial-population rule: `init_range_low`/`init_range_high`, `gene_space`, `gene_type` (single dtype or nested per-gene `[type, precision]`), `gene_constraint`, and `allow_duplicate_genes=False`. Previously, only the gene-space / init-range sampling step was applied; gene constraints and duplicate resolution were skipped, which could leave the grown rows in an invalid state.
699
+
31. A new `Report` mixin in `pygad/utils/report.py` adds `ga_instance.generate_report(filename, ...)` to build a PDF report of the run. The report bundles a configuration table, a run-summary table, the best solution, and every applicable plot (auto-selected based on the run's properties: SOO vs MOO, number of objectives, `save_solutions`, `save_best_solutions`). The report uses `reportlab` and `matplotlib`, both available through the new optional dependency extra `pip install pygad[report]`.
700
+
32. A new example `examples/example_generate_report.py` shows how to build a PDF report after running a multi-objective GA.
701
+
33. The `pygad.md`, `releases.md`, `visualize.md`, and `utils.md` documentation pages were updated to reflect the new module layout, the renamed methods, the new `generate_report()` entry point, and the new NSGA-III instance attributes (`nsga3_num_divisions`, `nsga3_reference_points`). The "Other Instance Attributes & Methods" section in `pygad.md` is now grouped by area (Lifecycle, Population, Fitness, Parent Selection, NSGA-II, NSGA-III, Crossover, Mutation, Elitism, Gene Constraints, Saving) so each method or attribute appears under its topic.
Copy file name to clipboardExpand all lines: docs/source/utils.md
+33-16Lines changed: 33 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -320,28 +320,45 @@ Selects the parents for the NSGA-III algorithm to solve multi-objective optimiza
320
320
321
321
Selects the parents for the NSGA-III algorithm to solve multi-objective optimization problems. It selects the parents using the tournament selection technique where the within-front comparison is based on the niche count (instead of the crowding distance used by `tournament_selection_nsga2()`). Requires the `nsga3_num_divisions` parameter to be set.
322
322
323
+
## `pygad.utils.nsga` Submodule
324
+
325
+
The `pygad.utils.nsga` module has a class named `NSGA` that holds the building blocks shared by NSGA-II and NSGA-III. The methods inside this class are:
326
+
327
+
1.`non_dominated_sorting()`: Returns all the Pareto fronts by applying non-dominated sorting over the solutions.
328
+
2.`get_non_dominated_set()`: Returns the two sets of non-dominated and dominated solutions from the passed solutions. The Pareto front is the non-dominated set.
329
+
323
330
## `pygad.utils.nsga2` Submodule
324
331
325
-
The `pygad.utils.nsga2` module has a class named `NSGA2` that implements NSGA-II. The methods inside this class are:
332
+
The `pygad.utils.nsga2` module has a class named `NSGA2` that implements the NSGA-II-specific primitives. The methods inside this class are:
326
333
327
-
1.`non_dominated_sorting()`: Returns all the pareto fronts by applying non-dominated sorting over the solutions.
328
-
2.`get_non_dominated_set()`: Returns the 2 sets of non-dominated solutions and dominated solutions from the passed solutions. Note that the Pareto front consists of the solutions in the non-dominated set.
329
-
3.`crowding_distance()`: Calculates the crowding distance for all solutions in the current pareto front.
330
-
4.`sort_solutions_nsga2()`: Sort the solutions. If the problem is single-objective, then the solutions are sorted by sorting the fitness values of the population. If it is multi-objective, then non-dominated sorting and crowding distance are applied to sort the solutions.
334
+
1.`crowding_distance()`: Calculates the crowding distance for all solutions in the current Pareto front.
335
+
2.`sort_solutions_nsga2()`: Sort the solutions. If the problem is single-objective, the solutions are sorted by their fitness values. If it is multi-objective, non-dominated sorting and crowding distance are applied to sort the solutions.
331
336
332
337
## `pygad.utils.nsga3` Submodule
333
338
334
-
The `pygad.utils.nsga3` module has a class named `NSGA3` that implements NSGA-III. The methods inside this class are:
335
-
336
-
1.`generate_reference_points()`: Build the structured grid of reference points on the unit simplex using the Das-Dennis (stars-and-bars) method.
337
-
2.`compute_ideal_point()`: Return the ideal point (column maximum under PyGAD's maximisation convention).
338
-
3.`find_extreme_points()`: For each objective axis, return the solution that best represents the corner of that axis based on the Achievement Scalarising Function (ASF).
339
-
4.`compute_intercepts()`: Fit a hyperplane through the M extreme points and return the per-axis intercept point used as the normalisation denominator. Falls back to the nadir (worst per objective) when the hyperplane cannot be fitted or when the intercept is degenerate.
340
-
5.`normalise_fitness()`: Scale each fitness row to the [0, 1] range using the ideal point and the intercepts.
341
-
6.`associate_to_reference_points()`: For every normalised solution, return the nearest reference index and the perpendicular distance to that reference line.
342
-
7.`niching_select()`: Pick K survivors from the critical front using niche counts and per-niche tie-breaking rules.
The `pygad.utils.nsga3` module has a class named `NSGA3` that implements the NSGA-III algorithm primitives. NSGA-III novel names start with `nsga3_` to make the algorithm surface easy to spot.
340
+
341
+
1.`nsga3_generate_reference_points()`: Build the structured grid of reference points on the unit simplex using the Das-Dennis (stars-and-bars) method.
342
+
2.`nsga3_compute_ideal_point()`: Return the ideal point (column maximum under PyGAD's maximization convention).
343
+
3.`nsga3_find_extreme_points()`: For each objective axis, return the solution that best represents the corner of that axis based on the Achievement Scalarizing Function (ASF).
344
+
4.`nsga3_compute_intercepts()`: Fit a hyperplane through the M extreme points and return the per-axis intercept point used as the normalization denominator. Falls back to the nadir (worst per objective) when the hyperplane cannot be fitted or when the intercept is degenerate.
345
+
5.`nsga3_normalize_fitness()`: Scale each fitness row to the `[0, 1]` range using the ideal point and the intercepts.
346
+
6.`nsga3_associate_to_reference_points()`: For every normalized solution, return the nearest reference index and the perpendicular distance to that reference line.
347
+
7.`nsga3_niching_select()`: Pick `num_to_select` survivors from the critical front using niche counts and per-niche tie-breaking rules.
348
+
349
+
The selection methods `nsga3_selection()` and `tournament_selection_nsga3()` live in `pygad.utils.parent_selection`. The engine-time helpers (`_bootstrap_nsga3_reference_points()`, `_nsga3_grow_population()`, `_nsga3_generate_extra_random_solutions()`, `_nsga3_generate_single_random_gene()`) live in `pygad.utils.engine`.
350
+
351
+
Two module-level constants in `pygad.utils.nsga3` control the numerical safeguards: `NSGA3_ASF_EPSILON` (default `1e-6`) and `NSGA3_INTERCEPT_NEAR_ZERO` (default `1e-12`).
352
+
353
+
## `pygad.utils.report` Submodule
354
+
355
+
The `pygad.utils.report` module has a class named `Report` that adds the `generate_report()` method to the `pygad.GA` class. It builds a PDF report of the GA run, bundling the configuration table, a run summary, the best solution, and every applicable plot. Requires the optional dependencies `reportlab` and `matplotlib`:
356
+
357
+
```
358
+
pip install pygad[report]
359
+
```
360
+
361
+
See [`generate_report()`](https://pygad.readthedocs.io/en/latest/pygad.html#generate-report) and the runnable example at [`examples/example_generate_report.py`](https://github.com/ahmedfgad/GeneticAlgorithmPython/tree/master/examples/example_generate_report.py).
Copy file name to clipboardExpand all lines: docs/source/visualize.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,7 +80,7 @@ For M=3 (NSGA-III on DTLZ2):
80
80
81
81
## `plot_pareto_front_pcp()`
82
82
83
-
Parallel-coordinates view of the final non-dominated set. Each objective is a vertical axis. Each non-dominated solution becomes a polyline that crosses every axis. Values are normalised per objective so very different scales remain comparable. Useful for any M >= 2 and especially for M >= 4.
83
+
Parallel-coordinates view of the final non-dominated set. Each objective is a vertical axis. Each non-dominated solution becomes a polyline that crosses every axis. Values are normalized per objective so very different scales remain comparable. Useful for any M >= 2 and especially for M >= 4.
Heatmap of the final non-dominated set. Rows are solutions, columns are objectives, colour is the raw objective value. Rows are sorted by objective `sort_by` (default `0`); pass `sort_by=None` to keep the original order.
107
+
Heatmap of the final non-dominated set. Rows are solutions, columns are objectives, color is the raw objective value. Rows are sorted by objective `sort_by` (default `0`); pass `sort_by=None` to keep the original order.
0 commit comments