Constraints
Add a constraint
Use add_constraint
to add a single constraint.
julia> c = MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Nonnegatives(2))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Nonnegatives}(1)
add_constraint
returns a ConstraintIndex
type, which is used to refer to the added constraint in other calls.
Check if a ConstraintIndex
is valid using is_valid
.
julia> MOI.is_valid(model, c)
true
Use add_constraints
to add a number of constraints of the same type.
julia> c = MOI.add_constraints(
model,
[x[1], x[2]],
[MOI.GreaterThan(0.0), MOI.GreaterThan(1.0)]
)
2-element Vector{MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.GreaterThan{Float64}}}:
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.GreaterThan{Float64}}(1)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.GreaterThan{Float64}}(2)
This time, a vector of ConstraintIndex
are returned.
Use supports_constraint
to check if the model supports adding a constraint type.
julia> MOI.supports_constraint(
model,
MOI.VariableIndex,
MOI.GreaterThan{Float64},
)
true
Delete a constraint
Use delete
to delete a constraint.
julia> MOI.delete(model, c)
julia> MOI.is_valid(model, c)
false
Constraint attributes
The following attributes are available for constraints:
ConstraintName
ConstraintPrimalStart
ConstraintDualStart
ConstraintPrimal
ConstraintDual
ConstraintBasisStatus
ConstraintFunction
CanonicalConstraintFunction
ConstraintSet
Get and set these attributes using get
and set
.
julia> MOI.set(model, MOI.ConstraintName(), c, "con_c")
julia> MOI.get(model, MOI.ConstraintName(), c)
"con_c"
Constraints by function-set pairs
Below is a list of common constraint types and how they are represented as function-set pairs in MOI. In the notation below, $x$ is a vector of decision variables, $x_i$ is a scalar decision variable, $\alpha, \beta$ are scalar constants, $a, b$ are constant vectors, A
is a constant matrix and $\mathbb{R}_+$ (resp. $\mathbb{R}_-$) is the set of non-negative (resp. non-positive) real numbers.
Linear constraints
Mathematical Constraint | MOI Function | MOI Set |
---|---|---|
$a^Tx \le \beta$ | ScalarAffineFunction | LessThan |
$a^Tx \ge \alpha$ | ScalarAffineFunction | GreaterThan |
$a^Tx = \beta$ | ScalarAffineFunction | EqualTo |
$\alpha \le a^Tx \le \beta$ | ScalarAffineFunction | Interval |
$x_i \le \beta$ | VariableIndex | LessThan |
$x_i \ge \alpha$ | VariableIndex | GreaterThan |
$x_i = \beta$ | VariableIndex | EqualTo |
$\alpha \le x_i \le \beta$ | VariableIndex | Interval |
$Ax + b \in \mathbb{R}_+^n$ | VectorAffineFunction | Nonnegatives |
$Ax + b \in \mathbb{R}_-^n$ | VectorAffineFunction | Nonpositives |
$Ax + b = 0$ | VectorAffineFunction | Zeros |
By convention, solvers are not expected to support nonzero constant terms in the ScalarAffineFunction
s the first four rows of the preceding table because they are redundant with the parameters of the sets. For example, encode $2x + 1 \le 2$ as $2x \le 1$.
Constraints with VariableIndex
in LessThan
, GreaterThan
, EqualTo
, or Interval
sets have a natural interpretation as variable bounds. As such, it is typically not natural to impose multiple lower- or upper-bounds on the same variable, and the solver interfaces will throw respectively LowerBoundAlreadySet
or UpperBoundAlreadySet
.
Moreover, adding two VariableIndex
constraints on the same variable with the same set is impossible because they share the same index as it is the index of the variable, see ConstraintIndex
.
It is natural, however, to impose upper- and lower-bounds separately as two different constraints on a single variable. The difference between imposing bounds by using a single Interval
constraint and by using separate LessThan
and GreaterThan
constraints is that the latter will allow the solver to return separate dual multipliers for the two bounds, while the former will allow the solver to return only a single dual for the interval constraint.
Conic constraints
Mathematical Constraint | MOI Function | MOI Set |
---|---|---|
$\lVert Ax + b\rVert_2 \le c^Tx + d$ | VectorAffineFunction | SecondOrderCone |
$y \ge \lVert x \rVert_2$ | VectorOfVariables | SecondOrderCone |
$2yz \ge \lVert x \rVert_2^2, y,z \ge 0$ | VectorOfVariables | RotatedSecondOrderCone |
$(a_1^Tx + b_1,a_2^Tx + b_2,a_3^Tx + b_3) \in \mathcal{E}$ | VectorAffineFunction | ExponentialCone |
$A(x) \in \mathcal{S}_+$ | VectorAffineFunction | PositiveSemidefiniteConeTriangle |
$B(x) \in \mathcal{S}_+$ | VectorAffineFunction | PositiveSemidefiniteConeSquare |
$x \in \mathcal{S}_+$ | VectorOfVariables | PositiveSemidefiniteConeTriangle |
$x \in \mathcal{S}_+$ | VectorOfVariables | PositiveSemidefiniteConeSquare |
where $\mathcal{E}$ is the exponential cone (see ExponentialCone
), $\mathcal{S}_+$ is the set of positive semidefinite symmetric matrices, $A$ is an affine map that outputs symmetric matrices and $B$ is an affine map that outputs square matrices.
Quadratic constraints
Mathematical Constraint | MOI Function | MOI Set |
---|---|---|
$\frac{1}{2}x^TQx + a^Tx + b \ge 0$ | ScalarQuadraticFunction | GreaterThan |
$\frac{1}{2}x^TQx + a^Tx + b \le 0$ | ScalarQuadraticFunction | LessThan |
$\frac{1}{2}x^TQx + a^Tx + b = 0$ | ScalarQuadraticFunction | EqualTo |
Bilinear matrix inequality | VectorQuadraticFunction | PositiveSemidefiniteCone... |
For more details on the internal format of the quadratic functions see ScalarQuadraticFunction
or VectorQuadraticFunction
.
Discrete and logical constraints
Mathematical Constraint | MOI Function | MOI Set |
---|---|---|
$x_i \in \mathbb{Z}$ | VariableIndex | Integer |
$x_i \in \{0,1\}$ | VariableIndex | ZeroOne |
$x_i \in \{0\} \cup [l,u]$ | VariableIndex | Semicontinuous |
$x_i \in \{0\} \cup \{l,l+1,\ldots,u-1,u\}$ | VariableIndex | Semiinteger |
At most one component of $x$ can be nonzero | VectorOfVariables | SOS1 |
At most two components of $x$ can be nonzero, and if so they must be adjacent components | VectorOfVariables | SOS2 |
$y = 1 \implies a^T x \in S$ | VectorAffineFunction | Indicator |
JuMP mapping
The following bullet points show examples of how JuMP constraints are translated into MOI function-set pairs:
@constraint(m, 2x + y <= 10)
becomesScalarAffineFunction
-in-LessThan
@constraint(m, 2x + y >= 10)
becomesScalarAffineFunction
-in-GreaterThan
@constraint(m, 2x + y == 10)
becomesScalarAffineFunction
-in-EqualTo
@constraint(m, 0 <= 2x + y <= 10)
becomesScalarAffineFunction
-in-Interval
@constraint(m, 2x + y in ArbitrarySet())
becomesScalarAffineFunction
-in-ArbitrarySet
.
Variable bounds are handled in a similar fashion:
@variable(m, x <= 1)
becomesVariableIndex
-in-LessThan
@variable(m, x >= 1)
becomesVariableIndex
-in-GreaterThan
One notable difference is that a variable with an upper and lower bound is translated into two constraints, rather than an interval, that is:
@variable(m, 0 <= x <= 1)
becomesVariableIndex
-in-LessThan
andVariableIndex
-in-GreaterThan
.