Design feedback: Elastic feasibility & model-repair workflow in Pyomo

5 views
Skip to first unread message

Sato Takenori

unread,
Feb 16, 2026, 9:27:33 AM (5 days ago) Feb 16
to Pyomo Forum
Hi all,

First of all, thanks for making this great modeling tool available.

While working with Pyomo in practice, I often encounter the question:

    “The model is infeasible — what do we need to change to make it feasible?”

Rather than only reporting infeasibility, I’ve been experimenting with an elastic feasibility wrapper in Pyomo to measure:

- how far a model is from feasibility
- which constraints would require relaxation
- how feasibility repair interacts with the original objective

----------------------------------------
Formulation
----------------------------------------

For each inequality constraint, I introduce both slack (non-penalized)
and violation (penalized) variables:

For body <= ub:

    body + slack - viol == ub
    slack >= 0
    viol >= 0
    penalty applied only to viol

For body >= lb:

    body - slack + viol == lb
    slack >= 0
    viol >= 0
    penalty applied only to viol

A single-variable approach initially reversed the feasible region, so separating slack and violation resolved that issue.

Equality constraints use two violation variables (positive and negative), penalizing their sum.

----------------------------------------
Objective handling
----------------------------------------

To avoid confusion between the minimized form passed to the solver and the original objective interpretation (especially for maximization problems), I now explicitly distinguish:

- solver_objective_expr/value (minimized form passed to the solver)
- natural_objective_expr/value (original interpretation)

----------------------------------------
Penalty scaling observation
----------------------------------------

If the penalty coefficient is too small, the model may prefer violating constraints (e.g., dropping demand in a transportation model), because violation becomes “cheaper” than operational cost.

I documented this as an optional note in the project README.

----------------------------------------

Questions:

1) Does this slack + violation formulation align with recommended Pyomo practice?
2) Is there an established approach for scaling penalty coefficients in elastic models?
3) Are there existing Pyomo tools or patterns for structured feasibility repair that I may have overlooked?

Project link: https://github.com/ggsato/totsu

I would greatly appreciate any feedback or practical perspectives.

Thanks,
Takenori

Siirola, John

unread,
Feb 16, 2026, 11:40:05 AM (5 days ago) Feb 16
to pyomo...@googlegroups.com

Hi Takenori,

 

