# Multi-objective MINLP problem in JuMP

**URL:** https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117
**Category:** Optimization (Mathematical)
**Tags:** jump, gurobi
**Created:** [August 23, 2023, 4:12pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117 "2023-08-23T16:12:19Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 23, 2023, 4:12pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/1 "2023-08-23T16:12:19Z")

</div>

In the continuation of [this comment](https://github.com/anriseth/MultiJuMP.jl/pull/55#issuecomment-1689602292) and [this post](https://discourse.julialang.org/t/help-with-multi-objective-non-linear-jump-problem/98487/5), I was wondering about the implementation of a multi-objective MINLP problem in JuMP using [MOA](https://github.com/jump-dev/MultiObjectiveAlgorithms.jl).  
Since @Arpit_Bhatia used `MOA` for a [nonlinear multi-objective portfolio optimization](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/portfolio/#Multi-objective-portfolio-optimization) problem (by Ipopt solver) and in the [JuMP’s main example for multi-objective optimization](https://jump.dev/JuMP.jl/stable/tutorials/linear/multi_objective_knapsack/#Multi-objective-knapsack), it has been applied to a MIP (by HiGHS solver), now how we can combine them to use `MOA` for MINLP (e.g. by [Juniper](https://github.com/lanl-ansi/Juniper.jl))?

---

<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 23, 2023, 7:40pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/2 "2023-08-23T19:40:17Z")

</div>

Do you have an example that doesn’t work? It should be fine.

```julia
julia> using JuMP

julia> import Ipopt

julia> import Juniper

julia> import MultiObjectiveAlgorithms as MOA

julia> ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
MathOptInterface.OptimizerWithAttributes(Ipopt.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("print_level") => 0])

julia> juniper = optimizer_with_attributes(Juniper.Optimizer, "nl_solver" => ipopt)
MathOptInterface.OptimizerWithAttributes(Juniper.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("nl_solver") => MathOptInterface.OptimizerWithAttributes(Ipopt.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("print_level") => 0])])

julia> model = Model(() -> MOA.Optimizer(juniper))
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: MOA[algorithm=MultiObjectiveAlgorithms.Lexicographic, optimizer=Juniper]

julia> set_silent(model)

julia> set_attribute(model, MOA.Algorithm(), MOA.Dichotomy())

julia> set_attribute(model, MOA.SolutionLimit(), 10)

julia> @variable(model, 1 <= x[1:5] <= 5, Int)
5-element Vector{VariableRef}:
 x[1]
 x[2]
 x[3]
 x[4]
 x[5]

julia> @variable(model, obj[1:2])
2-element Vector{VariableRef}:
 obj[1]
 obj[2]

julia> @objective(model, Max, obj)
2-element Vector{VariableRef}:
 obj[1]
 obj[2]

julia> @NLconstraint(model, obj[1] <= sum(log(x[i]) for i in 1:5))
(obj[1] - (log(x[1]) + log(x[2]) + log(x[3]) + log(x[4]) + log(x[5]))) - 0.0 ≤ 0

julia> c = rand(5)
5-element Vector{Float64}:
 0.9564024316877537
 0.3761897861649184
 0.9402157284498638
 0.5496119699788227
 0.2809383737680249

julia> @NLconstraint(model, obj[2] <= sum(c[i] * x[i] for i in 1:5))
(obj[2] - (0.9564024316877537 * x[1] + 0.3761897861649184 * x[2] + 0.9402157284498638 * x[3] + 0.5496119699788227 * x[4] + 0.2809383737680249 * x[5])) - 0.0 ≤ 0

julia> @constraint(model, sum(x) <= 20)
x[1] + x[2] + x[3] + x[4] + x[5] ≤ 20

julia> optimize!(model)

julia> solution_summary(model)
* Solver : MOA[algorithm=MultiObjectiveAlgorithms.Dichotomy, optimizer=Juniper]

* Status
  Result count : 10
  Termination status : LOCALLY_SOLVED
  Message from the solver:
  "Solve complete. Found 10 solution(s)"

* Candidate solution (result #1)
  Primal status : FEASIBLE_POINT
  Dual status : NO_SOLUTION
  Objective value : [6.93147e+00,-8.06555e+03]
  Objective bound : [6.93147e+00,1.40168e+01]
  Relative gap : 0.00000e+00

* Work counters
  Solve time (sec) : 4.35057e-01

```

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 24, 2023, 8:47am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/3 "2023-08-24T08:47:02Z")

</div>

Thanks for the response. Consider the following code:

```julia
A = rand(1,10)
B = rand(1,10)

T=length(A)
M=10^6

c_S = 60
c_R = 100

using JuMP
import Juniper
import HiGHS
import MultiObjectiveAlgorithms as MOA

model = JuMP.Model(() -> MOA.Optimizer(HiGHS.Optimizer))

set_attribute(model, MOA.Algorithm(), MOA.Dichotomy())
set_attribute(model, MOA.SolutionLimit(), 5)

@variable(model, S >= 0);
@variable(model, 1 <= R <= 3);
@variable(model, y1[t = 1:T], Bin);
@variable(model, y2[t = 1:T], Bin);
@variable(model, Y[t = 1:T] >= 0);
@variable(model, O[t = 1:T] >= 0);
@variable(model, V[t = 0:T] >= 0);
@variable(model, Q[t = 1:T] >= 0);

@constraint(model, V[0] == 0);
@constraint(model, [t in 1:T], Q[t] == B[t] * R);

@constraint(model, [t in 1:T], Y[t] <= A[t]);
@constraint(model, [t in 1:T], Y[t] <= V[t-1]);
@constraint(model, [t in 1:T], Y[t] >= A[t] - M * (1 - y1[t]));
@constraint(model, [t in 1:T], Y[t] >= V[t-1] - M * y1[t]);

@constraint(model, [t in 1:T], V[t] <= V[t-1] + Q[t] - O[t] - Y[t]);
@constraint(model, [t in 1:T], V[t] <= S - Y[t]);
@constraint(model, [t in 1:T], V[t] >= V[t-1] + Q[t] - O[t] - Y[t] - M * (1 - y2[t]));
@constraint(model, [t in 1:T], V[t] >= S - Y[t] - M * y2[t]);

@objective(model, Max, [-c_S * S - c_R * R, sum(Y[t] for t in 1:T)])

optimize!(model)
solution_summary(model)

println(objective_value(model))
println("S = ", value.(S), "\n","A = ",value.(R))

```

Now I want to have a solution when I am changing the first objective function to the quadratic term `-c_S * S^2 - c_R * R` (similar to the approach of @Arpit_Bhatia in [NL MO portfolio optimization](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/portfolio/#Multi-objective-portfolio-optimization)).

---

<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 24, 2023, 9:32am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/4 "2023-08-24T09:32:36Z")

</div>

You need to use a solver that supports mixed integer quadratic programs. Use Juniper like i did above, or use Gurobi.

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 24, 2023, 10:39am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/5 "2023-08-24T10:39:14Z")

</div>

When I just replaced `HiGHS` with `Ipopt` and `Juniper`, without changing the objective function into a quadratic form, the code takes lots of time to run. It’s still running! What do you think about?

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 24, 2023, 10:43am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/6 "2023-08-24T10:43:49Z")

