# Binary variables in Ipopt

**URL:** https://discourse.julialang.org/t/binary-variables-in-ipopt/114111
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [May 10, 2024, 2:44pm UTC](https://discourse.julialang.org/t/binary-variables-in-ipopt/114111 "2024-05-10T14:44:53Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![heiwie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heiwie/32/208105_2.png) [@heiwie](https://discourse.julialang.org/u/heiwie)
#### Post date: [May 10, 2024, 2:44pm UTC](https://discourse.julialang.org/t/binary-variables-in-ipopt/114111/1 "2024-05-10T14:44:53Z")

</div>

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:

```julia
@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).

---

<div class="post-metadata">

### Author: ![mtanneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mtanneau/32/17787_2.png) [@mtanneau](https://discourse.julialang.org/u/mtanneau)
#### Post date: [May 10, 2024, 8:29pm UTC](https://discourse.julialang.org/t/binary-variables-in-ipopt/114111/2 "2024-05-10T20:29:07Z")

</div>

This type of constraint is also known as a [_complementarity constraint_](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/complementarity/).

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

```julia
@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.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 10, 2024, 9:25pm UTC](https://discourse.julialang.org/t/binary-variables-in-ipopt/114111/3 "2024-05-10T21:25:07Z")

</div>

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.
