How to make if in the objective function

There is a distinction between conditionals on parameters of the model (i.e., conditionals at the model creation time) and conditionals on variable values (i.e., conditionals at the model evaluation/solving time).

The approach you describe works for conditionals on model parameters (creation time). In your example, you build a non-linear objective function (i.e., variables multiply each other) and the assemblage of the objective function uses if statements. Nice, but this is literally just building a (possibly complicated) polynomial before running the model, and passing the polynomial object to JuMP. How the polynomial was built, if conditionals were used or not, is irrelevant to JuMP. JuMP just received an object describing a polynomial and will pass it to the underlying solver. As for any other method call, the called method (i.e., @objective in this case) has no idea how the values passed as arguments to it were produced. The fact @objective is a macro may lead to confusion, as a macro could have a peek at how the values were produced, but this is not the case here.

The problem is that @sogrbilja wants the JuMP model to behave differently depending on which values the x variables assume during the model solving process by JuMP/‘underlying solver’. This behaviour cannot be straightforwardly described by a simple polynomial object, the conditional must be inside the polynomial, inside the formula, but the polynomial/formula object does not support this construction. This is the reason your suggestion

  sum1 = sum(  PRODAMOUNT[op_k, u_k, t] * _PRODUCTs_ALL[op["product"]]["bagSize"] 
                        for (op_k, op) in _ORDER_PRODUCTs_ALL    )
  if sum1 == 0

will not work: sum1 == 0 always evaluates to false. sum1 is a “polynomial” object with variables x which are of unknown value before solving the model, sum1 is never just the number zero. For @sogrbilja to obtain what he wants, the conditional must be inserted inside the “polynomial” object, for the solver to deal with it during the solving process. There is a trick for doing something like this, and it was mentioned by @odow and reiterated by @tomerarnon:

This is sometimes called a Big-M formulation, and @odow gave an example of the approach here

Big-M formulations have weak bounds and may be hard to prove optimality with them, but they are the only alternative I am aware if you want to model the problem as a MILP (Mixed-Integer Linear Program).

3 Likes