Pyomo / pyomo

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

Issue with XOR in GDP extension #2976

Open alessandrozocca opened 10 months ago

alessandrozocca commented 10 months ago

The documentation of the GDP extension says

Modelers often ask to model if-then-else relationships. These can be expressed as a disjunction as follows:

$\left[ Y_1, \ \text{constraints}, \ \text{for }\textit{then} \right] \vee \left[Y_2, \ \text{constraints}, \ \text{for }\textit{else}\right]$ $Y_1 \veebar Y_2$

Here, if the Boolean $Y_1$ is True, then the constraints in the first disjunct are enforced; otherwise, the constraints in the second disjunct are enforced.

This suggests that if the indicator variable $Y_i$ is false the constraints in the corresponding disjunction are simply ignored. In particular, all the logical operators seem to be applied only to the indicator variables $Y_i$. That seems to be true until the provided additional examples where a direct xor between disjunctions is presented

$[x = 0] \veebar [y = 0]$

A minimal Pyomo model below shows that the xor between disjunctions does not hold, as both $x$ and $y$ have a final value of $0$.

from pyomo.environ import *
from pyomo.gdp import *

PYO_SOLVER = SolverFactory('cbc')

model = ConcreteModel()
model.x = Var(domain=Binary)
model.y = Var(domain=Binary)

@model.Disjunction(xor=True)
def constraint(model):
    return [
        [model.x == 0],
        [model.y == 0]
    ]

@model.Objective(sense=minimize)
def objective(model):
    return  model.x + model.y

TransformationFactory('gdp.bigm').apply_to(model)
PYO_SOLVER.solve(model, tee = True)

print('Pyomo objective:', model.objective())
print('x:', model.x())
print('y:', model.y())

I believe that this part of Pyomo's documentation is incorrect and might lead users to an incorrect interpretation of the provided functionality.

Pyomo version: 6.6.2 Python version: 3.11 Operating system: macOS 13 How Pyomo was installed: poetry Solver: CBC, but other solvers result in the same mistake

emma58 commented 10 months ago

Thanks for the report @alessandrozocca, you are correct that that XOR is a typo and should be an OR. We enforce an XOR over the two indicator variables, but not over the algebraic expressions themselves. Most precisely, that Pyomo model reads as: $Y_1 \implies (x = 0)$ $Y_2 \implies (y = 0)$ $Y_1 \veebar Y_2$