Search code examples
pyomo

Pyomo - Disjunctive Programming - Passing a BigM Suffix


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.


Solution

  • 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