Dear all,
trying to set up a simple MINLP somehow fails for me with: MathOptInterface.ScalarNonlinearFunction
Code:
using JuMP
using HiGHS
using Pavito, Pajarito, Hypatia
using LinearAlgebra
import Ipopt, GLPK
vector_model = Model(
optimizer_with_attributes(
Pavito.Optimizer,
"mip_solver" => optimizer_with_attributes(GLPK.Optimizer),
"cont_solver" =>
optimizer_with_attributes(Ipopt.Optimizer),
),
)
vector_model = Model(
optimizer_with_attributes(
Pajarito.Optimizer,
"oa_solver" => optimizer_with_attributes(
HiGHS.Optimizer,
MOI.Silent() => true,
"mip_feasibility_tolerance" => 1e-8,
"mip_rel_gap" => 1e-6,
),
"conic_solver" =>
optimizer_with_attributes(Hypatia.Optimizer, MOI.Silent() => false),
)
)
mymatrix = [0 0.8 0.3 0.1;
0.3 0.1 0.1 0.1;
0.7 0.7 0.2 0.3]
@variable(vector_model, x[1:3] >= 0, integer = true)
@constraint(vector_model, sum(x) <= 3)
threshold = 1
lambda = 0.1
@objective(vector_model, Max, sum(x'*mymatrix)-threshold + lambda * sum(abs.(x)))
optimize!(vector_model)
println(JuMP.value.(x) / maximum(JuMP.value.(x)))
Any help is highly appreciated.
Kind regards,
Stephan
Pajarito and Hypatia are conic solvers, which means that they handle nonlinear functions, but only specific types of nonlinear functions. Your error is saying that the choice of solver does not support your general nonlinear objective function.
1 Like
The issue is the term sum(abs.(x)))
This comes up fairly often, e.g.: Abs in JuMP - #3 by odow
You need to reformulate sum(abs.(x)))
as sum(t)
where you’ve defined
@variable(vector_model, t[1:length(x)] >= 0)
@constraint(vector_model, [i=1:length(x)], x[i] <= t[i])
@constraint(vector_model, [i=1:length(x)], -t[i] <= x[i])
1 Like
So this would probably need to be Min
not Max
and read
@objective(vector_model, Min, sum(x'*mymatrix)-threshold + lambda * sum(t))
1 Like
Thanks @jd-foster , should have checked the forum before hand for that common issue.
Kind regards,
Stephan
odow
November 16, 2023, 7:05pm
6
Hi @stephanmg ,
The failure is because you’re trying to use the new nonlinear interface Nonlinear Modeling · JuMP , but I haven’t updated Pavito yet.
You need to use the legacy interface, Nonlinear Modeling (Legacy) · JuMP , but it requires you to change:
@objective(vector_model, Minn, sum(x'*mymatrix)-threshold + lambda * sum(abs.(x)))
into
@NLobjective(vector_model, Min, sum(sum(x[i] * mymatrix[i, j] for i in 1:3) for j in 1:3) - threshold + lambda * sum(abs(x[i] for i in 1:3)))
(I didn’t test, so I might have made a typo, but that should point you in the right direction.)
Also note that Pajarito is not applicable here. It requires the model in conic form. Pavito is the nonlinear solver.
1 Like