I am working on a supply chain optimisation problem using Pyomo and I need to set up a constraint on specific variables in the model. The constraint is that the variable should be within the set (0,1) or (200, to infinity). However, when I try to set up that constraint I am getting a TypeError, here is my code:
def rail_rule(model):
for route in routes:
if "rail" in route[0].lower():
dest = route[0]
dg = route[1]
sg = route[2]
site = route[3]
return model.x[dest, dg, sg, site]>=200 or model.x[dest, dg, sg, site]<=1
model.railconst = Constraint(rule = rail_rule)
I get this error when I run it :
TypeError: Relational expression used in an unexpected Boolean context.
The inequality expression:
200.0 <= x[RAIL - KENSINGTON,8,8,BROCKLESBY]
contains non-constant terms (variables) that were evaluated in an
unexpected Boolean context at
File '<ipython-input-168-901363ebc86f>', line 8:
return model.x[dest, dg, sg, site]>=200 or model.x[dest, dg, sg, site]<=1
Evaluating Pyomo variables in a Boolean context, e.g.
if expression <= 5:
is generally invalid. If you want to obtain the Boolean value of the
expression based on the current variable values, explicitly evaluate the
expression using the value() function:
if value(expression) <= 5:
or
if value(expression <= 5):
So my understanding is that I cant give Pyomo a boolean expression as a constraint, but I am quite new to Pyomo and not too sure if that's what my issue is or if I am doing it correctly.
This constraint could also be implemented in the variable intialisation as boundaries, but I cant find a way to set up two boundaries on a single variable in Pyomo.
Thanks !
There are different ways to handle this:
(1) Use binary variables. Assume you have a good upper bound on x, i.e., x ∈ [0, U]. Then formulate the constraints
x ≤ 1 + (U-1) δ
x ≥ 200 δ
δ ∈ {0,1} (binary variable)
This is the easiest way.
(2) If you don't have a good upper bound on x, you can use a SOS1 set. (SOS1 means Special Ordered Set of type 1). Assume x,s1,s2 ≥ 0.
x ≤ 1 + s1
x ≥ 200 - s2
s1,s2 ∈ SOS1 (s1,s2 form a SOS1 set)
(3) Use disjunctive programming.