14"""Quadratic constraint in a model."""
16from typing
import Any, Iterator
25 """A quadratic constraint for an optimization model.
27 A QuadraticConstraint adds the following restriction on feasible solutions to
28 an optimization model:
29 lb <= sum_i a_i x_i + sum_i sum_{j : i <= j} b_ij x_i x_j <= ub
30 where x_i are the decision variables of the problem. lb == ub is allowed, and
31 this models an equality constraint. lb > ub is also allowed, but the
32 optimization problem will be infeasible.
34 Quadratic constraints have limited mutability. You can delete a variable
35 that the constraint uses, or you can delete the entire constraint. You
36 currently cannot update bounds or coefficients. This may change in future
39 A QuadraticConstraint can be queried as follows:
40 * lower_bound: a float property, lb above. Should not be NaN nor +inf.
41 * upper_bound: a float property, ub above. Should not be NaN nor -inf.
42 * get_linear_coefficient(): get the a_i * x_i terms. The variable must be
43 from the same model as this constraint, and the a_i must be finite and not
44 NaN. The coefficient for any variable not set is 0.0.
45 * get_quadratic_coefficient(): like get_linear_coefficient() but for the
46 b_ij terms. Note that get_quadratic_coefficient(x, y, 8) and
47 get_quadratic_coefficient(y, x, 8) have the same result.
49 The name is optional, read only, and used only for debugging. Non-empty names
52 Do not create a QuadraticConstraint directly, use
53 Model.add_quadratic_constraint() instead. Two QuadraticConstraint objects
54 can represent the same constraint (for the same model). They will have the
55 same underlying QuadraticConstraint.elemental for storing the data. The
56 QuadraticConstraint class is simply a reference to an Elemental.
59 __slots__ =
"_elemental",
"_id"
61 def __init__(self, elem: elemental.Elemental, cid: int) ->
None:
62 """Internal only, prefer Model functions (add_quadratic_constraint() and get_quadratic_constraint())."""
63 if not isinstance(cid, int):
64 raise TypeError(f
"cid type should be int, was:{type(cid).__name__!r}")
70 """The quadratic expression of the constraint must be at least this."""
72 enums.DoubleAttr1.QUADRATIC_CONSTRAINT_LOWER_BOUND, (self.
_id,)
77 """The quadratic expression of the constraint must be at most this."""
79 enums.DoubleAttr1.QUADRATIC_CONSTRAINT_UPPER_BOUND, (self.
_id,)
84 """The name of this constraint."""
86 enums.ElementType.QUADRATIC_CONSTRAINT, self.
_id
91 """A unique (for the model) identifier for this constraint."""
95 def elemental(self) -> elemental.Elemental:
96 """Internal use only."""
100 """Returns the linear coefficient for var in the constraint's quadratic expression."""
101 from_model.model_is_same(var, self)
103 enums.DoubleAttr2.QUADRATIC_CONSTRAINT_LINEAR_COEFFICIENT,
108 """Yields variable/coefficient pairs from the linear part of the constraint.
110 Only the pairs with nonzero coefficient are returned.
113 The variable, coefficient pairs.
116 enums.DoubleAttr2.QUADRATIC_CONSTRAINT_LINEAR_COEFFICIENT, 0, self.
_id
119 enums.DoubleAttr2.QUADRATIC_CONSTRAINT_LINEAR_COEFFICIENT, keys
121 for i
in range(len(keys)):
124 coefficient=float(coefs[i]),
130 """Returns the quadratic coefficient for the pair (var1, var2) in the constraint's quadratic expression."""
131 from_model.model_is_same(var1, self)
132 from_model.model_is_same(var2, self)
134 enums.SymmetricDoubleAttr3.QUADRATIC_CONSTRAINT_QUADRATIC_COEFFICIENT,
135 (self.
_id, var1.id, var2.id),
139 """Yields variable/coefficient pairs from the quadratic part of the constraint.
141 Only the pairs with nonzero coefficient are returned.
144 The variable, coefficient pairs.
147 enums.SymmetricDoubleAttr3.QUADRATIC_CONSTRAINT_QUADRATIC_COEFFICIENT,
152 enums.SymmetricDoubleAttr3.QUADRATIC_CONSTRAINT_QUADRATIC_COEFFICIENT,
155 for i
in range(len(keys)):
161 coefficient=float(coefs[i]),
165 """Returns the name, or a string containing the id if the name is empty."""
166 return self.
name if self.
name else f
"quadratic_constraint_{self.id}"
169 return f
"<QuadraticConstraint id: {self.id}, name: {self.name!r}>"
172 if isinstance(other, QuadraticConstraint):
173 return self.
_id == other._id
and self.
_elemental is other._elemental