Help with multi-objective, non-linear JuMP problem

This single objective version below works just fine:

    using JuMP
    using Ipopt

	S, L, U  = 1000, 15, 40
	N = 54
	r = rand(54, 2)
	model = Model(Ipopt.Optimizer)
	@variable(model, s[i=1:N], start=14)
	@NLexpression(model, obj1, sum( r[i,1] / s[i] for i in 1:N))
	@NLexpression(model, obj2, sum( r[i,2] / s[i] for i in 1:N))
	@NLobjective(
		model,
		Min,
	 	obj1 + obj2
	)
	@constraint(model, L .≤ s .≤ U)
	@constraint(model, sum(s) ≤ S)
	JuMP.optimize!(model)
	value.(s)

If I change the objective to this:

	@NLobjective(
		model,
		Min,
	 	[obj1, obj2]
	)

I get an Unsupported expression error. Is it because of the solver I’m using? If someone can point me in the right direction, it would be very much appreciated!

I think Ipopt is a single-objective solver. Have you tried explicitly multi-objective ones like jump-dev/MultiObjectiveAlgorithms.jl · JuMP ?

1 Like

I did try that but I don’t understand it well enough to know if what I’m doing should even be expected to work. I tried the following two variations and they both produce the same Unsupported expression error:

	import HiGHS
	import MultiObjectiveAlgorithms as MOA
	model = JuMP.Model(() -> MOA.Optimizer(HiGHS.Optimizer))
model = JuMP.Model(() -> MOA.Optimizer(Ipopt.Optimizer))

I haven’t tried multi-objective JuMP yet, but the tutorials (Simple multi-objective examples · JuMP) seem to suggest that there is an additional step which looks somewhat like this

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

Basically you need to tell the solver how to prioritize the objectives

1 Like

Vector-valued nonlinear objectives are currently not supported. But you can work-around this by introducing an intermediate variable:

julia> using JuMP

julia> import Ipopt

julia> import MultiObjectiveAlgorithms as MOA

julia> S, L, U, N = 1000, 15, 40, 54
(1000, 15, 40, 54)

julia> r = rand(54, 2);

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

julia> set_silent(model)

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

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

julia> @variable(model, L <= s[1:N] <= U, start = 14);

julia> @constraint(model, sum(s) <= S);

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

julia> @NLconstraint(model, [i=1:2], obj[i] == sum(r[j, i] / s[j] for j in 1:N));

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

julia> optimize!(model)

julia> for i in 1:result_count(model)
           println("Solution $i")
           println("  Objective = ", objective_value(model; result = i))
           # println(value.(s; result = i))
       end
Solution 1
  Objective = [1.301662920394281, 1.4623640207630741]
Solution 2
  Objective = [1.3055226089750172, 1.42828408366959]
Solution 3
  Objective = [1.316550684889867, 1.3920126114808964]
Solution 4
  Objective = [1.333160463352082, 1.3592565385479682]
Solution 5
  Objective = [1.3545043825902743, 1.3305717489020021]
Solution 6
  Objective = [1.3800656024907705, 1.3066224590810092]
Solution 7
  Objective = [1.407792737347257, 1.2893101957186606]
Solution 8
  Objective = [1.43828364753188, 1.2782264523557885]
Solution 9
  Objective = [1.4544662674597648, 1.2751661435451191]
Solution 10
  Objective = [1.469182305027906, 1.2741557079126375]
3 Likes