14 #ifndef OR_TOOLS_SAT_INTEGER_EXPR_H_
15 #define OR_TOOLS_SAT_INTEGER_EXPR_H_
55 IntegerSumLE(
const std::vector<Literal>& enforcement_literals,
56 const std::vector<IntegerVariable>& vars,
57 const std::vector<IntegerValue>& coeffs,
72 void FillIntegerReason();
74 const std::vector<Literal> enforcement_literals_;
75 const IntegerValue upper_bound_;
83 bool is_registered_ =
false;
84 IntegerValue rev_lb_fixed_vars_;
87 int rev_num_fixed_vars_;
92 std::vector<IntegerVariable> vars_;
93 std::vector<IntegerValue> coeffs_;
94 std::vector<IntegerValue> max_variations_;
96 std::vector<Literal> literal_reason_;
99 std::vector<IntegerLiteral> integer_reason_;
100 std::vector<IntegerValue> reason_coeffs_;
138 const std::vector<IntegerVariable> vars_;
139 const IntegerVariable min_var_;
142 std::vector<IntegerLiteral> integer_reason_;
164 bool PropagateLinearUpperBound(const std::vector<IntegerVariable>& vars,
165 const std::vector<IntegerValue>& coeffs,
166 IntegerValue upper_bound);
169 const IntegerVariable min_var_;
170 std::vector<IntegerValue> expr_lbs_;
174 int rev_unique_candidate_ = 0;
191 const IntegerVariable a_;
192 const IntegerVariable b_;
193 const IntegerVariable p_;
215 const IntegerVariable a_;
216 const IntegerVariable b_;
217 const IntegerVariable c_;
234 const IntegerVariable a_;
235 const IntegerValue b_;
236 const IntegerVariable c_;
253 const IntegerVariable x_;
254 const IntegerVariable s_;
265 template <
typename VectorInt>
267 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
270 CHECK_GE(vars.size(), 1);
271 if (vars.size() == 1) {
311 const int num_vars = vars.size();
312 if (num_vars > 100) {
313 std::vector<IntegerVariable> bucket_sum_vars;
315 std::vector<IntegerVariable> local_vars;
316 std::vector<IntegerValue> local_coeffs;
319 const int num_buckets =
static_cast<int>(std::round(std::sqrt(num_vars)));
320 for (
int b = 0;
b < num_buckets; ++
b) {
322 local_coeffs.clear();
325 const int limit = num_vars * (
b + 1);
326 for (; i * num_buckets < limit; ++i) {
327 local_vars.push_back(vars[i]);
331 bucket_lb +=
std::min(term1, term2);
332 bucket_ub +=
std::max(term1, term2);
335 const IntegerVariable bucket_sum =
337 bucket_sum_vars.push_back(bucket_sum);
338 local_vars.push_back(bucket_sum);
339 local_coeffs.push_back(IntegerValue(-1));
341 {}, local_vars, local_coeffs, IntegerValue(0),
model);
343 model->TakeOwnership(constraint);
348 local_coeffs.clear();
349 for (
const IntegerVariable
var : bucket_sum_vars) {
350 local_vars.push_back(
var);
351 local_coeffs.push_back(IntegerValue(1));
354 {}, local_vars, local_coeffs, IntegerValue(upper_bound),
model);
356 model->TakeOwnership(constraint);
363 IntegerValue(upper_bound),
model);
365 model->TakeOwnership(constraint);
370 template <
typename VectorInt>
372 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
376 for (
int64& ref : negated_coeffs) ref = -ref;
381 template <
typename VectorInt>
383 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
392 template <
typename VectorInt>
394 const std::vector<Literal>& enforcement_literals,
395 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
398 CHECK_GE(vars.size(), 1);
399 if (vars.size() == 1) {
403 enforcement_literals,
405 vars[0],
FloorRatio(IntegerValue(upper_bound),
409 enforcement_literals,
411 vars[0],
CeilRatio(IntegerValue(-upper_bound),
421 enforcement_literals);
430 enforcement_literals);
435 IntegerValue expression_min(0);
437 for (
int i = 0; i < vars.size(); ++i) {
440 ? integer_trail->LowerBound(vars[i])
441 : integer_trail->UpperBound(vars[i]));
443 if (expression_min == upper_bound) {
444 for (
int i = 0; i < vars.size(); ++i) {
449 vars[i], integer_trail->LowerBound(vars[i]))));
454 vars[i], integer_trail->UpperBound(vars[i]))));
459 enforcement_literals, vars,
461 IntegerValue(upper_bound),
model);
463 model->TakeOwnership(constraint);
469 template <
typename VectorInt>
471 const std::vector<Literal>& enforcement_literals,
472 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
476 for (
int64& ref : negated_coeffs) ref = -ref;
478 negated_coeffs, -lower_bound);
482 template <
typename VectorInt>
484 Literal is_le,
const std::vector<IntegerVariable>& vars,
495 template <
typename VectorInt>
497 Literal is_ge,
const std::vector<IntegerVariable>& vars,
509 if (cst.
vars.empty()) {
510 if (cst.
lb <= 0 && cst.
ub >= 0)
return;
516 std::vector<int64> converted_coeffs;
517 for (
const IntegerValue v : cst.
coeffs) converted_coeffs.push_back(v.value());
529 const absl::Span<const Literal> enforcement_literals,
531 if (enforcement_literals.empty()) {
534 if (cst.
vars.empty()) {
535 if (cst.
lb <= 0 && cst.
ub >= 0)
return;
540 std::vector<Literal> converted_literals(enforcement_literals.begin(),
541 enforcement_literals.end());
542 std::vector<int64> converted_coeffs;
543 for (
const IntegerValue v : cst.
coeffs) converted_coeffs.push_back(v.value());
547 converted_literals, cst.
vars, converted_coeffs, cst.
ub.value()));
551 converted_literals, cst.
vars, converted_coeffs, cst.
lb.value()));
557 template <
typename VectorInt>
559 Literal is_eq,
const std::vector<IntegerVariable>& vars,
574 template <
typename VectorInt>
576 const std::vector<IntegerVariable>& vars,
const VectorInt&
coefficients,
596 template <
typename VectorInt>
598 const VectorInt&
coefficients,
const std::vector<IntegerVariable>& vars) {
600 std::vector<IntegerVariable> new_vars = vars;
607 for (
int i = 0; i < new_vars.size(); ++i) {
618 new_vars.push_back(sum);
620 new_coeffs.push_back(-1);
629 IntegerVariable min_var,
const std::vector<IntegerVariable>& vars) {
631 for (
const IntegerVariable&
var : vars) {
638 model->TakeOwnership(constraint);
647 const std::vector<LinearExpression>& exprs) {
651 IntegerVariable min_var;
652 if (min_expr.
vars.size() == 1 &&
653 std::abs(min_expr.
coeffs[0].value()) == 1) {
654 if (min_expr.
coeffs[0].value() == 1) {
655 min_var = min_expr.
vars[0];
666 std::vector<IntegerVariable> min_sum_vars = min_expr.
vars;
667 std::vector<int64> min_sum_coeffs;
668 for (IntegerValue coeff : min_expr.
coeffs) {
669 min_sum_coeffs.push_back(coeff.value());
671 min_sum_vars.push_back(min_var);
672 min_sum_coeffs.push_back(-1);
675 -min_expr.
offset.value()));
679 std::vector<IntegerVariable> vars = expr.vars;
680 std::vector<int64> coeffs;
681 for (IntegerValue coeff : expr.coeffs) {
682 coeffs.push_back(coeff.value());
684 vars.push_back(min_var);
685 coeffs.push_back(-1);
691 model->TakeOwnership(constraint);
698 IntegerVariable max_var,
const std::vector<IntegerVariable>& vars) {
700 std::vector<IntegerVariable> negated_vars;
701 for (
const IntegerVariable&
var : vars) {
709 model->TakeOwnership(constraint);
715 const std::vector<IntegerVariable>& vars) {
728 const std::vector<IntegerVariable>& vars) {
741 std::function<void(Model*)>
IsOneOf(IntegerVariable
var,
742 const std::vector<Literal>& selectors,
743 const std::vector<IntegerValue>& values);
764 LOG(FATAL) <<
"Not supported";
786 LOG(FATAL) <<
"Not supported";
800 model->TakeOwnership(constraint);
815 model->TakeOwnership(constraint);
822 #endif // OR_TOOLS_SAT_INTEGER_EXPR_H_