Skip to content

Commit 58a9c28

Browse files
committed
add MOI.modify for multiple changes at once
1 parent 670d2fa commit 58a9c28

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

src/MOI_wrapper/MOI_wrapper.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,40 @@ function MOI.modify(
21552155
return
21562156
end
21572157

2158+
function MOI.modify(
2159+
model::Optimizer,
2160+
cis::Vector{MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},S}},
2161+
changes::Vector{MOI.ScalarCoefficientChange{Float64}},
2162+
) where {S}
2163+
nels = length(cis)
2164+
@assert nels == length(changes)
2165+
rows = Vector{Cint}(undef, nels)
2166+
cols = Vector{Cint}(undef, nels)
2167+
coefs = Vector{Cdouble}(undef, nels)
2168+
for i in 1:nels
2169+
row = Cint(_info(model, cis[i]).row)
2170+
col = column(model, changes[i].variable)
2171+
nnz = glp_get_mat_row(model, row, C_NULL, C_NULL)
2172+
indices, coefficients = zeros(Cint, nnz), zeros(Cdouble, nnz)
2173+
glp_get_mat_row(model, row, offset(indices), offset(coefficients))
2174+
index = something(findfirst(isequal(col), indices), 0)
2175+
if index > 0
2176+
coefficients[index] = changes[i].new_coefficient
2177+
else
2178+
push!(indices, cols[i])
2179+
push!(coefficients, changes[i].new_coefficient)
2180+
end
2181+
glp_set_mat_row(
2182+
model,
2183+
row,
2184+
length(indices),
2185+
offset(indices),
2186+
offset(coefficients),
2187+
)
2188+
end
2189+
return
2190+
end
2191+
21582192
function MOI.set(
21592193
model::Optimizer,
21602194
::MOI.ConstraintFunction,

test/MOI_wrapper.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,51 @@ function test_variable_basis_status()
544544
return
545545
end
546546

547+
function test_multiple_modifications()
548+
model = GLPK.Optimizer()
549+
550+
x = MOI.add_variables(model, 3)
551+
552+
saf = MOI.ScalarAffineFunction(
553+
[
554+
MOI.ScalarAffineTerm(1.0, x[1]),
555+
MOI.ScalarAffineTerm(1.0, x[2]),
556+
MOI.ScalarAffineTerm(1.0, x[3]),
557+
],
558+
0.0,
559+
)
560+
ci1 = MOI.add_constraint(model, saf, MOI.LessThan(1.0))
561+
ci2 = MOI.add_constraint(model, saf, MOI.LessThan(2.0))
562+
563+
MOI.set(
564+
model,
565+
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
566+
saf,
567+
)
568+
569+
fc1 = MOI.get(model, MOI.ConstraintFunction(), ci1)
570+
@test MOI.coefficient.(fc1.terms) == [1.0, 1.0, 1.0]
571+
fc2 = MOI.get(model, MOI.ConstraintFunction(), ci2)
572+
@test MOI.coefficient.(fc2.terms) == [1.0, 1.0, 1.0]
573+
obj = MOI.get(
574+
model,
575+
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
576+
)
577+
@test MOI.coefficient.(obj.terms) == [1.0, 1.0, 1.0]
578+
579+
changes_cis = [
580+
MOI.ScalarCoefficientChange(MOI.VariableIndex(1), 4.0)
581+
MOI.ScalarCoefficientChange(MOI.VariableIndex(1), 0.5)
582+
MOI.ScalarCoefficientChange(MOI.VariableIndex(3), 2.0)
583+
]
584+
MOI.modify(model, [ci1, ci2, ci2], changes_cis)
585+
586+
fc1 = MOI.get(model, MOI.ConstraintFunction(), ci1)
587+
@test MOI.coefficient.(fc1.terms) == [4.0, 1.0, 1.0]
588+
fc2 = MOI.get(model, MOI.ConstraintFunction(), ci2)
589+
@test MOI.coefficient.(fc2.terms) == [2.0, 1.0, 0.5]
590+
end
591+
547592
end # module
548593

549594
TestMOIWrapper.runtests()

0 commit comments

Comments
 (0)