The Bridges
submodule
A constraint can often be written in a number of equivalent formulations. For example, the constraint $l \le a^\top x \le u$ (ScalarAffineFunction
-in-Interval
) could be re-formulated as two constraints: $a^\top x \ge l$ (ScalarAffineFunction
-in-GreaterThan
) and $a^\top x \le u$ (ScalarAffineFunction
-in-LessThan
). An alternative re-formulation is to add a dummy variable y
with the constraints $l \le y \le u$ (SingleVariable
-in-Interval
) and $a^\top x - y = 0$ (ScalarAffineFunction
-in-EqualTo
).
To avoid each solver having to code these transformations manually, MathOptInterface provides bridges. A bridge is a small transformation from one constraint type to another (potentially collection of) constraint type. Because these bridges are included in MathOptInterface, they can be re-used by any optimizer. Some bridges also implement constraint modifications and constraint primal and dual translations.
For example, the SplitIntervalBridge
defines the reformulation of a ScalarAffineFunction
-in-Interval
constraint into a ScalarAffineFunction
-in-GreaterThan
and a ScalarAffineFunction
-in-LessThan
constraint. SplitInterval
is the bridge optimizer that applies the SplitIntervalBridge
rewriting rule. Given an optimizer optimizer
implementing ScalarAffineFunction
-in-GreaterThan
and ScalarAffineFunction
-in-LessThan
, the optimizer
optimizer = MOI.Bridges.Constraint.SplitInterval{Float64}(model)
MOI.supports_constraint(
optimizer, MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}
)
# output
true
will additionally support ScalarAffineFunction
-in-Interval
. Note that these Bridges.Constraint.SingleBridgeOptimizer
s are mainly used for testing bridges.
It is recommended to rather use Bridges.full_bridge_optimizer
which automatically selects the appropriate constraint bridges for unsupported constraints.
optimizer = MOI.Bridges.full_bridge_optimizer(model, Float64)
Variable reformulations
A variable is often created constrained in a set unsupported by the solver while it could be parametrized by variables constrained in supported sets. For example, the Bridges.Variable.VectorizeBridge
defines the reformulation of a constrained variable in GreaterThan
into a constrained vector of one variable in Nonnegatives
. The Bridges.Variable.Vectorize
is the bridge optimizer that applies the Bridges.Variable.VectorizeBridge
rewriting rule. Given an optimizer optimizer
implementing constrained variables in Nonnegatives
, the optimizer
optimizer = MOI.Bridges.Variable.Vectorize{Float64}(model)
MOI.supports_add_constrained_variable(optimizer, MOI.GreaterThan{Float64})
# output
true
will additionally support constrained variables in GreaterThan
. Note that these Bridges.Variable.SingleBridgeOptimizer
are mainly used for testing bridges.
It is recommended to rather use Bridges.full_bridge_optimizer
, which automatically selects the appropriate bridges for unsupported constrained variables.