Skip to content

Commit 535e7f0

Browse files
authored
Merge pull request #1104 from jump-dev/bl/cache_constrained_variables
Fix constrained variables for caching optimizer
2 parents 5896072 + 3a2a555 commit 535e7f0

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

src/Utilities/cachingoptimizer.jl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ function MOI.add_variables(m::CachingOptimizer, n)
239239
return vindices
240240
end
241241

242+
function MOI.supports_add_constrained_variable(m::CachingOptimizer, S::Type{<:MOI.AbstractScalarSet})
243+
return MOI.supports_add_constrained_variable(m.model_cache, S) && (m.state == NO_OPTIMIZER || MOI.supports_add_constrained_variable(m.optimizer, S))
244+
end
242245
function MOI.add_constrained_variable(m::CachingOptimizer, set::MOI.AbstractScalarSet)
243246
if m.state == MOIU.ATTACHED_OPTIMIZER
244247
if m.mode == MOIU.AUTOMATIC
@@ -257,8 +260,7 @@ function MOI.add_constrained_variable(m::CachingOptimizer, set::MOI.AbstractScal
257260
MOI.add_constrained_variable(m.optimizer, set)
258261
end
259262
end
260-
vindex = MOI.add_variable(m.model_cache)
261-
cindex = MOI.add_constraint(m.model_cache, MOI.SingleVariable(vindex), set)
263+
vindex, cindex = MOI.add_constrained_variable(m.model_cache, set)
262264
if m.state == MOIU.ATTACHED_OPTIMIZER
263265
m.model_to_optimizer_map[vindex] = vindex_optimizer
264266
m.optimizer_to_model_map[vindex_optimizer] = vindex
@@ -268,6 +270,16 @@ function MOI.add_constrained_variable(m::CachingOptimizer, set::MOI.AbstractScal
268270
return vindex, cindex
269271
end
270272

273+
function _supports_add_constrained_variables(m::CachingOptimizer, S::Type{<:MOI.AbstractVectorSet})
274+
return MOI.supports_add_constrained_variables(m.model_cache, S) && (m.state == NO_OPTIMIZER || MOI.supports_add_constrained_variables(m.optimizer, S))
275+
end
276+
# Split in two to solve ambiguity
277+
function MOI.supports_add_constrained_variables(m::CachingOptimizer, ::Type{MOI.Reals})
278+
return _supports_add_constrained_variables(m, MOI.Reals)
279+
end
280+
function MOI.supports_add_constrained_variables(m::CachingOptimizer, S::Type{<:MOI.AbstractVectorSet})
281+
return _supports_add_constrained_variables(m, S)
282+
end
271283
function MOI.add_constrained_variables(m::CachingOptimizer, set::MOI.AbstractVectorSet)
272284
if m.state == ATTACHED_OPTIMIZER
273285
if m.mode == AUTOMATIC
@@ -286,8 +298,7 @@ function MOI.add_constrained_variables(m::CachingOptimizer, set::MOI.AbstractVec
286298
MOI.add_constrained_variables(m.optimizer, set)
287299
end
288300
end
289-
vindices = MOI.add_variables(m.model_cache, MOI.dimension(set))
290-
cindex = MOI.add_constraint(m.model_cache, MOI.VectorOfVariables(vindices), set)
301+
vindices, cindex = MOI.add_constrained_variables(m.model_cache, set)
291302
if m.state == ATTACHED_OPTIMIZER
292303
for (vindex, vindex_optimizer) in zip(vindices, vindices_optimizer)
293304
m.model_to_optimizer_map[vindex] = vindex_optimizer

test/Utilities/cachingoptimizer.jl

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,3 +479,58 @@ for state in (MOIU.NO_OPTIMIZER, MOIU.EMPTY_OPTIMIZER, MOIU.ATTACHED_OPTIMIZER)
479479
end
480480
end
481481
end
482+
483+
mutable struct NoFreeVariables <: MOI.AbstractOptimizer
484+
inner::MOIU.Model{Float64}
485+
function NoFreeVariables()
486+
return new(MOIU.Model{Float64}())
487+
end
488+
end
489+
MOI.is_empty(model::NoFreeVariables) = MOI.is_empty(model.inner)
490+
MOI.empty!(model::NoFreeVariables) = MOI.empty!(model.inner)
491+
MOI.get(model::NoFreeVariables, attr::MOI.AnyAttribute, idx::Vector) = MOI.get(model.inner, attr, idx)
492+
MOI.get(model::NoFreeVariables, attr::MOI.AnyAttribute, args...) = MOI.get(model.inner, attr, args...)
493+
MOI.supports_add_constrained_variables(::NoFreeVariables, ::Type{MOI.Reals}) = false
494+
MOI.supports_add_constrained_variable(::NoFreeVariables, ::Type{<:MOI.AbstractScalarSet}) = true
495+
function MOI.add_constrained_variable(model::NoFreeVariables, set::MOI.AbstractScalarSet)
496+
return MOI.add_constrained_variable(model.inner, set)
497+
end
498+
MOI.supports_add_constrained_variables(::NoFreeVariables, ::Type{<:MOI.AbstractVectorSet}) = true
499+
function MOI.add_constrained_variables(model::NoFreeVariables, set::MOI.AbstractVectorSet)
500+
return MOI.add_constrained_variables(model.inner, set)
501+
end
502+
503+
MOI.Utilities.supports_default_copy_to(::NoFreeVariables, names::Bool) = !names
504+
function MOI.copy_to(dest::NoFreeVariables, src::MOI.ModelLike; kwargs...)
505+
return MOI.Utilities.automatic_copy_to(dest, src; kwargs...)
506+
end
507+
508+
function constrained_variables_test(model)
509+
@test !MOI.supports_add_constrained_variables(model, MOI.Reals)
510+
@test MOI.supports_add_constrained_variable(model, MOI.ZeroOne)
511+
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.ZeroOne)
512+
@test MOI.supports_add_constrained_variables(model, MOI.Nonnegatives)
513+
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Nonnegatives)
514+
scalar_set = MOI.ZeroOne()
515+
x, cx = MOI.add_constrained_variable(model, scalar_set)
516+
vector_set = MOI.Nonnegatives(2)
517+
y, cy = MOI.add_constrained_variables(model, vector_set)
518+
constraint_types = Set([(MOI.SingleVariable, MOI.ZeroOne), (MOI.VectorOfVariables, MOI.Nonnegatives)])
519+
@test Set(MOI.get(model.model_cache, MOI.ListOfConstraints())) == constraint_types
520+
if MOIU.state(model) == MOIU.EMPTY_OPTIMIZER
521+
MOIU.attach_optimizer(model)
522+
end
523+
@test Set(MOI.get(model.optimizer, MOI.ListOfConstraints())) == constraint_types
524+
end
525+
526+
@testset "Constrained Variables" begin
527+
cache = NoFreeVariables()
528+
optimizer = NoFreeVariables()
529+
model = MOIU.CachingOptimizer(cache, optimizer)
530+
constrained_variables_test(model)
531+
MOI.empty!(cache)
532+
MOI.empty!(optimizer)
533+
model = MOIU.CachingOptimizer(cache, MOIU.AUTOMATIC)
534+
MOIU.reset_optimizer(model, optimizer)
535+
constrained_variables_test(model)
536+
end

0 commit comments

Comments
 (0)