Add LP sensitivity analysis (duals + reduced costs) to the diet example#154
Open
cafzal wants to merge 7 commits into
Open
Add LP sensitivity analysis (duals + reduced costs) to the diet example#154cafzal wants to merge 7 commits into
cafzal wants to merge 7 commits into
Conversation
…mple Adds a Sensitivity Analysis section after the first solve (constraint .DualValue/.Slack and variable .ReducedCost via getConstraints()/getVariables()) and a dairy-cap shadow-price cell after the re-solve (dairy_constraint.DualValue). Surfaces cuOpt's LP dual information, which the example previously omitted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: cafzal <cameron.afzal@gmail.com>
The stock dairy<=6 cap makes the model PrimalInfeasible (sodium is binding and dairy is the only low-sodium protein/calorie source), so the added-constraint shadow-price demo couldn't run. Cap hamburger+hot dog<=0.4 instead: it frees the binding sodium constraint (stays feasible) while binding (cost rises), yielding a real shadow price. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: cafzal <cameron.afzal@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: cafzal <cameron.afzal@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: cafzal <cameron.afzal@gmail.com>
521fb4f to
c5235e8
Compare
This was referenced Jun 5, 2026
Author
|
@rgsl888prabhu For visibility: Here's a small addition to showcase use of shadow price and reduced cost in an existing example. |
rgsl888prabhu
approved these changes
Jun 5, 2026
rapids-bot Bot
pushed a commit
to NVIDIA/cuopt
that referenced
this pull request
Jun 5, 2026
…1393) Adds a per-problem-type **dual / sensitivity** capability note to the concepts-only `cuopt-numerical-optimization-formulation` skill, so the agent guides users correctly on what cuOpt exposes after a solve: - **LP** — shadow prices (constraint duals) + reduced costs - **MILP** — none (integer optima are not continuous) - **QP** — shadow prices + reduced costs Two edits: a `Duals / sensitivity` row in the LP/MILP/QP comparison table, and a short post-solve note giving the decision meaning — **shadow price = where to invest** (marginal objective gain from relaxing a binding constraint) and **reduced cost = near-miss** (how far a left-out option must improve before it enters the solution). As a concepts skill it states *what's supported per type* and *what it means*, and defers *how to read them* to the language-specific API skills (no API symbols inlined). **Why.** Surfaced from real integration use — wiring solver-exact sensitivity/explainability into a downstream multi-objective decision layer. The formulation skill covered how to *formulate* but not which problem types yield sensitivity information, which is exactly what a user needs before relying on it (e.g. not expecting duals off a MILP). The note also reflects the review feedback on #1355: a concepts skill carries no maturity ("beta") labels and no specific API symbols — both drift out of date, with no CI to catch the staleness. **Validation & gating.** `ci/utils/validate_skills.sh` passes (skill structure, marketplace manifest, `AGENTS.md` references). The NVSkills-Eval pipeline — which also (re)generates `BENCHMARK.md`, the skill card, and the signature — is the gate and is **pending**: `skills/**` CI needs a maintainer and cannot be triggered from a fork branch. **Related.** - NVIDIA/cuopt-examples#154 — the diet LP duals example: a runnable worked case of the shadow-price / reduced-cost reading this note describes. - Codebase-side sensitivity gaps (objective/RHS ranging; exposing variable/basis status) are tracked separately as #1394 and #1395. Authors: - Cameron Afzal (https://github.com/cafzal) Approvers: - Ramakrishnap (https://github.com/rgsl888prabhu) URL: #1393
…VIDIA#151) Signed-off-by: cafzal <cameron.afzal@gmail.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
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.
LP sensitivity analysis (duals + reduced costs) — diet example
Extends the diet LP example to read the dual information cuOpt returns for a solved LP — the economic "why" behind the optimal plan. Motivated by NVIDIA/cuopt#1393, which clarifies cuOpt's dual / sensitivity-analysis support per problem type (LP/QP, not integer models); companion to the QP efficient-frontier-with-duals example in #151 (LP here, QP there).
diet_optimization/diet_optimization_lp.ipynb— after the first solve, reads each constraint's dual (DualValue,Slack) and each variable's reduced cost (ReducedCost) viaproblem.getConstraints()/problem.getVariables(), with a plain-language binding-vs-slack reading. The "add a constraint" step then reads the dual of the added constraint (meat_constraint.DualValue) — the marginal cost of the cap. This also replaces the example's existingdairy (milk + ice cream) <= 6cap, which is infeasible (max_sodiumis binding and dairy is the only low-sodium way to meet the protein/calorie minimums, so the stock notebook's "Solution Comparison" printed "No optimal solution found"), with a feasible, bindinghamburger + hot dog <= 0.4.diet_optimization/README.mdupdated to match.Runs on cuOpt alone (Colab GPU), follows the repo's notebook idiom (GPU check →
cuopt-cu12install → solve), and ships output-stripped (repo convention — every cuopt-examples notebook has 0 cell outputs); run evidence below.User testing
Run end-to-end on a Colab GPU runtime (
cuopt-cu12) — clean, no errors:Optimal, $11.83. Binding constraints carry nonzero duals —min_protein +0.093,min_calories +0.003,max_sodium −0.002— while slack ones price to ~0; every food left out of the diet has a positive reduced cost (macaroni +1.34the largest), i.e. how far its per-serving price must fall to enter the diet.hamburger + hot dog <= 0.4, the re-solve isOptimalat $11.86 (up from $11.83); the cap binds at hamburger = 0.400 with dual −0.164 (slack 0) — allowing one more serving would lower cost ~$0.16, matching the empirical $0.03 / 0.205 ≈ $0.15.raw cell output
Notes