Skip to content

Commit ad8cf99

Browse files
authored
[Bridges.Constraint] change conversion cost to 0.5 for ScalarAffineFunction (#3063)
1 parent 2172e4b commit ad8cf99

3 files changed

Lines changed: 25 additions & 10 deletions

File tree

src/Bridges/Constraint/bridges/AbstractFunctionConversionBridge.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,22 @@ function conversion_cost(
275275
::Type{<:MOI.ScalarAffineFunction},
276276
::Type{MOI.VariableIndex},
277277
)
278-
return 1.0
278+
# We want to favor bridges which convert VariableIndex or VectorOfVariables
279+
# into ScalarAffineFunction or VectorAffineFunction.
280+
#
281+
# This is most useful for conic solvers, which often support
282+
# VectorAffineFunction-in-S, but not VectorOfVariables-in-S.
283+
#
284+
# The value in this function controls the cost of the transformation
285+
# VectorOfVariables-in-S -> VectorAffineFunction-in-S. When we had the
286+
# previous cost of `1.0`, there might be an alternative bridge
287+
# VectorOfVariables-in-S -> VectorAffineFunction-in-S2 which also has a cost
288+
# of `1.0`, and so, depending on the order in which we choose bridges, we
289+
# might end up using a more complicated bridge that adds a different set
290+
# type to the model.
291+
#
292+
# This was a practical concern for Hypatia in MathOptInterface.jl#3062.
293+
return 0.5
279294
end
280295

281296
function conversion_cost(

test/Bridges/General/test_lazy_bridge_optimizer.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,14 +1150,14 @@ Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported an
11501150
"""
11511151
Bridge graph with 2 variable nodes, 5 constraint nodes and 2 objective nodes.
11521152
[1] constrained variables in `MOI.Reals` are bridged (distance 1) by $(MOI.Bridges.Variable.FreeBridge{T}).
1153-
[2] constrained variables in `MOI.RotatedSecondOrderCone` are bridged (distance 11) by $(MOI.Bridges.Variable.RSOCtoPSDBridge{T}).
1154-
(1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 14) by $(MOI.Bridges.Constraint.QuadtoSOCBridge{T}).
1155-
(2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 13) by $(MOI.Bridges.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.RotatedSecondOrderCone}).
1156-
(3) `MOI.VariableIndex`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 1) by $(MOI.Bridges.Constraint.ScalarFunctionizeBridge{T,MOI.EqualTo{T}}).
1153+
[2] constrained variables in `MOI.RotatedSecondOrderCone` are bridged (distance 10.5) by $(MOI.Bridges.Variable.RSOCtoPSDBridge{T}).
1154+
(1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 13.5) by $(MOI.Bridges.Constraint.QuadtoSOCBridge{T}).
1155+
(2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 12.5) by $(MOI.Bridges.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.RotatedSecondOrderCone}).
1156+
(3) `MOI.VariableIndex`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 0.5) by $(MOI.Bridges.Constraint.ScalarFunctionizeBridge{T,MOI.EqualTo{T}}).
11571157
(4) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are bridged (distance 1) by $(MOI.Bridges.Constraint.ScalarizeBridge{T,MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}).
1158-
(5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are bridged (distance 14) by $(MOI.Bridges.Constraint.QuadtoSOCBridge{T}).
1159-
|1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is bridged (distance 31) by $(MOI.Bridges.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}}).
1160-
|2| objective function of type `MOI.VariableIndex` is bridged (distance 1) by $(MOI.Bridges.Objective.FunctionizeBridge{T,MOI.VariableIndex}).
1158+
(5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are bridged (distance 13.5) by $(MOI.Bridges.Constraint.QuadtoSOCBridge{T}).
1159+
|1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is bridged (distance 29.5) by $(MOI.Bridges.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}}).
1160+
|2| objective function of type `MOI.VariableIndex` is bridged (distance 0.5) by $(MOI.Bridges.Objective.FunctionizeBridge{T,MOI.VariableIndex}).
11611161
""",
11621162
)
11631163
end

test/Utilities/test_copy.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ function test_create_variables_using_supports_add_constrained_variable()
503503
@test MOI.get(
504504
bridged_dest,
505505
MOI.ConstraintBridgingCost{MOI.VectorOfVariables,MOI.Nonpositives}(),
506-
) == 1.0
506+
) == 0.5
507507
@test MOI.supports_add_constrained_variables(bridged_dest, MOI.Zeros)
508508
@test MOI.get(bridged_dest, MOI.VariableBridgingCost{MOI.Zeros}()) == 1.0
509509
@test MOI.supports_constraint(
@@ -514,7 +514,7 @@ function test_create_variables_using_supports_add_constrained_variable()
514514
@test MOI.get(
515515
bridged_dest,
516516
MOI.ConstraintBridgingCost{MOI.VectorOfVariables,MOI.Zeros}(),
517-
) == 3.0
517+
) == 2.5
518518
index_map = MOI.copy_to(bridged_dest, src)
519519
@test length(dest.constraintIndices) == 6
520520

0 commit comments

Comments
 (0)