Pyomo / pyomo

An object-oriented algebraic modeling language in Python for structured optimization problems.
https://www.pyomo.org
Other
2.01k stars 517 forks source link

Solving model with cloned summed expression fails #2174

Closed yonizim closed 2 years ago

yonizim commented 2 years ago

Summary

Lets look at a model with an objective which consists of nested summed expression. This expression is created using clone_expression command. Solving it with any solver fails, with the following error message: AttributeError: 'SumExpression' object has no attribute 'fixed'

Steps to reproduce the issue

A simple script which demonstrates the problem.

import itertools

import pyomo.environ as pyo
from pyomo.core.expr.numeric_expr import clone_expression
from pyomo.opt import SolverFactory

model = pyo.ConcreteModel()
idx_set_1 = [1, 2]
idx_set_2 = [1, 2]
model.x = pyo.Var(idx_set_1)

double_idx = list(itertools.product(idx_set_1, idx_set_2))
model.y = pyo.Var(double_idx)

vars_encoding_dict = {}
for idx in idx_set_1:
    vars_encoding_dict[id(model.x[idx])] = sum(model.y[idx, idx2] for idx2 in idx_set_2)

expr = sum(2*model.x[i] for i in model.x)
new_expr = clone_expression(expr=expr, substitute=vars_encoding_dict)
model.cost = pyo.Objective(expr=new_expr)

SolverFactory("cplex_direct").solve(model)

If we would replace the objective expression with the following equivalent line: new_expr = sum(2*vars_encoding_dict[id(model.x[i])] for i in model.x) the solver terminates successfully.

Error Message

Traceback (most recent call last):
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3444, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-681b08274767>", line 1, in <module>
    runfile('/Users/jonatan/projects/cadmium/pyomo_bugs/sum_expression_fixed.py', wdir='/Users/jonatan/projects/cadmium/pyomo_bugs')
  File "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/jonatan/projects/cadmium/pyomo_bugs/sum_expression_fixed.py", line 33, in <module>
    solver.solve(model_copy)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 119, in solve
    self._presolve(*args, **kwds)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 62, in _presolve
    self._set_instance(model, kwds)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/cplex_direct.py", line 360, in _set_instance
    self._add_block(model)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/cplex_direct.py", line 417, in _add_block
    self._set_objective(obj)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/cplex_direct.py", line 570, in _set_objective
    cplex_expr, referenced_vars = self._get_expr_from_pyomo_expr(obj.expr, self._max_obj_degree)
  File "/Users/jonatan/projects/cadmium/venvpoetry/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/cplex_direct.py", line 300, in _get_expr_from_pyomo_expr
    repn = generate_standard_repn(expr, quadratic=True)
  File "pyomo/repn/standard_repn.pyx", line 348, in pyomo.repn.standard_repn.generate_standard_repn
  File "pyomo/repn/standard_repn.pyx", line 957, in pyomo.repn.standard_repn._generate_standard_repn
  File "pyomo/repn/standard_repn.pyx", line 410, in pyomo.repn.standard_repn._collect_sum
AttributeError: 'SumExpression' object has no attribute 'fixed'

Information on your system

Pyomo version: 6.1.2 Python version: 3.8.6 Operating system: MacOSX 10.1.5.7 (Catalina) How Pyomo was installed (PyPI, conda, source): pypi Solver (if applicable): cplex_direct

Additional information

jsiirola commented 2 years ago

The root cause had to do with an old implementation of clone_expression that was not updated to the "pyomo4" expression rules. This was actually fixed on main a little over two weeks ago (PR #2143), and will be available in the next Pyomo release (not scheduled yet, but likely before the end of the month).