OR-Tools  9.2
cp_model.cc
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <cstdint>
17#include <initializer_list>
18#include <limits>
19#include <string>
20
21#include "absl/strings/str_format.h"
27
28namespace operations_research {
29namespace sat {
30
31BoolVar::BoolVar() : builder_(nullptr), index_(0) {}
32
34 : builder_(builder), index_(index) {}
35
36BoolVar BoolVar::WithName(const std::string& name) {
37 DCHECK(builder_ != nullptr);
38 if (builder_ == nullptr) return *this;
39 builder_->MutableProto()
41 ->set_name(name);
42 return *this;
43}
44
45std::string BoolVar::Name() const {
46 if (builder_ == nullptr) return "null";
47 const std::string& name =
48 builder_->Proto().variables(PositiveRef(index_)).name();
49 if (RefIsPositive(index_)) {
50 return name;
51 } else {
52 return absl::StrCat("Not(", name, ")");
53 }
54}
55
56std::string BoolVar::DebugString() const {
57 if (builder_ == nullptr) return "null";
58 if (index_ < 0) {
59 return absl::StrFormat("Not(%s)", Not().DebugString());
60 } else {
61 std::string output;
62 const IntegerVariableProto& var_proto = builder_->Proto().variables(index_);
63 // Special case for constant variables without names.
64 if (var_proto.name().empty() && var_proto.domain_size() == 2 &&
65 var_proto.domain(0) == var_proto.domain(1)) {
66 output.append(var_proto.domain(0) == 0 ? "false" : "true");
67 } else {
68 if (var_proto.name().empty()) {
69 absl::StrAppendFormat(&output, "BoolVar%i(", index_);
70 } else {
71 absl::StrAppendFormat(&output, "%s(", var_proto.name());
72 }
73 if (var_proto.domain(0) == var_proto.domain(1)) {
74 output.append(var_proto.domain(0) == 0 ? "false)" : "true)");
75 } else {
76 absl::StrAppend(&output, var_proto.domain(0), ", ", var_proto.domain(1),
77 ")");
78 }
79 }
80 return output;
81 }
82}
83
84BoolVar Not(BoolVar x) { return x.Not(); }
85
86std::ostream& operator<<(std::ostream& os, const BoolVar& var) {
87 os << var.DebugString();
88 return os;
89}
90
91IntVar::IntVar() : builder_(nullptr), index_(0) {}
92
94 : builder_(builder), index_(index) {
95 DCHECK(RefIsPositive(index_));
96}
97
99 if (var.builder_ == nullptr) {
100 *this = IntVar();
101 return;
102 }
103 builder_ = var.builder_;
104 index_ = builder_->GetOrCreateIntegerIndex(var.index_);
105 DCHECK(RefIsPositive(index_));
106}
107
109 if (builder_ != nullptr) {
110 const IntegerVariableProto& proto = builder_->Proto().variables(index_);
111 DCHECK_EQ(2, proto.domain_size());
112 DCHECK_GE(proto.domain(0), 0);
113 DCHECK_LE(proto.domain(1), 1);
114 }
115 return BoolVar(index_, builder_);
116}
117
118IntVar IntVar::WithName(const std::string& name) {
119 DCHECK(builder_ != nullptr);
120 if (builder_ == nullptr) return *this;
121 builder_->MutableProto()->mutable_variables(index_)->set_name(name);
122 return *this;
123}
124
125std::string IntVar::Name() const {
126 if (builder_ == nullptr) return "null";
127 return builder_->Proto().variables(index_).name();
128}
129
131 if (builder_ == nullptr) return Domain();
132 return ReadDomainFromProto(builder_->Proto().variables(index_));
133}
134
135std::string IntVar::DebugString() const {
136 if (builder_ == nullptr) return "null";
137 return VarDebugString(builder_->Proto(), index_);
138}
139
140// TODO(user): unfortunately, we need this indirection to get a DebugString()
141// in a const way from an index. Because building an IntVar is non-const.
142std::string VarDebugString(const CpModelProto& proto, int index) {
143 std::string output;
144
145 // Special case for constant variables without names.
146 const IntegerVariableProto& var_proto = proto.variables(index);
147 if (var_proto.name().empty() && var_proto.domain_size() == 2 &&
148 var_proto.domain(0) == var_proto.domain(1)) {
149 absl::StrAppend(&output, var_proto.domain(0));
150 } else {
151 if (var_proto.name().empty()) {
152 absl::StrAppend(&output, "V", index, "(");
153 } else {
154 absl::StrAppend(&output, var_proto.name(), "(");
155 }
156
157 // TODO(user): Use domain pretty print function.
158 if (var_proto.domain_size() == 2 &&
159 var_proto.domain(0) == var_proto.domain(1)) {
160 absl::StrAppend(&output, var_proto.domain(0), ")");
161 } else {
162 absl::StrAppend(&output, var_proto.domain(0), ", ", var_proto.domain(1),
163 ")");
164 }
165 }
166
167 return output;
168}
169
170std::ostream& operator<<(std::ostream& os, const IntVar& var) {
171 os << var.DebugString();
172 return os;
173}
174
176 DCHECK(var.builder_ != nullptr);
177 const int index = var.index_;
178 if (RefIsPositive(index)) {
179 variables_.push_back(index);
180 coefficients_.push_back(1);
181 } else {
182 // We add 1 - var instead.
183 variables_.push_back(PositiveRef(index));
184 coefficients_.push_back(-1);
185 constant_ += 1;
186 }
187}
188
190 DCHECK(var.builder_ != nullptr);
191 variables_.push_back(var.index_);
192 coefficients_.push_back(1);
193}
194
195LinearExpr::LinearExpr(int64_t constant) { constant_ = constant; }
196
198 LinearExpr result(expr_proto.offset());
199 for (int i = 0; i < expr_proto.vars_size(); ++i) {
200 result.variables_.push_back(expr_proto.vars(i));
201 result.coefficients_.push_back(expr_proto.coeffs(i));
202 }
203 return result;
204}
205
206LinearExpr LinearExpr::Sum(absl::Span<const IntVar> vars) {
207 LinearExpr result;
208 for (const IntVar& var : vars) {
209 result += var;
210 }
211 return result;
212}
213
214LinearExpr LinearExpr::Sum(absl::Span<const BoolVar> vars) {
215 LinearExpr result;
216 for (const BoolVar& var : vars) {
217 result += var;
218 }
219 return result;
220}
221
222LinearExpr LinearExpr::WeightedSum(absl::Span<const IntVar> vars,
223 absl::Span<const int64_t> coeffs) {
224 CHECK_EQ(vars.size(), coeffs.size());
225 LinearExpr result;
226 for (int i = 0; i < vars.size(); ++i) {
227 result += vars[i] * coeffs[i];
228 }
229 return result;
230}
231
232LinearExpr LinearExpr::WeightedSum(absl::Span<const BoolVar> vars,
233 absl::Span<const int64_t> coeffs) {
234 CHECK_EQ(vars.size(), coeffs.size());
235 LinearExpr result;
236 for (int i = 0; i < vars.size(); ++i) {
237 result += vars[i] * coeffs[i];
238 }
239 return result;
240}
241
243 LinearExpr result;
244 result += var * coefficient;
245 return result;
246}
247
249 LinearExpr result;
250 result += var * coefficient;
251 return result;
252}
253
255 constant_ += other.constant_;
256 variables_.insert(variables_.end(), other.variables_.begin(),
257 other.variables_.end());
258 coefficients_.insert(coefficients_.end(), other.coefficients_.begin(),
259 other.coefficients_.end());
260 return *this;
261}
262
264 constant_ -= other.constant_;
265 variables_.insert(variables_.end(), other.variables_.begin(),
266 other.variables_.end());
267 for (const int64_t coeff : other.coefficients_) {
268 coefficients_.push_back(-coeff);
269 }
270 return *this;
271}
272
274 constant_ *= factor;
275 for (int64_t& coeff : coefficients_) coeff *= factor;
276 return *this;
277}
278
279std::string LinearExpr::DebugString(const CpModelProto* proto) const {
280 std::string result;
281 for (int i = 0; i < variables_.size(); ++i) {
282 const int64_t coeff = coefficients_[i];
283 const std::string var_string = proto == nullptr
284 ? absl::StrCat("V", variables_[i])
285 : VarDebugString(*proto, variables_[i]);
286 if (i == 0) {
287 if (coeff == 1) {
288 absl::StrAppend(&result, var_string);
289 } else if (coeff == -1) {
290 absl::StrAppend(&result, "-", var_string);
291 } else if (coeff != 0) {
292 absl::StrAppend(&result, coeff, " * ", var_string);
293 }
294 } else if (coeff == 1) {
295 absl::StrAppend(&result, " + ", var_string);
296 } else if (coeff > 0) {
297 absl::StrAppend(&result, " + ", coeff, " * ", var_string);
298 } else if (coeff == -1) {
299 absl::StrAppend(&result, " - ", var_string);
300 } else if (coeff < 0) {
301 absl::StrAppend(&result, " - ", -coeff, " * ", var_string);
302 }
303 }
304
305 if (constant_ != 0) {
306 if (variables_.empty()) {
307 return absl::StrCat(constant_);
308 } else if (constant_ > 0) {
309 absl::StrAppend(&result, " + ", constant_);
310 } else {
311 absl::StrAppend(&result, " - ", -constant_);
312 }
313 }
314 return result;
315}
316
317std::ostream& operator<<(std::ostream& os, const LinearExpr& e) {
318 os << e.DebugString();
319 return os;
320}
321
323
325
327
329
330DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const IntVar> vars) {
331 DoubleLinearExpr result;
332 for (const IntVar& var : vars) {
333 result.AddTerm(var, 1.0);
334 }
335 return result;
336}
337
338DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const BoolVar> vars) {
339 DoubleLinearExpr result;
340 for (const BoolVar& var : vars) {
341 result.AddTerm(var, 1.0);
342 }
343 return result;
344}
345
347 absl::Span<const IntVar> vars, absl::Span<const double> coeffs) {
348 CHECK_EQ(vars.size(), coeffs.size());
349 DoubleLinearExpr result;
350 for (int i = 0; i < vars.size(); ++i) {
351 result.AddTerm(vars[i], coeffs[i]);
352 }
353 return result;
354}
355
357 absl::Span<const BoolVar> vars, absl::Span<const double> coeffs) {
358 CHECK_EQ(vars.size(), coeffs.size());
359 DoubleLinearExpr result;
360 for (int i = 0; i < vars.size(); ++i) {
361 result.AddTerm(vars[i], coeffs[i]);
362 }
363 return result;
364}
365
367 constant_ += value;
368 return *this;
369}
370
372 AddTerm(var, 1);
373 return *this;
374}
375
377 AddTerm(var, 1);
378 return *this;
379}
380
382 constant_ += expr.constant_;
383 variables_.insert(variables_.end(), expr.variables_.begin(),
384 expr.variables_.end());
385 coefficients_.insert(coefficients_.end(), expr.coefficients_.begin(),
386 expr.coefficients_.end());
387 return *this;
388}
389
391 variables_.push_back(var.index_);
392 coefficients_.push_back(coeff);
393 return *this;
394}
395
397 const int index = var.index_;
398 if (RefIsPositive(index)) {
399 variables_.push_back(index);
400 coefficients_.push_back(coeff);
401 } else {
402 variables_.push_back(PositiveRef(index));
403 coefficients_.push_back(-coeff);
404 constant_ += coeff;
405 }
406 return *this;
407}
408
410 constant_ -= value;
411 return *this;
412}
413
415 AddTerm(var, -1.0);
416 return *this;
417}
418
420 constant_ -= expr.constant_;
421 variables_.insert(variables_.end(), expr.variables_.begin(),
422 expr.variables_.end());
423 for (const double coeff : expr.coefficients()) {
424 coefficients_.push_back(-coeff);
425 }
426 return *this;
427}
428
430 constant_ *= coeff;
431 for (double& c : coefficients_) {
432 c *= coeff;
433 }
434 return *this;
435}
436
438 std::string result;
439 for (int i = 0; i < variables_.size(); ++i) {
440 const double coeff = coefficients_[i];
441 const std::string var_string = proto == nullptr
442 ? absl::StrCat("V", variables_[i])
443 : VarDebugString(*proto, variables_[i]);
444 if (i == 0) {
445 if (coeff == 1.0) {
446 absl::StrAppend(&result, var_string);
447 } else if (coeff == -1.0) {
448 absl::StrAppend(&result, "-", var_string);
449 } else if (coeff != 0.0) {
450 absl::StrAppend(&result, coeff, " * ", var_string);
451 }
452 } else if (coeff == 1.0) {
453 absl::StrAppend(&result, " + ", var_string);
454 } else if (coeff > 0.0) {
455 absl::StrAppend(&result, " + ", coeff, " * ", var_string);
456 } else if (coeff == -1.0) {
457 absl::StrAppend(&result, " - ", var_string);
458 } else if (coeff < 0.0) {
459 absl::StrAppend(&result, " - ", -coeff, " * ", var_string);
460 }
461 }
462
463 if (constant_ != 0.0) {
464 if (variables_.empty()) {
465 return absl::StrCat(constant_);
466 } else if (constant_ > 0.0) {
467 absl::StrAppend(&result, " + ", constant_);
468 } else {
469 absl::StrAppend(&result, " - ", -constant_);
470 }
471 }
472 return result;
473}
474
475std::ostream& operator<<(std::ostream& os, const DoubleLinearExpr& e) {
476 os << e.DebugString();
477 return os;
478}
479
481
484 return *this;
485}
486
487const std::string& Constraint::Name() const { return proto_->name(); }
488
489Constraint Constraint::OnlyEnforceIf(absl::Span<const BoolVar> literals) {
490 for (const BoolVar& var : literals) {
492 }
493 return *this;
494}
495
498 return *this;
499}
500
505}
506
511}
512
513void TableConstraint::AddTuple(absl::Span<const int64_t> tuple) {
514 CHECK_EQ(tuple.size(), proto_->table().vars_size());
515 for (const int64_t t : tuple) {
517 }
518}
519
520ReservoirConstraint::ReservoirConstraint(ConstraintProto* proto,
521 CpModelBuilder* builder)
522 : Constraint(proto), builder_(builder) {}
523
524void ReservoirConstraint::AddEvent(LinearExpr time, int64_t level_change) {
526 builder_->LinearExprToProto(time);
529 builder_->IndexFromConstant(1));
530}
531
533 int64_t level_change,
534 BoolVar is_active) {
536 builder_->LinearExprToProto(time);
538 proto_->mutable_reservoir()->add_active_literals(is_active.index_);
539}
540
542 int64_t transition_label) {
545 proto_->mutable_automaton()->add_transition_label(transition_label);
546}
547
549 IntervalVar y_coordinate) {
550 proto_->mutable_no_overlap_2d()->add_x_intervals(x_coordinate.index_);
551 proto_->mutable_no_overlap_2d()->add_y_intervals(y_coordinate.index_);
552}
553
554CumulativeConstraint::CumulativeConstraint(ConstraintProto* proto,
555 CpModelBuilder* builder)
556 : Constraint(proto), builder_(builder) {}
557
561 builder_->LinearExprToProto(demand);
562}
563
564IntervalVar::IntervalVar() : builder_(nullptr), index_() {}
565
567 : builder_(builder), index_(index) {}
568
570 DCHECK(builder_ != nullptr);
571 if (builder_ == nullptr) return *this;
572 builder_->MutableProto()->mutable_constraints(index_)->set_name(name);
573 return *this;
574}
575
577 DCHECK(builder_ != nullptr);
578 if (builder_ == nullptr) return LinearExpr();
580 builder_->Proto().constraints(index_).interval().start());
581}
582
584 DCHECK(builder_ != nullptr);
585 if (builder_ == nullptr) return LinearExpr();
587 builder_->Proto().constraints(index_).interval().size());
588}
589
591 DCHECK(builder_ != nullptr);
592 if (builder_ == nullptr) return LinearExpr();
594 builder_->Proto().constraints(index_).interval().end());
595}
596
598 DCHECK(builder_ != nullptr);
599 if (builder_ == nullptr) return BoolVar();
600 return BoolVar(builder_->Proto().constraints(index_).enforcement_literal(0),
601 builder_);
602}
603
604std::string IntervalVar::Name() const {
605 if (builder_ == nullptr) return "null";
606 return builder_->Proto().constraints(index_).name();
607}
608
609std::string IntervalVar::DebugString() const {
610 if (builder_ == nullptr) return "null";
611
612 CHECK_GE(index_, 0);
613 const CpModelProto& proto = builder_->Proto();
614 const ConstraintProto& ct_proto = proto.constraints(index_);
615 std::string output;
616 if (ct_proto.name().empty()) {
617 absl::StrAppend(&output, "IntervalVar", index_, "(");
618 } else {
619 absl::StrAppend(&output, ct_proto.name(), "(");
620 }
621 absl::StrAppend(&output, StartExpr().DebugString(&proto), ", ",
622 SizeExpr().DebugString(&proto), ", ",
623 EndExpr().DebugString(&proto), ", ",
625 return output;
626}
627
628std::ostream& operator<<(std::ostream& os, const IntervalVar& var) {
629 os << var.DebugString();
630 return os;
631}
632
633void CpModelBuilder::SetName(const std::string& name) {
634 cp_model_.set_name(name);
635}
636
637int CpModelBuilder::IndexFromConstant(int64_t value) {
638 if (!constant_to_index_map_.contains(value)) {
639 const int index = cp_model_.variables_size();
640 IntegerVariableProto* const var_proto = cp_model_.add_variables();
641 var_proto->add_domain(value);
642 var_proto->add_domain(value);
643 constant_to_index_map_[value] = index;
644 }
645 return constant_to_index_map_[value];
646}
647
648int CpModelBuilder::GetOrCreateIntegerIndex(int index) {
649 if (index >= 0) {
650 return index;
651 }
652 if (!bool_to_integer_index_map_.contains(index)) {
653 const int var = PositiveRef(index);
654 const IntegerVariableProto& old_var = cp_model_.variables(var);
655 const int new_index = cp_model_.variables_size();
656 IntegerVariableProto* const new_var = cp_model_.add_variables();
657 new_var->add_domain(0);
658 new_var->add_domain(1);
659 if (!old_var.name().empty()) {
660 new_var->set_name(absl::StrCat("Not(", old_var.name(), ")"));
661 }
662 AddEquality(IntVar(new_index, this), BoolVar(index, this));
663 bool_to_integer_index_map_[index] = new_index;
664 return new_index;
665 }
666 return bool_to_integer_index_map_[index];
667}
668
670 const int index = cp_model_.variables_size();
671 IntegerVariableProto* const var_proto = cp_model_.add_variables();
672 for (const auto& interval : domain) {
673 var_proto->add_domain(interval.start);
674 var_proto->add_domain(interval.end);
675 }
676 return IntVar(index, this);
677}
678
680 const int index = cp_model_.variables_size();
681 IntegerVariableProto* const var_proto = cp_model_.add_variables();
682 var_proto->add_domain(0);
683 var_proto->add_domain(1);
684 return BoolVar(index, this);
685}
686
688 return IntVar(IndexFromConstant(value), this);
689}
690
692 return BoolVar(IndexFromConstant(1), this);
693}
694
696 return BoolVar(IndexFromConstant(0), this);
697}
698
700 const LinearExpr& size,
701 const LinearExpr& end) {
702 return NewOptionalIntervalVar(start, size, end, TrueVar());
703}
704
706 int64_t size) {
708}
709
711 const LinearExpr& size,
712 const LinearExpr& end,
713 BoolVar presence) {
714 AddEquality(LinearExpr(start) + size, end).OnlyEnforceIf(presence);
715
716 const int index = cp_model_.constraints_size();
717 ConstraintProto* const ct = cp_model_.add_constraints();
718 ct->add_enforcement_literal(presence.index_);
719 IntervalConstraintProto* const interval = ct->mutable_interval();
720 *interval->mutable_start() = LinearExprToProto(start);
721 *interval->mutable_size() = LinearExprToProto(size);
722 *interval->mutable_end() = LinearExprToProto(end);
723 return IntervalVar(index, this);
724}
725
727 const LinearExpr& start, int64_t size, BoolVar presence) {
728 const int index = cp_model_.constraints_size();
729 ConstraintProto* const ct = cp_model_.add_constraints();
730 ct->add_enforcement_literal(presence.index_);
731 IntervalConstraintProto* const interval = ct->mutable_interval();
732 *interval->mutable_start() = LinearExprToProto(start);
733 interval->mutable_size()->set_offset(size);
734 *interval->mutable_end() = LinearExprToProto(start);
735 interval->mutable_end()->set_offset(interval->end().offset() + size);
736 return IntervalVar(index, this);
737}
738
739Constraint CpModelBuilder::AddBoolOr(absl::Span<const BoolVar> literals) {
740 ConstraintProto* const proto = cp_model_.add_constraints();
741 for (const BoolVar& lit : literals) {
742 proto->mutable_bool_or()->add_literals(lit.index_);
743 }
744 return Constraint(proto);
745}
746
747Constraint CpModelBuilder::AddAtLeastOne(absl::Span<const BoolVar> literals) {
748 return AddBoolOr(literals);
749}
750
751Constraint CpModelBuilder::AddAtMostOne(absl::Span<const BoolVar> literals) {
752 ConstraintProto* const proto = cp_model_.add_constraints();
753 for (const BoolVar& lit : literals) {
754 proto->mutable_at_most_one()->add_literals(lit.index_);
755 }
756 return Constraint(proto);
757}
758
759Constraint CpModelBuilder::AddExactlyOne(absl::Span<const BoolVar> literals) {
760 ConstraintProto* const proto = cp_model_.add_constraints();
761 for (const BoolVar& lit : literals) {
762 proto->mutable_exactly_one()->add_literals(lit.index_);
763 }
764 return Constraint(proto);
765}
766
767Constraint CpModelBuilder::AddBoolAnd(absl::Span<const BoolVar> literals) {
768 ConstraintProto* const proto = cp_model_.add_constraints();
769 for (const BoolVar& lit : literals) {
770 proto->mutable_bool_and()->add_literals(lit.index_);
771 }
772 return Constraint(proto);
773}
774
775Constraint CpModelBuilder::AddBoolXor(absl::Span<const BoolVar> literals) {
776 ConstraintProto* const proto = cp_model_.add_constraints();
777 for (const BoolVar& lit : literals) {
778 proto->mutable_bool_xor()->add_literals(lit.index_);
779 }
780 return Constraint(proto);
781}
782
783void CpModelBuilder::FillLinearTerms(const LinearExpr& left,
784 const LinearExpr& right,
786 for (const int x : left.variables()) {
787 proto->add_vars(x);
788 }
789 for (const int64_t coeff : left.coefficients()) {
790 proto->add_coeffs(coeff);
791 }
792 for (const int x : right.variables()) {
793 proto->add_vars(x);
794 }
795 for (const int64_t coeff : right.coefficients()) {
796 proto->add_coeffs(-coeff);
797 }
798}
799
801 const LinearExpr& right) {
802 ConstraintProto* const proto = cp_model_.add_constraints();
803 FillLinearTerms(left, right, proto->mutable_linear());
804 const int64_t rhs = right.constant() - left.constant();
805 proto->mutable_linear()->add_domain(rhs);
806 proto->mutable_linear()->add_domain(rhs);
807 return Constraint(proto);
808}
809
811 const LinearExpr& right) {
812 ConstraintProto* const proto = cp_model_.add_constraints();
813 FillLinearTerms(left, right, proto->mutable_linear());
814 const int64_t rhs = right.constant() - left.constant();
815 proto->mutable_linear()->add_domain(rhs);
816 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
817 return Constraint(proto);
818}
819
821 const LinearExpr& right) {
822 ConstraintProto* const proto = cp_model_.add_constraints();
823 FillLinearTerms(left, right, proto->mutable_linear());
824 const int64_t rhs = right.constant() - left.constant();
825 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
826 proto->mutable_linear()->add_domain(rhs);
827 return Constraint(proto);
828}
829
831 const LinearExpr& right) {
832 ConstraintProto* const proto = cp_model_.add_constraints();
833 FillLinearTerms(left, right, proto->mutable_linear());
834 const int64_t rhs = right.constant() - left.constant();
835 proto->mutable_linear()->add_domain(rhs + 1);
836 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
837 return Constraint(proto);
838}
839
841 const LinearExpr& right) {
842 ConstraintProto* const proto = cp_model_.add_constraints();
843 FillLinearTerms(left, right, proto->mutable_linear());
844 const int64_t rhs = right.constant() - left.constant();
845 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
846 proto->mutable_linear()->add_domain(rhs - 1);
847 return Constraint(proto);
848}
849
851 const Domain& domain) {
852 ConstraintProto* const proto = cp_model_.add_constraints();
853 for (const int x : expr.variables()) {
854 proto->mutable_linear()->add_vars(x);
855 }
856 for (const int64_t coeff : expr.coefficients()) {
857 proto->mutable_linear()->add_coeffs(coeff);
858 }
859 const int64_t cst = expr.constant();
860 for (const auto& i : domain) {
861 proto->mutable_linear()->add_domain(i.start - cst);
862 proto->mutable_linear()->add_domain(i.end - cst);
863 }
864 return Constraint(proto);
865}
866
868 const LinearExpr& right) {
869 ConstraintProto* const proto = cp_model_.add_constraints();
870 FillLinearTerms(left, right, proto->mutable_linear());
871 const int64_t rhs = right.constant() - left.constant();
872 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::min());
873 proto->mutable_linear()->add_domain(rhs - 1);
874 proto->mutable_linear()->add_domain(rhs + 1);
875 proto->mutable_linear()->add_domain(std::numeric_limits<int64_t>::max());
876 return Constraint(proto);
877}
878
879Constraint CpModelBuilder::AddAllDifferent(absl::Span<const IntVar> vars) {
880 ConstraintProto* const proto = cp_model_.add_constraints();
881 for (const IntVar& var : vars) {
882 auto* expr = proto->mutable_all_diff()->add_exprs();
883 expr->add_vars(var.index_);
884 expr->add_coeffs(1);
885 }
886 return Constraint(proto);
887}
888
889Constraint CpModelBuilder::AddAllDifferent(absl::Span<const LinearExpr> exprs) {
890 ConstraintProto* const proto = cp_model_.add_constraints();
891 for (const LinearExpr& expr : exprs) {
892 *proto->mutable_all_diff()->add_exprs() = LinearExprToProto(expr);
893 }
894 return Constraint(proto);
895}
896
898 std::initializer_list<LinearExpr> exprs) {
899 ConstraintProto* const proto = cp_model_.add_constraints();
900 for (const LinearExpr& expr : exprs) {
901 *proto->mutable_all_diff()->add_exprs() = LinearExprToProto(expr);
902 }
903 return Constraint(proto);
904}
905
907 IntVar index, absl::Span<const IntVar> variables, IntVar target) {
908 ConstraintProto* const proto = cp_model_.add_constraints();
909 proto->mutable_element()->set_index(index.index_);
910 proto->mutable_element()->set_target(target.index_);
911 for (const IntVar& var : variables) {
912 proto->mutable_element()->add_vars(var.index_);
913 }
914 return Constraint(proto);
915}
916
918 absl::Span<const int64_t> values,
919 IntVar target) {
920 ConstraintProto* const proto = cp_model_.add_constraints();
921 proto->mutable_element()->set_index(index.index_);
922 proto->mutable_element()->set_target(target.index_);
923 for (int64_t value : values) {
924 proto->mutable_element()->add_vars(IndexFromConstant(value));
925 }
926 return Constraint(proto);
927}
928
930 return CircuitConstraint(cp_model_.add_constraints());
931}
932
934 return MultipleCircuitConstraint(cp_model_.add_constraints());
935}
936
938 absl::Span<const IntVar> vars) {
939 ConstraintProto* const proto = cp_model_.add_constraints();
940 for (const IntVar& var : vars) {
941 proto->mutable_table()->add_vars(var.index_);
942 }
943 return TableConstraint(proto);
944}
945
947 absl::Span<const IntVar> vars) {
948 ConstraintProto* const proto = cp_model_.add_constraints();
949 for (const IntVar& var : vars) {
950 proto->mutable_table()->add_vars(var.index_);
951 }
952 proto->mutable_table()->set_negated(true);
953 return TableConstraint(proto);
954}
955
957 absl::Span<const IntVar> variables,
958 absl::Span<const IntVar> inverse_variables) {
959 ConstraintProto* const proto = cp_model_.add_constraints();
960 for (const IntVar& var : variables) {
961 proto->mutable_inverse()->add_f_direct(var.index_);
962 }
963 for (const IntVar& var : inverse_variables) {
964 proto->mutable_inverse()->add_f_inverse(var.index_);
965 }
966 return Constraint(proto);
967}
968
970 int64_t max_level) {
971 ConstraintProto* const proto = cp_model_.add_constraints();
972 proto->mutable_reservoir()->set_min_level(min_level);
973 proto->mutable_reservoir()->set_max_level(max_level);
974 return ReservoirConstraint(proto, this);
975}
976
978 absl::Span<const IntVar> transition_variables, int starting_state,
979 absl::Span<const int> final_states) {
980 ConstraintProto* const proto = cp_model_.add_constraints();
981 for (const IntVar& var : transition_variables) {
982 proto->mutable_automaton()->add_vars(var.index_);
983 }
984 proto->mutable_automaton()->set_starting_state(starting_state);
985 for (const int final_state : final_states) {
986 proto->mutable_automaton()->add_final_states(final_state);
987 }
989}
990
991LinearExpressionProto CpModelBuilder::LinearExprToProto(const LinearExpr& expr,
992 bool negate) {
993 LinearExpressionProto expr_proto;
994 for (const int var : expr.variables()) {
995 expr_proto.add_vars(var);
996 }
997 const int64_t mult = negate ? -1 : 1;
998 for (const int64_t coeff : expr.coefficients()) {
999 expr_proto.add_coeffs(coeff * mult);
1000 }
1001 expr_proto.set_offset(expr.constant() * mult);
1002 return expr_proto;
1003}
1004
1006 absl::Span<const IntVar> vars) {
1007 ConstraintProto* ct = cp_model_.add_constraints();
1008 *ct->mutable_lin_max()->mutable_target() =
1009 LinearExprToProto(target, /*negate=*/true);
1010 for (const IntVar& var : vars) {
1011 *ct->mutable_lin_max()->add_exprs() =
1012 LinearExprToProto(var, /*negate=*/true);
1013 }
1014 return Constraint(ct);
1015}
1016
1018 absl::Span<const LinearExpr> exprs) {
1019 ConstraintProto* ct = cp_model_.add_constraints();
1020 *ct->mutable_lin_max()->mutable_target() =
1021 LinearExprToProto(target, /*negate=*/true);
1022 for (const LinearExpr& expr : exprs) {
1023 *ct->mutable_lin_max()->add_exprs() =
1024 LinearExprToProto(expr, /*negate=*/true);
1025 }
1026 return Constraint(ct);
1027}
1028
1030 const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1031 ConstraintProto* ct = cp_model_.add_constraints();
1032 *ct->mutable_lin_max()->mutable_target() =
1033 LinearExprToProto(target, /*negate=*/true);
1034 for (const LinearExpr& expr : exprs) {
1035 *ct->mutable_lin_max()->add_exprs() =
1036 LinearExprToProto(expr, /*negate=*/true);
1037 }
1038 return Constraint(ct);
1039}
1040
1042 absl::Span<const IntVar> vars) {
1043 ConstraintProto* ct = cp_model_.add_constraints();
1044 *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1045 for (const IntVar& var : vars) {
1046 *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(var);
1047 }
1048 return Constraint(ct);
1049}
1050
1052 absl::Span<const LinearExpr> exprs) {
1053 ConstraintProto* ct = cp_model_.add_constraints();
1054 *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1055 for (const LinearExpr& expr : exprs) {
1056 *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1057 }
1058 return Constraint(ct);
1059}
1060
1062 const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1063 ConstraintProto* ct = cp_model_.add_constraints();
1064 *ct->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1065 for (const LinearExpr& expr : exprs) {
1066 *ct->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1067 }
1068 return Constraint(ct);
1069}
1070
1072 const LinearExpr& numerator,
1073 const LinearExpr& denominator) {
1074 ConstraintProto* const proto = cp_model_.add_constraints();
1075 *proto->mutable_int_div()->mutable_target() = LinearExprToProto(target);
1076 *proto->mutable_int_div()->add_exprs() = LinearExprToProto(numerator);
1077 *proto->mutable_int_div()->add_exprs() = LinearExprToProto(denominator);
1078 return Constraint(proto);
1079}
1080
1082 const LinearExpr& expr) {
1083 ConstraintProto* const proto = cp_model_.add_constraints();
1084 *proto->mutable_lin_max()->mutable_target() = LinearExprToProto(target);
1085 *proto->mutable_lin_max()->add_exprs() = LinearExprToProto(expr);
1086 *proto->mutable_lin_max()->add_exprs() =
1087 LinearExprToProto(expr, /*negate=*/true);
1088 return Constraint(proto);
1089}
1090
1092 const LinearExpr& var,
1093 const LinearExpr& mod) {
1094 ConstraintProto* const proto = cp_model_.add_constraints();
1095 *proto->mutable_int_mod()->mutable_target() = LinearExprToProto(target);
1096 *proto->mutable_int_mod()->add_exprs() = LinearExprToProto(var);
1097 *proto->mutable_int_mod()->add_exprs() = LinearExprToProto(mod);
1098 return Constraint(proto);
1099}
1100
1102 const LinearExpr& target, absl::Span<const IntVar> vars) {
1103 ConstraintProto* const proto = cp_model_.add_constraints();
1104 *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1105 for (const IntVar& var : vars) {
1106 *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(var);
1107 }
1108 return Constraint(proto);
1109}
1110
1112 const LinearExpr& target, absl::Span<const LinearExpr> exprs) {
1113 ConstraintProto* const proto = cp_model_.add_constraints();
1114 *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1115 for (const LinearExpr& expr : exprs) {
1116 *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(expr);
1117 }
1118 return Constraint(proto);
1119}
1120
1122 const LinearExpr& target, std::initializer_list<LinearExpr> exprs) {
1123 ConstraintProto* const proto = cp_model_.add_constraints();
1124 *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1125 for (const LinearExpr& expr : exprs) {
1126 *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(expr);
1127 }
1128 return Constraint(proto);
1129}
1131 const LinearExpr& left,
1132 const LinearExpr& right) {
1133 ConstraintProto* const proto = cp_model_.add_constraints();
1134 *proto->mutable_int_prod()->mutable_target() = LinearExprToProto(target);
1135 *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(left);
1136 *proto->mutable_int_prod()->add_exprs() = LinearExprToProto(right);
1137
1138 return Constraint(proto);
1139}
1140
1141Constraint CpModelBuilder::AddNoOverlap(absl::Span<const IntervalVar> vars) {
1142 ConstraintProto* const proto = cp_model_.add_constraints();
1143 for (const IntervalVar& var : vars) {
1144 proto->mutable_no_overlap()->add_intervals(var.index_);
1145 }
1146 return Constraint(proto);
1147}
1148
1150 return NoOverlap2DConstraint(cp_model_.add_constraints());
1151}
1152
1154 ConstraintProto* const proto = cp_model_.add_constraints();
1155 *proto->mutable_cumulative()->mutable_capacity() =
1156 LinearExprToProto(capacity);
1157 return CumulativeConstraint(proto, this);
1158}
1159
1161 cp_model_.clear_objective();
1163 for (const int x : expr.variables()) {
1164 cp_model_.mutable_objective()->add_vars(x);
1165 }
1166 for (const int64_t coeff : expr.coefficients()) {
1167 cp_model_.mutable_objective()->add_coeffs(coeff);
1168 }
1169 cp_model_.mutable_objective()->set_offset(expr.constant());
1170}
1171
1173 cp_model_.clear_objective();
1175 for (const int x : expr.variables()) {
1176 cp_model_.mutable_objective()->add_vars(x);
1177 }
1178 for (const int64_t coeff : expr.coefficients()) {
1179 cp_model_.mutable_objective()->add_coeffs(-coeff);
1180 }
1181 cp_model_.mutable_objective()->set_offset(-expr.constant());
1182 cp_model_.mutable_objective()->set_scaling_factor(-1.0);
1183}
1184
1186 cp_model_.clear_objective();
1188 for (int i = 0; i < expr.variables().size(); ++i) {
1189 cp_model_.mutable_floating_point_objective()->add_vars(expr.variables()[i]);
1191 expr.coefficients()[i]);
1192 }
1195}
1196
1198 cp_model_.clear_objective();
1200 for (int i = 0; i < expr.variables().size(); ++i) {
1201 cp_model_.mutable_floating_point_objective()->add_vars(expr.variables()[i]);
1203 expr.coefficients()[i]);
1204 }
1207}
1208
1210 absl::Span<const IntVar> variables,
1213 DecisionStrategyProto* const proto = cp_model_.add_search_strategy();
1214 for (const IntVar& var : variables) {
1215 proto->add_variables(var.index_);
1216 }
1217 proto->set_variable_selection_strategy(var_strategy);
1218 proto->set_domain_reduction_strategy(domain_strategy);
1219}
1220
1222 absl::Span<const BoolVar> variables,
1225 DecisionStrategyProto* const proto = cp_model_.add_search_strategy();
1226 for (const BoolVar& var : variables) {
1227 proto->add_variables(var.index_);
1228 }
1229 proto->set_variable_selection_strategy(var_strategy);
1230 proto->set_domain_reduction_strategy(domain_strategy);
1231}
1232
1234 cp_model_.mutable_solution_hint()->add_vars(var.index_);
1236}
1237
1239 if (var.index_ >= 0) {
1240 cp_model_.mutable_solution_hint()->add_vars(var.index_);
1242 } else {
1243 cp_model_.mutable_solution_hint()->add_vars(PositiveRef(var.index_));
1244 cp_model_.mutable_solution_hint()->add_values(!value);
1245 }
1246}
1247
1249 cp_model_.mutable_solution_hint()->Clear();
1250}
1251
1253 cp_model_.mutable_assumptions()->Add(lit.index_);
1254}
1255
1256void CpModelBuilder::AddAssumptions(absl::Span<const BoolVar> literals) {
1257 for (const BoolVar& lit : literals) {
1258 cp_model_.mutable_assumptions()->Add(lit.index_);
1259 }
1260}
1261
1263 cp_model_.mutable_assumptions()->Clear();
1264}
1265
1267 cp_model_ = model_proto;
1268 // Rebuild constant to index map.
1269 constant_to_index_map_.clear();
1270 for (int i = 0; i < cp_model_.variables_size(); ++i) {
1271 const IntegerVariableProto& var = cp_model_.variables(i);
1272 if (var.domain_size() == 2 && var.domain(0) == var.domain(1)) {
1273 constant_to_index_map_[var.domain(0)] = i;
1274 }
1275 }
1276 // This one would be more complicated to rebuild. Let's just clear it.
1277 bool_to_integer_index_map_.clear();
1278}
1279
1281 CHECK_GE(index, 0);
1282 CHECK_LT(index, cp_model_.variables_size());
1283 const IntegerVariableProto& proto = cp_model_.variables(index);
1284 CHECK_EQ(2, proto.domain_size())
1285 << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1286 "is not Boolean";
1287 CHECK_GE(0, proto.domain(0))
1288 << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1289 "is not Boolean";
1290 CHECK_LE(1, proto.domain(1))
1291 << "CpModelBuilder::GetBoolVarFromProtoIndex: The domain of the variable "
1292 "is not Boolean";
1293 return BoolVar(index, this);
1294}
1295
1297 CHECK_GE(index, 0);
1298 CHECK_LT(index, cp_model_.variables_size());
1299 return IntVar(index, this);
1300}
1301
1303 CHECK_GE(index, 0);
1304 CHECK_LT(index, cp_model_.constraints_size());
1305 const ConstraintProto& ct = cp_model_.constraints(index);
1306 CHECK_EQ(ct.constraint_case(), ConstraintProto::kInterval)
1307 << "CpModelBuilder::GetIntervalVarFromProtoIndex: the referenced "
1308 "object is not an interval variable";
1309 return IntervalVar(index, this);
1310}
1311
1313 const LinearExpr& expr) {
1314 int64_t result = expr.constant();
1315 const std::vector<int>& variables = expr.variables();
1316 const std::vector<int64_t>& coefficients = expr.coefficients();
1317 for (int i = 0; i < variables.size(); ++i) {
1318 result += r.solution(variables[i]) * coefficients[i];
1319 }
1320 return result;
1321}
1322
1324 const int ref = x.index_;
1325 if (RefIsPositive(ref)) {
1326 return r.solution(ref) == 1;
1327 } else {
1328 return r.solution(PositiveRef(ref)) == 0;
1329 }
1330}
1331
1332} // namespace sat
1333} // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:892
#define CHECK_LT(val1, val2)
Definition: base/logging.h:705
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:702
#define CHECK_GE(val1, val2)
Definition: base/logging.h:706
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:894
#define DCHECK(condition)
Definition: base/logging.h:889
#define CHECK_LE(val1, val2)
Definition: base/logging.h:704
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:890
We call domain any subset of Int64 = [kint64min, kint64max].
Specialized automaton constraint.
Definition: cp_model.h:663
void AddTransition(int tail, int head, int64_t transition_label)
Adds a transitions to the automaton.
Definition: cp_model.cc:541
A Boolean variable.
Definition: cp_model.h:72
std::string Name() const
Returns the name of the variable.
Definition: cp_model.cc:45
BoolVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:36
std::string DebugString() const
Definition: cp_model.cc:56
BoolVar()
A default constructed BoolVar can be used to mean not defined yet.
Definition: cp_model.cc:31
BoolVar Not() const
Returns the logical negation of the current Boolean variable.
Definition: cp_model.h:88
Specialized circuit constraint.
Definition: cp_model.h:567
void AddArc(int tail, int head, BoolVar literal)
Add an arc to the circuit.
Definition: cp_model.cc:501
Constraint OnlyEnforceIf(absl::Span< const BoolVar > literals)
The constraint will be enforced iff all literals listed here are true.
Definition: cp_model.cc:489
Constraint WithName(const std::string &name)
Sets the name of the constraint.
Definition: cp_model.cc:482
const std::string & Name() const
Returns the name of the constraint (or the empty string if not set).
Definition: cp_model.cc:487
Constraint(ConstraintProto *proto)
Definition: cp_model.cc:480
::operations_research::sat::NoOverlap2DConstraintProto * mutable_no_overlap_2d()
::operations_research::sat::TableConstraintProto * mutable_table()
const std::string & name() const
Definition: cp_model.pb.h:9412
const ::operations_research::sat::IntervalConstraintProto & interval() const
::operations_research::sat::RoutesConstraintProto * mutable_routes()
void set_name(ArgT0 &&arg0, ArgT... args)
int32_t enforcement_literal(int index) const
Definition: cp_model.pb.h:9472
::operations_research::sat::AutomatonConstraintProto * mutable_automaton()
const ::operations_research::sat::TableConstraintProto & table() const
::operations_research::sat::CumulativeConstraintProto * mutable_cumulative()
::operations_research::sat::CircuitConstraintProto * mutable_circuit()
::operations_research::sat::ReservoirConstraintProto * mutable_reservoir()
Wrapper class around the cp_model proto.
Definition: cp_model.h:720
Constraint AddAtMostOne(absl::Span< const BoolVar > literals)
At most one literal is true. Sum literals <= 1.
Definition: cp_model.cc:751
void AddHint(IntVar var, int64_t value)
Adds hinting to a variable.
Definition: cp_model.cc:1233
TableConstraint AddForbiddenAssignments(absl::Span< const IntVar > vars)
Adds an forbidden assignments constraint.
Definition: cp_model.cc:946
Constraint AddMinEquality(const LinearExpr &target, absl::Span< const IntVar > vars)
Adds target == min(vars).
Definition: cp_model.cc:1005
Constraint AddLinearConstraint(const LinearExpr &expr, const Domain &domain)
Adds expr in domain.
Definition: cp_model.cc:850
void ClearAssumptions()
Remove all assumptions from the model.
Definition: cp_model.cc:1262
Constraint AddAbsEquality(const LinearExpr &target, const LinearExpr &expr)
Adds target == abs(expr).
Definition: cp_model.cc:1081
void AddAssumptions(absl::Span< const BoolVar > literals)
Adds multiple literals to the model as assumptions.
Definition: cp_model.cc:1256
IntervalVar NewFixedSizeIntervalVar(const LinearExpr &start, int64_t size)
Creates an interval variable with a fixed size.
Definition: cp_model.cc:705
MultipleCircuitConstraint AddMultipleCircuitConstraint()
Adds a multiple circuit constraint, aka the "VRP" (Vehicle Routing Problem) constraint.
Definition: cp_model.cc:933
BoolVar TrueVar()
Creates an always true Boolean variable.
Definition: cp_model.cc:691
IntVar NewIntVar(const Domain &domain)
Creates an integer variable with the given domain.
Definition: cp_model.cc:669
void ClearHints()
Removes all hints.
Definition: cp_model.cc:1248
void Maximize(const LinearExpr &expr)
Adds a linear maximization objective.
Definition: cp_model.cc:1172
BoolVar NewBoolVar()
Creates a Boolean variable.
Definition: cp_model.cc:679
Constraint AddAtLeastOne(absl::Span< const BoolVar > literals)
Same as AddBoolOr. Sum literals >= 1.
Definition: cp_model.cc:747
Constraint AddMaxEquality(const LinearExpr &target, absl::Span< const IntVar > vars)
Adds target == max(vars).
Definition: cp_model.cc:1041
Constraint AddMultiplicationEquality(const LinearExpr &target, absl::Span< const LinearExpr > exprs)
Adds target == prod(exprs).
Definition: cp_model.cc:1111
void AddDecisionStrategy(absl::Span< const IntVar > variables, DecisionStrategyProto::VariableSelectionStrategy var_strategy, DecisionStrategyProto::DomainReductionStrategy domain_strategy)
Adds a decision strategy on a list of integer variables.
Definition: cp_model.cc:1209
IntervalVar NewOptionalIntervalVar(const LinearExpr &start, const LinearExpr &size, const LinearExpr &end, BoolVar presence)
Creates an optional interval variable from 3 affine expressions and a Boolean variable.
Definition: cp_model.cc:710
CircuitConstraint AddCircuitConstraint()
Adds a circuit constraint.
Definition: cp_model.cc:929
Constraint AddVariableElement(IntVar index, absl::Span< const IntVar > variables, IntVar target)
Adds the element constraint: variables[index] == target.
Definition: cp_model.cc:906
Constraint AddGreaterThan(const LinearExpr &left, const LinearExpr &right)
Adds left > right.
Definition: cp_model.cc:830
void CopyFrom(const CpModelProto &model_proto)
Replaces the current model with the one from the given proto.
Definition: cp_model.cc:1266
Constraint AddLessThan(const LinearExpr &left, const LinearExpr &right)
Adds left < right.
Definition: cp_model.cc:840
Constraint AddBoolXor(absl::Span< const BoolVar > literals)
Adds the constraint that an odd number of literals is true.
Definition: cp_model.cc:775
void SetName(const std::string &name)
Sets the name of the model.
Definition: cp_model.cc:633
Constraint AddElement(IntVar index, absl::Span< const int64_t > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: cp_model.cc:917
void AddAssumption(BoolVar lit)
Adds a literal to the model as assumptions.
Definition: cp_model.cc:1252
void Minimize(const LinearExpr &expr)
Adds a linear minimization objective.
Definition: cp_model.cc:1160
BoolVar FalseVar()
Creates an always false Boolean variable.
Definition: cp_model.cc:695
Constraint AddBoolAnd(absl::Span< const BoolVar > literals)
Adds the constraint that all literals must be true.
Definition: cp_model.cc:767
IntervalVar GetIntervalVarFromProtoIndex(int index)
Returns the interval variable from its index in the proto.
Definition: cp_model.cc:1302
CumulativeConstraint AddCumulative(LinearExpr capacity)
The cumulative constraint.
Definition: cp_model.cc:1153
Constraint AddLessOrEqual(const LinearExpr &left, const LinearExpr &right)
Adds left <= right.
Definition: cp_model.cc:820
ReservoirConstraint AddReservoirConstraint(int64_t min_level, int64_t max_level)
Adds a reservoir constraint with optional refill/emptying events.
Definition: cp_model.cc:969
Constraint AddEquality(const LinearExpr &left, const LinearExpr &right)
Adds left == right.
Definition: cp_model.cc:800
NoOverlap2DConstraint AddNoOverlap2D()
The no_overlap_2d constraint prevents a set of boxes from overlapping.
Definition: cp_model.cc:1149
Constraint AddGreaterOrEqual(const LinearExpr &left, const LinearExpr &right)
Adds left >= right.
Definition: cp_model.cc:810
Constraint AddBoolOr(absl::Span< const BoolVar > literals)
Adds the constraint that at least one of the literals must be true.
Definition: cp_model.cc:739
IntVar GetIntVarFromProtoIndex(int index)
Returns the integer variable from its index in the proto.
Definition: cp_model.cc:1296
AutomatonConstraint AddAutomaton(absl::Span< const IntVar > transition_variables, int starting_state, absl::Span< const int > final_states)
An automaton constraint.
Definition: cp_model.cc:977
IntervalVar NewOptionalFixedSizeIntervalVar(const LinearExpr &start, int64_t size, BoolVar presence)
Creates an optional interval variable with a fixed size.
Definition: cp_model.cc:726
Constraint AddDivisionEquality(const LinearExpr &target, const LinearExpr &numerator, const LinearExpr &denominator)
Adds target = num / denom (integer division rounded towards 0).
Definition: cp_model.cc:1071
BoolVar GetBoolVarFromProtoIndex(int index)
Returns the Boolean variable from its index in the proto.
Definition: cp_model.cc:1280
Constraint AddNotEqual(const LinearExpr &left, const LinearExpr &right)
Adds left != right.
Definition: cp_model.cc:867
Constraint AddModuloEquality(const LinearExpr &target, const LinearExpr &var, const LinearExpr &mod)
Adds target = var % mod.
Definition: cp_model.cc:1091
Constraint AddAllDifferent(absl::Span< const IntVar > vars)
This constraint forces all variables to have different values.
Definition: cp_model.cc:879
TableConstraint AddAllowedAssignments(absl::Span< const IntVar > vars)
Adds an allowed assignments constraint.
Definition: cp_model.cc:937
IntVar NewConstant(int64_t value)
Creates a constant variable.
Definition: cp_model.cc:687
IntervalVar NewIntervalVar(const LinearExpr &start, const LinearExpr &size, const LinearExpr &end)
Creates an interval variable from 3 affine expressions.
Definition: cp_model.cc:699
Constraint AddInverseConstraint(absl::Span< const IntVar > variables, absl::Span< const IntVar > inverse_variables)
An inverse constraint.
Definition: cp_model.cc:956
Constraint AddExactlyOne(absl::Span< const BoolVar > literals)
Exactly one literal is true. Sum literals == 1.
Definition: cp_model.cc:759
Constraint AddNoOverlap(absl::Span< const IntervalVar > vars)
Adds a no-overlap constraint that ensures that all present intervals do not overlap in time.
Definition: cp_model.cc:1141
const CpModelProto & Proto() const
Definition: cp_model.h:1061
::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > * mutable_assumptions()
::operations_research::sat::DecisionStrategyProto * add_search_strategy()
::operations_research::sat::FloatObjectiveProto * mutable_floating_point_objective()
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
void set_name(ArgT0 &&arg0, ArgT... args)
::operations_research::sat::PartialVariableAssignment * mutable_solution_hint()
::operations_research::sat::ConstraintProto * mutable_constraints(int index)
::operations_research::sat::IntegerVariableProto * mutable_variables(int index)
::operations_research::sat::ConstraintProto * add_constraints()
::operations_research::sat::IntegerVariableProto * add_variables()
::operations_research::sat::CpObjectiveProto * mutable_objective()
const ::operations_research::sat::ConstraintProto & constraints(int index) const
Specialized cumulative constraint.
Definition: cp_model.h:700
void AddDemand(IntervalVar interval, LinearExpr demand)
Adds a pair (interval, demand) to the constraint.
Definition: cp_model.cc:558
::operations_research::sat::LinearExpressionProto * add_demands()
Definition: cp_model.pb.h:8332
A dedicated container for linear expressions with double coefficients.
Definition: cp_model.h:349
double constant() const
Returns the constant term.
Definition: cp_model.h:413
DoubleLinearExpr & operator+=(double value)
Adds a constant value to the linear expression.
Definition: cp_model.cc:366
std::string DebugString(const CpModelProto *proto=nullptr) const
Debug string. See the documentation for LinearExpr::DebugString().
Definition: cp_model.cc:437
static DoubleLinearExpr WeightedSum(absl::Span< const IntVar > vars, absl::Span< const double > coeffs)
Constructs the scalar product of variables and coefficients.
Definition: cp_model.cc:346
const std::vector< double > & coefficients() const
Returns the vector of coefficients.
Definition: cp_model.h:407
const std::vector< int > & variables() const
Returns the vector of variable indices.
Definition: cp_model.h:404
DoubleLinearExpr & operator-=(double value)
Adds a constant value to the linear expression.
Definition: cp_model.cc:409
DoubleLinearExpr & AddTerm(IntVar var, double coeff)
Adds a term (var * coeff) to the linear expression.
Definition: cp_model.cc:390
DoubleLinearExpr & operator*=(double coeff)
Multiply the linear expression by a constant.
Definition: cp_model.cc:429
static DoubleLinearExpr Sum(absl::Span< const IntVar > vars)
Constructs the sum of a list of variables.
Definition: cp_model.cc:330
An integer variable.
Definition: cp_model.h:140
BoolVar ToBoolVar() const
Cast IntVar -> BoolVar.
Definition: cp_model.cc:108
std::string Name() const
Returns the name of the variable (or the empty string if not set).
Definition: cp_model.cc:125
IntVar()
A default constructed IntVar can be used to mean not defined yet.
Definition: cp_model.cc:91
std::string DebugString() const
Definition: cp_model.cc:135
IntVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:118
::operations_research::Domain Domain() const
Definition: cp_model.cc:130
void set_name(ArgT0 &&arg0, ArgT... args)
const ::operations_research::sat::LinearExpressionProto & end() const
Definition: cp_model.pb.h:7831
const ::operations_research::sat::LinearExpressionProto & start() const
Definition: cp_model.pb.h:7741
const ::operations_research::sat::LinearExpressionProto & size() const
Definition: cp_model.pb.h:7921
Represents a Interval variable.
Definition: cp_model.h:446
LinearExpr SizeExpr() const
Returns the size linear expression.
Definition: cp_model.cc:583
LinearExpr StartExpr() const
Returns the start linear expression.
Definition: cp_model.cc:576
BoolVar PresenceBoolVar() const
Returns a BoolVar indicating the presence of this interval.
Definition: cp_model.cc:597
std::string Name() const
Returns the name of the interval (or the empty string if not set).
Definition: cp_model.cc:604
std::string DebugString() const
Returns a debug string.
Definition: cp_model.cc:609
IntervalVar WithName(const std::string &name)
Sets the name of the variable.
Definition: cp_model.cc:569
LinearExpr EndExpr() const
Returns the end linear expression.
Definition: cp_model.cc:590
IntervalVar()
A default constructed IntervalVar can be used to mean not defined yet.
Definition: cp_model.cc:564
A dedicated container for linear expressions.
Definition: cp_model.h:239
LinearExpr & operator+=(const LinearExpr &other)
Definition: cp_model.cc:254
LinearExpr & operator-=(const LinearExpr &other)
Definition: cp_model.cc:263
LinearExpr & operator*=(int64_t factor)
Definition: cp_model.cc:273
static LinearExpr WeightedSum(absl::Span< const IntVar > vars, absl::Span< const int64_t > coeffs)
Constructs the scalar product of variables and coefficients.
Definition: cp_model.cc:222
static LinearExpr Sum(absl::Span< const IntVar > vars)
Constructs the sum of a list of variables.
Definition: cp_model.cc:206
std::string DebugString(const CpModelProto *proto=nullptr) const
Debug string.
Definition: cp_model.cc:279
const std::vector< int64_t > & coefficients() const
Returns the vector of coefficients.
Definition: cp_model.h:290
const std::vector< int > & variables() const
Returns the vector of variable indices.
Definition: cp_model.h:287
int64_t constant() const
Returns the constant term.
Definition: cp_model.h:296
LinearExpr()=default
Creates an empty linear expression with value zero.
static LinearExpr FromProto(const LinearExpressionProto &proto)
Constructs a linear expr from its proto representation.
Definition: cp_model.cc:197
static LinearExpr Term(IntVar var, int64_t coefficient)
Constructs var * coefficient.
Definition: cp_model.cc:242
void AddArc(int tail, int head, BoolVar literal)
Add an arc to the circuit.
Definition: cp_model.cc:507
Specialized no_overlap2D constraint.
Definition: cp_model.h:680
void AddRectangle(IntervalVar x_coordinate, IntervalVar y_coordinate)
Adds a rectangle (parallel to the axis) to the constraint.
Definition: cp_model.cc:548
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
Specialized reservoir constraint.
Definition: cp_model.h:630
void AddOptionalEvent(LinearExpr time, int64_t level_change, BoolVar is_active)
Adds an optional event.
Definition: cp_model.cc:532
void AddEvent(LinearExpr time, int64_t level_change)
Adds a mandatory event.
Definition: cp_model.cc:524
::operations_research::sat::LinearExpressionProto * add_time_exprs()
Definition: cp_model.pb.h:8416
Specialized assignment constraint.
Definition: cp_model.h:613
void AddTuple(absl::Span< const int64_t > tuple)
Adds a tuple of possible values to the constraint.
Definition: cp_model.cc:513
This file implements a wrapper around the CP-SAT model proto.
CpModelProto proto
CpModelProto const * model_proto
const std::string name
const Constraint * ct
int64_t value
IntVar * var
Definition: expr_array.cc:1874
absl::Span< const double > coefficients
std::ostream & operator<<(std::ostream &os, const BoolVar &var)
Definition: cp_model.cc:86
bool RefIsPositive(int ref)
std::string VarDebugString(const CpModelProto &proto, int index)
Definition: cp_model.cc:142
BoolVar Not(BoolVar x)
A convenient wrapper so we can write Not(x) instead of x.Not() which is sometimes clearer.
Definition: cp_model.cc:84
bool SolutionBooleanValue(const CpSolverResponse &r, BoolVar x)
Evaluates the value of a Boolean literal in a solver response.
Definition: cp_model.cc:1323
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
int64_t SolutionIntegerValue(const CpSolverResponse &r, const LinearExpr &expr)
Evaluates the value of an linear expression in a solver response.
Definition: cp_model.cc:1312
Collection of objects used to extend the Constraint Solver library.
Literal literal
Definition: optimization.cc:85
int index
Definition: pack.cc:509
int64_t demand
Definition: resource.cc:125
int64_t time
Definition: resource.cc:1691
IntervalVar * interval
Definition: resource.cc:100
int64_t coefficient
int64_t capacity
int64_t tail
int64_t head
std::optional< int64_t > end
int64_t start
const double coeff
const double constant