14 #ifndef OR_TOOLS_SAT_PB_CONSTRAINT_H_
15 #define OR_TOOLS_SAT_PB_CONSTRAINT_H_
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/types/span.h"
83 std::vector<LiteralWithCoeff>* cst, Coefficient* bound_shift,
84 Coefficient* max_value);
98 std::vector<LiteralWithCoeff>* cst, Coefficient* bound_shift,
99 Coefficient* max_value);
109 Coefficient bound_shift, Coefficient max_value);
117 Coefficient bound_shift,
118 Coefficient max_value);
122 const std::vector<LiteralWithCoeff>& cst);
127 std::vector<LiteralWithCoeff>* cst, Coefficient* rhs);
153 std::vector<LiteralWithCoeff>* cst);
157 const Coefficient
Rhs(
int i)
const {
return rhs_[i]; }
158 const std::vector<LiteralWithCoeff>&
Constraint(
int i)
const {
159 return constraints_[i];
163 bool AddConstraint(
const std::vector<LiteralWithCoeff>& cst,
164 Coefficient max_value, Coefficient rhs);
166 std::vector<Coefficient> rhs_;
167 std::vector<std::vector<LiteralWithCoeff>> constraints_;
186 return AbsCoefficient(terms_[
var]);
210 const Coefficient
bound = max_sum_ - rhs_;
222 int trail_index)
const;
234 const Trail& trail,
int trail_index);
259 Coefficient initial_slack, Coefficient target);
269 Coefficient
Rhs()
const {
return rhs_; }
270 Coefficient
MaxSum()
const {
return max_sum_; }
276 const BooleanVariable
var =
literal.Variable();
277 const Coefficient term_encoding =
literal.IsPositive() ? coeff : -coeff;
284 rhs_ -=
std::min(coeff, AbsCoefficient(terms_[
var]));
285 max_sum_ += AbsCoefficient(term_encoding + terms_[
var]) -
286 AbsCoefficient(terms_[
var]);
291 CHECK_GE(max_sum_, 0) <<
"Overflow";
292 terms_[
var] += term_encoding;
299 const BooleanVariable
var =
literal.Variable();
301 return std::min(coeff, AbsCoefficient(terms_[
var]));
314 Coefficient AbsCoefficient(Coefficient
a)
const {
return a > 0 ?
a : -
a; }
317 Coefficient ComputeMaxSum()
const;
329 Coefficient max_sum_;
337 class UpperBoundedLinearConstraint;
378 const std::vector<LiteralWithCoeff>& cst);
382 Coefficient
Rhs()
const {
return rhs_; }
390 bool InitializeRhs(Coefficient rhs,
int trail_index, Coefficient* threshold,
406 bool Propagate(
int trail_index, Coefficient* threshold,
Trail* trail,
413 void Untrail(Coefficient* threshold,
int trail_index);
431 BooleanVariable propagated_variable,
432 std::vector<Literal>* reason);
438 Coefficient* conflict_slack);
453 const Trail& trail,
int trail_index,
473 int64_t
hash()
const {
return hash_; }
480 Coefficient GetSlackFromThreshold(Coefficient threshold) {
481 return (index_ < 0) ? threshold : coeffs_[index_] + threshold;
483 void Update(Coefficient slack, Coefficient* threshold) {
484 *threshold = (index_ < 0) ? slack : slack - coeffs_[index_];
485 already_propagated_end_ = starts_[index_ + 1];
490 bool is_marked_for_deletion_;
492 int first_reason_trail_index_;
497 int already_propagated_end_;
506 std::vector<Coefficient> coeffs_;
507 std::vector<int> starts_;
508 std::vector<Literal> literals_;
520 conflicting_constraint_index_(-1),
521 num_learned_constraint_before_cleanup_(0),
522 constraint_activity_increment_(1.0),
523 parameters_(
model->GetOrCreate<SatParameters>()),
524 stats_(
"PbConstraints"),
525 num_constraint_lookups_(0),
526 num_inspected_constraint_literals_(0),
527 num_threshold_updates_(0) {
528 model->GetOrCreate<
Trail>()->RegisterPropagator(
this);
533 LOG(
INFO) <<
"num_constraint_lookups_: " << num_constraint_lookups_;
534 LOG(
INFO) <<
"num_threshold_updates_: " << num_threshold_updates_;
539 void Untrail(
const Trail& trail,
int trail_index)
final;
540 absl::Span<const Literal>
Reason(
const Trail& trail,
541 int trail_index)
const final;
548 if (!constraints_.empty()) {
549 to_update_.
resize(num_variables << 1);
550 enqueue_helper_.
reasons.resize(num_variables);
564 bool AddConstraint(
const std::vector<LiteralWithCoeff>& cst, Coefficient rhs,
570 Coefficient rhs,
Trail* trail);
582 if (conflicting_constraint_index_ == -1)
return nullptr;
583 return constraints_[conflicting_constraint_index_.value()].get();
598 constraints_[
index]->MarkForDeletion();
599 DeleteConstraintMarkedForDeletion();
605 return num_inspected_constraint_literals_;
610 bool PropagateNext(
Trail* trail);
614 void ComputeNewLearnedConstraintLimit();
615 void DeleteSomeLearnedConstraintIfNeeded();
620 void DeleteConstraintMarkedForDeletion();
629 DEFINE_INT_TYPE(ConstraintIndex, int32_t);
630 struct ConstraintIndexWithCoeff {
631 ConstraintIndexWithCoeff() {}
632 ConstraintIndexWithCoeff(
bool n, ConstraintIndex i, Coefficient c)
634 bool need_untrail_inspection;
635 ConstraintIndex
index;
640 std::vector<std::unique_ptr<UpperBoundedLinearConstraint>> constraints_;
651 SparseBitset<ConstraintIndex> to_untrail_;
655 absl::flat_hash_map<int64_t, std::vector<UpperBoundedLinearConstraint*>>
656 possible_duplicates_;
659 PbConstraintsEnqueueHelper enqueue_helper_;
663 ConstraintIndex conflicting_constraint_index_;
666 int target_number_of_learned_constraint_;
667 int num_learned_constraint_before_cleanup_;
668 double constraint_activity_increment_;
671 SatParameters* parameters_;
674 mutable StatsGroup stats_;
675 int64_t num_constraint_lookups_;
676 int64_t num_inspected_constraint_literals_;
677 int64_t num_threshold_updates_;
694 first_variable_.
resize(num_variables);
705 if (seen_[
var])
return first_variable_[
var];
706 const BooleanVariable reference_var =
708 if (reference_var ==
var)
return var;
709 if (seen_[reference_var])
return first_variable_[reference_var];
710 seen_.
Set(reference_var);
711 first_variable_[reference_var] =
var;
#define CHECK_GE(val1, val2)
#define CHECK_GT(val1, val2)
#define DCHECK_GT(val1, val2)
void resize(size_type new_size)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Set(IntegerType index)
void ClearAndResize(IntegerType size)
std::string StatString() const
int NumConstraints() const
bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound, bool use_upper_bound, Coefficient upper_bound, std::vector< LiteralWithCoeff > *cst)
CanonicalBooleanLinearProblem()
const Coefficient Rhs(int i) const
const std::vector< LiteralWithCoeff > & Constraint(int i) const
LiteralIndex Index() const
std::string DebugString() const
Class that owns everything related to a particular optimization model.
void ReduceCoefficients()
Coefficient MaxSum() const
Literal GetLiteral(BooleanVariable var) const
Coefficient ComputeSlackForTrailPrefix(const Trail &trail, int trail_index) const
Coefficient ReduceCoefficientsAndComputeSlackForTrailPrefix(const Trail &trail, int trail_index)
void ReduceSlackTo(const Trail &trail, int trail_index, Coefficient initial_slack, Coefficient target)
const std::vector< BooleanVariable > & PossibleNonZeros() const
std::string DebugString()
Coefficient CancelationAmount(Literal literal, Coefficient coeff) const
void ReduceGivenCoefficient(BooleanVariable var)
void AddTerm(Literal literal, Coefficient coeff)
void AddToRhs(Coefficient value)
void ClearAndResize(int num_variables)
void CopyIntoVector(std::vector< LiteralWithCoeff > *output)
Coefficient GetCoefficient(BooleanVariable var) const
int NumberOfConstraints() const
bool Propagate(Trail *trail) final
~PbConstraints() override
void RescaleActivities(double scaling_factor)
void ClearConflictingConstraint()
int64_t num_inspected_constraint_literals() const
absl::Span< const Literal > Reason(const Trail &trail, int trail_index) const final
bool AddConstraint(const std::vector< LiteralWithCoeff > &cst, Coefficient rhs, Trail *trail)
int64_t num_threshold_updates() const
void DeleteConstraint(int index)
UpperBoundedLinearConstraint * ConflictingConstraint()
PbConstraints(Model *model)
UpperBoundedLinearConstraint * ReasonPbConstraint(int trail_index) const
void UpdateActivityIncrement()
void BumpActivity(UpperBoundedLinearConstraint *constraint)
void Untrail(const Trail &trail, int trail_index) final
int64_t num_constraint_lookups() const
void Resize(int num_variables)
bool AddLearnedConstraint(const std::vector< LiteralWithCoeff > &cst, Coefficient rhs, Trail *trail)
void Enqueue(Literal true_literal, int propagator_id)
BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const
void set_activity(double activity)
Coefficient ComputeCancelation(const Trail &trail, int trail_index, const MutableUpperBoundedLinearConstraint &conflict)
bool Propagate(int trail_index, Coefficient *threshold, Trail *trail, PbConstraintsEnqueueHelper *helper)
void set_is_learned(bool is_learned)
void FillReason(const Trail &trail, int source_trail_index, BooleanVariable propagated_variable, std::vector< Literal > *reason)
bool HasIdenticalTerms(const std::vector< LiteralWithCoeff > &cst)
void ResolvePBConflict(const Trail &trail, BooleanVariable var, MutableUpperBoundedLinearConstraint *conflict, Coefficient *conflict_slack)
bool InitializeRhs(Coefficient rhs, int trail_index, Coefficient *threshold, Trail *trail, PbConstraintsEnqueueHelper *helper)
int already_propagated_end() const
void Untrail(Coefficient *threshold, int trail_index)
void AddToConflict(MutableUpperBoundedLinearConstraint *conflict)
UpperBoundedLinearConstraint(const std::vector< LiteralWithCoeff > &cst)
bool is_used_as_a_reason() const
bool is_marked_for_deletion() const
BooleanVariable FirstVariableWithSameReason(BooleanVariable var)
VariableWithSameReasonIdentifier(const Trail &trail)
void Resize(int num_variables)
Coefficient ComputeCanonicalRhs(Coefficient upper_bound, Coefficient bound_shift, Coefficient max_value)
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
bool ApplyLiteralMapping(const absl::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)
void SimplifyCanonicalBooleanLinearConstraint(std::vector< LiteralWithCoeff > *cst, Coefficient *rhs)
DEFINE_INT_TYPE(ClauseIndex, int)
bool ComputeBooleanLinearExpressionCanonicalForm(std::vector< LiteralWithCoeff > *cst, Coefficient *bound_shift, Coefficient *max_value)
bool BooleanLinearExpressionIsCanonical(const std::vector< LiteralWithCoeff > &cst)
const Coefficient kCoefficientMax(std::numeric_limits< Coefficient::ValueType >::max())
Collection of objects used to extend the Constraint Solver library.
#define IF_STATS_ENABLED(instructions)
bool operator==(const LiteralWithCoeff &other) const
LiteralWithCoeff(Literal l, Coefficient c)
LiteralWithCoeff(Literal l, int64_t c)
UpperBoundedLinearConstraint * pb_constraint
std::vector< ReasonInfo > reasons
void Enqueue(Literal l, int source_trail_index, UpperBoundedLinearConstraint *ct, Trail *trail)
std::vector< Literal > conflict