pyomo
pyomo copied to clipboard
Referenced Vars are duplicated with Direct/Persistent Solvers
Summary
When a Pyomo model has a Reference to a Var, the Var gets populated to the direct/persistent solver multiple times.
@dguittet found this issue in a larger IDAES flowsheet.
Steps to reproduce the issue
Here is the Pyomo model:
from pyomo.environ import *
m = ConcreteModel()
m.x = Var()
m.y = Reference(m.x)
m.z = Reference(m.x)
m.c = Constraint(expr=m.x>=1)
m.o = Objective(expr=m.x)
Solving it with one of the direct solvers has an interesting result.
Error Message
cplex_direct
Version identifier: 12.10.0.0 | 2019-11-27 | 843d4de
CPXPARAM_Read_DataCheck 1
Tried aggregator 1 time.
LP Presolve eliminated 1 rows and 3 columns.
All rows and columns eliminated.
Presolve time = 0.00 sec. (0.00 ticks)
Gets the correct solution, but 3 columns instead of 1.
gurobi_direct
Gurobi Optimizer version 9.5.1 build v9.5.1rc2 (mac64[x86])
Thread count: 8 physical cores, 16 logical processors, using up to 16 threads
Optimize a model with 1 rows, 3 columns and 1 nonzeros
Model fingerprint: 0x9dade6cf
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+00, 1e+00]
Bounds range [0e+00, 0e+00]
RHS range [1e+00, 1e+00]
Presolve removed 1 rows and 3 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Iteration Objective Primal Inf. Dual Inf. Time
0 1.0000000e+00 0.000000e+00 3.000000e-06 0s
Solved in 0 iterations and 0.00 seconds (0.00 work units)
Optimal objective 1.000000000e+00
Similar to cplex_direct, but again two additional columns
xpress_direct
?1030 Error: Duplicate column names are not allowed - column 0 would have same name as column 1
---------------------------------------------------------------------------
SolverError Traceback (most recent call last)
<ipython-input-20-14f537bc27c1> in <module>
----> 1 s.solve(m, tee=True)
~/Software/pyomo/pyomo/solvers/plugins/solvers/direct_solver.py in solve(self, *args, **kwds)
118 initial_time = time.time()
119
--> 120 self._presolve(*args, **kwds)
121
122 presolve_completion_time = time.time()
~/Software/pyomo/pyomo/solvers/plugins/solvers/direct_solver.py in _presolve(self, *args, **kwds)
61 raise ValueError(msg)
62
---> 63 self._set_instance(model, kwds)
64
65 DirectOrPersistentSolver._presolve(self, **kwds)
~/Software/pyomo/pyomo/solvers/plugins/solvers/xpress_direct.py in _set_instance(self, model, kwds)
317 "Error message: {0}".format(e))
318 raise Exception(msg)
--> 319 self._add_block(model)
320
321 def _add_block(self, block):
~/Software/pyomo/pyomo/solvers/plugins/solvers/xpress_direct.py in _add_block(self, block)
320
321 def _add_block(self, block):
--> 322 DirectOrPersistentSolver._add_block(self, block)
323
324 def _add_constraint(self, con):
~/Software/pyomo/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py in _add_block(self, block)
203 active=True,
204 sort=True):
--> 205 self._add_var(var)
206
207 for sub_block in block.block_data_objects(descend_into=True,
~/Software/pyomo/pyomo/solvers/plugins/solvers/xpress_direct.py in _add_var(self, var)
284
285 xpress_var = xpress.var(name=varname, lb=lb, ub=ub, vartype=vartype)
--> 286 self._solver_model.addVariable(xpress_var)
287
288 ## bounds on binary variables don't seem to be set correctly
SolverError: ?1030 Error: Duplicate column names are not allowed - column 0 would have same name as column 1
Xpress notices that we're adding identically named columns and (properly, IMHO) throws an error.
Information on your system
Pyomo version: 6.4.2.dev0 (74b5005f) Python version: 3.7.7 Operating system: macOS How Pyomo was installed (PyPI, conda, source): source Solver (if applicable): cplex/gurobi/xpress
Additional information
It would be straightforward to add a check in _add_var
for xpress_direct to fix the immediate issue. But I wonder if cplex/gurobi are really doing what is desirable in these circumstances, and if the fix shouldn't be made in base class, if possible.