From 38464c27b96e9818257b22c61d2458890957d0fe Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 15 Aug 2023 19:15:10 +1200 Subject: [PATCH] Fix bug modifying a constraint after deletion (#515) --- Project.toml | 2 +- src/MOI_wrapper/MOI_wrapper.jl | 4 +++ test/MOI/MOI_wrapper.jl | 46 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 059d151..a696d4a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Gurobi" uuid = "2e9cd046-0924-5485-92f1-d5272153d98b" repo = "https://github.com/jump-dev/Gurobi.jl" -version = "1.0.1" +version = "1.0.2" [deps] LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3" diff --git a/src/MOI_wrapper/MOI_wrapper.jl b/src/MOI_wrapper/MOI_wrapper.jl index ad5dcfc..4fdb053 100644 --- a/src/MOI_wrapper/MOI_wrapper.jl +++ b/src/MOI_wrapper/MOI_wrapper.jl @@ -3459,6 +3459,7 @@ function MOI.modify( c::MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},<:Any}, chg::MOI.ScalarCoefficientChange{Float64}, ) + _update_if_necessary(model) ret = GRBchgcoeffs( model, 1, @@ -3476,6 +3477,7 @@ function MOI.modify( cis::Vector{MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},S}}, changes::Vector{MOI.ScalarCoefficientChange{Float64}}, ) where {S} + _update_if_necessary(model) nels = length(cis) @assert nels == length(changes) rows = Vector{Cint}(undef, nels) @@ -3497,6 +3499,7 @@ function MOI.modify( ::MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}, chg::MOI.ScalarCoefficientChange{Float64}, ) + _update_if_necessary(model) ret = GRBsetdblattrelement( model, "Obj", @@ -3514,6 +3517,7 @@ function MOI.modify( ::MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}, changes::Vector{MOI.ScalarCoefficientChange{Float64}}, ) + _update_if_necessary(model) nels = length(changes) cols = Vector{Cint}(undef, nels) coefs = Vector{Cdouble}(undef, nels) diff --git a/test/MOI/MOI_wrapper.jl b/test/MOI/MOI_wrapper.jl index 321b9db..f254ba9 100644 --- a/test/MOI/MOI_wrapper.jl +++ b/test/MOI/MOI_wrapper.jl @@ -811,6 +811,52 @@ function test_dual_qcp_failure() return end +function test_modify_after_delete() + model = Gurobi.Optimizer(GRB_ENV) + x = MOI.add_variable(model) + c = [MOI.add_constraint(model, i * x, MOI.LessThan(i)) for i in [1.0, 2.0]] + MOI.delete(model, c[1]) + MOI.modify(model, c[2], MOI.ScalarCoefficientChange(x, 4.0)) + @test MOI.get(model, MOI.ConstraintFunction(), c[2]) ≈ 4.0 * x + return +end + +function test_modify_after_delete_plural() + model = Gurobi.Optimizer(GRB_ENV) + x = MOI.add_variable(model) + c = [MOI.add_constraint(model, i * x, MOI.LessThan(i)) for i in [1.0, 2.0]] + MOI.delete(model, c[1]) + MOI.modify(model, [c[2]], [MOI.ScalarCoefficientChange(x, 4.0)]) + @test MOI.get(model, MOI.ConstraintFunction(), c[2]) ≈ 4.0 * x + return +end + +function test_modify_after_delete_objective() + model = Gurobi.Optimizer(GRB_ENV) + x = MOI.add_variables(model, 2) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + f = 1.0 * x[1] + 2.0 * x[2] + attr = MOI.ObjectiveFunction{typeof(f)}() + MOI.set(model, attr, f) + MOI.delete(model, x[1]) + MOI.modify(model, attr, MOI.ScalarCoefficientChange(x[2], 3.0)) + @test MOI.get(model, attr) ≈ 3.0 * x[2] + return +end + +function test_modify_after_delete_objective_plural() + model = Gurobi.Optimizer(GRB_ENV) + x = MOI.add_variables(model, 2) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + f = 1.0 * x[1] + 2.0 * x[2] + attr = MOI.ObjectiveFunction{typeof(f)}() + MOI.set(model, attr, f) + MOI.delete(model, x[1]) + MOI.modify(model, attr, [MOI.ScalarCoefficientChange(x[2], 3.0)]) + @test MOI.get(model, attr) ≈ 3.0 * x[2] + return +end + end TestMOIWrapper.runtests()