Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
|
#include <integer.h>
Public Member Functions | |
IntegerEncoder (Model *model) | |
IntegerEncoder (const IntegerEncoder &)=delete | |
This type is neither copyable nor movable. | |
IntegerEncoder & | operator= (const IntegerEncoder &)=delete |
~IntegerEncoder () | |
void | ReserveSpaceForNumVariables (int num_vars) |
Memory optimization: you can call this before encoding variables. | |
void | FullyEncodeVariable (IntegerVariable var) |
bool | VariableIsFullyEncoded (IntegerVariable var) const |
const std::vector< ValueLiteralPair > & | FullDomainEncoding (IntegerVariable var) const |
const std::vector< ValueLiteralPair > & | PartialDomainEncoding (IntegerVariable var) const |
std::pair< IntegerLiteral, IntegerLiteral > | Canonicalize (IntegerLiteral i_lit) const |
Literal | GetOrCreateAssociatedLiteral (IntegerLiteral i_lit) |
Literal | GetOrCreateLiteralAssociatedToEquality (IntegerVariable var, IntegerValue value) |
void | AssociateToIntegerLiteral (Literal literal, IntegerLiteral i_lit) |
void | AssociateToIntegerEqualValue (Literal literal, IntegerVariable var, IntegerValue value) |
bool | IsFixedOrHasAssociatedLiteral (IntegerLiteral i_lit) const |
LiteralIndex | GetAssociatedLiteral (IntegerLiteral i_lit) const |
LiteralIndex | GetAssociatedEqualityLiteral (IntegerVariable var, IntegerValue value) const |
void | DisableImplicationBetweenLiteral () |
void | AddAllImplicationsBetweenAssociatedLiterals () |
const InlinedIntegerLiteralVector & | GetIntegerLiterals (Literal lit) const |
Returns the IntegerLiterals that were associated with the given Literal. | |
const InlinedIntegerValueVector & | GetEqualityLiterals (Literal lit) const |
const std::vector< IntegerVariable > & | GetAllAssociatedVariables (Literal lit) const |
IntegerVariable | GetLiteralView (Literal lit) const |
ABSL_MUST_USE_RESULT bool | LiteralOrNegationHasView (Literal lit, IntegerVariable *view=nullptr, bool *view_is_direct=nullptr) const |
LiteralIndex | SearchForLiteralAtOrBefore (IntegerLiteral i_lit, IntegerValue *bound) const |
Literal | GetTrueLiteral () |
Gets the literal always set to true, make it if it does not exist. | |
Literal | GetFalseLiteral () |
std::vector< ValueLiteralPair > | PartialGreaterThanEncoding (IntegerVariable var) const |
bool | UpdateEncodingOnInitialDomainChange (IntegerVariable var, Domain domain) |
Each integer variable x will be associated with a set of literals encoding (x >= v) for some values of v. This class maintains the relationship between the integer variables and such literals which can be created by a call to CreateAssociatedLiteral().
The advantage of creating such Boolean variables is that the SatSolver which is driving the search can then take this variable as a decision and maintain these variables activity and so on. These variables can also be propagated directly by the learned clauses.
This class also support a non-lazy full domain encoding which will create one literal per possible value in the domain. See FullyEncodeVariable(). This is meant to be called by constraints that directly work on the variable values like a table constraint or an all-diff constraint.
|
inlineexplicit |
|
delete |
This type is neither copyable nor movable.
|
inline |
void operations_research::sat::IntegerEncoder::AddAllImplicationsBetweenAssociatedLiterals | ( | ) |
This is tricky: AddBinaryClause() might trigger propagation that causes the encoding to be filtered. So we make a copy...
literal => previous.
Definition at line 226 of file integer.cc.
void operations_research::sat::IntegerEncoder::AssociateToIntegerEqualValue | ( | Literal | literal, |
IntegerVariable | var, | ||
IntegerValue | value ) |
The function is symmetric and we only deal with positive variable.
Detect literal view. Note that the same literal can be associated to more than one variable, and thus already have a view. We don't change it in this case.
We use the "do not insert if present" behavior of .insert() to do just one lookup.
If this key is already associated, make the two literals equal.
Fix literal for value outside the domain.
Update equality_by_var. Note that due to the equality_to_associated_literal_ hash table, there should never be any duplicate values for a given variable.
Fix literal for constant domain.
Special case for the first and last value.
(var == value) <=> (var >= value) and (var <= value).
Update reverse encoding.
Definition at line 434 of file integer.cc.
void operations_research::sat::IntegerEncoder::AssociateToIntegerLiteral | ( | Literal | literal, |
IntegerLiteral | i_lit ) |
Associates the Boolean literal to (X >= bound) or (X == value). If a literal was already associated to this fact, this will add an equality constraints between both literals. If the fact is trivially true or false, this will fix the given literal.
Always transform to positive variable.
We just insert the part corresponding to the literal with positive variable.
Corner case if adding implication cause this to be fixed.
Resize reverse encoding.
Detect the case >= max or <= min and properly register them. Note that both cases will happen at the same time if there is just two possible value in the domain.
Definition at line 364 of file integer.cc.
std::pair< IntegerLiteral, IntegerLiteral > operations_research::sat::IntegerEncoder::Canonicalize | ( | IntegerLiteral | i_lit | ) | const |
Returns the "canonical" (i_lit, negation of i_lit) pair. This mainly deal with domain with initial hole like [1,2][5,6] so that if one ask for x <= 3, this get canonicalized in the pair (x <= 2, x >= 5).
Definition at line 246 of file integer.cc.
|
inline |
Advanced usage. It is more efficient to create the associated literals in order, but it might be anoying to do so. Instead, you can first call DisableImplicationBetweenLiteral() and when you are done creating all the associated literals, you can call (only at level zero) AddAllImplicationsBetweenAssociatedLiterals() which will also turn back on the implications between literals for the one that will be added afterwards.
const std::vector< ValueLiteralPair > & operations_research::sat::IntegerEncoder::FullDomainEncoding | ( | IntegerVariable | var | ) | const |
Returns the list of literal <=> var == value currently associated to the given variable. The result is sorted by value. We filter literal at false, and if a literal is true, then you will get a singleton. To be sure to get the full set of encoded value, then you should call this at level zero.
The FullDomainEncoding() just check VariableIsFullyEncoded() and returns the same result.
Definition at line 145 of file integer.cc.
void operations_research::sat::IntegerEncoder::FullyEncodeVariable | ( | IntegerVariable | var | ) |
Fully encode a variable using its current initial domain. If the variable is already fully encoded, this does nothing.
This creates new Booleans variables as needed: 1) num_values for the literals X == value. Except when there is just two value in which case only one variable is created. 2) num_values - 3 for the literals X >= value or X <= value (using their negation). The -3 comes from the fact that we can reuse the equality literals for the two extreme points.
The encoding for NegationOf(var) is automatically created too. It reuses the same Boolean variable as the encoding of var.
Mark var and Negation(var) as fully encoded.
Definition at line 79 of file integer.cc.
|
inline |
LiteralIndex operations_research::sat::IntegerEncoder::GetAssociatedEqualityLiteral | ( | IntegerVariable | var, |
IntegerValue | value ) const |
Definition at line 317 of file integer.cc.
LiteralIndex operations_research::sat::IntegerEncoder::GetAssociatedLiteral | ( | IntegerLiteral | i_lit | ) | const |
Definition at line 540 of file integer.cc.
|
inline |
|
inline |
|
inline |
|
inline |
If it exists, returns a [0,1] integer variable which is equal to 1 iff the given literal is true. Returns kNoIntegerVariable if such variable does not exist. Note that one can create one by creating a new IntegerVariable and calling AssociateToIntegerEqualValue().
Literal operations_research::sat::IntegerEncoder::GetOrCreateAssociatedLiteral | ( | IntegerLiteral | i_lit | ) |
Returns, after creating it if needed, a Boolean literal such that:
This add the proper implications with the two "neighbor" literals of this one if they exist. This is the "list encoding" in: Thibaut Feydy, Peter J. Stuckey, "Lazy Clause Generation Reengineered", CP 2009.
Remove trivial literal.
Canonicalize and see if we have an equivalent literal already.
Definition at line 273 of file integer.cc.
Literal operations_research::sat::IntegerEncoder::GetOrCreateLiteralAssociatedToEquality | ( | IntegerVariable | var, |
IntegerValue | value ) |
Check for trivial true/false literal to avoid creating variable for no reasons.
Definition at line 327 of file integer.cc.
|
inline |
bool operations_research::sat::IntegerEncoder::IsFixedOrHasAssociatedLiteral | ( | IntegerLiteral | i_lit | ) | const |
Returns kNoLiteralIndex if there is no associated or the associated literal otherwise.
Tricky: for domain with hole, like [0,1][5,6], we assume some equivalence classes, like >=2, >=3, >=4 are all the same as >= 5.
Definition at line 531 of file integer.cc.
ABSL_MUST_USE_RESULT bool operations_research::sat::IntegerEncoder::LiteralOrNegationHasView | ( | Literal | lit, |
IntegerVariable * | view = nullptr, | ||
bool * | view_is_direct = nullptr ) const |
If this is true, then a literal can be linearized with an affine expression involving an integer variable.
If a literal has both views, we want to always keep the same representative: the smallest IntegerVariable.
Definition at line 582 of file integer.cc.
|
delete |
const std::vector< ValueLiteralPair > & operations_research::sat::IntegerEncoder::PartialDomainEncoding | ( | IntegerVariable | var | ) | const |
We can cleanup the current encoding in this case.
Definition at line 151 of file integer.cc.
std::vector< ValueLiteralPair > operations_research::sat::IntegerEncoder::PartialGreaterThanEncoding | ( | IntegerVariable | var | ) | const |
Returns the set of Literal associated to IntegerLiteral of the form var >= value. We make a copy, because this can be easily invalidated when calling any function of this class. So it is less efficient but safer.
Tricky: we need to account for holes.
Definition at line 602 of file integer.cc.
void operations_research::sat::IntegerEncoder::ReserveSpaceForNumVariables | ( | int | num_vars | ) |
Memory optimization: you can call this before encoding variables.
Definition at line 73 of file integer.cc.
LiteralIndex operations_research::sat::IntegerEncoder::SearchForLiteralAtOrBefore | ( | IntegerLiteral | i_lit, |
IntegerValue * | bound ) const |
Returns a Boolean literal associated with a bound lower than or equal to the one of the given IntegerLiteral. If the given IntegerLiteral is true, then the returned literal should be true too. Returns kNoLiteralIndex if no such literal was created.
Ex: if 'i' is (x >= 4) and we already created a literal associated to (x >= 2) but not to (x >= 3), we will return the literal associated with (x >= 2).
We need the entry at or before. We take the element before the upper_bound() which is either the encoding of i if it already exists, or the encoding just before it.
We ask for who is implied by -var >= -bound, so we look for the var >= value with value > bound and take its negation.
Compute tight bound if there are holes, we have X <= candidate.
Definition at line 554 of file integer.cc.
bool operations_research::sat::IntegerEncoder::UpdateEncodingOnInitialDomainChange | ( | IntegerVariable | var, |
Domain | domain ) |
Makes sure all element in the >= encoding are non-trivial and canonical. The input variable must be positive.
Fix >= literal that can be fixed. We filter and canonicalize the encoding.
We are past the end, so always false.
We are at or before the beginning, so always true.
Same for equality encoding. This will be lazily cleaned on the next PartialDomainEncoding() call.
Definition at line 638 of file integer.cc.
bool operations_research::sat::IntegerEncoder::VariableIsFullyEncoded | ( | IntegerVariable | var | ) | const |
Returns true if we know that PartialDomainEncoding(var) span the full domain of var. This is always true if FullyEncodeVariable(var) has been called.
Once fully encoded, the status never changes.
This cleans equality_by_var_[index] as a side effect and in particular, sorts it by values.
Definition at line 110 of file integer.cc.