# Multi-objective: have no optimal solutions after changing the priority of the objectives

**URL:** <https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump, gurobi\
**Created:** [December 27, 2023, 2:39am UTC](https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078 "2023-12-27T02:39:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shaolin](https://avatars.discourse-cdn.com/v4/letter/s/e0b2c6/32.png) [@Shaolin](https://discourse.julialang.org/u/Shaolin)\
**Post date:** [December 27, 2023, 2:39am UTC](https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078/1 "2023-12-27T02:39:45Z")

</div>

Hi,  
I have a 4-objective optimization model using Gurobi, and there was the optimal solution when I set the poriority of one order (e.g. [4,3,2,1]). but when the priority changes ((e.g. [2,3,4,1])), the optimal solution cannot be obtained.

Below is the simple code I set and ran. Is there any wrong with this set?

```julia
using JuMP, Gurobi
import MultiObjectiveAlgorithms as MOA

model = Model()
@variable(…)
@constraint(…)
@expression(model,f1,…)
@expression(model,f2,…)
@expression(model,f3,…)
@expression(model,f4,…)
@objective(model,Min,[f1, f2, f3, f4])

set_optimizer(model, () -> MOA.Optimizer(Gurobi.Optimizer))
set_attribute(model, MOA.Algorithm(), MOA.Hierarchical())

set_attribute(model, MOA.ObjectivePriority(1), 4)  
set_attribute(model, MOA.ObjectivePriority(2), 3)
set_attribute(model, MOA.ObjectivePriority(3), 2)
set_attribute(model, MOA.ObjectivePriority(4), 1)

optimize!(model)

```

And below is the output when there was no optimal solution.

```julia
Optimize a model with 2054 rows, 13260 columns and 46184 nonzeros      
Coefficient statistics:
  Matrix range [1e+00, 5e+10]
  Objective range [1e+00, 5e+06]
  Bounds range [1e+00, 1e+00]
  RHS range [1e+00, 1e+11]
Warning: Model contains large matrix coefficients
Warning: Model contains large rhs
         Consider reformulating model or setting NumericFocus parameter to avoid numerical issues.
LP warm-start: use basis
Warning: Markowitz tolerance tightened to 0.03125
Iteration Objective Primal Inf. Dual Inf. Time        
       0 -1.6384000e+34 7.420476e+36 1.638400e+04 0s        
       1 9.7566885e+07 0.000000e+00 0.000000e+00 0s        

Solved in 1 iterations and 0.02 seconds (0.00 work units)
Optimal objective 9.756688463e+07

User-callback calls 27, time in user-callback 0.00 sec
Gurobi Optimizer version 11.0.0 build v11.0.0rc2 (win64 - Windows 10.0 
(19045.2))

CPU model: Intel(R) Xeon(R) CPU E5-1620 v4 @ 3.50GHz, instruction set [SSE2|AVX|AVX2]
Thread count: 4 physical cores, 8 logical processors, using up to 4 threads

Optimize a model with 2055 rows, 13260 columns and 59444 nonzeros      
Coefficient statistics:
  Matrix range [1e+00, 5e+10]
  Objective range [4e+05, 1e+13]
  Bounds range [1e+00, 1e+00]
  RHS range [1e+00, 1e+11]
Warning: Model contains large matrix coefficients
Warning: Model contains large objective coefficients
Warning: Model contains large rhs
         Consider reformulating model or setting NumericFocus parameter to avoid numerical issues.
LP warm-start: use basis
Iteration Objective Primal Inf. Dual Inf. Time
       0 -1.2542692e+40 4.531669e+33 1.254269e+10 0s        

Solved in 1850 iterations and 0.09 seconds (0.11 work units)
Infeasible model

User-callback calls 1879, time in user-callback 0.00 sec

```

Thanks.

---

<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:** [December 27, 2023, 3:34am UTC](https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078/2 "2023-12-27T03:34:01Z")

</div>

Hi @Shaolin, thanks for posting the question over here.

Can you include a reproducible example?

When I use the data you sent me, I get:

```julia
julia> solution_summary(model)
* Solver : MOA[algorithm=MultiObjectiveAlgorithms.Hierarchical, optimizer=Gurobi]

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

* Candidate solution (result #1)
  Primal status : FEASIBLE_POINT
  Dual status : NO_SOLUTION
  Objective value : [-3.15912e+10,1.04274e+14,1.17896e+08,3.32927e+07]
  Objective bound : [-3.15912e+10,1.04274e+14,1.07637e+08,3.06829e+07]
  Dual objective value : 3.06829e+07

* Work counters
  Solve time (sec) : 2.49966e+00
  Barrier iterations : 0
  Node count : 0

```

Without looking too deeply, the biggest issue appears to be:

> [@Shaolin](#):
>
> ```julia
> Warning: Model contains large matrix coefficients
> Warning: Model contains large objective coefficients
> Warning: Model contains large rhs
> Consider reformulating model or setting NumericFocus parameter to avoid numerical issues.
> 
> ```

Try to rescale your model so that the coefficients are 1e6 or smaller. For example, the `Water_min` objective has a value of `1e14`. Use a different unit, like mega-liters instead of liters.

---

<div class="post-metadata">

**Author:** ![Shaolin](https://avatars.discourse-cdn.com/v4/letter/s/e0b2c6/32.png) [@Shaolin](https://discourse.julialang.org/u/Shaolin)\
**Post date:** [December 27, 2023, 7:07am UTC](https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078/3 "2023-12-27T07:07:20Z")

</div>

Hi @odow , thank you for your comments.  
I changed the units and no longer get the warning. But still can’t find the optimal solution when the priority changes, like:

```julia
set_attribute(model, MOA.ObjectivePriority(1), 2) 
set_attribute(model, MOA.ObjectivePriority(2), 3)
set_attribute(model, MOA.ObjectivePriority(3), 4)
set_attribute(model, MOA.ObjectivePriority(4), 1)

```

And here the clean code and data.

[code&data](https://drive.google.com/file/d/1fWs_gYk3rQKaYXyCbyjYzDDKrbIZ1PK-/view?usp=sharing)

---

<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:** [December 29, 2023, 2:38am UTC](https://discourse.julialang.org/t/multi-objective-have-no-optimal-solutions-after-changing-the-priority-of-the-objectives/108078/4 "2023-12-29T02:38:59Z")

</div>

You really need to change the units on the constraints, not just by re-scaling the objective.

Gurobi has a good set of articles on numerical issues:

> **[Guidelines for Numerical Issues - Gurobi Optimization](https://www.gurobi.com/documentation/current/refman/guidelines_for_numerical_i.html)**
>
> Est. reading time: 1 minute

> **[Avoid hiding large coefficients - Gurobi Optimization](https://www.gurobi.com/documentation/current/refman/avoid_hiding_large_coeffic.html)**
>
> Est. reading time: 1 minute

> **[Why scaling and geometry is relevant - Gurobi Optimization](https://www.gurobi.com/documentation/current/refman/why_scaling_and_geometry_i.html)**
>
> Est. reading time: 1 minute

Here’s how I’d write your model:

```julia
using JuMP
import CSV
import DataFrames
import Gurobi
import MultiObjectiveAlgorithms as MOA

data = CSV.read("data.csv", DataFrames.DataFrame)
n = nrow(data)

PI = [623.75,357.37,227.91,701.06,197.26,4527.03,293.04,-16.82,479.54,923.48,426.19,282.5566667,132.8]
WI = [206,1160,3016,1726,1598,365,1010,1876,230,302,2871,1433,2340]
FI = [12.32429686,5.759303271,1.486327048,3.205533846,5.881588758,9.323822963,5.312003246,3.847869561,6.821161941,4.193942646,3.57359744,5.650965092,7.696433774]
GI = [1.19,0.74,0.35,0.63,0.61,0.94,6.84,0.99,1.27,1.33,1.28,0.28,0.61]
XI = [11888.218490594381, 12414.226607455736, 533.9122822424877, 183.48414095294515, 3650.7712263207227, 104594.74027733805, 19355.056903806755, 1133.9787794219592, 10.221437080474042, 27586.665274751886, 2765.6134903319276, 2424.772619481199, 26.692913728869367]

for j in 1:13
    data[:, "Y$j"] ./= 1_000
end
data[!, "Cr"] = data[:,"Cr"] ./ 1_000_000
XI ./= 1_000

model = Model()
@variable(model, 0 <= X[i in 1:n, j in 1:13] <= ceil(data[i, "R$j"]))
@constraints(model, begin
    [i in 1:n], sum(X[i, :]) <= 1
    [i in 1:n], sum(X[i,j]*data[i,"Y$j"]*WI[j] for j in 1:13) <= data[i, "w2020"]
    X * FI .<= data[:, "f2020"]
    X * GI .<= data[:, "g2020"]
    X * PI .>= data[:, "p2020"]
    [j in 1:13], sum(data[i,"Y$j"]*X[i,j]*data[i,"Cr"] for i in 1:n) >= XI[j]
end)
@expressions(model, begin
    W_min, sum(sum(X[i,j] * data[i,"Y$j"] * WI[j] for j in 1:13) * data[i,"Cr"] for i in 1:n)
    P_max, data[:,"Cr"]' * X * PI
    F_min, data[:,"Cr"]' * X * FI
    G_min, data[:,"Cr"]' * X * GI
end)
@objective(model, Min, [-P_max, W_min, F_min, G_min])
set_optimizer(model, () -> MOA.Optimizer(Gurobi.Optimizer))
set_attribute(model, MOA.Algorithm(), MOA.Hierarchical())
set_attribute.(model, MOA.ObjectivePriority.(1:4), [2, 3, 4, 1])
# This may also help
# set_attribute.(model, MOA.ObjectiveRelativeTolerance.(1:4), 0.01)
optimize!(model)
termination_status(model)
solution_summary(model)

```

Even after this, you still see the occasional `Warning: Markowitz tolerance tightened to` warning, which is an indicator of numerical difficulty.
