MBM update (preparation for InfGDP)#133
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #133 +/- ##
==========================================
+ Coverage 99.35% 99.37% +0.02%
==========================================
Files 17 17
Lines 1858 1926 +68
==========================================
+ Hits 1846 1914 +68
Misses 12 12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
80229ad to
ae550d1
Compare
|
@dnguyen227 I am open to arguments otherwise, but I am not sure that I see the utility of deactivating disjuncts. If a constraint is infeasible, we should probably just throw an error. This would simplify things and I am not sure deleting bad disjuncts leads to a useful formulation. |
I overlooked this in my original implementation, below is the paper's call to remove infeasible disjuncts.
Where (2) is the subproblem solving for M, and ki' is the disjunct term. With regard to the utility of actually implementing this. I'm assuming that for the infinite-dimensional case, disjuncts can become infeasible at certain support points while being feasible in others, and this is would be worth the hassle of having code to deactivate disjuncts (at specific support points). Let me know your thoughts. |
If I understand correctly, an infeasible problem means the constraints in a disjunct are fundamentally infeasible regardless of the global constraints and other disjuncts. If this is true, then seems like modelling it as such is a fundamental modelling mistake. |
Fair enough. I've removed the deactivation logic and replaced it with an informative error. |
pulsipher
left a comment
There was a problem hiding this comment.
Nearly there, just a few minor suggestions.
This PR refactors the MBM implementation to use a unified submodel infrastructure (GDPSubmodel) with cached submodels and infeasible disjunct detection. The
_mini_model + _constraint_to_objective pattern is replaced by create_submodel + prepare_objectives + _raw_M, which separates submodel construction from objective evaluation and enables extension by InfiniteOpt.
EXAMPLE
Given a disjunction with:
When reformulating Y[1]'s constraints with respect to Y[2]'s feasible region (0 ≤ x ≤ 55):
Before (single M per disjunct pair, no caching):
Each call to _mini_model creates a new submodel from scratch. M values are computed via _constraint_to_objective which sets the objective directly. No
infeasible disjunct detection — unbounded subproblems silently use default_M.
After (per-constraint M, cached submodels, infeasibility detection):
Key structural changes:
evaluate to Numbers at support points)
Relevant tests were added to cover per-constraint M values, infeasible disjunct detection, global constraint detection, and unbounded subproblem fallback.