14"""Linear constraint in a model."""
16from typing
import Any, Iterator, Optional
25 """An indicator constraint for an optimization model.
27 An IndicatorConstraint adds the following restriction on feasible solutions to
28 an optimization model:
29 if z == 1 then lb <= sum_{i in I} a_i * x_i <= ub
30 where z is a binary decision variable (or its negation) and x_i are the
31 decision variables of the problem. Equality constraints lb == ub is allowed,
32 which models the constraint:
33 if z == 1 then sum_{i in I} a_i * x_i == b
34 Setting lb > ub will result in an InvalidArgument error at solve time.
36 Indicator constraints have limited mutability. You can delete a variable
37 that the constraint uses, or you can delete the entire constraint. You
38 currently cannot update bounds or coefficients. This may change in future
41 If the indicator variable is deleted or was None at creation time, the
42 constraint will lead to an invalid model at solve time, unless the constraint
43 is deleted before solving.
45 The name is optional, read only, and used only for debugging. Non-empty names
48 Do not create an IndicatorConstraint directly, use
49 Model.add_indicator_constraint() instead. Two IndicatorConstraint objects can
50 represent the same constraint (for the same model). They will have the same
51 underlying IndicatorConstraint.elemental for storing the data. The
52 IndicatorConstraint class is simply a reference to an Elemental.
55 __slots__ =
"_elemental",
"_id"
57 def __init__(self, elem: elemental.Elemental, cid: int) ->
None:
58 """Internal only, prefer Model functions (add_indicator_constraint() and get_indicator_constraint())."""
59 if not isinstance(cid, int):
60 raise TypeError(f
"cid type should be int, was:{type(cid).__name__!r}")
67 enums.DoubleAttr1.INDICATOR_CONSTRAINT_LOWER_BOUND, (self.
_id,)
73 enums.DoubleAttr1.INDICATOR_CONSTRAINT_UPPER_BOUND, (self.
_id,)
79 enums.BoolAttr1.INDICATOR_CONSTRAINT_ACTIVATE_ON_ZERO, (self.
_id,)
85 enums.VariableAttr1.INDICATOR_CONSTRAINT_INDICATOR, (self.
_id,)
94 enums.ElementType.INDICATOR_CONSTRAINT, self.
_id
102 def elemental(self) -> elemental.Elemental:
103 """Internal use only."""
107 from_model.model_is_same(var, self)
109 enums.DoubleAttr2.INDICATOR_CONSTRAINT_LINEAR_COEFFICIENT,
113 def terms(self) -> Iterator[variables.LinearTerm]:
114 """Yields the variable/coefficient pairs with nonzero coefficient for this linear constraint."""
116 enums.DoubleAttr2.INDICATOR_CONSTRAINT_LINEAR_COEFFICIENT, 0, self.
_id
119 enums.DoubleAttr2.INDICATOR_CONSTRAINT_LINEAR_COEFFICIENT, keys
121 for i
in range(len(keys)):
124 coefficient=float(coefs[i]),
128 """Returns the bounded expression from lower_bound, upper_bound and terms."""
129 return variables.BoundedLinearExpression(
134 """Returns the name, or a string containing the id if the name is empty."""
135 return self.
name if self.
name else f
"linear_constraint_{self.id}"
138 return f
"<LinearConstraint id: {self.id}, name: {self.name!r}>"
141 if isinstance(other, IndicatorConstraint):
142 return self.
_id == other._id
and self.
_elemental is other._elemental
146 return hash(self.
_id)