</div>

I just replaced

```julia
import HiGHS
import MultiObjectiveAlgorithms as MOA

model = JuMP.Model(() -> MOA.Optimizer(HiGHS.Optimizer))

set_attribute(model, MOA.Algorithm(), MOA.Dichotomy())
set_attribute(model, MOA.SolutionLimit(), 5)

```

with

```julia
import Ipopt

import Juniper

import MultiObjectiveAlgorithms as MOA

ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)

juniper = optimizer_with_attributes(Juniper.Optimizer, "nl_solver" => ipopt)

model = Model(() -> MOA.Optimizer(juniper))

set_silent(model)

set_attribute(model, MOA.Algorithm(), MOA.Dichotomy())

set_attribute(model, MOA.SolutionLimit(), 10)

```

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 24, 2023, 1:01pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/7 "2023-08-24T13:01:42Z")

</div>

Do you have any idea about difference between running time of these two set of solvers for this problem?

---

<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 24, 2023, 5:23pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/8 "2023-08-24T17:23:08Z")

</div>

Gurobi will be faster

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 25, 2023, 3:45pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/9 "2023-08-25T15:45:47Z")

</div>

When I used the `Gurobi`, I got this error:

> MathOptInterface.SetAttributeNotAllowed{MathOptInterface.TimeLimitSec}: Setting attribute MathOptInterface.TimeLimitSec() cannot be performed. You may want to use a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call `reset_optimizer` before doing this operation if the `CachingOptimizer` is in `MANUAL` mode.

---

<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 25, 2023, 10:05pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/10 "2023-08-25T22:05:34Z")

</div>

