Pyomo and conditional objective function

2019-07-27 02:42发布

问题:

Is it possible (and if so how) to use an objective function that has a conditional expression?

Changing the example from the docs, I would like an expression like:

def objective_function(model):
   return model.x[0] if model.x[1] < const else model.x[2]

model.Obj = Objective(rule=objective_function, sense=maximize)

Can this be modelled directly like this or do I have to consider some sort of transformation (and if so how would this look like)?

Just executing the above gives an error message like:

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):

which I think is because Pyomo thinks I'd like to obtain a value, instead of an expression with the variable.

回答1:

One way to formulate that is by using a logical disjunction. You can look into the Pyomo.GDP documentation for usage, but it would look like:

m.helper_var = Var()
m.obj = Objective(expr=m.helper_var)
m.lessthan = Disjunct()
m.lessthan.linker = Constraint(expr=m.helper_var == m.x[0])
m.lessthan.constr = Constraint(expr=m.x[1] < const)
m.greaterthan = Disjunct()
m.greaterthan.linker = Constraint(expr=m.helper_var == m.x[2])
m.greaterthan.constr = Constraint(expr=m.x[1] >= const)
m.lessthanorgreaterthan = Disjunction(expr=[m.lessthan, m.greaterthan])
# some kind of transformation (convex hull or big-M)

You can also formulate this using complementarity constraints.