Skip to content

Commit a419260

Browse files
authored
Fix check for NumVars when there is a ScalarNonlinearFunction (#633)
1 parent 5186074 commit a419260

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

src/MOI_wrapper/MOI_multi_objective.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ function MOI.set(
2929
attr::MultiObjectiveFunction,
3030
f::MOI.ScalarAffineFunction,
3131
)
32-
num_vars = length(model.variable_info)
32+
_update_if_necessary(model)
33+
pInt = Ref{Cint}(0)
34+
ret = GRBgetintattr(model, "NumVars", pInt)
35+
_check_ret(model, ret)
36+
num_vars = pInt[]
3337
obj = zeros(Float64, num_vars)
3438
for term in f.terms
3539
column = _info(model, term.variable).column

src/MOI_wrapper/MOI_wrapper.jl

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,11 @@ end
12011201
###
12021202

12031203
function _zero_objective(model::Optimizer)
1204-
num_vars = length(model.variable_info)
1204+
_update_if_necessary(model)
1205+
pInt = Ref{Cint}(0)
1206+
ret = GRBgetintattr(model, "NumVars", pInt)
1207+
_check_ret(model, ret)
1208+
num_vars = pInt[]
12051209
obj = zeros(Float64, num_vars)
12061210
ret = GRBdelq(model)
12071211
_check_ret(model, ret)
@@ -1275,7 +1279,11 @@ function MOI.set(
12751279
ret = GRBdelq(model)
12761280
_check_ret(model, ret)
12771281
end
1278-
num_vars = length(model.variable_info)
1282+
_update_if_necessary(model)
1283+
pInt = Ref{Cint}(0)
1284+
ret = GRBgetintattr(model, "NumVars", pInt)
1285+
_check_ret(model, ret)
1286+
num_vars = pInt[]
12791287
obj = zeros(Float64, num_vars)
12801288
for term in f.terms
12811289
obj[column(model, term.variable)] += term.coefficient
@@ -1292,9 +1300,13 @@ end
12921300

12931301
function _get_affine_objective(model::Optimizer; is_multiobjective::Bool)
12941302
_update_if_necessary(model)
1295-
dest = zeros(length(model.variable_info))
1303+
pInt = Ref{Cint}(0)
1304+
ret = GRBgetintattr(model, "NumVars", pInt)
1305+
_check_ret(model, ret)
1306+
num_vars = pInt[]
1307+
dest = zeros(num_vars)
12961308
name = is_multiobjective ? "ObjN" : "Obj"
1297-
ret = GRBgetdblattrarray(model, name, 0, length(dest), dest)
1309+
ret = GRBgetdblattrarray(model, name, 0, num_vars, dest)
12981310
_check_ret(model, ret)
12991311
terms = MOI.ScalarAffineTerm{Float64}[]
13001312
for (index, info) in model.variable_info
@@ -1330,7 +1342,11 @@ function MOI.set(
13301342
affine_indices, affine_coefficients, I, J, V =
13311343
_indices_and_coefficients(model, f)
13321344
# We need to zero out any existing linear objective.
1333-
obj = zeros(length(model.variable_info))
1345+
_update_if_necessary(model)
1346+
pInt = Ref{Cint}(0)
1347+
ret = GRBgetintattr(model, "NumVars", pInt)
1348+
_check_ret(model, ret)
1349+
obj = zeros(pInt[])
13341350
for (i, c) in zip(affine_indices, affine_coefficients)
13351351
obj[i+1] = c
13361352
end
@@ -1354,8 +1370,12 @@ function MOI.get(
13541370
::MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}},
13551371
)
13561372
_update_if_necessary(model)
1357-
dest = zeros(length(model.variable_info))
1358-
ret = GRBgetdblattrarray(model, "Obj", 0, length(dest), dest)
1373+
pInt = Ref{Cint}(0)
1374+
ret = GRBgetintattr(model, "NumVars", pInt)
1375+
_check_ret(model, ret)
1376+
num_vars = pInt[]
1377+
dest = zeros(num_vars)
1378+
ret = GRBgetdblattrarray(model, "Obj", 0, num_vars, dest)
13591379
_check_ret(model, ret)
13601380
terms = MOI.ScalarAffineTerm{Float64}[]
13611381
for (index, info) in model.variable_info
@@ -3448,6 +3468,7 @@ function MOI.set(model::Optimizer, attr::MOI.Name, name::String)
34483468
end
34493469

34503470
MOI.get(model::Optimizer, ::MOI.NumberOfVariables) = length(model.variable_info)
3471+
34513472
function MOI.get(model::Optimizer, ::MOI.ListOfVariableIndices)
34523473
return sort!(collect(keys(model.variable_info)), by = x -> x.value)
34533474
end

test/MOI/MOI_wrapper.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,23 @@ function test_objbound_errors_when_GRB_INFINITY()
16411641
return
16421642
end
16431643

1644+
function test_set_nonlinear_objective_twice()
1645+
if !Gurobi._supports_nonlinear()
1646+
return
1647+
end
1648+
model =
1649+
MOI.Bridges.full_bridge_optimizer(Gurobi.Optimizer(GRB_ENV), Float64)
1650+
MOI.set(model, MOI.Silent(), true)
1651+
x, _ = MOI.add_constrained_variable(model, MOI.Interval(2.0, 3.0))
1652+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
1653+
f = MOI.ScalarNonlinearFunction(:exp, Any[x])
1654+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
1655+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
1656+
MOI.optimize!(model)
1657+
@test isapprox(MOI.get(model, MOI.ObjectiveValue()), exp(2.0); atol = 1e-4)
1658+
return
1659+
end
1660+
16441661
end # TestMOIWrapper
16451662

16461663
TestMOIWrapper.runtests()

0 commit comments

Comments
 (0)