Skip to content

feat(phase-12e): NSGA-II is Phase 12c (surface_fn) and 12d (forced flyover) aware#24

Merged
harsh-pandhe merged 1 commit into
mainfrom
feat/phase-12e-nsga-rl-surface
May 20, 2026
Merged

feat(phase-12e): NSGA-II is Phase 12c (surface_fn) and 12d (forced flyover) aware#24
harsh-pandhe merged 1 commit into
mainfrom
feat/phase-12e-nsga-rl-surface

Conversation

@harsh-pandhe
Copy link
Copy Markdown
Owner

Summary

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.

Changes in multi_optimizer.py

  • _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 — 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 a new offset gene; not in this PR. The NSGA-II/GA parity is the high-value win.

Test plan

  • tests/test_nsga_phase12.py4 new: pure-vertical NSGA-II unchanged, accepts surface_fn + corridor_half_width and uses lateral-offset gene, honours forced_flyover_zones, honours no_tower_zones
  • Full suite 195 → 203 passing, zero regressions

…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.
@harsh-pandhe harsh-pandhe merged commit cf84e25 into main May 20, 2026
2 checks passed
@harsh-pandhe harsh-pandhe deleted the feat/phase-12e-nsga-rl-surface branch May 20, 2026 08:03
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.

1 participant