Skip to content

v2.2.1

Latest

Choose a tag to compare

@LucasBoTang LucasBoTang released this 11 Jun 08:37
· 82 commits to main since this release

🎉 We're happy to announce the PyEPO 2.2.1 release. 🎉

This is a maintenance release driven by a full-codebase audit: every loss, backend, metric, and the DSL were adversarially reviewed, and each fix ships with a regression test. Highlights: correct MAXIMIZE gradients for the one-sided estimators, a repaired sklearn scorer, exact setObj semantics for partial prediction, and JAX losses that are now safe under jax.jit.

What's New

Bug Fixes

  • Fixed DBB and one-sided I-MLE / AI-MLE: the informative perturbation direction now flips for MAXIMIZE problems (torch & JAX)
  • Fixed listwise LTR: the Boltzmann target puts its mass on the best pool solutions, per Mandi et al. (2022)
  • Fixed multiplicative perturbation (DPOMul / PFYLMul): known fixed costs keep factor exactly 1 under partial prediction
  • Fixed sklearn / auto-sklearn scorers: SPOError now receives (pred, true) in the right order
  • Fixed vrpRCIModel: rounded-capacity cuts now cover 2-customer routes
  • Fixed calUnambRegret: loose-side tie-set rounding for MAXIMIZE and uniform precision scaling
  • Fixed regret metrics to include the DSL objective offset and reject quadratic objectives
  • Fixed DSL setObj: predicted costs always scatter onto fixed costs (full-coverage bases and permutations are no longer dropped); internal solves route through _setFullObj
  • Fixed DSL expressions: numpy-style broadcasting, objective-only variables, bare objective constants, negative-axis sum, and the missing - / / operators
  • Fixed relax() to preserve addConstr cuts across all backends
  • Fixed the away-step Frank-Wolfe active set: a full buffer merges into the smallest atom instead of corrupting slot 0 (torch & JAX)
  • Fixed JAX RNG under jax.jit: implicit keys are rejected (the noise was constant-folded); loss(..., key=...) is now callable; PG / CaVE labels carry no gradient
  • Fixed solver failures to raise clear RuntimeErrors on every backend, plus guarded Gurobi / COPT imports, dataset input validation, and the CaVE binary-vertex check

Performance

  • Sparse node-arc incidence for Gurobi / COPT shortest path (dense build was O(nodes × arcs) memory)
  • Tolerance-based solution-pool dedup: first-order solver noise no longer grows the pool unboundedly
  • optDatasetConstrs reuses one model instead of rebuilding per instance
  • Opt-in cut recycling (recycle_cuts=True) for DFJ / RCI: discovered cuts join Gurobi's lazy pool across solves

Tests

  • Closed-form MAXIMIZE gradient gates, scorer-orientation and capacity-cut regressions, torch-JAX parity for every fix