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