Pyomo / pyomo

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

Model transformation for maximin or minimax models (min/max functions in Pyomo) #2944

Open MLopez-Ibanez opened 1 year ago

MLopez-Ibanez commented 1 year ago

Summary

A very common model is the maximin (or minimax). The model transformation required to linearize such models are well-known. It would be very useful if Pyomo supported such model transformations out of the box.

Perhaps the first step would be for handle min() and max() in the same way as sum() and report a clear error (see the cryptic error currently reported below).

# example.py
from pyomo.environ import *
m = ConcreteModel()
m.x = Var(within=NonNegativeReals)
m.Ann=1+2*m.x
m.Bob=2+m.x
m.Carol=5-m.x/2
m.obj=Objective(expr=min((m.Ann,m.Bob,m.Carol)),sense=maximize)
m.pprint()
opt = SolverFactory('cbc') 
opt.solve(m, tee=True)

Error Message

---------------------------------------------------------------------------
PyomoException                            Traceback (most recent call last)
/tmp/ipykernel_11272/3773921463.py in <module>
      5 m.Bob=2+m.x
      6 m.Carol=abs(5-m.x/2)
----> 7 m.obj=Objective(expr=min((m.Ann,m.Bob,m.Carol)),sense=maximize)
      8 m.pprint()
      9 opt = SolverFactory('cbc')

~/.local/lib/python3.10/site-packages/pyomo/core/expr/relational_expr.py in __bool__(self)
     46         if self.is_constant():
     47             return bool(self())
---> 48         raise PyomoException(
     49             """
     50 Cannot convert non-constant Pyomo expression (%s) to bool.

PyomoException: Cannot convert non-constant Pyomo expression (2 + x  <  1 + 2*x) to bool.
This error is usually caused by using a Var, unit, or mutable Param in a
Boolean context such as an "if" statement, or when checking container
membership or equality. For example,
    >>> m.x = Var()
    >>> if m.x >= 1:
    ...     pass
and
    >>> m.y = Var()
    >>> if m.y in [m.x, m.y]:
    ...     pass
would both cause this exception.

Information on your system

Pyomo version: 6.6.1 Python version: 3.10.12 Operating system: Linux How Pyomo was installed (PyPI, conda, source): pip

Additional information

MLopez-Ibanez commented 1 year ago

Sorry, it should have been an feature request.

blnicho commented 1 year ago

@MLopez-Ibanez is this the same as a bilevel optimization problem? If so, there is an existing Pyomo extension that might already have some of the functionality that you're asking for. The package is called PAO and you can find an example here: https://pao.readthedocs.io/en/latest/examples.html

MLopez-Ibanez commented 1 year ago

@MLopez-Ibanez is this the same as a bilevel optimization problem? If so, there is an existing Pyomo extension that might already have some of the functionality that you're asking for. The package is called PAO and you can find an example here: https://pao.readthedocs.io/en/latest/examples.html

No, this is a much simpler transformation than bilevel optimization and similar to the transformations available in: https://github.com/Pyomo/pyomo/tree/main/pyomo/core/plugins/transform (perhaps @jsiirola knows what I am talking about).