Skip to content

Commit dcc5ebb

Browse files
authored
Merge pull request #383 from JuliaOpt/bl/bridgeupdate
Updates to LazyBridgeOptimizers
2 parents 4805984 + ce8dc33 commit dcc5ebb

File tree

8 files changed

+61
-25
lines changed

8 files changed

+61
-25
lines changed

docs/src/apireference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,4 @@ Bridges.LogDetBridge
311311
Bridges.SOCtoPSDCBridge
312312
Bridges.RSOCtoPSDCBridge
313313
```
314-
For each bridge defined in this package, a corresponding bridge optimizer is available with the same name but "Bridge" suffix, e.g. `SplitInterval` is an `SingleBridgeOptimizer` for the `SplitIntervalBridge`.
314+
For each bridge defined in this package, a corresponding bridge optimizer is available with the same name without the "Bridge" suffix, e.g., `SplitInterval` is an `SingleBridgeOptimizer` for the `SplitIntervalBridge`.

src/Bridges/bridge.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ type `F`-in`S` created by the bride `b` in the model (i.e., of length equal to t
3131
MOI.get(b::AbstractBridge, ::MOI.ListOfConstraintIndices{F, S}) where {F, S} = CI{F, S}[]
3232

3333
"""
34-
supportedconstrainttypes(BT::Type{<:AbstractBridge})::Bool
34+
MOI.supportsconstraint(BT::Type{<:AbstractBridge}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})::Bool
3535
36-
Return a list of the types of constraints that can be bridged with a bridge of type `BT`.
36+
Return a `Bool` indicating whether the bridges of type `BT` support bridging `F`-in-`S` constraints.
3737
"""
38-
function supportedconstrainttypes end
38+
MOI.supportsconstraint(::Type{<:AbstractBridge}, ::Type{<:MOI.AbstractFunction}, ::Type{<:MOI.AbstractSet}) = false
3939

4040
"""
4141
addedconstrainttypes(BT::Type{<:AbstractBridge}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})::Bool

src/Bridges/detbridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function LogDetBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.LogDetCon
8585
LogDetBridge(Δ, l, sdindex, lcindex, tlindex)
8686
end
8787

88-
supportedconstrainttypes(::Type{LogDetBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.LogDetConeTriangle), (MOI.VectorAffineFunction{T}, MOI.LogDetConeTriangle)]
88+
MOI.supportsconstraint(::Type{LogDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.LogDetConeTriangle}) where T = true
8989
addedconstrainttypes(::Type{LogDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.LogDetConeTriangle}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle), (MOI.VectorAffineFunction{T}, MOI.ExponentialCone), (MOI.ScalarAffineFunction{T}, MOI.LessThan{T})]
9090

9191
"""
@@ -177,7 +177,7 @@ function RootDetBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.RootDetC
177177
RootDetBridge(Δ, sdindex, gmindex)
178178
end
179179

180-
supportedconstrainttypes(::Type{RootDetBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.RootDetConeTriangle), (MOI.VectorAffineFunction{T}, MOI.RootDetConeTriangle)]
180+
MOI.supportsconstraint(::Type{RootDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RootDetConeTriangle}) where T = true
181181
addedconstrainttypes(::Type{RootDetBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RootDetConeTriangle}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle), (MOI.VectorAffineFunction{T}, MOI.GeometricMeanCone)]
182182

183183
# Attributes, Bridge acting as an model

src/Bridges/geomeanbridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ function GeoMeanBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.Geometri
9191
GeoMeanBridge(d, xij, tubc, socrc)
9292
end
9393

94-
supportedconstrainttypes(::Type{GeoMeanBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.GeometricMeanCone), (MOI.VectorAffineFunction{T}, MOI.GeometricMeanCone)]
94+
MOI.supportsconstraint(::Type{GeoMeanBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.GeometricMeanCone}) where T = true
9595
addedconstrainttypes(::Type{GeoMeanBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.GeometricMeanCone}) where T = [(MOI.ScalarAffineFunction{T}, MOI.LessThan{T}), (MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)]
9696

9797
# Attributes, Bridge acting as an model

src/Bridges/intervalbridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function SplitIntervalBridge{T}(model, f::MOI.ScalarAffineFunction{T}, s::MOI.In
1313
SplitIntervalBridge(lower, upper)
1414
end
1515

16-
supportedconstrainttypes(::Type{SplitIntervalBridge{T}}) where T = [(MOI.ScalarAffineFunction{T}, MOI.Interval{T})]
16+
MOI.supportsconstraint(::Type{SplitIntervalBridge{T}}, ::Type{MOI.ScalarAffineFunction{T}}, ::Type{MOI.Interval{T}}) where T = true
1717
addedconstrainttypes(::Type{SplitIntervalBridge{T}}, ::Type{MOI.ScalarAffineFunction{T}}, ::Type{MOI.Interval{T}}) where T = [(MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}), (MOI.ScalarAffineFunction{T}, MOI.LessThan{T})]
1818

1919
# Attributes, Bridge acting as an model

src/Bridges/lazybridgeoptimizer.jl

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,17 @@ function _dist(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{
3535
end
3636
end
3737

38-
"""
39-
addbridge!(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
40-
41-
Enable the use of the bridges of type `BT` by `b`.
42-
"""
43-
function addbridge!(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
44-
push!(b.bridgetypes, BT)
38+
# Update `b.dist` and `b.dest` for constraint types in `constraints`
39+
function update_dist!(b::LazyBridgeOptimizer, constraints)
4540
# Bellman-Ford algorithm
4641
changed = true # Has b.dist changed in the last iteration ?
4742
while changed
4843
changed = false
49-
i = 0
5044
for BT in b.bridgetypes
51-
i += 1
52-
for (F, S) in supportedconstrainttypes(BT)
53-
if all(C -> MOI.supportsconstraint(b, C...), addedconstrainttypes(BT, F, S))
45+
for (F, S) in constraints
46+
if MOI.supportsconstraint(BT, F, S) && all(C -> MOI.supportsconstraint(b, C[1], C[2]), addedconstrainttypes(BT, F, S))
5447
# Number of bridges needed using BT
55-
dist = sum(C -> _dist(b, C...), addedconstrainttypes(BT, F, S))
48+
dist = sum(C -> _dist(b, C[1], C[2]), addedconstrainttypes(BT, F, S))
5649
# Is it better that what can currently be done ?
5750
if dist < _dist(b, F, S)
5851
b.dist[(F, S)] = dist
@@ -65,9 +58,52 @@ function addbridge!(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
6558
end
6659
end
6760

61+
function fill_required_constraints!(required::Set{Tuple{DataType, DataType}}, b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})
62+
if MOI.supportsconstraint(b.model, F, S) || (F, S) in keys(b.best)
63+
return # The constraint is supported
64+
end
65+
if (F, S) in required
66+
return # The requirements for this constraint have already been added or are being added
67+
end
68+
# The constraint is not supported yet, add in `required` the required constraint types to bridge it
69+
push!(required, (F, S))
70+
for BT in b.bridgetypes
71+
if MOI.supportsconstraint(BT, F, S)
72+
for C in addedconstrainttypes(BT, F, S)
73+
fill_required_constraints!(required, b, C[1], C[2])
74+
end
75+
end
76+
end
77+
end
78+
79+
# Compute dist[(F, S)] and best[(F, S)]
80+
function update_constraint!(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})
81+
required = Set{Tuple{DataType, DataType}}()
82+
fill_required_constraints!(required, b, F, S)
83+
update_dist!(b, required)
84+
end
85+
86+
"""
87+
addbridge!(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
88+
89+
Enable the use of the bridges of type `BT` by `b`.
90+
"""
91+
function addbridge!(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
92+
push!(b.bridgetypes, BT)
93+
# Some constraints (F, S) in keys(b.best) may now be bridged
94+
# with a less briges than `b.dist[(F, S)] using `BT`
95+
update_dist!(b, keys(b.best))
96+
end
97+
6898
# It only bridges when the constraint is not supporting, hence the name "Lazy"
6999
function isbridged(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})
70100
!MOI.supportsconstraint(b.model, F, S)
71101
end
72-
supportsbridgingconstraint(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet}) = (F, S) in keys(b.best)
73-
bridgetype(b::LazyBridgeOptimizer{BT}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet}) where BT = b.best[(F, S)]
102+
function supportsbridgingconstraint(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})
103+
update_constraint!(b, F, S)
104+
(F, S) in keys(b.best)
105+
end
106+
function bridgetype(b::LazyBridgeOptimizer{BT}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet}) where BT
107+
update_constraint!(b, F, S)
108+
b.best[(F, S)]
109+
end

