Skip to content

[FEA] Expose basis / variable status on the LP solution (companion to reduced costs) #1394

Open

Description

@cafzal

Is your feature request related to a problem? Please describe.

cuOpt's LP/QP solution exposes dual values and reduced costs, but not basis / variable status (basic vs. nonbasic-at-lower-bound vs. nonbasic-at-upper-bound). Basis status is the standard companion to reduced costs in an LP sensitivity report: it says which variables are at a bound, where a reduced cost is a meaningful "this would enter / change if its coefficient improved by X" signal, versus basic / interior, where the reduced cost is ~0. Without it, code reading get_reduced_cost() can't cleanly tell a genuine near-miss from an interior variable.

It is also the degeneracy signal: a basic variable at a bound flags a degenerate vertex, so a consumer can mark that dual directional rather than quote a non-unique number as precise. That trust-calibration is what matters most on large, degenerate models, and the prerequisite for any honest sensitivity layer.

This surfaced building solver-exact sensitivity/explainability on top of cuOpt (a downstream multi-objective decision layer): the at-bound-vs-basic distinction is load-bearing for interpreting reduced costs, and we currently reconstruct it heuristically from the primal values plus variable bounds.

Describe the solution you'd like

A public accessor on the LP solution, e.g. get_variable_status() / get_constraint_status() (C++), with C API and Python equivalents, returning a public basis-status enum (BASIC / NONBASIC_LOWER / NONBASIC_UPPER / FIXED / FREE, plus NO_BASIS when no basis exists). The data already exists internally: the dual-simplex solver computes a full basis (variable_status_t / vstatus, cpp/src/dual_simplex/initial_basis.hpp). So the work is mainly (a) a public enum, (b) plumbing vstatus from the dual-simplex result through to the public optimization_problem_solution, (c) the getter plus C API, cython bindings, and tests.

Two design points for maintainers:

  1. Public enum shape. The internal variable_status_t is {BASIC, NONBASIC_LOWER, NONBASIC_UPPER, NONBASIC_FREE, NONBASIC_FIXED, SUPERBASIC}. The call is whether to expose all of these or fold some (SUPERBASIC, or the FREE/FIXED split) into a leaner public enum.
  2. PDLP semantics. For the PDLP path the accessor should return an explicit NO_BASIS status rather than a heuristic reconstruction. Since PDLP frequently wins the concurrent race, "no basis exists" is the common case, and an honest signal there is most of the feature's value: it tells the consumer these duals are tolerance-accurate approximations, not basis-exact.

Describe alternatives you've considered

  • Reconstructing status downstream from the primal solution plus bounds (what we do now): brittle near bounds, and impossible to get right at degenerate points.
  • Inferring from reduced_cost == 0: unreliable under degeneracy (basic variables can have zero reduced cost, and vice versa).

Additional context

Related: the diet LP duals example (dual values + reduced costs), NVIDIA/cuopt-examples#154, surfaces exactly the reduced costs this status accessor would annotate (which foods are at a bound = near-misses vs basic/interior).

Activity

  1. chris-maes commented on Jun 9, 2026

    @chris-maes
    Contributor

    How would you use the basis information (e.g. BASIC, NONBASIC_LOWER, NONBASIC_UPPER, FIXED, FREE) if cuOpt gave it to you?

  2. cafzal commented on Jun 10, 2026

    @cafzal
    ContributorAuthor

    @chris-maes, Frontier is my open-source multi-objective toolkit to help decision-makers navigate trade-offs using AI. I integrated cuOpt for the exact LP path, so it already reads your duals. Basis status would sharpen three calls the agent currently infers from the primal solution and bounds:

    • Action: The lever per option: NONBASIC_LOWER: 'it just missed, improve it.' NONBASIC_UPPER: 'hit a cap so raise it.' FIXED: 'keep off the near-miss list.'

    • Freedom: Where the choice is free, so a nonbasic variable at ~0 reduced cost is an alternative optimum. This requires a vertex.

    • Confidence: How far to trust each number, so the agent flags it directional vs. exact.

    In this example, the duals already say improve-it / raise-the-cap / where-to-invest; basis status would make that exact at the bounds.

    Happy to help scope or user test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions