Binary variables in Ipopt

I am using Ipopt in JuMP to solve a non-linear hydropower optimization problem. After realizing that there may be spillage in periods where the reservoir is half empty, I want to add a constraint which only allows spillage if the reservoir in the end of a period is full:

@constraint(model, spi[t, n] <= max_inflow * delta[t, n])
@constraint(model, max_capacity - l[t, n]  <= max_capacity * (1 - delta[t, n]))

Here, spi is the spillage variable for node n in time period t and l is the reservoir level in the end of time period t in node n. The delta variable is the binary variable.

Since Ipopt does not handle binary variables I am looking for an alternative way to formulate this restriction. I would like a reformulation which works with Ipopt and not a solver which can solve non-linear problems with binary variables. The reason for this is that I have tried to use Juniper, but the problem is too big to solve (I always get a memory error).

1 Like

This type of constraint is also known as a complementarity constraint.

Assuming that your spi[t, n] variable is non-negative, and that l[t,n] <= max_capacity always holds, then you can write it as

@constraint(model, spi[t, n] * (max_capacity - l[t, n]) == 0)

To see that it’s equivalent to your previous formulation, note that this constraint enforces that the product of two non-negative numbers is equal to zero.
This cannot happen if both terms are positive.

If you take a look at the link above, you will see that JuMP has various ways of formulating such constraints.

Finally, note that mixed-complementarity problems are notoriously hard to solve. Ipopt is not guaranteed to yield a global optimum, or even a feasible solution.
The quality of the result will likely depend on the quality of the starting point.


Note that i still need to write a complementarity to nonlinear bridge, so at the moment you cannot use JuMPs complementarity constraints with Ipopt. You need to write the reformulation manually.

1 Like