Pyomo / pyomo

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

Issue with Piecewise constraint and GLPK #3203

Open Ogaday opened 6 months ago

Ogaday commented 6 months ago

Summary

I'm having trouble with Piecewise constraints and the GLPK solver.

I've reproduced the problem with a simple example from Pyomo's github. See below for error message.

Steps to reproduce the issue

# Steps to reproduce
$ glpsol --version
# GLPSOL--GLPK LP/MIP Solver 5.0
$ python piecewise.py
# Error...
# piecewise.py
"""Simple Piecewise example.

Adapted from: https://github.com/Pyomo/pyomo/blob/main/examples/pyomo/piecewise/points.py
"""

import pyomo.environ as pyo

solver = "glpk"
x = [0.0, 1.5, 3.0, 5.0]
y = [1.1, -1.1, 2.0, 1.1]

model = pyo.ConcreteModel()
model.x = pyo.Var(bounds=(min(x), max(x)))
model.y = pyo.Var()

model.fx = pyo.Piecewise(model.y, model.x, pw_pts=x, pw_constr_type="EQ", f_rule=y)

model.o = pyo.Objective(expr=model.y)

if __name__ == "__main__":
    solver = pyo.SolverFactory(solver)
    solver.solve(model).write()

Error Message

ERROR: Solver (glpk) returned non-zero return code (1)
ERROR: Solver log: GLPSOL--GLPK LP/MIP Solver 5.0 Parameter(s) specified in
the command line:
     --write /tmp/tmp9rrz7ols.glpk.raw --wglp /tmp/tmpeg1_vla_.glpk.glp
     --cpxlp /tmp/tmp2n5b9j40.pyomo.lp
    Reading problem data from '/tmp/tmp2n5b9j40.pyomo.lp'...
    /tmp/tmp2n5b9j40.pyomo.lp:40: invalid bound definition CPLEX LP file
    processing error
Traceback (most recent call last):
  File "/home/ogaday/Code/Other/pyomo-piecewise-issue/pyomo_piecewise_issue.py", line 36, in <module>
    solver.solve(model).write()
  File "/home/ogaday/Code/Other/pyomo-piecewise-issue/.venv/lib/python3.10/site-packages/pyomo/opt/base/solvers.py", line 628, in solve
    raise ApplicationError("Solver (%s) did not exit normally" % self.name)
pyomo.common.errors.ApplicationError: Solver (glpk) did not exit normally

tmp2n5b9j40.pyomo.lp:

\* Source Pyomo model name=unknown *\

min 
x1:
+1 x2

s.t.

c_e_x3_:
+1 x4
-1.5 x5
-3.0 x6
-5.0 x7
= 0

c_e_x8_:
+1 x2
-1.1 x9
+1.1 x5
-2.0 x6
-1.1 x7
= 0

c_e_x10_:
+1 x9
+1 x5
+1 x6
+1 x7
= 1

bounds
   -inf <= x2 <= +inf
   0.0 <= x4 <= 5.0
   0 <= x9 <= +inf
   0 <= x5 <= +inf
   0 <= x6 <= +inf
   0 <= x7 <= +inf
SOS

x11: S2::
  x9:1
  x5:2
  x6:3
  x7:4

end

Information on your system

Pyomo version: pyomo 6.7.1 Python version: Python 3.10.8 Operating system: Ubuntu 22.04.4 LTS on Windows 10 x86_64 (WSL) / Kernel: 5.15.146.1-microsoft-standard-WSL2 How Pyomo was installed (PyPI, conda, source): PyPI/Poetry Solver (if applicable): GLPK 5.0

Solver installed via apt:

sudo apt install glpk-doc glpk-utils libglpk-dev python3-swiglpk
# glpk-doc is already the newest version (5.0-1).
# glpk-utils is already the newest version (5.0-1).
# libglpk-dev is already the newest version (5.0-1).
# python3-swiglpk is already the newest version (4.65.1-1build2).

Additional information

Changing the solver to cbc, or setting pw_repn="DCC" both seem to solve the issue. Is this behaviour expected? My optimisation knowledge is fairly shallow. If there are some combinations of solvers and arguments that aren't feasible could this be documented?

Thanks in advance!

mrmundt commented 6 months ago

Looking into this briefly, I believe this is an issue in the LP writer. It appears to be converting Piecewise to SOS rather than any of the piecewise options, which I believe would be the preferred option (e.g., Pwl).

@michaelbynum , @jsiirola - Thoughts?

Note - the issue starts in line 40, aka:

x11: S2::
  x9:1
  x5:2
  x6:3
  x7:4