/
indicator_activate_on_zero.jl
89 lines (83 loc) · 2.74 KB
/
indicator_activate_on_zero.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
79
80
81
82
83
84
85
86
87
88
89
"""
IndicatorActiveOnFalseBridge{T}
The `IndicatorActiveOnFalseBridge` replaces an indicator constraint activated
on 0 with a variable ``z_0`` with the constraint activated on 1, with a variable ``z_1``.
It stores the added `variable_index` and added constraints:
- ``z_1 \\in \\mathbb{B}`` in `zero_one_cons`
- ``z_0 + z_1 == 1`` in `` in `disjunction_cons`
- The added `ACTIVATE_ON_ONE` indicator constraint in `indicator_cons_index`.
"""
struct IndicatorActiveOnFalseBridge{
T,
F<:MOI.AbstractVectorFunction,
S<:MOI.AbstractScalarSet,
} <: AbstractBridge
variable_index::MOI.VariableIndex
zero_one_cons::MOI.ConstraintIndex{MOI.SingleVariable,MOI.ZeroOne}
disjunction_cons::MOI.ConstraintIndex{
MOI.ScalarAffineFunction{T},
MOI.EqualTo{T},
}
indicator_cons_index::MOI.ConstraintIndex{
F,
MOI.IndicatorSet{MOI.ACTIVATE_ON_ONE,S},
}
end
function bridge_constraint(
::Type{IndicatorActiveOnFalseBridge{T,F,S}},
model::MOI.ModelLike,
f::MOI.VectorAffineFunction{T},
s::IS,
) where {
S<:MOI.AbstractScalarSet,
T<:Real,
F,
IS<:MOI.IndicatorSet{MOI.ACTIVATE_ON_ZERO,S},
}
f_scalars = MOIU.eachscalar(f)
z2, zo_cons = MOI.add_constrained_variable(model, MOI.ZeroOne())
# z1 + z2 == 1
z1_z2 = MOIU.operate(+, T, f_scalars[1], MOI.SingleVariable(z2))
dcons = MOIU.normalize_and_add_constraint(model, z1_z2, MOI.EqualTo(one(T)))
f2 = MOIU.operate(vcat, T, MOI.SingleVariable(z2), f_scalars[2])
ci = MOI.add_constraint(
model,
f2,
MOI.IndicatorSet{MOI.ACTIVATE_ON_ONE}(s.set),
)
return IndicatorActiveOnFalseBridge{T,F,S}(z2, zo_cons, dcons, ci)
end
function MOI.supports_constraint(
::Type{<:IndicatorActiveOnFalseBridge{T}},
::Type{<:MOI.VectorAffineFunction},
::Type{<:MOI.IndicatorSet{MOI.ACTIVATE_ON_ZERO}},
) where {T}
return true
end
function MOIB.added_constrained_variable_types(
::Type{<:IndicatorActiveOnFalseBridge},
)
return [(MOI.ZeroOne,)]
end
function MOIB.added_constraint_types(
::Type{IndicatorActiveOnFalseBridge{T,F,S}},
) where {T,F,S}
return [
(MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}),
(F, MOI.IndicatorSet{MOI.ACTIVATE_ON_ONE,S}),
]
end
function concrete_bridge_type(
::Type{<:IndicatorActiveOnFalseBridge{T}},
::Type{F},
::Type{MOI.IndicatorSet{MOI.ACTIVATE_ON_ZERO,S}},
) where {T,F<:MOI.VectorAffineFunction,S<:MOI.AbstractScalarSet}
return IndicatorActiveOnFalseBridge{T,F,S}
end
function concrete_bridge_type(
::Type{<:IndicatorActiveOnFalseBridge},
::Type{F},
::Type{MOI.IndicatorSet{MOI.ACTIVATE_ON_ZERO,S}},
) where {F<:MOI.VectorAffineFunction,S<:MOI.AbstractScalarSet}
return IndicatorActiveOnFalseBridge{Float64,F,S}
end