/
polyhedra_to_lp_bridge.jl
78 lines (71 loc) · 2.75 KB
/
polyhedra_to_lp_bridge.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
PolyhedraToLPBridge{T}
The `PolyhedraToLPBridge` converts a constraint `VF`-in-`PolyhedraOptSet`
into the constraints `F`-in-`EqualTo` for the hyperplanes and `F`-to-`LessThan`
for halfspaces.
"""
struct PolyhedraToLPBridge{T, F} <: MOI.Bridges.Constraint.AbstractBridge
hyperplanes::Vector{MOI.ConstraintIndex{F, MOI.EqualTo{T}}}
halfspaces::Vector{MOI.ConstraintIndex{F, MOI.LessThan{T}}}
end
function MOI.Bridges.Constraint.bridge_constraint(
::Type{PolyhedraToLPBridge{T, F}}, model::MOI.ModelLike,
f::MOI.AbstractVectorFunction, p::PolyhedraOptSet) where {T, F}
vf = MOIU.eachscalar(f)
hps = [
MOIU.normalize_and_add_constraint(model, func(T, h.a, vf, F), MOI.EqualTo(convert(T, h.β)))
for h in hyperplanes(p.rep)
]
hss = [
MOIU.normalize_and_add_constraint(model, func(T, h.a, vf, F), MOI.LessThan(convert(T, h.β)))
for h in halfspaces(p.rep)
]
return PolyhedraToLPBridge{T, F}(hps, hss)
end
function func(T::Type, a::AbstractVector, vf, F::Type)
func = zero(F)
for (α, f) in zip(a, vf)
MOIU.operate!(+, T, func, MOIU.operate!(*, T, f, convert(T, α)))
end
return func
end
MOI.supports_constraint(::Type{PolyhedraToLPBridge{T}},
::Type{<:MOI.AbstractVectorFunction},
::Type{<:PolyhedraOptSet}) where {T} = true
function MOI.Bridges.added_constrained_variable_types(::Type{<:PolyhedraToLPBridge})
return Tuple{DataType}[]
end
function MOI.Bridges.added_constraint_types(::Type{PolyhedraToLPBridge{T, F}}) where {T, F}
return [(F, MOI.EqualTo{T}), (F, MOI.LessThan{T})]
end
function MOI.Bridges.Constraint.concrete_bridge_type(
::Type{<:PolyhedraToLPBridge{T}},
VF::Type{<:MOI.AbstractVectorFunction},
::Type{<:PolyhedraOptSet}) where T
SF = MOIU.scalar_type(VF)
TermType = MOIU.promote_operation(*, T, T, SF)
F = MOIU.promote_operation(+, T, TermType, TermType)
return PolyhedraToLPBridge{T, F}
end
# Attributes, Bridge acting as an model
function MOI.get(b::PolyhedraToLPBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.EqualTo{T}}) where {T, F}
return length(b.hyperplanes)
end
function MOI.get(b::PolyhedraToLPBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.EqualTo{T}}) where {T, F}
return b.hyperplanes
end
function MOI.get(b::PolyhedraToLPBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.LessThan{T}}) where {T, F}
return length(b.halfspaces)
end
function MOI.get(b::PolyhedraToLPBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.LessThan{T}}) where {T, F}
return b.halfspaces
end
# Indices
function MOI.delete(model::MOI.ModelLike, b::PolyhedraToLPBridge)
for h in b.hyperplanes
MOI.delete(model, h)
end
for h in b.halfspaces
MOI.delete(model, h)
end
end