Analyzing Results
Every solve persists an execution, and the execution page is where you read the result. It is built around one principle: lead with facts that are exact for your solution, and label everything that is approximate.
In the Model Workspace, the results drawer that opens after a solve shows a compact summary — status, objective, how many variables were assigned — and a View full results link to the execution page described here.
The structured solution
A solved assignment or routing model used to read as a wall of assign_v3_o107 = 1 rows. The execution page now recovers the index structure those flat names came from and leads with a grouped view: one block per variable family, sub-grouped by the first index — assign → v3 → the members chosen for it.
- Non-zero only is on by default: the grouped view shows the decisions (binary members that are on show just their label; anything else shows its value).
- The Table toggle switches to the full flat table, including per-variable sensitivity columns.
- Variables with no recoverable structure render flat in an "Other variables" bucket — nothing regresses for continuous or custom-named models.
- On very large solutions the grouped view renders a bounded prefix (500 values) with a Show all opt-in, so the page stays responsive.
Structure recovery is server-side and honest: a model compiled from a JModel source carries its real index sets, authoritatively. For flat or imported models, JAOT parses the conventional name_1_2 numeric-suffix pattern only — anything ambiguous is left flat rather than guessed.
The solve summary
The Solve summary card states how the model solved, honestly:
- "Proven optimal at the root node — no branching" — the presolver and cuts closed the problem immediately.
- "Optimal proven after N nodes" — real branch-and-bound work happened.
- "Time limit reached — best solution has gap X%" — you got the incumbent, not a proof.
Below the headline: the objective value, the final gap, node and iteration counts, and wall-clock solve time. (This card replaced a live convergence chart that was empirically a flat line for real models — solvers find the incumbent almost immediately and spend the rest of the run proving optimality, so a curve suggested progress that wasn't the story.)
Exact analysis
The Analysis section is computed on demand from the solution x* and the problem data — not from the LP relaxation — so every figure is exact for the integer solution and solver-agnostic:
- Binding constraints — "12 of 439 constraints are binding at the optimum (no slack)", with the tightest constraints listed first: activity, operator, and right-hand side per row.
- Utilization — per ≤-constraint, activity as a percentage of its right-hand side, so "capacity is at 97%" is one glance.
- Objective contributions — which terms c·x* actually drive the objective, as a ranked bar list.
Very large models degrade gracefully: the analysis is bounded (the most informative rows lead, a truncation note appears) rather than slow.
The classic LP-relaxation shadow prices are still available, demoted into a collapsed section underneath and deduplicated ("47 constraints · shadow price 1.0" instead of 47 identical rows). For a MIP they are duals of a different, easier problem — directional at best — which is exactly why they no longer lead the page. See Understanding Your Solution for how to read them, and for the plain-language AI explanation of the result.
The variables chart
The Visualization tab charts variable magnitudes. When every non-zero variable has the same value — the normal case for a binary assignment solution, where a bar chart of identical bars carries zero information — it collapses to an aggregate ("N variables at 1, M at zero") with a Show chart anyway override.
API
Everything on the page is available programmatically:
GET /api/v2/models/executions/{execution_id}
GET /api/v2/models/executions/{execution_id}/exact-analysis
The first returns the persisted execution (solution variables include the recovered family and index_tuple); the second computes the exact analysis on demand — binding constraints, slack/utilization, and objective contributions.