src/Bridges/rsocbridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function RSOCBridge{T}(model, f::MOI.VectorAffineFunction{T}, s::MOI.RotatedSeco
3535
RSOCBridge{T}(soc)
3636
end
3737

38-
supportedconstrainttypes(::Type{RSOCBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.RotatedSecondOrderCone), (MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)]
38+
MOI.supportsconstraint(::Type{RSOCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = true
3939
addedconstrainttypes(::Type{RSOCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = [(MOI.VectorAffineFunction{T}, MOI.SecondOrderCone)]
4040

4141
# Attributes, Bridge acting as an model

src/Bridges/soctopsdbridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ end
6464
_SOCtoPSDCaff(f::MOI.VectorOfVariables, ::Type{T}) where T = _SOCtoPSDCaff(MOI.VectorAffineFunction{T}(f), T)
6565
_SOCtoPSDCaff(f::MOI.VectorAffineFunction, ::Type) = _SOCtoPSDCaff(f, MOIU.eachscalar(f)[1])
6666

67-
supportedconstrainttypes(::Type{SOCtoPSDCBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.SecondOrderCone), (MOI.VectorAffineFunction{T}, MOI.SecondOrderCone)]
67+
MOI.supportsconstraint(::Type{SOCtoPSDCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.SecondOrderCone}) where T = true
6868
addedconstrainttypes(::Type{SOCtoPSDCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.SecondOrderCone}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle)]
6969

7070
function MOI.canget(instance::MOI.AbstractOptimizer, a::Union{MOI.ConstraintPrimal, MOI.ConstraintDual}, ::Type{SOCtoPSDCBridge{T}}) where T
@@ -115,7 +115,7 @@ struct RSOCtoPSDCBridge{T} <: AbstractBridge
115115
dim::Int
116116
cr::CI{MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle}
117117
end
118-
supportedconstrainttypes(::Type{RSOCtoPSDCBridge{T}}) where T = [(MOI.VectorOfVariables, MOI.RotatedSecondOrderCone), (MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)]
118+
MOI.supportsconstraint(::Type{RSOCtoPSDCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = true
119119
addedconstrainttypes(::Type{RSOCtoPSDCBridge{T}}, ::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}}, ::Type{MOI.RotatedSecondOrderCone}) where T = [(MOI.VectorAffineFunction{T}, MOI.PositiveSemidefiniteConeTriangle)]
120120
function RSOCtoPSDCBridge{T}(instance, f, s::MOI.RotatedSecondOrderCone) where T
121121
d = MOI.dimension(s)-1

0 commit comments

Comments
 (0)