feat(phase-12e): NSGA-II is Phase 12c (surface_fn) and 12d (forced flyover) aware#24
Merged
Merged
Conversation
…d flyover) aware
Until now the GA accepted surface_fn (Phase 12c joint H+V) and
forced_flyover_zones (Phase 12d) but NSGA-II quietly ignored them.
Anyone wanting Pareto + horizontal optimization had no path. Same for
fly-over obstacles on the multi-objective track.
multi_optimizer changes:
- _RopewayProblem takes surface_fn + forced_flyover_zones kwargs
- When cfg.corridor_half_width_m > 0 the pymoo n_var picks up the
4th per-slot gene (lateral offset) via the shared _genes_per_slot
helper from optimizer.py — keeps the GA and NSGA-II genome
layouts identical
- Decoder is now zone-aware (no_tower_zones passed in), matching the
GA's behaviour so NSGA-II never wastes evaluations on tower-in-zone
individuals
- Final alignment construction carries surface_fn and
forced_flyover_zones forward so the evaluator sees them
- optimize_pareto signature extended with both kwargs; defaults
None / [] keep all existing callers behaviourally identical
Scope note: RL env (Gymnasium RopewayRoutingEnv) is a follow-up — its
action space would need new offset gene; not in this PR. The
NSGA-II/GA parity is the high-value win.
Tests: tests/test_nsga_phase12.py — 4 new
- pure-vertical NSGA-II still produces a feasible front (no offsets)
- NSGA-II accepts surface_fn + corridor_half_width and uses the
lateral-offset gene to route around a centreline wall
- NSGA-II honours forced_flyover_zones (no fly-over violations in
the best feasible solution)
- NSGA-II honours no_tower_zones (decoder zone-awareness reaches
pymoo path)
Full suite 195 -> 203, zero regressions.
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.
Summary
Until now the GA accepted
surface_fn(Phase 12c joint H+V) andforced_flyover_zones(Phase 12d) but NSGA-II quietly ignored them. Anyone wanting Pareto + horizontal optimization had no path; same for fly-over obstacles on the multi-objective track.Changes in
multi_optimizer.py_RopewayProblemtakessurface_fn+forced_flyover_zoneskwargscfg.corridor_half_width_m > 0the pymoon_varpicks up the 4th per-slot gene (lateral offset) via the shared_genes_per_slothelper — keeps the GA and NSGA-II genome layouts identicalno_tower_zonespassed in), matching the GA's behaviour so NSGA-II never wastes evaluations on tower-in-zone individualssurface_fnandforced_flyover_zonesforward so the evaluator sees themoptimize_paretosignature extended with both kwargs; defaultsNone / []keep all existing callers behaviourally identicalScope note
RL env (Gymnasium
RopewayRoutingEnv) is a follow-up — its action space would need a new offset gene; not in this PR. The NSGA-II/GA parity is the high-value win.Test plan
tests/test_nsga_phase12.py— 4 new: pure-vertical NSGA-II unchanged, acceptssurface_fn+corridor_half_widthand uses lateral-offset gene, honoursforced_flyover_zones, honoursno_tower_zones