@@ -6,24 +6,34 @@ Mapping between bridged variables and the bridge that bridged the variable.
6
6
mutable struct Map <: AbstractDict{MOI.VariableIndex, AbstractBridge}
7
7
# Bridged constrained variables
8
8
# `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
10
10
# `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
12
12
# ` 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}
14
19
# `i` -> `bridge`: `VariableIndex(-i)` was bridged by `bridge`.
15
20
bridges:: Vector{Union{Nothing, AbstractBridge}}
16
21
sets:: Vector{Union{Nothing, DataType}}
17
22
# If `nothing`, it cannot be computed because some bridges does not support it
18
23
unbridged_function:: Union{Nothing, Dict{MOI.VariableIndex, MOI.AbstractScalarFunction}}
19
24
end
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
21
30
22
31
# Implementation of `AbstractDict` interface.
23
32
24
33
Base. isempty (map:: Map ) = all (bridge -> bridge === nothing , map. bridges)
25
34
function Base. empty! (map:: Map )
26
- empty! (map. index_in_vector_of_variables)
35
+ empty! (map. info)
36
+ empty! (map. index_in_vector)
27
37
empty! (map. bridges)
28
38
empty! (map. sets)
29
39
if map. unbridged_function === nothing
@@ -34,7 +44,7 @@ function Base.empty!(map::Map)
34
44
return map
35
45
end
36
46
function bridge_index (map:: Map , vi:: MOI.VariableIndex )
37
- index = map. index_in_vector_of_variables [- vi. value]
47
+ index = map. info [- vi. value]
38
48
if index ≤ 0
39
49
return - vi. value
40
50
else
@@ -43,23 +53,45 @@ function bridge_index(map::Map, vi::MOI.VariableIndex)
43
53
end
44
54
function Base. haskey (map:: Map , vi:: MOI.VariableIndex )
45
55
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
47
58
end
48
59
function Base. getindex (map:: Map , vi:: MOI.VariableIndex )
49
60
return map. bridges[bridge_index (map, vi)]
50
61
end
51
62
function 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
54
83
return map
55
84
end
56
85
function Base. delete! (map:: Map , vis:: Vector{MOI.VariableIndex} )
57
86
if has_keys (map, vis)
87
+ for vi in vis
88
+ map. index_in_vector[- vi. value] = - 1
89
+ end
58
90
map. bridges[bridge_index (map, first (vis))] = nothing
59
91
map. sets[bridge_index (map, first (vis))] = nothing
60
92
return
61
93
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`." ))
63
95
end
64
96
end
65
97
function Base. keys (map:: Map )
@@ -74,7 +106,7 @@ function number_of_variables(map::Map)
74
106
num = 0
75
107
for i in eachindex (map. bridges)
76
108
if map. bridges[i] != = nothing
77
- if iszero (map. index_in_vector_of_variables [i])
109
+ if iszero (map. info [i])
78
110
num += 1
79
111
else
80
112
num += length_of_vector_of_variables (map, MOI. VariableIndex (- i))
@@ -157,9 +189,12 @@ Return a `Bool` indicating whether `vis` was returned by
157
189
[`add_keys_for_bridge`](@ref) and has not been deleted yet.
158
190
"""
159
191
function 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
+ )
163
198
end
164
199
165
200
"""
@@ -169,7 +204,7 @@ If `vi` was bridged in a scalar set, it returns 0. Otherwise, it
169
204
returns the dimension of the set.
170
205
"""
171
206
function 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)]
173
208
end
174
209
175
210
"""
178
213
Return the index of `vi` in the vector of variables in which it was bridged.
179
214
"""
180
215
function 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])
186
217
end
187
218
188
219
"""
@@ -194,7 +225,7 @@ returns `false` even if all bridges were deleted while `isempty` would return
194
225
by [`MathOptInterface.Bridges.AbstractBridgeOptimizer`](@ref) to shortcut
195
226
operations in case variable bridges are not used.
196
227
"""
197
- has_bridges (map:: Map ) = ! isempty (map. index_in_vector_of_variables )
228
+ has_bridges (map:: Map ) = ! isempty (map. info )
198
229
199
230
"""
200
231
add_key_for_bridge(map::Map, bridge::AbstractBridge,
@@ -209,7 +240,8 @@ function add_key_for_bridge(map::Map, bridge::AbstractBridge,
209
240
set:: MOI.AbstractScalarSet )
210
241
index = - (length (map. bridges) + 1 )
211
242
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 )
213
245
push! (map. bridges, bridge)
214
246
push! (map. sets, typeof (set))
215
247
if map. unbridged_function != = nothing
@@ -239,11 +271,13 @@ function add_keys_for_bridge(map::Map, bridge::AbstractBridge,
239
271
else
240
272
variables = MOI. VariableIndex[MOI. VariableIndex (- (length (map. bridges) + i))
241
273
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 )
243
276
push! (map. bridges, bridge)
244
277
push! (map. sets, typeof (set))
245
278
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)
247
281
push! (map. bridges, nothing )
248
282
push! (map. sets, nothing )
249
283
end
@@ -282,7 +316,9 @@ function function_for(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables})
282
316
variables = MOI. VariableIndex[]
283
317
for i in ci. value: - 1 : - length (map. bridges)
284
318
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
286
322
push! (variables, vi)
287
323
else
288
324
break
0 commit comments