Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
|
#include <integer.h>
Public Member Functions | |
IntegerTrail (Model *model) | |
IntegerTrail (const IntegerTrail &)=delete | |
This type is neither copyable nor movable. | |
IntegerTrail & | operator= (const IntegerTrail &)=delete |
~IntegerTrail () final | |
bool | Propagate (Trail *trail) final |
void | Untrail (const Trail &trail, int literal_trail_index) final |
absl::Span< const Literal > | Reason (const Trail &trail, int trail_index, int64_t conflict_id) const final |
IntegerVariable | NumIntegerVariables () const |
void | ReserveSpaceForNumVariables (int num_vars) |
IntegerVariable | AddIntegerVariable (IntegerValue lower_bound, IntegerValue upper_bound) |
IntegerVariable | AddIntegerVariable (const Domain &domain) |
const Domain & | InitialVariableDomain (IntegerVariable var) const |
bool | UpdateInitialDomain (IntegerVariable var, Domain domain) |
IntegerVariable | GetOrCreateConstantIntegerVariable (IntegerValue value) |
int | NumConstantVariables () const |
IntegerVariable | AddIntegerVariable () |
IntegerValue | LowerBound (IntegerVariable i) const |
Returns the current lower/upper bound of the given integer variable. | |
IntegerValue | UpperBound (IntegerVariable i) const |
const IntegerValue * | LowerBoundsData () const |
bool | IsFixed (IntegerVariable i) const |
Checks if the variable is fixed. | |
IntegerValue | FixedValue (IntegerVariable i) const |
Checks that the variable is fixed and returns its value. | |
IntegerValue | LowerBound (AffineExpression expr) const |
Same as above for an affine expression. | |
IntegerValue | UpperBound (AffineExpression expr) const |
bool | IsFixed (AffineExpression expr) const |
IntegerValue | FixedValue (AffineExpression expr) const |
IntegerLiteral | LowerBoundAsLiteral (IntegerVariable i) const |
IntegerLiteral | UpperBoundAsLiteral (IntegerVariable i) const |
IntegerLiteral | LowerBoundAsLiteral (AffineExpression expr) const |
IntegerLiteral | UpperBoundAsLiteral (AffineExpression expr) const |
bool | IntegerLiteralIsTrue (IntegerLiteral l) const |
Returns the current value (if known) of an IntegerLiteral. | |
bool | IntegerLiteralIsFalse (IntegerLiteral l) const |
IntegerValue | LevelZeroLowerBound (IntegerVariable var) const |
Returns globally valid lower/upper bound on the given integer variable. | |
IntegerValue | LevelZeroUpperBound (IntegerVariable var) const |
IntegerValue | LevelZeroLowerBound (AffineExpression exp) const |
Returns globally valid lower/upper bound on the given affine expression. | |
IntegerValue | LevelZeroUpperBound (AffineExpression exp) const |
bool | IsFixedAtLevelZero (IntegerVariable var) const |
Returns true if the variable is fixed at level 0. | |
bool | IsFixedAtLevelZero (AffineExpression expr) const |
Returns true if the affine expression is fixed at level 0. | |
IntegerValue | ConditionalLowerBound (Literal l, IntegerVariable i) const |
IntegerValue | ConditionalLowerBound (Literal l, AffineExpression expr) const |
IntegerValue | ConditionalUpperBound (Literal l, IntegerVariable i) const |
Returns the current upper bound assuming the literal is true. | |
IntegerValue | ConditionalUpperBound (Literal l, AffineExpression expr) const |
void | RelaxLinearReason (IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< IntegerLiteral > *reason) const |
void | AppendRelaxedLinearReason (IntegerValue slack, absl::Span< const IntegerValue > coeffs, absl::Span< const IntegerVariable > vars, std::vector< IntegerLiteral > *reason) const |
Same as above but take in IntegerVariables instead of IntegerLiterals. | |
void | RelaxLinearReason (IntegerValue slack, absl::Span< const IntegerValue > coeffs, std::vector< int > *trail_indices) const |
Same as above but relax the given trail indices. | |
void | RemoveLevelZeroBounds (std::vector< IntegerLiteral > *reason) const |
ABSL_MUST_USE_RESULT bool | Enqueue (IntegerLiteral i_lit) |
ABSL_MUST_USE_RESULT bool | Enqueue (IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason) |
ABSL_MUST_USE_RESULT bool | SafeEnqueue (IntegerLiteral i_lit, absl::Span< const IntegerLiteral > integer_reason) |
ABSL_MUST_USE_RESULT bool | ConditionalEnqueue (Literal lit, IntegerLiteral i_lit, std::vector< Literal > *literal_reason, std::vector< IntegerLiteral > *integer_reason) |
ABSL_MUST_USE_RESULT bool | Enqueue (IntegerLiteral i_lit, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason, int trail_index_with_same_reason) |
ABSL_MUST_USE_RESULT bool | EnqueueWithLazyReason (IntegerLiteral i_lit, int id, IntegerValue propagation_slack, LazyReasonInterface *explainer) |
Lazy reason API. | |
ABSL_MUST_USE_RESULT bool | RootLevelEnqueue (IntegerLiteral i_lit) |
void | EnqueueLiteral (Literal literal, absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason) |
std::vector< Literal > | ReasonFor (IntegerLiteral literal) const |
void | MergeReasonInto (absl::Span< const IntegerLiteral > literals, std::vector< Literal > *output) const |
int64_t | num_enqueues () const |
int64_t | timestamp () const |
int64_t | num_level_zero_enqueues () const |
Same as num_enqueues but only count the level zero changes. | |
void | RegisterWatcher (SparseBitset< IntegerVariable > *p) |
bool | ReportConflict (absl::Span< const Literal > literal_reason, absl::Span< const IntegerLiteral > integer_reason) |
bool | ReportConflict (absl::Span< const IntegerLiteral > integer_reason) |
bool | VariableLowerBoundIsFromLevelZero (IntegerVariable var) const |
Returns true if the variable lower bound is still the one from level zero. | |
void | RegisterReversibleClass (ReversibleInterface *rev) |
int | Index () const |
void | AppendNewBounds (std::vector< IntegerLiteral > *output) const |
void | AppendNewBoundsFrom (int base_index, std::vector< IntegerLiteral > *output) const |
int | FindTrailIndexOfVarBefore (IntegerVariable var, int threshold) const |
bool | InPropagationLoop () const |
void | NotifyThatPropagationWasAborted () |
IntegerVariable | NextVariableToBranchOnInPropagationLoop () const |
bool | CurrentBranchHadAnIncompletePropagation () |
IntegerVariable | FirstUnassignedVariable () const |
bool | HasPendingRootLevelDeduction () const |
Return true if we can fix new fact at level zero. | |
void | RegisterDebugChecker (std::function< bool(absl::Span< const Literal > clause, absl::Span< const IntegerLiteral > integers)> checker) |
void | AddAllGreaterThanConstantReason (absl::Span< AffineExpression > exprs, IntegerValue target_min, std::vector< int > *indices) const |
Public Member Functions inherited from operations_research::sat::SatPropagator | |
SatPropagator (const std::string &name) | |
SatPropagator (const SatPropagator &)=delete | |
This type is neither copyable nor movable. | |
SatPropagator & | operator= (const SatPropagator &)=delete |
virtual | ~SatPropagator ()=default |
void | SetPropagatorId (int id) |
Sets/Gets this propagator unique id. | |
int | PropagatorId () const |
bool | PropagatePreconditionsAreSatisfied (const Trail &trail) const |
######################## Implementations below ######################## | |
bool | PropagationIsDone (const Trail &trail) const |
Returns true iff all the trail was inspected by this propagator. | |
virtual bool | IsEmpty () const |
Additional Inherited Members | |
Protected Attributes inherited from operations_research::sat::SatPropagator | |
const std::string | name_ |
int | propagator_id_ |
int | propagation_trail_index_ |
This class maintains a set of integer variables with their current bounds. Bounds can be propagated from an external "source" and this class helps to maintain the reason for each propagation.
|
inlineexplicit |
|
delete |
This type is neither copyable nor movable.
|
final |
Definition at line 698 of file integer.cc.
|
inline |
This is used by the GreaterThanAtLeastOneOf() lazy reason.
Skip if we already have an explanation for expr >= target_min. Note that we already do that while processing the returned indices, so this mainly save a FindLowestTrailIndexThatExplainBound() call per skipped indices, which can still be costly.
We need to find the index that explain the bound.
|
inline |
Same as AddIntegerVariable() but uses the maximum possible range. Note that since we take negation of bounds in various places, we make sure that we don't have overflow when we take the negation of the lower bound or of the upper bound.
IntegerVariable operations_research::sat::IntegerTrail::AddIntegerVariable | ( | const Domain & | domain | ) |
Same as above but for a more complex domain specified as a sorted list of disjoint intervals. See the Domain class.
Definition at line 868 of file integer.cc.
IntegerVariable operations_research::sat::IntegerTrail::AddIntegerVariable | ( | IntegerValue | lower_bound, |
IntegerValue | upper_bound ) |
Adds a new integer variable. Adding integer variable can only be done when the decision level is zero (checked). The given bounds are INCLUSIVE and must not cross.
Note on integer overflow: 'upper_bound - lower_bound' must fit on an int64_t, this is DCHECKed. More generally, depending on the constraints that are added, the bounds magnitude must be small enough to satisfy each constraint overflow precondition.
Definition at line 837 of file integer.cc.
void operations_research::sat::IntegerTrail::AppendNewBounds | ( | std::vector< IntegerLiteral > * | output | ) | const |
Inspects the trail and output all the non-level zero bounds (one per variables) to the output. The algo is sparse if there is only a few propagations on the trail.
Definition at line 2065 of file integer.cc.
void operations_research::sat::IntegerTrail::AppendNewBoundsFrom | ( | int | base_index, |
std::vector< IntegerLiteral > * | output ) const |
Inspects the trail and output all the non-level zero bounds from the base index (one per variables) to the output. The algo is sparse if there is only a few propagations on the trail.
In order to push the best bound for each variable, we loop backward.
Definition at line 2071 of file integer.cc.
void operations_research::sat::IntegerTrail::AppendRelaxedLinearReason | ( | IntegerValue | slack, |
absl::Span< const IntegerValue > | coeffs, | ||
absl::Span< const IntegerVariable > | vars, | ||
std::vector< IntegerLiteral > * | reason ) const |
Same as above but take in IntegerVariables instead of IntegerLiterals.
Definition at line 1047 of file integer.cc.
bool operations_research::sat::IntegerTrail::ConditionalEnqueue | ( | Literal | lit, |
IntegerLiteral | i_lit, | ||
std::vector< Literal > * | literal_reason, | ||
std::vector< IntegerLiteral > * | integer_reason ) |
Pushes the given integer literal assuming that the Boolean literal is true. This can do a few things:
We can't push anything in this case.
We record it for this propagation phase (until the next untrail) as this is relatively fast and heuristics can exploit this.
Definition at line 1269 of file integer.cc.
|
inline |
|
inline |
|
inline |
|
inline |
bool operations_research::sat::IntegerTrail::CurrentBranchHadAnIncompletePropagation | ( | ) |
If we had an incomplete propagation, it is important to fix all the variables and not really on the propagation to do so. This is related to the InPropagationLoop() code above.
Definition at line 1481 of file integer.cc.
|
inline |
Enqueue new information about a variable bound. Calling this with a less restrictive bound than the current one will have no effect.
The reason for this "assignment" must be provided as:
IMPORTANT: Notice the inversed sign in the literal reason. This is a bit confusing but internally SAT use this direction for efficiency.
Note(user): Duplicates Literal/IntegerLiteral are supported because we call STLSortAndRemoveDuplicates() in MergeReasonInto(), but maybe they shouldn't for efficiency reason.
|
inline |
|
inline |
Same as Enqueue(), but takes an extra argument which if smaller than integer_trail_.size() is interpreted as the trail index of an old Enqueue() that had the same reason as this one. Note that the given Span must still be valid as they are used in case of conflict.
void operations_research::sat::IntegerTrail::EnqueueLiteral | ( | Literal | literal, |
absl::Span< const Literal > | literal_reason, | ||
absl::Span< const IntegerLiteral > | integer_reason ) |
Enqueues the given literal on the trail. See the comment of Enqueue() for the reason format.
Definition at line 1392 of file integer.cc.
|
inline |
int operations_research::sat::IntegerTrail::FindTrailIndexOfVarBefore | ( | IntegerVariable | var, |
int | threshold ) const |
Returns the trail index < threshold of a TrailEntry about var. Returns -1 if there is no such entry (at a positive decision level). This is basically the trail index of the lower bound of var at the time.
Important: We do some optimization internally, so this should only be used from within a LazyReasonFunction().
Optimization. We assume this is only called when computing a reason, so we can ignore this trail_index if we already need a more restrictive reason for this var.
Hacky: We know this is only called with threshold == trail_index of the trail entry we are trying to explain. So this test can only trigger when a variable was shown to be already implied by the current conflict.
Disable the other optim if we might expand this literal during 1-UIP resolution.
Check the validity of the cached index and use it if possible.
Definition at line 946 of file integer.cc.
IntegerVariable operations_research::sat::IntegerTrail::FirstUnassignedVariable | ( | ) | const |
Definition at line 1485 of file integer.cc.
|
inline |
|
inline |
IntegerVariable operations_research::sat::IntegerTrail::GetOrCreateConstantIntegerVariable | ( | IntegerValue | value | ) |
Same as AddIntegerVariable(value, value), but this is a bit more efficient because it reuses another constant with the same value if its exist.
Note(user): Creating constant integer variable is a bit wasteful, but not that much, and it allows to simplify a lot of constraints that do not need to handle this case any differently than the general one. Maybe there is a better solution, but this is not really high priority as of December 2016.
Definition at line 925 of file integer.cc.
|
inline |
|
inline |
const Domain & operations_research::sat::IntegerTrail::InitialVariableDomain | ( | IntegerVariable | var | ) | const |
Returns the initial domain of the given variable. Note that the min/max are updated with level zero propagation, but not holes.
Definition at line 876 of file integer.cc.
bool operations_research::sat::IntegerTrail::InPropagationLoop | ( | ) | const |
Basic heuristic to detect when we are in a propagation loop, and suggest a good variable to branch on (taking the middle value) to get out of it.
We count the number of propagation at the current level, and returns true if it seems really large. Note that we disable this if we are in fixed search.
Definition at line 1434 of file integer.cc.
|
inline |
|
inline |
Returns the current value (if known) of an IntegerLiteral.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Returns the integer literal that represent the current lower/upper bound of the given affine expression. In case the expression is constant, it returns IntegerLiteral::TrueLiteral().
|
inline |
|
inline |
If one needs to do a lot of LowerBound()/UpperBound() it will be faster to cache the current pointer to the underlying vector.
void operations_research::sat::IntegerTrail::MergeReasonInto | ( | absl::Span< const IntegerLiteral > | literals, |
std::vector< Literal > * | output ) const |
Appends the reason for the given integer literals to the output and call STLSortAndRemoveDuplicates() on it. This function accept "constant" literal.
Any indices lower than that means that there is no reason needed.
Definition at line 1825 of file integer.cc.
IntegerVariable operations_research::sat::IntegerTrail::NextVariableToBranchOnInPropagationLoop | ( | ) | const |
We try to select a variable with a large domain that was propagated a lot already.
Definition at line 1452 of file integer.cc.
void operations_research::sat::IntegerTrail::NotifyThatPropagationWasAborted | ( | ) |
Definition at line 1444 of file integer.cc.
|
inline |
Returns the number of enqueues that changed a variable bounds. We don't count enqueues called with a less restrictive bound than the current one.
Note(user): this can be used to see if any of the bounds changed. Just looking at the integer trail index is not enough because at level zero it doesn't change since we directly update the "fixed" bounds.
|
inline |
int operations_research::sat::IntegerTrail::NumConstantVariables | ( | ) | const |
The +1 if for the special key zero (the only case when we have an odd number of entries).
Definition at line 940 of file integer.cc.
|
inline |
Returns the number of created integer variables.
|
delete |
|
finalvirtual |
SatPropagator interface. These functions make sure the current bounds information is in sync with the current solver literal trail. Any class/propagator using this class must make sure it is synced to the correct state before calling any of its functions.
Make sure that our internal "integer_search_levels_" size matches the sat decision levels. At the level zero, integer_search_levels_ should be empty.
This is required because when loading a model it is possible that we add (literal <-> integer literal) associations for literals that have already been propagated here. This often happens when the presolve is off and many variables are fixed.
Process all the "associated" literals and Enqueue() the corresponding bounds.
The reason is simply the associated literal.
Implements operations_research::sat::SatPropagator.
Definition at line 705 of file integer.cc.
|
finalvirtual |
Reimplemented from operations_research::sat::SatPropagator.
Definition at line 2047 of file integer.cc.
std::vector< Literal > operations_research::sat::IntegerTrail::ReasonFor | ( | IntegerLiteral | literal | ) | const |
Returns the reason (as set of Literal currently false) for a given integer literal. Note that the bound must be less restrictive than the current bound (checked).
Definition at line 1819 of file integer.cc.
|
inline |
|
inline |
|
inline |
void operations_research::sat::IntegerTrail::RelaxLinearReason | ( | IntegerValue | slack, |
absl::Span< const IntegerValue > | coeffs, | ||
std::vector< int > * | trail_indices ) const |
Same as above but relax the given trail indices.
We start by filtering *trail_indices:
We ignore level zero entries.
If the coeff is too large, we cannot relax this entry.
This is a bit hacky, but when it is used from MergeReasonIntoInternal(), we never relax a reason that will not be expanded because it is already part of the current conflict.
The slack might have changed since the entry was added.
Relax, and decide what to do with the new value of index.
Same code as in the first block.
If we aborted early because of the slack, we need to push all remaining indices back into the reason.
Definition at line 1062 of file integer.cc.
void operations_research::sat::IntegerTrail::RelaxLinearReason | ( | IntegerValue | slack, |
absl::Span< const IntegerValue > | coeffs, | ||
std::vector< IntegerLiteral > * | reason ) const |
Advanced usage. Given the reason for (Sum_i coeffs[i] * reason[i].var >= current_lb) initially in reason, this function relaxes the reason given that we only need the explanation of (Sum_i coeffs[i] * reason[i].var >= current_lb - slack).
Preconditions:
*reason must initially contains the trivial initial reason, that is the current lower-bound of each variables.
Definition at line 1025 of file integer.cc.
void operations_research::sat::IntegerTrail::RemoveLevelZeroBounds | ( | std::vector< IntegerLiteral > * | reason | ) | const |
Removes from the reasons the literal that are always true. This is mainly useful for experiments/testing.
Definition at line 1159 of file integer.cc.
|
inline |
|
inline |
void operations_research::sat::IntegerTrail::ReserveSpaceForNumVariables | ( | int | num_vars | ) |
Optimization: you can call this before calling AddIntegerVariable() num_vars time.
We only store the domain for the positive variable.
Because we always create both a variable and its negation.
Definition at line 821 of file integer.cc.
bool operations_research::sat::IntegerTrail::RootLevelEnqueue | ( | IntegerLiteral | i_lit | ) |
Sometimes we infer some root level bounds but we are not at the root level. In this case, we will update the level-zero bounds right away, but will delay the current push until the next restart.
We update right away the level zero bounds, but delay the actual enqueue until we are back at level zero. This allow to properly push any associated literal.
Definition at line 1229 of file integer.cc.
bool operations_research::sat::IntegerTrail::SafeEnqueue | ( | IntegerLiteral | i_lit, |
absl::Span< const IntegerLiteral > | integer_reason ) |
Enqueue new information about a variable bound. It has the same behavior as the Enqueue() method, except that it accepts true and false integer literals, both for i_lit, and for the integer reason.
This method will do nothing if i_lit is a true literal. It will report a conflict if i_lit is a false literal, and enqueue i_lit normally otherwise. Furthemore, it will check that the integer reason does not contain any false literals, and will remove true literals before calling ReportConflict() or Enqueue().
Most of our propagation code do not use "constant" literal, so to not have to test for them in Enqueue(), we clear them beforehand.
Definition at line 1252 of file integer.cc.
|
inline |
|
finalvirtual |
Reverts the state so that all the literals with a trail index greater or equal to the given one are not processed for propagation. Note that the trail current decision level is already reverted before this is called.
Resize lazy reason.
Clear reason.
We notify the new level once all variables have been restored to their old value.
Reimplemented from operations_research::sat::SatPropagator.
Definition at line 768 of file integer.cc.
bool operations_research::sat::IntegerTrail::UpdateInitialDomain | ( | IntegerVariable | var, |
Domain | domain ) |
Takes the intersection with the current initial variable domain.
Update directly the level zero bounds.
Do not forget to update the watchers.
Update the encoding.
Definition at line 886 of file integer.cc.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |