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