@@ -6,24 +6,34 @@ Mapping between bridged variables and the bridge that bridged the variable.
66mutable struct Map <: AbstractDict{MOI.VariableIndex, AbstractBridge}
77 # Bridged constrained variables
88 # `i` -> `0`: `VariableIndex(-i)` was added with `add_constrained_variable`.
9- # `i` -> `-j`: `VariableIndex(-i)` is was the first variable of
9+ # `i` -> `-j`: `VariableIndex(-i)` was the first variable of
1010 # `add_constrained_variables` with a set of dimension `j`.
11- # `i` -> `j`: `VariableIndex(-i)` is was the `j`th variable of
11+ # `i` -> `j`: `VariableIndex(-i)` was the `j`th variable of
1212 # ` add_constrained_variables`.
13- index_in_vector_of_variables:: Vector{Int}
13+ info:: Vector{Int}
14+ # `i` -> `-1`: `VariableIndex(-i)` was deleted.
15+ # `i` -> `0`: `VariableIndex(-i)` was added with `add_constrained_variable`.
16+ # `i` -> `j`: `VariableIndex(-i)` is the `j`th variable of a constrained
17+ # vector of variables, taking deletion into account.
18+ index_in_vector:: Vector{Int}
1419 # `i` -> `bridge`: `VariableIndex(-i)` was bridged by `bridge`.
1520 bridges:: Vector{Union{Nothing, AbstractBridge}}
1621 sets:: Vector{Union{Nothing, DataType}}
1722 # If `nothing`, it cannot be computed because some bridges does not support it
1823 unbridged_function:: Union{Nothing, Dict{MOI.VariableIndex, MOI.AbstractScalarFunction}}
1924end
20- Map () = Map (Int[], Union{Nothing, AbstractBridge}[], Union{Nothing, DataType}[], Dict {MOI.VariableIndex, MOI.AbstractScalarFunction} ())
25+ function Map ()
26+ return Map (Int[], Int[], Union{Nothing, AbstractBridge}[],
27+ Union{Nothing, DataType}[],
28+ Dict {MOI.VariableIndex, MOI.AbstractScalarFunction} ())
29+ end
2130
2231# Implementation of `AbstractDict` interface.
2332
2433Base. isempty (map:: Map ) = all (bridge -> bridge === nothing , map. bridges)
2534function Base. empty! (map:: Map )
26- empty! (map. index_in_vector_of_variables)
35+ empty! (map. info)
36+ empty! (map. index_in_vector)
2737 empty! (map. bridges)
2838 empty! (map. sets)
2939 if map. unbridged_function === nothing
@@ -34,7 +44,7 @@ function Base.empty!(map::Map)
3444 return map
3545end
3646function bridge_index (map:: Map , vi:: MOI.VariableIndex )
37- index = map. index_in_vector_of_variables [- vi. value]
47+ index = map. info [- vi. value]
3848 if index ≤ 0
3949 return - vi. value
4050 else
@@ -43,23 +53,45 @@ function bridge_index(map::Map, vi::MOI.VariableIndex)
4353end
4454function Base. haskey (map:: Map , vi:: MOI.VariableIndex )
4555 return - length (map. bridges) ≤ vi. value ≤ - 1 &&
46- map. bridges[bridge_index (map, vi)] != = nothing
56+ map. bridges[bridge_index (map, vi)] != = nothing &&
57+ map. index_in_vector[- vi. value] != - 1
4758end
4859function Base. getindex (map:: Map , vi:: MOI.VariableIndex )
4960 return map. bridges[bridge_index (map, vi)]
5061end
5162function Base. delete! (map:: Map , vi:: MOI.VariableIndex )
52- map. bridges[bridge_index (map, vi)] = nothing
53- map. sets[bridge_index (map, vi)] = nothing
63+ if iszero (map. info[- vi. value])
64+ # Delete scalar variable
65+ map. bridges[bridge_index (map, vi)] = nothing
66+ map. sets[bridge_index (map, vi)] = nothing
67+ elseif has_keys (map, [vi])
68+ # Delete whole vector
69+ delete! (map, [vi])
70+ else
71+ # Delete variable in vector and resize vector
72+ map. info[bridge_index (map, vi)] += 1
73+ for i in (- vi. value): length (map. index_in_vector)
74+ if map. index_in_vector[i] == - 1
75+ continue
76+ elseif bridge_index (map, vi) != bridge_index (map, MOI. VariableIndex (- i))
77+ break
78+ end
79+ map. index_in_vector[i] -= 1
80+ end
81+ end
82+ map. index_in_vector[- vi. value] = - 1
5483 return map
5584end
5685function Base. delete! (map:: Map , vis:: Vector{MOI.VariableIndex} )
5786 if has_keys (map, vis)
87+ for vi in vis
88+ map. index_in_vector[- vi. value] = - 1
89+ end
5890 map. bridges[bridge_index (map, first (vis))] = nothing
5991 map. sets[bridge_index (map, first (vis))] = nothing
6092 return
6193 else
62- throw (ArgumentError (" $vis is not a valid key vector as returned by `add_keys_for_bridge`." ))
94+ throw (ArgumentError (" ` $vis ` is not a valid key vector as returned by `add_keys_for_bridge`." ))
6395 end
6496end
6597function Base. keys (map:: Map )
@@ -74,7 +106,7 @@ function number_of_variables(map::Map)
74106 num = 0
75107 for i in eachindex (map. bridges)
76108 if map. bridges[i] != = nothing
77- if iszero (map. index_in_vector_of_variables [i])
109+ if iszero (map. info [i])
78110 num += 1
79111 else
80112 num += length_of_vector_of_variables (map, MOI. VariableIndex (- i))
@@ -157,9 +189,12 @@ Return a `Bool` indicating whether `vis` was returned by
157189[`add_keys_for_bridge`](@ref) and has not been deleted yet.
158190"""
159191function has_keys (map:: Map , vis:: Vector{MOI.VariableIndex} )
160- return length_of_vector_of_variables (map, first (vis)) == length (vis) &&
161- all (vi -> bridge_index (map, vi) == - first (vis). value, vis) &&
162- haskey (map, vis[1 ])
192+ return isempty (vis) || (
193+ length_of_vector_of_variables (map, first (vis)) == length (vis) &&
194+ all (vi -> bridge_index (map, vi) == bridge_index (map, first (vis)), vis) &&
195+ all (vi -> haskey (map, vi), vis) &&
196+ all (i -> vis[i]. value < vis[i - 1 ]. value, 2 : length (vis))
197+ )
163198end
164199
165200"""
@@ -169,7 +204,7 @@ If `vi` was bridged in a scalar set, it returns 0. Otherwise, it
169204returns the dimension of the set.
170205"""
171206function length_of_vector_of_variables (map:: Map , vi:: MOI.VariableIndex )
172- return - map. index_in_vector_of_variables [bridge_index (map, vi)]
207+ return - map. info [bridge_index (map, vi)]
173208end
174209
175210"""
178213Return the index of `vi` in the vector of variables in which it was bridged.
179214"""
180215function index_in_vector_of_variables (map:: Map , vi:: MOI.VariableIndex )
181- index = map. index_in_vector_of_variables[- vi. value]
182- if index < 0
183- index = 1
184- end
185- return IndexInVector (index)
216+ return IndexInVector (map. index_in_vector[- vi. value])
186217end
187218
188219"""
@@ -194,7 +225,7 @@ returns `false` even if all bridges were deleted while `isempty` would return
194225by [`MathOptInterface.Bridges.AbstractBridgeOptimizer`](@ref) to shortcut
195226operations in case variable bridges are not used.
196227"""
197- has_bridges (map:: Map ) = ! isempty (map. index_in_vector_of_variables )
228+ has_bridges (map:: Map ) = ! isempty (map. info )
198229
199230"""
200231 add_key_for_bridge(map::Map, bridge::AbstractBridge,
@@ -209,7 +240,8 @@ function add_key_for_bridge(map::Map, bridge::AbstractBridge,
209240 set:: MOI.AbstractScalarSet )
210241 index = - (length (map. bridges) + 1 )
211242 variable = MOI. VariableIndex (index)
212- push! (map. index_in_vector_of_variables, 0 )
243+ push! (map. info, 0 )
244+ push! (map. index_in_vector, 0 )
213245 push! (map. bridges, bridge)
214246 push! (map. sets, typeof (set))
215247 if map. unbridged_function != = nothing
@@ -239,11 +271,13 @@ function add_keys_for_bridge(map::Map, bridge::AbstractBridge,
239271 else
240272 variables = MOI. VariableIndex[MOI. VariableIndex (- (length (map. bridges) + i))
241273 for i in 1 : MOI. dimension (set)]
242- push! (map. index_in_vector_of_variables, - MOI. dimension (set))
274+ push! (map. info, - MOI. dimension (set))
275+ push! (map. index_in_vector, 1 )
243276 push! (map. bridges, bridge)
244277 push! (map. sets, typeof (set))
245278 for i in 2 : MOI. dimension (set)
246- push! (map. index_in_vector_of_variables, i)
279+ push! (map. info, i)
280+ push! (map. index_in_vector, i)
247281 push! (map. bridges, nothing )
248282 push! (map. sets, nothing )
249283 end
@@ -282,7 +316,9 @@ function function_for(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables})
282316 variables = MOI. VariableIndex[]
283317 for i in ci. value: - 1 : - length (map. bridges)
284318 vi = MOI. VariableIndex (i)
285- if bridge_index (map, vi) == - ci. value
319+ if map. index_in_vector[- vi. value] == - 1
320+ continue
321+ elseif bridge_index (map, vi) == - ci. value
286322 push! (variables, vi)
287323 else
288324 break
0 commit comments