I am implementing a disjunctive programming problem in Pyomo. In the disjuncts I have nonconvex nonlinear constraints. Therefore I can't use the BigM transformation directly. I have to pass suffixes with the values of the bigM. Here is a snippet of my code:
m = ConcreteModel()
m.Block1 = Block()
#... Here some variables and other constraints are defined.
# Defining the rule for the disjunct:
def _d(disjunct, flag):
m = disjunct.parent_block()
if flag:
# Here 2 constraints are valid
disjunct.c1 = Constraint(expr=x1==0)
disjunct.c2 = Constraint(expr=x2==0)
else:
# Here 7 constraints are valid
disjunct.c1 = Constraint(expr=y1==0)
disjunct.c2 = Constraint(expr=y2==0)
disjunct.c3 = Constraint(expr=y3==0)
...
# Define the disjunct:
m.Block1.d1 = Disjunct([0,1], rule=_d)
# Define the disjunction
def _c1(model):
return [model.d1[0], model.d1[1]]
m.Block1.c1 = Disjunction(rule=_c1)
# Applying the transformation:
TransformationFactory('gdp.bigm').apply_to(m)
I have to pass suffixes for the bigM and don't know how to do this. Also how can this be done with different bigM-values for different constraints?
I'm looking forward for your help.
For linear constraints, Pyomo can automatically compute appropriate big-M values for you. For nonlinear constraints, you'll want to add:
m.BigM = Suffix(direction=Suffix.LOCAL)
m.BigM[m.Block1.d1[0].c1] = your_value_here
Note that different ways of expressing disjunctions are also available, which might make things easier for you. I personally like option 2 the best if I want to be clear, and option 3 if I want to be more concise: http://pyomo.readthedocs.io/en/latest/modeling_extensions/gdp.html