First off, thank you for reaching out!  Infeasibility diagnostics is certainly something that we are interested in, and would love to have more discussions around (either here on the Forum, or at the weekly developer calls (Tuesdays, 12:30 – 14:00 MT – email wg-p...@sandia.gov if you are interested in joining and we will send the call-in information).

 

Some quick initial answers to your questions:

  1. This seems reasonable, although in practice, we only add “violation” variables (which for various reasons we call “slacks”).  The reason is that all the solvers that we use support inequalities, so we don’t go through the effort to convert inequalities to equalities.  Pyomo has a standard transformation to do this for you (“core.add_slack_variables”; implemented in pyomo.core.plugins.transform.add_slack_vars)
  2. We generally leave the slack scaling at “1”.  If the model is exceptionally poorly scaled, then scaling the slacks would make a lot of sense.  Alternatively, you can rescale your model. Again, there is a standard transform to assist in rescaling models: “core.scale_model” (implemented in pyomo.core.plugins.transform.scaling).  Generating scaling factors is itself a tricky exercise.  The best solution is always to use your knowledge of the problem to scale the model.  There are tools for attempting to “auto scale” a model, e.g., see the AutoScaler class in IDAES: https://idaes-pse.readthedocs.io/en/latest/explanations/scaling_toolbox/applying_scaling_tools.html
  3. In addition to the three already mentioned, additional useful tools / inspiration include:
    1. The Minimal Intractable System finder: https://pyomo.readthedocs.io/en/latest/explanation/analysis/iis.html
    2. The IDAES diagnostics toolbox (geared towards NLPs): https://idaes-pse.readthedocs.io/en/latest/explanations/model_diagnostics/

 

Best,

John

 

From: pyomo...@googlegroups.com <pyomo...@googlegroups.com> On Behalf Of Sato Takenori
Sent: Monday, February 16, 2026 6:47 AM
To: Pyomo Forum <pyomo...@googlegroups.com>
Subject: [EXTERNAL] Design feedback: Elastic feasibility & model-repair workflow in Pyomo

 

You don't often get email from takeno...@gmail.com. Learn why this is important

--
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pyomo-forum/5ff54311-ddb4-4506-a36e-3fda33691eefn%40googlegroups.com.

Sato Takenori

unread,
Feb 17, 2026, 9:23:53 PM (4 days ago) Feb 17
to pyomo...@googlegroups.com
Hi John,

Thanks very much for your detailed answers and for the invitation to join the developer call.
I think I still have a lot to learn about Pyomo before I can meaningfully follow those discussions, but I really appreciate the offer.


> we only add “violation” variables (which for various reasons we call “slacks”)

For example, would this mean adding a nonnegative violation variable to relax an inequality constraint?

And adding such variables can be done via "core.add_slack_variables"?

The reason I used an equality form is not only to quantify violation, but also to expose structural slack explicitly.
Without slack, a zero-violation solution would appear “flat.”
In practice, however, the distribution of slack reveals where the model is tight or relaxed.

My intention is to make infeasibility and near-infeasibility structurally interpretable, rather than only measurable.

Anyway, I will consider using a different term, not slack, to avoid confusion. 


> We generally leave the slack scaling at “1”.

That makes sense, especially since proper scaling often depends on domain knowledge.
I will study "core.scale_model" more carefully.


> In addition to the three already mentioned, additional useful tools / inspiration include:

Thanks! These are very helpful. I will experiment with them.

Best,  
Takenori

2026年2月17日(火) 1:40 'Siirola, John' via Pyomo Forum <pyomo...@googlegroups.com>:
You received this message because you are subscribed to a topic in the Google Groups "Pyomo Forum" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyomo-forum/6YDxgZniIkQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pyomo-forum...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pyomo-forum/SA9PR09MB482943950BABF53EE284DED4DA6CA%40SA9PR09MB4829.namprd09.prod.outlook.com.

Sato Takenori

unread,
Feb 18, 2026, 2:21:25 AM (3 days ago) Feb 18
to pyomo...@googlegroups.com
Hi John,

Thanks again for your earlier explanations — they helped me clarify the direction in Totsu. Before I move further, I’d like to confirm two assumptions and ask for your advice.

1. About "core.add_slack_variables" vs “repair planning”

If I used "core.add_slack_variables", it seems conceptually similar to our "violation_only" mode — it can measure “distance to feasibility” (how much each constraint is violated), but it does not naturally incorporate the original objective in a way that yields a concrete “repair plan” (i.e., a feasible solution that is also good with respect to the original objective). Is that understanding correct?

2. About scaling strategy for “penalty coefficient = 1”

I like the idea, “penalty coefficient = 1”, because tuning penalty weights is confusing for non-experts and often destroys comparability across models. I investigated "core.scale_model" and found an important practical limitation: it only applies scaling factors that are explicitly attached (via "scaling_factor" suffix) to individual components (variables/constraints/objectives). I expected that "core.scale_model" is an automatic normalization step. But it turned out it isn't. Users must supply component-level scaling, which is hard for non-experts.

A few questions here:
* Is there a recommended conceptual approach for assigning scaling factors at the component level (especially for non-experts)?
* Has Pyomo considered (or does it already have) any mechanism to automatically propose/default scaling factors, specifically to make “penalty = 1” a reasonable default for elastic/repair formulations?

Any guidance would be hugely appreciated!

Best,
Takenori

2026年2月17日(火) 10:05 Sato Takenori <takeno...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages