14#ifndef OR_TOOLS_SAT_PB_CONSTRAINT_H_
15#define OR_TOOLS_SAT_PB_CONSTRAINT_H_
25#include "absl/container/flat_hash_map.h"
26#include "absl/log/check.h"
27#include "absl/strings/string_view.h"
28#include "absl/types/span.h"
34#include "ortools/sat/sat_parameters.pb.h"
49 std::numeric_limits<Coefficient::ValueType>::max());
92 std::vector<LiteralWithCoeff>* cst, Coefficient* bound_shift,
93 Coefficient* max_value);
107 std::vector<LiteralWithCoeff>* cst, Coefficient* bound_shift,
108 Coefficient* max_value);
118 Coefficient bound_shift, Coefficient max_value);
126 Coefficient bound_shift,
127 Coefficient max_value);
135 std::vector<LiteralWithCoeff>* cst, Coefficient* rhs);
166 std::vector<LiteralWithCoeff>* cst);
170 Coefficient
Rhs(
int i)
const {
return rhs_[
i]; }
172 return constraints_[
i];
176 bool AddConstraint(absl::Span<const LiteralWithCoeff> cst,
177 Coefficient max_value, Coefficient rhs);
179 std::vector<Coefficient> rhs_;
180 std::vector<std::vector<LiteralWithCoeff>> constraints_;
198 return AbsCoefficient(terms_[
var]);
222 const Coefficient
bound = max_sum_ - rhs_;
234 int trail_index)
const;
246 const Trail& trail,
int trail_index);
271 Coefficient initial_slack, Coefficient target);
281 Coefficient
Rhs()
const {
return rhs_; }
282 Coefficient
MaxSum()
const {
return max_sum_; }
288 const BooleanVariable
var =
literal.Variable();
289 const Coefficient term_encoding =
literal.IsPositive() ? coeff : -coeff;
296 rhs_ -= std::min(coeff, AbsCoefficient(terms_[
var]));
297 max_sum_ += AbsCoefficient(term_encoding + terms_[
var]) -
298 AbsCoefficient(terms_[
var]);
303 CHECK_GE(max_sum_, 0) <<
"Overflow";
304 terms_[
var] += term_encoding;
311 const BooleanVariable
var =
literal.Variable();
313 return std::min(coeff, AbsCoefficient(terms_[
var]));
326 Coefficient AbsCoefficient(Coefficient
a)
const {
return a > 0 ?
a : -
a; }
329 Coefficient ComputeMaxSum()
const;
341 Coefficient max_sum_;
349class UpperBoundedLinearConstraint;
390 const std::vector<LiteralWithCoeff>& cst);
394 Coefficient
Rhs()
const {
return rhs_; }
402 bool InitializeRhs(Coefficient rhs,
int trail_index, Coefficient* threshold,
418 bool Propagate(
int trail_index, Coefficient* threshold,
Trail* trail,
425 void Untrail(Coefficient* threshold,
int trail_index);
443 BooleanVariable propagated_variable,
444 std::vector<Literal>* reason);
450 Coefficient* conflict_slack);
465 const Trail& trail,
int trail_index,
485 uint64_t
hash()
const {
return hash_; }
492 Coefficient GetSlackFromThreshold(Coefficient threshold) {
493 return (index_ < 0) ? threshold : coeffs_[index_] + threshold;
495 void Update(Coefficient slack, Coefficient* threshold) {
496 *threshold = (index_ < 0) ? slack : slack - coeffs_[index_];
497 already_propagated_end_ = starts_[index_ + 1];
502 bool is_marked_for_deletion_;
504 int first_reason_trail_index_;
509 int already_propagated_end_;
518 std::vector<Coefficient> coeffs_;
519 std::vector<int> starts_;
520 std::vector<Literal> literals_;
532 conflicting_constraint_index_(-1),
533 num_learned_constraint_before_cleanup_(0),
534 constraint_activity_increment_(1.0),
535 parameters_(
model->GetOrCreate<SatParameters>()),
536 stats_(
"PbConstraints"),
537 num_constraint_lookups_(0),
538 num_inspected_constraint_literals_(0),
539 num_threshold_updates_(0) {
549 LOG(INFO) <<
"num_constraint_lookups_: " << num_constraint_lookups_;
550 LOG(INFO) <<
"num_threshold_updates_: " << num_threshold_updates_;
555 void Untrail(
const Trail& trail,
int trail_index)
final;
556 absl::Span<const Literal>
Reason(
const Trail& trail,
int trail_index,
557 int64_t conflict_id)
const final;
564 if (!constraints_.empty()) {
565 to_update_.
resize(num_variables << 1);
566 enqueue_helper_.
reasons.resize(num_variables);
580 bool AddConstraint(
const std::vector<LiteralWithCoeff>& cst, Coefficient rhs,
586 Coefficient rhs,
Trail* trail);
590 bool IsEmpty() const final {
return constraints_.empty(); }
599 if (conflicting_constraint_index_ == -1)
return nullptr;
600 return constraints_[conflicting_constraint_index_.value()].get();
615 constraints_[
index]->MarkForDeletion();
616 DeleteConstraintMarkedForDeletion();
622 return num_inspected_constraint_literals_;
627 bool PropagateNext(
Trail* trail);
631 void ComputeNewLearnedConstraintLimit();
632 void DeleteSomeLearnedConstraintIfNeeded();
637 void DeleteConstraintMarkedForDeletion();
647 struct ConstraintIndexWithCoeff {
648 ConstraintIndexWithCoeff() =
default;
649 ConstraintIndexWithCoeff(
bool n, ConstraintIndex
i, Coefficient c)
650 : need_untrail_inspection(n), index(
i), coefficient(c) {}
651 bool need_untrail_inspection;
652 ConstraintIndex index;
653 Coefficient coefficient;
657 std::vector<std::unique_ptr<UpperBoundedLinearConstraint>> constraints_;
668 SparseBitset<ConstraintIndex> to_untrail_;
672 absl::flat_hash_map<int64_t, std::vector<UpperBoundedLinearConstraint*>>
673 possible_duplicates_;
676 PbConstraintsEnqueueHelper enqueue_helper_;
680 ConstraintIndex conflicting_constraint_index_;
683 int target_number_of_learned_constraint_;
684 int num_learned_constraint_before_cleanup_;
685 double constraint_activity_increment_;
688 SatParameters* parameters_;
691 mutable StatsGroup stats_;
692 int64_t num_constraint_lookups_;
693 int64_t num_inspected_constraint_literals_;
694 int64_t num_threshold_updates_;
716 first_variable_.
resize(num_variables);
727 if (seen_[
var])
return first_variable_[
var];
728 const BooleanVariable reference_var =
730 if (reference_var ==
var)
return var;
731 if (seen_[reference_var])
return first_variable_[reference_var];
732 seen_.
Set(reference_var);
733 first_variable_[reference_var] =
var;
void ClearAndResize(IntegerType size)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Set(IntegerType index)
std::string StatString() const
int NumConstraints() const
Getters. All the constraints are guaranteed to be in canonical form.
CanonicalBooleanLinearProblem & operator=(const CanonicalBooleanLinearProblem &)=delete
Coefficient Rhs(int i) const
const std::vector< LiteralWithCoeff > & Constraint(int i) const
CanonicalBooleanLinearProblem()=default
CanonicalBooleanLinearProblem(const CanonicalBooleanLinearProblem &)=delete
This type is neither copyable nor movable.
bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound, bool use_upper_bound, Coefficient upper_bound, std::vector< LiteralWithCoeff > *cst)
std::string DebugString() const
LiteralIndex Index() const
Coefficient MaxSum() const
std::string DebugString()
Returns a string representation of the constraint.
Coefficient ReduceCoefficientsAndComputeSlackForTrailPrefix(const Trail &trail, int trail_index)
Coefficient CancelationAmount(Literal literal, Coefficient coeff) const
Returns the "cancelation" amount of AddTerm(literal, coeff).
void ReduceCoefficients()
Coefficient GetCoefficient(BooleanVariable var) const
Returns the coefficient (>= 0) of the given variable.
Coefficient ComputeSlackForTrailPrefix(const Trail &trail, int trail_index) const
void AddToRhs(Coefficient value)
Adds a non-negative value to this constraint Rhs().
void CopyIntoVector(std::vector< LiteralWithCoeff > *output)
Copies this constraint into a vector<LiteralWithCoeff> representation.
const std::vector< BooleanVariable > & PossibleNonZeros() const
void ReduceSlackTo(const Trail &trail, int trail_index, Coefficient initial_slack, Coefficient target)
void ReduceGivenCoefficient(BooleanVariable var)
void AddTerm(Literal literal, Coefficient coeff)
void ClearAndResize(int num_variables)
Literal GetLiteral(BooleanVariable var) const
void UpdateActivityIncrement()
bool AddConstraint(const std::vector< LiteralWithCoeff > &cst, Coefficient rhs, Trail *trail)
bool Propagate(Trail *trail) final
PbConstraints & operator=(const PbConstraints &)=delete
int64_t num_constraint_lookups() const
Some statistics.
void Resize(int num_variables)
Changes the number of variables.
bool IsEmpty() const final
PbConstraints(const PbConstraints &)=delete
This type is neither copyable nor movable.
void ClearConflictingConstraint()
PbConstraints(Model *model)
~PbConstraints() override
int NumberOfConstraints() const
Returns the number of constraints managed by this class.
UpperBoundedLinearConstraint * ReasonPbConstraint(int trail_index) const
absl::Span< const Literal > Reason(const Trail &trail, int trail_index, int64_t conflict_id) const final
int64_t num_inspected_constraint_literals() const
void BumpActivity(UpperBoundedLinearConstraint *constraint)
bool AddLearnedConstraint(const std::vector< LiteralWithCoeff > &cst, Coefficient rhs, Trail *trail)
int64_t num_threshold_updates() const
void RescaleActivities(double scaling_factor)
void DeleteConstraint(int index)
Only used for testing.
UpperBoundedLinearConstraint * ConflictingConstraint()
void Untrail(const Trail &trail, int trail_index) final
Base class for all the SAT constraints.
BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const
void Enqueue(Literal true_literal, int propagator_id)
void RegisterPropagator(SatPropagator *propagator)
void MarkForDeletion()
API to mark a constraint for deletion before actually deleting it.
void ResolvePBConflict(const Trail &trail, BooleanVariable var, MutableUpperBoundedLinearConstraint *conflict, Coefficient *conflict_slack)
UpperBoundedLinearConstraint(const std::vector< LiteralWithCoeff > &cst)
Takes a pseudo-Boolean formula in canonical form.
Coefficient ComputeCancelation(const Trail &trail, int trail_index, const MutableUpperBoundedLinearConstraint &conflict)
bool Propagate(int trail_index, Coefficient *threshold, Trail *trail, PbConstraintsEnqueueHelper *helper)
void set_activity(double activity)
void AddToConflict(MutableUpperBoundedLinearConstraint *conflict)
void FillReason(const Trail &trail, int source_trail_index, BooleanVariable propagated_variable, std::vector< Literal > *reason)
void Untrail(Coefficient *threshold, int trail_index)
bool is_marked_for_deletion() const
int already_propagated_end() const
bool HasIdenticalTerms(absl::Span< const LiteralWithCoeff > cst)
Returns true if the given terms are the same as the one in this constraint.
bool InitializeRhs(Coefficient rhs, int trail_index, Coefficient *threshold, Trail *trail, PbConstraintsEnqueueHelper *helper)
bool is_used_as_a_reason() const
void set_is_learned(bool is_learned)
BooleanVariable FirstVariableWithSameReason(BooleanVariable var)
VariableWithSameReasonIdentifier(const VariableWithSameReasonIdentifier &)=delete
This type is neither copyable nor movable.
VariableWithSameReasonIdentifier & operator=(const VariableWithSameReasonIdentifier &)=delete
void Clear()
Clears the cache. Call this before each conflict analysis.
void Resize(int num_variables)
VariableWithSameReasonIdentifier(const Trail &trail)
void resize(size_type new_size)
void SimplifyCanonicalBooleanLinearConstraint(std::vector< LiteralWithCoeff > *cst, Coefficient *rhs)
bool ApplyLiteralMapping(const util_intops::StrongVector< LiteralIndex, LiteralIndex > &mapping, std::vector< LiteralWithCoeff > *cst, Coefficient *bound_shift, Coefficient *max_value)
Coefficient ComputeNegatedCanonicalRhs(Coefficient lower_bound, Coefficient bound_shift, Coefficient max_value)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
bool BooleanLinearExpressionIsCanonical(absl::Span< const LiteralWithCoeff > cst)
Returns true iff the Boolean linear expression is in canonical form.
Coefficient ComputeCanonicalRhs(Coefficient upper_bound, Coefficient bound_shift, Coefficient max_value)
H AbslHashValue(H h, const IntVar &i)
– ABSL HASHING SUPPORT --------------------------------------------------—
const Coefficient kCoefficientMax(std::numeric_limits< Coefficient::ValueType >::max())
bool ComputeBooleanLinearExpressionCanonicalForm(std::vector< LiteralWithCoeff > *cst, Coefficient *bound_shift, Coefficient *max_value)
In SWIG mode, we don't want anything besides these top-level includes.
#define IF_STATS_ENABLED(instructions)
#define DEFINE_STRONG_INT64_TYPE(integer_type_name)
#define DEFINE_STRONG_INDEX_TYPE(index_type_name)
Represents a term in a pseudo-Boolean formula.
LiteralWithCoeff()=default
LiteralWithCoeff(Literal l, Coefficient c)
bool operator==(const LiteralWithCoeff &other) const
LiteralWithCoeff(Literal l, int64_t c)
UpperBoundedLinearConstraint * pb_constraint
void Enqueue(Literal l, int source_trail_index, UpperBoundedLinearConstraint *ct, Trail *trail)
int propagator_id
The propagator id of PbConstraints.
std::vector< Literal > conflict
A temporary vector to store the last conflict.
std::vector< ReasonInfo > reasons