Skip to content

Fix VaEA worse elimination and align its selection with the reference - #42

Merged
Zhenyu2Liang merged 5 commits into
EMI-Group:mainfrom
flyingdoubleG:fix-vaea-niching
Oct 26, 2026
Merged

Zhenyu2Liang merged 5 commits into
EMI-Group:mainfrom
flyingdoubleG:fix-vaea-niching

Conversation

@flyingdoubleG

Copy link
Copy Markdown
Contributor

Description

VaEA's worse-elimination step almost never fires, which costs most of its convergence pressure. Over 200 generations with pop_size=100 (3 seeds), ZDT1 ends at IGD 0.106 / 0.148 / 0.150, against about 0.005 for NSGA-II, NSGA-III and SPEA/R under the same budget.

Worse elimination is applied to the wrong solution. In VaEA (Xiang et al., 2017, and PlatEMO's VaEA/EnvironmentalSelection.m), each niching iteration does two things:

  1. Maximum-vector-angle-first: add the remaining solution ρ with the largest minimum angle to the selected set.
  2. Worse elimination: among the solutions still remaining, take the one with the smallest minimum angle to the selected set. If it lies within π/(2(N+1)) of its nearest selected solution and converges better (smaller sum of normalized objectives), it replaces that neighbour.

The current loop runs step 2 on ρ itself. By construction, ρ has the largest minimum angle, so it is almost never within the threshold. The swap therefore essentially never happens: a better-converged solution right next to a selected one is never let in.

The selection also differs from the reference in three smaller ways, which this PR aligns as well:

  • Normalization uses S_t = F_1 ∪ … ∪ F_k, not all 2N merged solutions. Dominated solutions beyond F_k were stretching z_max.
  • When no complete front fits, the extreme solutions are the ones with the smallest angle to each axis. Previously argmin of each objective was used, which picks the solution at the opposite extreme.
  • Parents are selected uniformly at random, as in VaEA, rather than by a tournament on the sum of objectives.

Effect (IGD after 200 generations, pop_size=100, seeds 0–2, same script before and after):

before after
ZDT1 (n=30) 0.1059 / 0.1475 / 0.1497 0.0057 / 0.0054 / 0.0059
DTLZ2 (m=3, d=12) 0.0550 / 0.0559 / 0.0543 0.0542 / 0.0536 / 0.0539

For reference, a version with only the elimination fix (keeping the tournament mating and the 2N normalization) gives 0.018 / 0.063 / 0.031 on ZDT1, so all four changes contribute.

Test. test_vaea_worse_elimination builds eight mutually non-dominated solutions. Two of them, P and Q, are about 2° apart, and P converges better. The test mocks evaluate, runs one step(), and checks that P survives and Q does not.

  • Before the fix it fails: the survivors are {(0,1), (1,0), (0.3,0.75), (0.51,0.5)}, i.e. Q is kept and P is dropped.
  • With the fix it passes.

unit_test/algorithms/test_moea_generated.py also passes.

Checklist

  • I have formatted my Python code with ruff.
  • I have good commit messages.
  • If adding new algorithms, problems, operators:
    • Added related test cases.
    • Added docstring to explain important parameters.

Worse elimination compared the solution just added by maximum-vector-angle-first
with its nearest selected neighbour. That solution has the largest minimum
angle by construction, so it almost never fell within pi/(2(N+1)) and the
elimination never fired. In VaEA (and PlatEMO) it is the remaining solution
with the smallest angle to the selected set that may replace its nearest
selected neighbour.

Also follow the reference in the rest of the selection: normalize over
S_t = F_1 u ... u F_k rather than all 2N solutions, take the extreme solutions
as those closest in angle to each axis, and select parents at random.

@Zhenyu2Liang Zhenyu2Liang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing the bugs

@Zhenyu2Liang

Copy link
Copy Markdown
Collaborator

I updated the axis-extreme selection to use S_fit directly instead of norm_fit:

unit = S_fit / (torch.norm(S_fit, dim=1, keepdim=True) + 1e-6)

The worse-elimination regression test still passes on CPU and CUDA. Across seeds 0–2 with a population of 100 and 200 generations, ZDT1 results were unchanged and DTLZ2 results were nearly identical.

@Zhenyu2Liang
Zhenyu2Liang merged commit 66f2326 into EMI-Group:main Oct 26, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants