Repository navigation
Conversation
get_non_dominated_set built a new numpy array from zip() for every pair of solutions and called .all()/.any() on it. The fitness vectors are tiny, so this cost far more than the comparison itself. When all fitness vectors are 1D numeric numpy arrays of the same dtype and shape, convert them to lists once and compare them with plain Python. non_dominated_sorting calls this function once per front, so it gets faster too. Output (pair objects and order) is unchanged; other inputs keep the old loop. Multi-objective GA workload: 58.90 ms -> 21.99 ms (62.7% faster). Co-Authored-By: Aiden <aiden@weco.ai>
📊 Change summary1 files changed · +40 / −0 lines pie showData
title Lines changed per file (40 total)
"pygad/utils/nsga.py" : 40
Per-file breakdown
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
NSGA.get_non_dominated_setinpygad/utils/nsga.pyfaster.non_dominated_sortingcalls it for every front, so it gets faster too.What & Why
Before,
get_non_dominated_setchecked every pair of solutions. For each pair it built a new numpy array fromzip(). Then it called.all()and.any()on two more arrays. The fitness vectors are short, so this numpy work cost much more than the comparison itself.non_dominated_sortingalso called this loop once for each Pareto front.Now, when all fitness vectors are 1D numeric numpy arrays of the same dtype and shape, the code converts each vector to a list once. Then it compares the lists with plain Python. Solution
jdominates solutioniwhen all values ofjare>=and the two rows are not equal. This is the same rule as before: "all>=and any>".non_dominated_sortingcalls this function once per front, so it gets faster too. The same pair objects go into the same lists in the same order. Other inputs still use the old loop.Results
Times are per call, best of 7 runs, one CPU core.
test_adaptive_mutation_mutation_probability_multi_objective(10 solutions, 2 objectives)non_dominated_sorting, 50 solutions x 2 objectivesnon_dominated_sorting, 200 solutions x 3 objectivesget_non_dominated_set, fitness vectors are Python lists (old loop is used)get_non_dominated_set, 1 solution (old loop is used)Why this is safe and easy to maintain
The change is small and stays inside
get_non_dominated_set. The new path is a short double loop with one clear domination test. It returns the same pair objects in the same order. The old loop stays for all other inputs. The NSGA-III tests, the adaptive mutation tests and the save solutions tests cover this code.Validation
pygad.GAruns that copytest_adaptive_mutation_mutation_probability_multi_objective, plus 13 directnon_dominated_sortingcalls with ties, duplicates, int fitness and one objective. Before 58.90 ms, after 21.99 ms (3 repeat runs: 0.378, 0.353, 0.388 of the old time). The output was checked to be identical to the unmodified code.python -m pytest -q tests/test_adaptive_mutation.py tests/test_save_solutions.py tests/test_gene_space.py tests/test_gene_space_allow_duplicate_genes.py tests/test_nsga3.py tests/test_nsga3_dtlz2.py tests/test_nsga3_pipeline.py tests/test_nsga3_population_growth.py-> 596 passed (same as onmaster).AI assistance
The code change was generated by Codex (gpt-6.1-sol) candidates and tracked with Weco Observe. Each candidate was timed and its output was compared with the original code by an automated benchmark harness. The tests were run on the final patch.
Weco share link: https://dashboard.weco.ai/share/PYAiMz5MRfbwe0rWTcdOuZYmr0ssct2v