# Could not solve optimization problem with max/min in constraints

**URL:** https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [August 5, 2024, 12:11pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839 "2024-08-05T12:11:15Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![VPBML](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vpbml/32/212617_2.png) [@VPBML](https://discourse.julialang.org/u/VPBML)
#### Post date: [August 5, 2024, 12:11pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/1 "2024-08-05T12:11:15Z")

</div>

Hi,  
I wonder why JuMP could not solve the following optimization problem with max/min in the constraints. I would really appreciate it if you could show me how to solve this issue.

```julia
using JuMP, Ipopt

model = Model(Ipopt.Optimizer);
set_silent(model)
@variable(model, ir1, start = 3.0)
@variable(model, ir2, start = 3.0)
@variable(model, ir3, start = 3.0)
@variable(model, SP, start = 5.0)
@variable(model, yA, start = 1.0)
@variable(model, yF, start = 2.0)

@NLobjective(model, Min, 1.0)
@NLconstraint(model, ir2 - min(ir1, yA*SP) == 0)
@NLconstraint(model, ir2 - yF == 0)
@NLconstraint(model, ir3 - max(ir1, yF) == 0)
@NLconstraint(model, ir3 - yA*SP == 0)
@NLconstraint(model, yA - 1.0 == 0)
@NLconstraint(model, yF - 2.0 == 0)
@NLconstraint(model, SP*yA - yF == 0)
optimize!(model)

```

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [August 5, 2024, 2:43pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/2 "2024-08-05T14:43:48Z")

</div>

First, it is always useful not to set the solver as silent when debugging the problem. By not setting `set_silent(model)` you would have got

```julia
This is Ipopt version 3.14.16, running with linear solver MUMPS 5.7.3.

Number of nonzeros in equality constraint Jacobian...: 17
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 11

Exception of type: TOO_FEW_DOF in file "Interfaces/IpIpoptApplication.cpp" at line 662:
 Exception message: status != TOO_FEW_DEGREES_OF_FREEDOM evaluated false: Too few degrees of freedom (rethrown)!

EXIT: Problem has too few degrees of freedom.

```

This already gives some hints, doesn’t it?

Even with a naked eye, I can see that since `yA=1` and `yF=2`, from the last equation `SP = yF/ya=2`, from the second equation `ir2=2`, from the fourth equation `ir3= 2`. What remains are two equations: `2 = min(ir1,2)` and `3=max(ir1,2)`. Just one variable and two equations.

Well, the original problem has six variables and seven equations. We did not know at the beginning if the equations are redundant, that is why I solved the problem, but redundancy of equations would be undesirable anyway.

By the way, it is no longer needed to use the NL-prefix when specifying nonlinear objective and constraints, see [Nonlinear Modeling · JuMP](https://jump.dev/JuMP.jl/stable/manual/nonlinear/).

One last thing: minimising the cost function f(x)=1 is trivial.

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [August 5, 2024, 3:10pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/3 "2024-08-05T15:10:59Z")

</div>

By the way, the equality constraint

x\_1 = \min(x\_2,x\_3x\_4)

containing minimization can be rewritten as a set of common linear/nonlinear equality and inequality constraints upon introducing an auxiliary variable

\begin{aligned} y &\leq x\_2\\ y &\leq x\_3x\_4\\ x\_1 &= y. \end{aligned}

But I guess that JuMP does this transformation automatically.

---

<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: [August 5, 2024, 9:13pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/4 "2024-08-05T21:13:23Z")

</div>

@VPBML, as @zdenek_hurak explains, your problem just doesn’t make much sense. You have 6 variables, seven constraints, and there is a single solution with every variable = 2 except yA = 1.

If you relax some of the constraints like `yA == 1` to be fixed variable bounds, we can get a solution:

```julia
using JuMP, Ipopt
model = Model(Ipopt.Optimizer);
# set_silent(model)
@variable(model, ir1, start = 3.0)
@variable(model, ir2, start = 3.0)
@variable(model, ir3, start = 3.0)
@variable(model, SP, start = 5.0)
@variable(model, yA, start = 1.0)
@variable(model, yF, start = 2.0)
@constraint(model, ir2 == min(ir1, yA*SP))
@constraint(model, ir2 == yF)
@constraint(model, ir3 == max(ir1, yF))
@constraint(model, ir3 == yA*SP)
fix(yA, 1.0)
fix(yF, 2.0)
@constraint(model, SP*yA == yF)
optimize!(model)

```

> [@zdenek\_hurak](#):
>
> But I guess that JuMP does this transformation automatically.

Nope. We use the non-smooth formulation `z = min(x, y)` directly.

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [August 5, 2024, 9:22pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/5 "2024-08-05T21:22:38Z")

</div>

Apparently, essentially the same problem is also discussed in the parallel thread [How to solve a nonlinear system with redundancy with NonlinearSolve.jl](https://discourse.julialang.org/t/how-to-solve-a-nonlinear-system-with-redundancy-with-nonlinearsolve-jl/117840).

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [August 5, 2024, 10:35pm UTC](https://discourse.julialang.org/t/could-not-solve-optimization-problem-with-max-min-in-constraints/117839/6 "2024-08-05T22:35:50Z")

</div>

> [@odow](#):
>
> > [@zdenek\_hurak](#):
> >
> > But I guess that JuMP does this transformation automatically.
> 
> Nope. We use the non-smooth formulation `z = min(x, y)` directly.

I was just wondering, is there any general advantage or disadvantage in one or the other formulation of the constraints from the perspective of solvers?

In particular, the formulation containing the `min`, that is, defining `f(x,y,z) = x - min(y,z)`, the equality constraint is `f(x,y,z) = 0`. And the formulation avoiding the `min`, that is, defining `F(x,y,z) = [x-y; x-z]`, the vector inequality constraint is `F(x,y,z) <= [0; 0] `? The function `f` defining the former is nonsmooth, while the function `F` defining the latter is smooth.
