Skip to content

Commit

Permalink
Add support for ConstraintPrimal of nonlinear constraints (#593)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Nov 29, 2024
1 parent deab7ff commit 2e84ecd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
23 changes: 23 additions & 0 deletions src/MOI_wrapper/MOI_nonlinear.jl
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,26 @@ function MOI.set(
model.name_to_constraint_index = nothing
return
end

function MOI.get(
model::Optimizer,
attr::MOI.ConstraintPrimal,
c::MOI.ConstraintIndex{MOI.ScalarNonlinearFunction},
)
_throw_if_optimize_in_progress(model, attr)
MOI.check_result_index_bounds(model, attr)
info = _info(model, c)
key = "X"
if attr.result_index > 1
MOI.set(
model,
MOI.RawOptimizerAttribute("SolutionNumber"),
attr.result_index - 1,
)
key = "Xn"
end
valueP = Ref{Cdouble}()
ret = GRBgetdblattrelement(model, key, Cint(info.resvar_index - 1), valueP)
_check_ret(model, ret)
return valueP[]
end
36 changes: 33 additions & 3 deletions test/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ function test_runtests()
# Timeouts
r"^test_nonlinear_expression_hs109$",
r"^test_nonlinear_expression_hs110$",
# MOI.get(MOI.ObjectiveValue()) fails for NL objectives
r"^test_nonlinear_expression_quartic$",
r"^test_nonlinear_expression_overrides_objective$",
# Nonlinear duals not computed
r"^test_nonlinear_duals$",
],
Expand Down Expand Up @@ -1478,6 +1475,39 @@ function test_scalar_quadratic_function_with_off_diag_in_scalar_nonlinear()
return
end

function test_multiple_solution_nonlinear_objective()
if !Gurobi._supports_nonlinear()
return
end
model =
MOI.Bridges.full_bridge_optimizer(Gurobi.Optimizer(GRB_ENV), Float64)
N = 30
x = MOI.add_variables(model, N)
MOI.add_constraints(model, x, MOI.ZeroOne())
MOI.set.(model, MOI.VariablePrimalStart(), x, 0.0)
item_weights = sin.(1:N)
MOI.add_constraint(
model,
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(item_weights, x), 0.0),
MOI.LessThan(10.0),
)
f = MOI.ScalarNonlinearFunction(
:+,
Any[MOI.ScalarNonlinearFunction(:exp, Any[x[i]]) for i in 1:N],
)
MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
MOI.optimize!(model)
count = MOI.get(model, MOI.ResultCount())
@test count > 1
for i in 1:count
x_val = MOI.get.(model, MOI.VariablePrimal(i), x)
obj_val = MOI.get(model, MOI.ObjectiveValue(i))
@test isapprox(obj_val, sum(exp.(x_val)); atol = 1e-6)
end
return
end

end # TestMOIWrapper

TestMOIWrapper.runtests()

0 comments on commit 2e84ecd

Please sign in to comment.