14 #ifndef OR_TOOLS_SAT_INTEGER_EXPR_H_
15 #define OR_TOOLS_SAT_INTEGER_EXPR_H_
25 #include "absl/types/span.h"
64 IntegerSumLE(
const std::vector<Literal>& enforcement_literals,
65 const std::vector<IntegerVariable>& vars,
66 const std::vector<IntegerValue>& coeffs,
93 void FillIntegerReason();
95 const std::vector<Literal> enforcement_literals_;
96 const IntegerValue upper_bound_;
104 bool is_registered_ =
false;
105 IntegerValue rev_lb_fixed_vars_;
108 int rev_num_fixed_vars_;
113 std::vector<IntegerVariable> vars_;
114 std::vector<IntegerValue> coeffs_;
115 std::vector<IntegerValue> max_variations_;
117 std::vector<Literal> literal_reason_;
120 std::vector<IntegerLiteral> integer_reason_;
121 std::vector<IntegerValue> reason_coeffs_;
135 const std::vector<IntegerVariable>& vars,
136 const std::vector<IntegerValue>& coeffs,
Model*
model);
141 const IntegerVariable target_;
142 const std::vector<IntegerVariable> vars_;
143 const std::vector<IntegerValue> coeffs_;
145 IntegerValue gcd_ = IntegerValue(1);
184 const std::vector<IntegerVariable> vars_;
185 const IntegerVariable min_var_;
188 std::vector<IntegerLiteral> integer_reason_;
210 bool PropagateLinearUpperBound(const std::vector<IntegerVariable>& vars,
211 const std::vector<IntegerValue>& coeffs,
215 const IntegerVariable min_var_;
216 std::vector<IntegerValue> expr_lbs_;
219 std::vector<IntegerValue> max_variations_;
220 std::vector<IntegerValue> reason_coeffs_;
223 int rev_unique_candidate_ = 0;
240 bool CanonicalizeCases();
244 bool PropagateWhenAllNonNegative();
248 IntegerValue min_p, IntegerValue max_p);
276 bool PropagateSigns();
311 const IntegerValue b_;
330 bool PropagateSignsAndTargetRange();
333 bool PropagateOuterBounds();
336 const IntegerValue mod_;
368 template <
typename VectorInt>
370 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
373 CHECK_GE(vars.size(), 1);
374 if (vars.size() == 1) {
389 const SatParameters& params = *
model->GetOrCreate<SatParameters>();
390 if (!params.new_linear_propagation()) {
409 if (params.new_linear_propagation()) {
420 model->TakeOwnership(constraint);
426 template <
typename VectorInt>
428 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
432 for (int64_t& ref : negated_coeffs) ref = -ref;
437 template <
typename VectorInt>
439 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
448 template <
typename VectorInt>
450 const std::vector<Literal>& enforcement_literals,
451 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
454 CHECK_GE(vars.size(), 1);
455 if (vars.size() == 1) {
459 enforcement_literals,
465 enforcement_literals,
473 const SatParameters& params = *
model->GetOrCreate<SatParameters>();
474 if (!params.new_linear_propagation()) {
480 enforcement_literals)(
model);
489 enforcement_literals)(
model);
494 IntegerValue expression_min(0);
496 for (
int i = 0; i < vars.size(); ++i) {
499 ? integer_trail->LowerBound(vars[i])
500 : integer_trail->UpperBound(vars[i]));
506 IntegerValue non_cached_min;
507 for (
int i = 0; i < vars.size(); ++i) {
509 const IntegerValue lb = integer_trail->LowerBound(vars[i]);
514 const IntegerValue ub = integer_trail->UpperBound(vars[i]);
520 if (non_cached_min > expression_min) {
521 std::vector<Literal> clause;
522 for (
const Literal l : enforcement_literals) {
523 clause.push_back(l.Negated());
528 if (params.new_linear_propagation()) {
530 enforcement_literals, vars,
535 enforcement_literals, vars,
539 model->TakeOwnership(constraint);
546 template <
typename VectorInt>
548 const std::vector<Literal>& enforcement_literals,
549 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
553 for (int64_t& ref : negated_coeffs) ref = -ref;
559 template <
typename VectorInt>
561 Literal is_le,
const std::vector<IntegerVariable>& vars,
572 template <
typename VectorInt>
574 Literal is_ge,
const std::vector<IntegerVariable>& vars,
586 if (cst.
vars.empty()) {
587 if (cst.
lb <= 0 && cst.
ub >= 0)
return;
593 std::vector<int64_t> converted_coeffs;
595 for (
const IntegerValue v : cst.
coeffs) converted_coeffs.push_back(v.value());
607 const absl::Span<const Literal> enforcement_literals,
609 if (enforcement_literals.empty()) {
612 if (cst.
vars.empty()) {
613 if (cst.
lb <= 0 && cst.
ub >= 0)
return;
616 std::vector<Literal> clause;
617 for (
const Literal lit : enforcement_literals) {
618 clause.push_back(lit.Negated());
624 std::vector<Literal> converted_literals(enforcement_literals.begin(),
625 enforcement_literals.end());
626 std::vector<int64_t> converted_coeffs;
627 for (
const IntegerValue v : cst.
coeffs) converted_coeffs.push_back(v.value());
631 converted_literals, cst.
vars, converted_coeffs, cst.
ub.value()));
635 converted_literals, cst.
vars, converted_coeffs, cst.
lb.value()));
650 template <
typename VectorInt>
652 Literal is_eq,
const std::vector<IntegerVariable>& vars,
667 template <
typename VectorInt>
669 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
689 template <
typename VectorInt>
691 const VectorInt&
coefficients,
const std::vector<IntegerVariable>& vars) {
693 std::vector<IntegerVariable> new_vars = vars;
700 for (
int i = 0; i < new_vars.size(); ++i) {
711 new_vars.push_back(sum);
713 new_coeffs.push_back(-1);
722 IntegerVariable min_var,
const std::vector<IntegerVariable>& vars) {
724 for (
const IntegerVariable&
var : vars) {
731 model->TakeOwnership(constraint);
740 const std::vector<LinearExpression>& exprs) {
744 IntegerVariable min_var;
745 if (min_expr.
vars.size() == 1 &&
746 std::abs(min_expr.
coeffs[0].value()) == 1 && min_expr.
offset == 0) {
747 if (min_expr.
coeffs[0].value() == 1) {
748 min_var = min_expr.
vars[0];
754 IntegerValue min_lb = min_expr.
Min(*integer_trail);
755 IntegerValue min_ub = min_expr.
Max(*integer_trail);
759 std::vector<IntegerVariable> min_sum_vars = min_expr.
vars;
760 std::vector<int64_t> min_sum_coeffs;
761 for (IntegerValue coeff : min_expr.
coeffs) {
762 min_sum_coeffs.push_back(coeff.value());
764 min_sum_vars.push_back(min_var);
765 min_sum_coeffs.push_back(-1);
768 -min_expr.
offset.value()));
772 std::vector<IntegerVariable> vars = expr.vars;
773 std::vector<int64_t> coeffs;
774 for (IntegerValue coeff : expr.coeffs) {
775 coeffs.push_back(coeff.value());
777 vars.push_back(min_var);
778 coeffs.push_back(-1);
784 model->TakeOwnership(constraint);
791 IntegerVariable max_var,
const std::vector<IntegerVariable>& vars) {
793 std::vector<IntegerVariable> negated_vars;
794 for (
const IntegerVariable&
var : vars) {
802 model->TakeOwnership(constraint);
808 std::function<void(Model*)>
IsOneOf(IntegerVariable
var,
809 const std::vector<Literal>& selectors,
810 const std::vector<IntegerValue>& values);
855 model->TakeOwnership(constraint);
869 model->TakeOwnership(constraint);
882 model->TakeOwnership(constraint);
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
void RegisterWith(GenericLiteralWatcher *watcher)
bool PropagateAtLevelZero()
std::pair< IntegerValue, IntegerValue > ConditionalLb(IntegerLiteral integer_literal, IntegerVariable target_var) const
IntegerSumLE(const std::vector< Literal > &enforcement_literals, const std::vector< IntegerVariable > &vars, const std::vector< IntegerValue > &coeffs, IntegerValue upper_bound, Model *model)
IntegerValue UpperBound(IntegerVariable i) const
IntegerVariable AddIntegerVariable(IntegerValue lower_bound, IntegerValue upper_bound)
IntegerValue LowerBound(IntegerVariable i) const
LevelZeroEquality(IntegerVariable target, const std::vector< IntegerVariable > &vars, const std::vector< IntegerValue > &coeffs, Model *model)
LinMinPropagator & operator=(const LinMinPropagator &)=delete
LinMinPropagator(const std::vector< LinearExpression > &exprs, IntegerVariable min_var, Model *model)
LinMinPropagator(const LinMinPropagator &)=delete
void RegisterWith(GenericLiteralWatcher *watcher)
void AddTerm(IntegerVariable var, IntegerValue coeff)
void RegisterWith(GenericLiteralWatcher *watcher)
MinPropagator(const std::vector< IntegerVariable > &vars, IntegerVariable min_var, IntegerTrail *integer_trail)
Class that owns everything related to a particular optimization model.
absl::Span< const double > coefficients
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
IntegerValue FloorRatio(IntegerValue dividend, IntegerValue positive_divisor)
std::function< void(Model *)> GreaterOrEqual(IntegerVariable v, int64_t lb)
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
std::function< void(Model *)> IsEqualToMaxOf(IntegerVariable max_var, const std::vector< IntegerVariable > &vars)
std::function< void(Model *)> ClauseConstraint(absl::Span< const Literal > literals)
std::function< void(Model *)> ConditionalWeightedSumLowerOrEqual(const std::vector< Literal > &enforcement_literals, const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t upper_bound)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
std::function< void(Model *)> FixedWeightedSumReif(Literal is_eq, const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t value)
std::function< BooleanVariable(Model *)> NewBooleanVariable()
std::function< void(Model *)> IsOneOf(IntegerVariable var, const std::vector< Literal > &selectors, const std::vector< IntegerValue > &values)
void LoadConditionalLinearConstraint(const absl::Span< const Literal > enforcement_literals, const LinearConstraint &cst, Model *model)
std::function< void(Model *)> ConditionalSum2LowerOrEqual(IntegerVariable a, IntegerVariable b, int64_t ub, const std::vector< Literal > &enforcement_literals)
std::function< void(Model *)> WeightedSumNotEqual(const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t value)
std::function< void(Model *)> ConditionalWeightedSumGreaterOrEqual(const std::vector< Literal > &enforcement_literals, const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t lower_bound)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
void AddConditionalAffinePrecedence(const std::vector< Literal > &enforcement_literals, AffineExpression left, AffineExpression right, Model *model)
std::function< void(Model *)> Sum2LowerOrEqual(IntegerVariable a, IntegerVariable b, int64_t ub)
std::function< void(Model *)> ProductConstraint(AffineExpression a, AffineExpression b, AffineExpression p)
void RegisterAndTransferOwnership(Model *model, T *ct)
std::function< IntegerVariable(Model *)> NewWeightedSum(const VectorInt &coefficients, const std::vector< IntegerVariable > &vars)
void LoadLinearConstraint(const ConstraintProto &ct, Model *m)
std::function< void(Model *)> Implication(const std::vector< Literal > &enforcement_literals, IntegerLiteral i)
std::function< void(Model *)> Sum3LowerOrEqual(IntegerVariable a, IntegerVariable b, IntegerVariable c, int64_t ub)
std::function< void(Model *)> WeightedSumLowerOrEqual(const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t upper_bound)
std::function< void(Model *)> FixedWeightedSum(const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t value)
std::function< void(Model *)> LowerOrEqual(IntegerVariable v, int64_t ub)
std::function< IntegerVariable(Model *)> NewIntegerVariable(int64_t lb, int64_t ub)
std::function< void(Model *)> DivisionConstraint(AffineExpression num, AffineExpression denom, AffineExpression div)
std::function< void(Model *)> FixedDivisionConstraint(AffineExpression a, IntegerValue b, AffineExpression c)
std::function< void(Model *)> ReifiedBoolAnd(const std::vector< Literal > &literals, Literal r)
std::function< void(Model *)> WeightedSumLowerOrEqualReif(Literal is_le, const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t upper_bound)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
std::function< void(Model *)> IsEqualToMinOf(IntegerVariable min_var, const std::vector< IntegerVariable > &vars)
std::function< void(Model *)> FixedModuloConstraint(AffineExpression a, IntegerValue b, AffineExpression c)
std::function< void(Model *)> WeightedSumGreaterOrEqualReif(Literal is_ge, const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t lower_bound)
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
std::function< void(Model *)> WeightedSumGreaterOrEqual(const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t lower_bound)
std::function< void(Model *)> ConditionalSum3LowerOrEqual(IntegerVariable a, IntegerVariable b, IntegerVariable c, int64_t ub, const std::vector< Literal > &enforcement_literals)
Collection of objects used to extend the Constraint Solver library.
AffineExpression Negated() const
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
std::vector< IntegerValue > coeffs
std::vector< IntegerVariable > vars
std::vector< IntegerValue > coeffs
IntegerValue Max(const IntegerTrail &integer_trail) const
std::vector< IntegerVariable > vars
IntegerValue Min(const IntegerTrail &integer_trail) const