# Mixed integer problem

**URL:** <https://discourse.julialang.org/t/mixed-integer-problem/133624>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [November 3, 2025, 2:52pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624 "2025-11-03T14:52:47Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [November 3, 2025, 2:52pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/1 "2025-11-03T14:52:47Z")

</div>

I attempt to define a mixed-integer optimization problem. To simplify the problem:

I have 10 wind turbines. I have 10 boolean variables that indicate whether the turbine is operating at full or partial power. If it is operating at partial power, it needs a power set value between zero and 100% of the demand. So I have another 10 real variables to optimize. The demand is time varying. The optimization goal is to ensure that demand matches production.

So I have 20 variables. But if some of the Boolean variables are true, then the real value (relative power) of the related turbine does not need to be optimized.

If I define the system in this way, I am concerned that the optimization time may be less than optimal. Can I define the problem in a way that if one of the boolean variables is true, the associated real variable is ignored?

I am using NOMAD.jl .

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [November 3, 2025, 3:06pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/2 "2025-11-03T15:06:14Z")

</div>

I guess you have some constraint making this impractical but the normal approach would be to do away with the booleans and only optimize the relative power values. Then you can infer your booleans from the result.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 3, 2025, 3:07pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/3 "2025-11-03T15:07:23Z")

</div>

> [@ufechner7](#):
>
> I have 10 wind turbines. I have 10 boolean variables that indicate whether the turbine is operating at full or partial power. If it is operating at partial power, it needs a power set value between zero and 100% of the demand.

Why do you need the boolean variables, then? Why not simply let the degrees of freedom be the power % values, bounded \in [0, 100]?

Adding boolean variables doesn’t seem to add anything to your problem, and makes the problem strictly harder (it is _much_ harder to do optimization with discrete parameters than with continuous differentiable parameters).

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [November 3, 2025, 3:16pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/4 "2025-11-03T15:16:00Z")

</div>

> [@stevengj](#):
>
> Why do you need the boolean variables, then? Why not simply let the degrees of freedom be the power % values, bounded \in [0, 100]?

Because ‘always on’ and 100% are not the same. 100% of the demand is less than fully on if the demand is less than 100%.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 3, 2025, 3:33pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/5 "2025-11-03T15:33:25Z")

</div>

> [@ufechner7](#):
>
> Because ‘always on’ and 100% are not the same. 100% of the demand is less than fully on if the demand is less than 100%.

Then why not make the parameter the % of the maximum power? Let the optimization keep this ≤ demand if that’s what is optimal. Or some other variation on this … hard to say without knowing more.

You should generally try hard to frame your optimization in terms of differentiable continuous parameters if at all possible. The whole trick in optimization is often to think more carefully about the problem formulation, rather than taking the problem formulation as a given and spending your time thinking about algorithms.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [November 3, 2025, 3:43pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/6 "2025-11-03T15:43:48Z")

</div>

> [@stevengj](#):
>
> Then why not make the parameter the % of the maximum power?

Not possible, because the parameter I am optimizing is not time-dependent. If I were to make it time-dependent, I would end up with many more variables to optimize. So, I have only three parameters to model the time dependency using a spline, and then one parameter per turbine, representing how much it shall contribute to the total demand.

Okay, what I could do is say that the parameter should be between zero and 2. One would mean 100% of the current demand, and 2 would mean always on.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [November 3, 2025, 3:44pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/7 "2025-11-03T15:44:04Z")

</div>

> [@ufechner7](#):
>
> The optimization goal is to ensure that demand matches production.

This is called a constraint.

> [@ufechner7](#):
>
> If I define the system in this way, I am concerned that the optimization time may be less than optimal.

I didn’t get you.

> [@ufechner7](#):
>
> Can I define the problem in a way that if one of the boolean variables is true, the associated real variable is ignored?

Maybe

```julia-auto
import JuMP
import Random
Random.seed!(1)

G = 3 # num of generators
P = [
    (m = 2, M = 6),
    (m = 1, M = 7),
    (m = 3, M = 8),
] # power range of generators

T = 4 # num of planning stages
D = [10, 20, 4, 16] # demand at each stage

model = JuMP.Model()
JuMP.@variable(model, b[1:T, 1:G], Bin)
JuMP.@variable(model, p[1:T, g = 1:G] ≤ P[g].M)
JuMP.@constraint(model, [t = 1:T, g = 1:G], b[t, g]P[g].M ≤ p[t, g])
JuMP.@constraint(model, [t = 1:T], D[t] ≤ sum(p[t, :]))

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 3, 2025, 4:19pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/8 "2025-11-03T16:19:59Z")

</div>

> [@ufechner7](#):
>
> If I were to make it time-dependent, I would end up with many more variables to optimize.

If you use efficient reverse-mode differentiation, having lots more optimization parameters is not necessarily a problem. The dominant cost is often the number of physics solves, which remains the same regardless of the number of parameters.

> [@ufechner7](#):
>
> Okay, what I could do is say that the parameter should be between zero and 2. One would mean 100% of the current demand, and 2 would mean always on.

Be careful not to make your objective function non-differentiable in the parameters.

One possibility would be to relax your `always_on` boolean variable to a quantity a \in [0, 1], while also having another continous variable p \in [0, 1] representing the “partial power” percentage of demand. Then set the actual power to be something like

P(t) = \max \{ p D(t), a P\_{\max} \}

where P\_{\max} is the maximum power and D(t) \in [0, P\_{\max}] is the demand. This is still non-differentiable because of the `max`, but you could relax that further with a softmax to get a differentiable approximation.

But it also may not be terrible to simply make the time-dependent power the variables and just have a lot of differentiable optimization variables, if you are careful about how you compute derivatives, as I said above.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [November 3, 2025, 4:39pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/9 "2025-11-03T16:39:17Z")

</div>

> [@stevengj](#):
>
> differentiable optimization variables

I don’t have any differentiable variables. I use a non-linear, time- and space-discrete simulation model ([GitHub - ufechner7/FLORIDyn.jl: Dynamic wind farm simulation software](https://github.com/ufechner7/FLORIDyn.jl)) and a black-box optimizer based on the Mesh Adaptive Direct Search (MADS) algorithm.

So I don’t think I have any differentiable variables. Wakes can suddenly change their direction even if one of the control inputs changes only a tiny bit.

One function evaluation needs about 1-2 seconds; therefore, I try to keep the number of function evaluations below 10000.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 3, 2025, 7:11pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/10 "2025-11-03T19:11:05Z")

</div>

> [@ufechner7](#):
>
> I don’t have any differentiable variables. I use a non-linear, time- and space-discrete simulation model

Why does that make it non-differentiable? If it’s a nonlinear system of ODEs \frac{du}{dt} = f(u,t,p) and the rhs is a differentiable function of the parameters p, then so is the solution u(p,t).

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [November 3, 2025, 7:15pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/11 "2025-11-03T19:15:33Z")

</div>

> [@stevengj](#):
>
> Why does that make it non-differentiable?

Well, if the output (the mean square error between the desired and the produced power) jumps when you change one of the control parameters, I would say then it is not differentiable. There might even be some hysteresis.

Is there any systematic way to determine if a problem is differentiable?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 3, 2025, 7:29pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/12 "2025-11-03T19:29:51Z")

</div>

> [@ufechner7](#):
>
> Well, if the output (the mean square error between the desired and the produced power) jumps when you change one of the control parameters, I would say then it is not differentiable. There might even be some hysteresis.

In a nonlinear ODE, the steady-state (t \to \infty) solution can jump discontinuously as you change a parameter, but I don’t see how the **finite-time behavior** can be discontinuous (assuming the rhs is differentiable), even if it changes rapidly?

(Hysteresis is also about jumps in the steady state.)

Indeed, for \frac{\partial u}{\partial t} = f(u,p,t) where the rhs is differentiable in u and p, you can write down an explicit linear ODE that is solved by the Jacobian \partial u/ \partial p, in which all of the terms are finite. (See e.g. section 9.2.1 of our [matrix-calculus course notes](https://arxiv.org/pdf/2501.14787).)

You can, course, have systems where the derivative grows exponentially large, but in some cases you can still get [useful sensitivities with “shadowing” methods](https://docs.sciml.ai/SciMLSensitivity/stable/tutorials/chaotic_ode/).

---

<div class="post-metadata">

**Author:** ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)\
**Post date:** [November 3, 2025, 8:57pm UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/13 "2025-11-03T20:57:58Z")

</div>

Isn’t this just an ordinary optimal control problem?

So if p is your power production and d the demand, you would have:

p \in [p\_{\min}, p\_{\max}]

With p\_{\min} being 0, and p\_{\max} = d. I don’t see why you would need binary variables at all? Or are you are in a situation where p\_{\min} \> 0 and p \in {0} \cup [p\_{\min}, p\_{\max}]?

In that case I only know sub-optimal tricks and I would also be interested in learning more of those.

---

<div class="post-metadata">

**Author:** ![RomeoV](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/romeov/32/37687_2.png) [@RomeoV](https://discourse.julialang.org/u/RomeoV)\
**Post date:** [November 4, 2025, 6:19am UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/14 "2025-11-04T06:19:02Z")

</div>

Not sure if this is obvious, but the most typical thing to do here in mixed integer optimization is to introduce linear constraints such as

```julia-auto
isfullpower = @variable(model, 1:10, Bin)
power = @variable(model, 1:10, 0 <= x[1:10] <= 1)
@constraint(model, power .>= isfullpower)

```

(typed on my phone, haven’t run it)

So this will force the power to be max when the binary variable is set to 1 (i.e., it will be “ignored” in the optimization), and enforce no constraint otherwise.

To get efficient optimization it’s important to avoid nonlinearities (e.g., `power .* isfullpower`) but there’s very efficient algorithms for this formulation based on branch-and-bound and “cuts” in the search space.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [November 4, 2025, 6:24am UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/15 "2025-11-04T06:24:07Z")

</div>

No, branch-and-bound is the last resort.

For large-scale MIPs, branch-and-bound phase can soon become hopeless, e.g.

```julia-auto
julia> JuMP.optimize!(cen)
Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - "Debian GNU/Linux 12 (bookworm)")

CPU model: AMD EPYC 7763 64-Core Processor, instruction set [SSE2|AVX|AVX2]
Thread count: 128 physical cores, 256 logical processors, using up to 4 threads

Non-default parameters:
Threads 4

Optimize a model with 255095 rows, 380304 columns and 1151071 nonzeros
Model fingerprint: 0x1404b631
Variable types: 241296 continuous, 139008 integer (139008 binary)
Coefficient statistics:
  Matrix range [9e-01, 2e+01]
  Objective range [1e+01, 3e+01]
  Bounds range [1e+00, 6e+01]
  RHS range [1e+00, 1e+05]
Presolve removed 45529 rows and 86809 columns
Presolve time: 2.92s
Presolved: 209566 rows, 293495 columns, 926555 nonzeros
Variable types: 165906 continuous, 127589 integer (127589 binary)
Deterministic concurrent LP optimizer: primal simplex, dual simplex, and barrier
Showing barrier log only...

Root barrier log...

Ordering time: 0.06s

Barrier statistics:
 AA' NZ : 4.338e+05
 Factor NZ : 2.239e+06 (roughly 160 MB of memory)
 Factor Ops : 6.271e+07 (less than 1 second per iteration)
 Threads : 1

                  Objective Residual
Iter Primal Dual Primal Dual Compl Time
   0 6.07548150e+08 -1.14935033e+08 1.75e+05 0.00e+00 4.81e+04 5s
   1 2.82978262e+08 -1.27610193e+08 8.05e+04 1.02e+02 2.25e+04 5s
  41 6.22675172e+06 6.22675171e+06 4.20e-09 4.09e-12 4.40e-09 9s

Barrier solved model in 41 iterations and 8.85 seconds (8.11 work units)
Optimal objective 6.22675172e+06

Root crossover log...

   18684 DPushes remaining with DInf 9.9772386e-05 9s
       0 DPushes remaining with DInf 0.0000000e+00 9s

   19260 PPushes remaining with PInf 0.0000000e+00 9s
       0 PPushes remaining with PInf 0.0000000e+00 9s

  Push phase complete: Pinf 0.0000000e+00, Dinf 1.5647128e-10 9s

Root simplex log...

Iteration Objective Primal Inf. Dual Inf. Time
   28777 6.2267517e+06 0.000000e+00 0.000000e+00 9s
Concurrent spin time: 0.00s

Solved with barrier
   29130 6.2267517e+06 0.000000e+00 0.000000e+00 10s
Extra simplex iterations after uncrush: 353

Root relaxation: objective 6.226752e+06, 29130 iterations, 6.14 seconds (5.05 work units)
Total elapsed time = 12.93s (DegenMoves)
Total elapsed time = 15.81s (DegenMoves)

    Nodes | Current Node | Objective Bounds | Work
 Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time

     0 0 6226751.71 0 7891 - 6226751.71 - - 17s
     0 2 6233116.25 0 8284 - 6233116.25 - - 211s
    33 74 6233123.71 7 8553 - 6233120.92 - 304 216s
    73 155 6233124.45 12 8545 - 6233120.92 - 148 220s
   154 332 6233132.50 23 8518 - 6233120.92 - 81.9 229s
   331 513 6233144.97 49 8452 - 6233120.92 - 51.7 241s
   512 765 6233151.52 76 8449 - 6233120.92 - 49.7 254s
   764 974 6233159.08 111 8376 - 6233120.92 - 41.5 269s
   973 1208 6233189.52 141 8350 - 6233120.92 - 37.2 281s
  1211 1458 6233206.16 177 8314 - 6233120.92 - 34.5 294s
...
  5243 5167 6233952.57 255 8633 - 6233952.57 - 25.1 895s
  5247 5170 6233958.06 429 8778 - 6233958.06 - 25.1 904s
  5248 5170 6233963.16 371 8547 - 6233963.16 - 25.1 915s
  5252 5173 6233970.65 214 8771 - 6233970.65 - 25.1 925s
...

```

---

<div class="post-metadata">

**Author:** ![RomeoV](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/romeov/32/37687_2.png) [@RomeoV](https://discourse.julialang.org/u/RomeoV)\
**Post date:** [November 4, 2025, 6:34am UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/17 "2025-11-04T06:34:23Z")

</div>

Can you elaborate your point? Here’s a source for my point.

> Mixed Integer Linear Programming problems are generally solved using a linear-programming based branch-and-bound algorithm.  
> [Mixed-Integer Programming (MIP/MILP) – A Primer on the Basics - Gurobi Optimization](https://www.gurobi.com/resources/mixed-integer-programming-mip-a-primer-on-the-basics/)

Gurobi is (one of) the leading optimizers for mixed integer programming.

Perhaps you’re saying by allowing any discrete variables at all we’re losing a lot of optimization performance? That may be true, but many things are fundamentally “integer valued”.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [November 4, 2025, 6:44am UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/18 "2025-11-04T06:44:19Z")

</div>

MIP by its nature is NP-hard.

Solving an MIP typically has a convex phase (root LP relaxation, adding cutting planes), followed by a branch-and-bound phase. The former is efficient, whereas the latter is not. Its difficulty is inherent, regardless of which solver you go with.

In practice it’s highly problem-dependent. Some problems, despite might look large, may be efficiently solved, whereas some are not.

It is easy to create an MIP instance that let Gurobi struggle in its branch-and-bound phase. e.g.

> [@How can I stop a Gurobi solve in JuMP in real time (like Ctrl+C) and still keep the solution?](https://discourse.julialang.org/t/how-can-i-stop-a-gurobi-solve-in-jump-in-real-time-like-ctrl-c-and-still-keep-the-solution/132841/2):
>
> Please press once. e.g. import JuMP, Gurobi, SparseArrays N = 50 # 754 seconds Q = 1. \* SparseArrays.dropzeros( SparseArrays.spdiagm( [i =\> rand(-9:9, N - i) for i in 0:div(N, 2)]... ) ) m = JuMP.Model(); JuMP.@variable(m, rand(-7:-3) \<= y[1:N] \<= rand(3:7)); JuMP.@variable(m, rand(-9:-5) \<= x[1:N] \<= rand(5:9)); JuMP.@objective(m, Min, (x'Q)y); JuMP.set\_optimizer(m, Gurobi.Optimizer) JuMP.optimize!(m); JuMP.solution\_summary(m) test: julia\> JuMP.optimize!(m); JuMP.solution\_s…

> [@RomeoV](#):
>
> Perhaps you’re saying by allowing any discrete variables at all we’re losing a lot of optimization performance? That may be true, but many things are fundamentally “integer valued”.

Integer variables should be added only when they are necessary.

* * *

By the way, @ufechner7 your title is too big, that attracts everyone to take a look.

---

<div class="post-metadata">

**Author:** ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)\
**Post date:** [November 10, 2025, 10:37am UTC](https://discourse.julialang.org/t/mixed-integer-problem/133624/19 "2025-11-10T10:37:47Z")

</div>

Dear @ufechner7,

I just went through the thread. If you’re still working on this topic, can you elaborate a bit the problem description. For the moment I grabbed the following quotes from post 1 and 6:

> [@ufechner7](#):
>
> I have 10 wind turbines. I have 10 boolean variables that indicate whether the turbine is operating at full or partial power. If it is operating at partial power, it needs a power set value between zero and 100% of the demand. So I have another 10 real variables to optimize. The demand is time varying. The optimization goal is to ensure that demand matches production.

> [@ufechner7](#):
>
> Not possible, because the parameter I am optimizing is not time-dependent. If I were to make it time-dependent, I would end up with many more variables to optimize. So, I have only three parameters to model the time dependency using a spline, and then one parameter per turbine, representing how much it shall contribute to the total demand.

So at first I thought you are working on a static problem, but then you mentioned working with `FLORIDyn.jl`. I understand that you use it as a black box wind power times series generator. Is my guess correct? If so, can you give a bit more detail about the temporal aspects, in particular the time step and number of time step in the wind time series and the demand time series?

Since you stated your intention to work with constant control parameters, I am guessing that you are working with pretty long time series, thus you’re reluctance to switch to time-varying control parameters. Is this correct?

Finally, can you elaborate on the spline you want to use: is it a kind of nonlinear control feedback?

Also, one thing I didn’t understand in your first question: "If it is operating at partial power, it needs a power set value between zero and 100% of the demand"→ Fine, at _partial power_ this imposes the constraint Pwind ≤ Pdemand. However, if the turbine operates at _full power_, then it seems that the Pwind ≤ Pdemand constraint is not guaranteed anymore. Can this create an overproduction issue or do you plan to reduce the power of other turbines?
