Skip to content

Commit 2a0fece

Browse files
committed
Respond to code review
1 parent 594bf94 commit 2a0fece

File tree

1 file changed

+26
-34
lines changed

1 file changed

+26
-34
lines changed

src/Utilities/penalty_relaxation.jl

+26-34
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ constraint.
2121
The penalty relaxation modifies constraints of the form ``f(x) \\in S`` into
2222
``f(x) + y - z \\in S``, where ``y, z \\ge 0``, and then it introduces a penalty
2323
term into the objective of ``a \\times (y + z)`` (if minimizing, else ``-a``),
24-
where `a` is the value in the `penalties` dictionary associated with the
25-
constraint that is being relaxed. If no value exists, the default is `default`.
24+
where ``a`` is `penalty`
2625
2726
When `S` is [`MOI.LessThan`](@ref) or [`MOI.GreaterThan`](@ref), we omit `y` or
2827
`z` respectively as a performance optimization.
@@ -60,26 +59,14 @@ julia> f isa MOI.ScalarAffineFunction{Float64}
6059
true
6160
```
6261
"""
63-
struct ScalarPenaltyRelaxation{T}
62+
struct ScalarPenaltyRelaxation{T} # <: MOI.AbstractFunctionModification
63+
# We don't make this a subtype of AbstractFunctionModification to avoid some
64+
# ambiguities with generic methods in Utilities and Bridges. The underlying
65+
# reason is that these reformulations can be written using the high-level
66+
# MOI API, so we don't need special handling for bridges and utilities.
6467
penalty::T
6568
end
6669

67-
function MOI.supports(
68-
::MOI.ModelLike,
69-
::ScalarPenaltyRelaxation{T},
70-
::Type{<:MOI.ConstraintIndex{F,<:MOI.AbstractScalarSet}},
71-
) where {T,F<:Union{MOI.ScalarAffineFunction{T},MOI.ScalarQuadraticFunction{T}}}
72-
return true
73-
end
74-
75-
function MOI.supports(
76-
::MOI.ModelLike,
77-
::ScalarPenaltyRelaxation,
78-
::Type{<:MOI.ConstraintIndex},
79-
)
80-
return false
81-
end
82-
8370
function _change_set_to_min_if_necessary(
8471
::Type{T},
8572
model::MOI.ModelLike,
@@ -94,6 +81,15 @@ function _change_set_to_min_if_necessary(
9481
return MOI.MIN_SENSE
9582
end
9683

84+
function MOI.modify(
85+
::MOI.ModelLike,
86+
::MOI.ConstraintIndex,
87+
::ScalarPenaltyRelaxation,
88+
)
89+
# A generic fallback if modification is not supported.
90+
return nothing
91+
end
92+
9793
function MOI.modify(
9894
model::MOI.ModelLike,
9995
ci::MOI.ConstraintIndex{F,<:MOI.AbstractScalarSet},
@@ -167,17 +163,13 @@ modifies the model in-place to create a penalized relaxation of the constraints.
167163
168164
## Reformulation
169165
170-
The penalty relaxation modifies constraints of the form ``f(x) \\in S`` into
171-
``f(x) + y - z \\in S``, where ``y, z \\ge 0``, and then it introduces a penalty
172-
term into the objective of ``a \\times (y + z)`` (if minimizing, else ``-a``),
173-
where `a` is the value in the `penalties` dictionary associated with the
174-
constraint that is being relaxed.
166+
See [`Utilities.ScalarPenaltyRelaxation`](@ref) for details of the
167+
reformulation.
175168
176-
If no value exists for the constraint in `penalties`, the penalty is `default`.
177-
If `default` is also `nothing`, then the constraint is skipped.
178-
179-
When `S` is [`MOI.LessThan`](@ref) or [`MOI.GreaterThan`](@ref), we omit `y` or
180-
`z` respectively as a performance optimization.
169+
For each constraint `ci`, the penalty passed to [`Utilities.ScalarPenaltyRelaxation`](@ref)
170+
is `get(penalties, ci, default)`. If the value is `nothing`, because `ci` does
171+
not exist in `penalties` and `default = nothing`, then the constraint is
172+
skipped.
181173
182174
## Return value
183175
@@ -299,12 +291,12 @@ function _modify_penalty_relaxation(
299291
if penalty === nothing
300292
continue
301293
end
302-
attr = ScalarPenaltyRelaxation(penalty)
303-
if !MOI.supports(model, attr, MOI.ConstraintIndex{F,S})
304-
@warn("Skipping PenaltyRelaxation of constraints of type $F-in-$S")
294+
delta = MOI.modify(model, ci, ScalarPenaltyRelaxation(penalty))
295+
if delta === nothing
296+
@warn("Skipping PenaltyRelaxation for constraints of type $F-in-$S")
305297
return
306298
end
307-
map[ci] = MOI.modify(model, ci, attr)
299+
map[ci] = delta
308300
end
309-
return map
301+
return
310302
end

0 commit comments

Comments
 (0)