This looks like a bug in Gurobi.jl. Let me fix it: [Fix support for MOI.TimeLimitSec by odow · Pull Request #518 · jump-dev/Gurobi.jl · GitHub](https://github.com/jump-dev/Gurobi.jl/pull/518)

---

<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 25, 2023, 11:42pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/11 "2023-08-25T23:42:14Z")

</div>

Fixed if you update Gurobi.jl to the newest version (v1.0.3)

Here’s how I would write your model:

```julia
using JuMP
import Gurobi
import MultiObjectiveAlgorithms as MOA
A = rand(1,10)
B = rand(1,10)
T = length(A)
M = 10^6
c_S = 60
c_R = 100
model = Model(() -> MOA.Optimizer(Gurobi.Optimizer));
set_silent(model)
set_attribute(model, MOA.Algorithm(), MOA.Dichotomy())
set_attribute(model, MOA.SolutionLimit(), 5)
@variables(model, begin
    0 <= S
    1 <= R <= 3
    y1[1:T], Bin
    y2[1:T], Bin
    0 <= Y[t = 1:T] <= A[t]
    0 <= O[1:T]
    0 <= V[0:T]
end);
fix(V[0], 0; force = true)
@expressions(model, begin
    Q[t in 1:T], B[t] * R
end)
@constraints(model, begin
    [t in 1:T], Y[t] <= V[t-1]
    [t in 1:T], Y[t] >= A[t] - M * (1 - y1[t])
    [t in 1:T], Y[t] >= V[t-1] - M * y1[t]
    [t in 1:T], V[t] <= V[t-1] + Q[t] - O[t] - Y[t]
    [t in 1:T], V[t] <= S - Y[t]
    [t in 1:T], V[t] >= V[t-1] + Q[t] - O[t] - Y[t] - M * (1 - y2[t])
    [t in 1:T], V[t] >= S - Y[t] - M * y2[t]
end);
@objective(model, Max, [-c_S * S - c_R * R, sum(Y)])
optimize!(model)
solution_summary(model)

```

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 26, 2023, 9:18am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/12 "2023-08-26T09:18:45Z")

</div>

It’s completely solved. I really appreciate you taking the time to rewrite my code into a nice structure.

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 26, 2023, 9:25am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/13 "2023-08-26T09:25:36Z")

</div>

My problem was solved, but since `Ipopt` + `Juniper` got an uncommon time (for me infinite) for running the code, It might be troubleshooting to have a look at it.

---

<div class="post-metadata">

### Author: ![JackaChou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jackachou/32/35269_2.png) [@JackaChou](https://discourse.julialang.org/u/JackaChou)
#### Post date: [August 27, 2023, 1:19am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/14 "2023-08-27T01:19:25Z")

</div>

Infinite time?

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 27, 2023, 12:58pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/15 "2023-08-27T12:58:09Z")

</div>

Yes, when I ran the above code with `Juniper` and `Ipopt` as the NL solver, I did not get response (my kernel was running for a long time …)

---

<div class="post-metadata">

### Author: ![JackaChou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jackachou/32/35269_2.png) [@JackaChou](https://discourse.julialang.org/u/JackaChou)
#### Post date: [August 28, 2023, 3:08am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/16 "2023-08-28T03:08:51Z")

</div>

Could u please share the code.

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 28, 2023, 10:49am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/17 "2023-08-28T10:49:14Z")

</div>

Yes, exactly [this](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/3)

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [August 28, 2023, 11:04am UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/18 "2023-08-28T11:04:08Z")

</div>

Using the code written by @odow solved the issue!  
**But still** , for my real case with vector size `A` of 365\*10, the solution time is infinite.

---

<div class="post-metadata">

### Author: ![ashefa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashefa/32/2525_2.png) [@ashefa](https://discourse.julialang.org/u/ashefa)
#### Post date: [September 28, 2023, 2:50pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/19 "2023-09-28T14:50:08Z")

</div>

Just one question about quadratic term in the multi-objective optimization. As it is mentioned in [this post](https://discourse.julialang.org/t/jump-constrain-with-quadratic-equation/91432/4) “HiGHS supports quadratic objectives”, but I got `BoundsError: attempt to access 0-element Vector{MultiObjectiveAlgorithms.SolutionPoint} at index [1] ` for this type of objectives in the multi-objective mode! Can you explain the reason?

---

<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: [September 28, 2023, 5:43pm UTC](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117/20 "2023-09-28T17:43:12Z")

</div>

Your problem didn’t find a solution. What does `solution_summary(model)` say?

[Next page](https://discourse.julialang.org/t/multi-objective-minlp-problem-in-jump/103117.md?page=2)
