-
Notifications
You must be signed in to change notification settings - Fork 568
Description
Summary
When constructing the dual problem on a primal model with ranged constraints, the mapping between dual variables and primal constraints in non-unique. Both duals will map to the same ranged primal constraint, and the ranged primal constraint will only map to one of the two dual variables. This also raises the issue of what to do when the user creates ranged constraints with variable bounds... or if it is still worth implementing a mapping if this is the case...
Steps to reproduce the issue
Here is an example that illustrates the issue:
# example.py
import pyomo.environ as pyo
m = pyo.ConcreteModel()
m.x1 = pyo.Var(domain=pyo.NonNegativeReals)
m.x2 = pyo.Var(domain=pyo.Reals)
m.con1 = pyo.Constraint(expr=(1, m.x1, 4))
m.con2 = pyo.Constraint(expr=m.x2 <= 10)
m.obj = pyo.Objective(expr=m.x1 + m.x2, sense=pyo.maximize)
dual = pyo.TransformationFactory("core.lp_dual").create_using(m)
# get transformation mapping
td = pyo.TransformationFactory('core.lp_dual')
# get primal constraints
print('Primal constraints from dual variables:')
primal_con1 = td.get_primal_constraint(dual, dual.x[0])
primal_con1.pprint()
primal_con2 = td.get_primal_constraint(dual, dual.x[1])
primal_con2.pprint()
primal_con3 = td.get_primal_constraint(dual, dual.x[2])
primal_con3.pprint()
# get dual variables
print('\nDual variables from primal constraints:')
dual_var1 = td.get_dual_var(dual, m.con1)
dual_var1.pprint()
dual_var2 = td.get_dual_var(dual, m.con2)
dual_var2.pprint()
...
Error Message
Here is the printed output illustrating the non-unique mapping:
$ # Output message here, including entire stack trace, if available
Primal constraints from dual variables:
con1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : 1.0 : x1 : 4.0 : True
con1 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : 1.0 : x1 : 4.0 : True
con2 : Size=1, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : -Inf : x2 : 10.0 : True
Dual variables from primal constraints:
{Member of x} : Size=3, Index={0, 1, 2}
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : None : None : 0 : False : True : NonPositiveReals
{Member of x} : Size=3, Index={0, 1, 2}
Key : Lower : Value : Upper : Fixed : Stale : Domain
2 : 0 : None : None : False : True : NonNegativeRealsInformation on your system
Pyomo version: 6.9.5
Python version: 3.14.3
Operating system: Ubuntu 22.04.5 LTS (WSL2/Windows 11)
How Pyomo was installed (PyPI, conda, source): pip install pyomo
Solver (if applicable): not applicable