pyomo icon indicating copy to clipboard operation
pyomo copied to clipboard

Referenced Vars are duplicated with Direct/Persistent Solvers

Open bknueven opened this issue 2 years ago • 0 comments

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.

bknueven avatar May 27 '22 23:05 bknueven