Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
assignment.cc
Go to the documentation of this file.
1// Copyright 2010-2024 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
14#include <stddef.h>
15
16#include <cstdint>
17#include <limits>
18#include <ostream>
19#include <string>
20#include <vector>
21
22#include "absl/container/flat_hash_map.h"
23#include "absl/strings/str_format.h"
24#include "absl/strings/str_join.h"
25#include "ortools/base/file.h"
26#include "ortools/base/hash.h"
30#include "ortools/base/types.h"
31#include "ortools/constraint_solver/assignment.pb.h"
33
34namespace operations_research {
35
36// ----------------- Solutions ------------------------
37
38// ----- IntVarElement -----
39
41
43
45 var_ = var;
46 min_ = std::numeric_limits<int64_t>::min();
47 max_ = std::numeric_limits<int64_t>::max();
48}
49
51 IntVarElement* element = new IntVarElement;
52 element->Copy(*this);
53 return element;
54}
55
56void IntVarElement::Copy(const IntVarElement& element) {
57 SetRange(element.min_, element.max_);
58 var_ = element.var_;
59 if (element.Activated()) {
60 Activate();
61 } else {
62 Deactivate();
63 }
64}
65
67 const IntVarAssignment& int_var_assignment_proto) {
68 min_ = int_var_assignment_proto.min();
69 max_ = int_var_assignment_proto.max();
70 if (int_var_assignment_proto.active()) {
71 Activate();
72 } else {
73 Deactivate();
74 }
75}
76
77bool IntVarElement::operator==(const IntVarElement& element) const {
78 if (var_ != element.var_) {
79 return false;
80 }
81 if (Activated() != element.Activated()) {
82 return false;
83 }
84 if (!Activated() && !element.Activated()) {
85 // If both elements are deactivated, then they are equal, regardless of
86 // their min and max.
87 return true;
88 }
89 return min_ == element.min_ && max_ == element.max_;
90}
91
93 IntVarAssignment* int_var_assignment_proto) const {
94 int_var_assignment_proto->set_var_id(var_->name());
95 int_var_assignment_proto->set_min(min_);
96 int_var_assignment_proto->set_max(max_);
97 int_var_assignment_proto->set_active(Activated());
98}
99
100std::string IntVarElement::DebugString() const {
101 if (Activated()) {
102 if (min_ == max_) {
103 return absl::StrFormat("(%d)", min_);
104 } else {
105 return absl::StrFormat("(%d..%d)", min_, max_);
106 }
107 } else {
108 return "(...)";
109 }
110}
111
112// ----- IntervalVarElement -----
113
115
117
119 var_ = var;
120 start_min_ = std::numeric_limits<int64_t>::min();
121 start_max_ = std::numeric_limits<int64_t>::max();
122 duration_min_ = std::numeric_limits<int64_t>::min();
123 duration_max_ = std::numeric_limits<int64_t>::max();
124 end_min_ = std::numeric_limits<int64_t>::min();
125 end_max_ = std::numeric_limits<int64_t>::max();
126 performed_min_ = 0;
127 performed_max_ = 1;
128}
129
132 element->Copy(*this);
133 return element;
134}
135
137 SetStartRange(element.start_min_, element.start_max_);
138 SetDurationRange(element.duration_min_, element.duration_max_);
139 SetEndRange(element.end_min_, element.end_max_);
140 SetPerformedRange(element.performed_min_, element.performed_max_);
141 var_ = element.var_;
142 if (element.Activated()) {
143 Activate();
144 } else {
145 Deactivate();
146 }
147}
148
150 performed_min_ = static_cast<int64_t>(var_->MustBePerformed());
151 performed_max_ = static_cast<int64_t>(var_->MayBePerformed());
152 if (performed_max_ != 0LL) {
153 start_min_ = var_->StartMin();
154 start_max_ = var_->StartMax();
155 duration_min_ = var_->DurationMin();
156 duration_max_ = var_->DurationMax();
157 end_min_ = var_->EndMin();
158 end_max_ = var_->EndMax();
159 }
160}
161
163 if (performed_max_ == performed_min_) {
164 var_->SetPerformed(performed_min_);
165 }
166 if (performed_max_ != 0LL) {
167 var_->SetStartRange(start_min_, start_max_);
168 var_->SetDurationRange(duration_min_, duration_max_);
169 var_->SetEndRange(end_min_, end_max_);
170 }
171}
172
174 const IntervalVarAssignment& interval_var_assignment_proto) {
175 start_min_ = interval_var_assignment_proto.start_min();
176 start_max_ = interval_var_assignment_proto.start_max();
177 duration_min_ = interval_var_assignment_proto.duration_min();
178 duration_max_ = interval_var_assignment_proto.duration_max();
179 end_min_ = interval_var_assignment_proto.end_min();
180 end_max_ = interval_var_assignment_proto.end_max();
181 performed_min_ = interval_var_assignment_proto.performed_min();
182 performed_max_ = interval_var_assignment_proto.performed_max();
183 if (interval_var_assignment_proto.active()) {
184 Activate();
185 } else {
186 Deactivate();
187 }
188}
189
191 IntervalVarAssignment* interval_var_assignment_proto) const {
192 interval_var_assignment_proto->set_var_id(var_->name());
193 interval_var_assignment_proto->set_start_min(start_min_);
194 interval_var_assignment_proto->set_start_max(start_max_);
195 interval_var_assignment_proto->set_duration_min(duration_min_);
196 interval_var_assignment_proto->set_duration_max(duration_max_);
197 interval_var_assignment_proto->set_end_min(end_min_);
198 interval_var_assignment_proto->set_end_max(end_max_);
199 interval_var_assignment_proto->set_performed_min(performed_min_);
200 interval_var_assignment_proto->set_performed_max(performed_max_);
201 interval_var_assignment_proto->set_active(Activated());
202}
203
205 if (Activated()) {
206 std::string out;
207 absl::StrAppendFormat(&out, "(start = %d", start_min_);
208 if (start_max_ != start_min_) {
209 absl::StrAppendFormat(&out, "..%d", start_max_);
210 }
211 absl::StrAppendFormat(&out, ", duration = %d", duration_min_);
212 if (duration_max_ != duration_min_) {
213 absl::StrAppendFormat(&out, "..%d", duration_max_);
214 }
215 absl::StrAppendFormat(&out, ", status = %d", performed_min_);
216 if (performed_max_ != performed_min_) {
217 absl::StrAppendFormat(&out, "..%d", performed_max_);
218 }
219 out.append(")");
220 return out;
221 } else {
222 return "(...)";
223 }
224}
225
227 if (var_ != element.var_) {
228 return false;
229 }
230 if (Activated() != element.Activated()) {
231 return false;
232 }
233 if (!Activated() && !element.Activated()) {
234 // If both elements are deactivated, then they are equal, regardless of
235 // their other fields.
236 return true;
237 }
238 return start_min_ == element.start_min_ && start_max_ == element.start_max_ &&
239 duration_min_ == element.duration_min_ &&
240 duration_max_ == element.duration_max_ &&
241 end_min_ == element.end_min_ && end_max_ == element.end_max_ &&
242 performed_min_ == element.performed_min_ &&
243 performed_max_ == element.performed_max_ && var_ == element.var_;
244}
245
246// ----- SequenceVarElement -----
247
249
251
253 var_ = var;
254 forward_sequence_.clear();
255 backward_sequence_.clear();
256 unperformed_.clear();
257}
258
260 SequenceVarElement* const element = new SequenceVarElement;
261 element->Copy(*this);
262 return element;
263}
264
266 forward_sequence_ = element.forward_sequence_;
267 backward_sequence_ = element.backward_sequence_;
268 unperformed_ = element.unperformed_;
269 var_ = element.var_;
270 if (element.Activated()) {
271 Activate();
272 } else {
273 Deactivate();
274 }
275}
276
278 var_->FillSequence(&forward_sequence_, &backward_sequence_, &unperformed_);
279}
280
282 var_->RankSequence(forward_sequence_, backward_sequence_, unperformed_);
283}
284
286 const SequenceVarAssignment& sequence_var_assignment_proto) {
287 for (const int32_t forward_sequence :
288 sequence_var_assignment_proto.forward_sequence()) {
289 forward_sequence_.push_back(forward_sequence);
290 }
291 for (const int32_t backward_sequence :
292 sequence_var_assignment_proto.backward_sequence()) {
293 backward_sequence_.push_back(backward_sequence);
294 }
295 for (const int32_t unperformed :
296 sequence_var_assignment_proto.unperformed()) {
297 unperformed_.push_back(unperformed);
298 }
299 if (sequence_var_assignment_proto.active()) {
300 Activate();
301 } else {
302 Deactivate();
303 }
304 DCHECK(CheckClassInvariants());
305}
306
308 SequenceVarAssignment* sequence_var_assignment_proto) const {
309 sequence_var_assignment_proto->set_var_id(var_->name());
310 sequence_var_assignment_proto->set_active(Activated());
311 for (const int forward_sequence : forward_sequence_) {
312 sequence_var_assignment_proto->add_forward_sequence(forward_sequence);
313 }
314 for (const int backward_sequence : backward_sequence_) {
315 sequence_var_assignment_proto->add_backward_sequence(backward_sequence);
316 }
317 for (const int unperformed : unperformed_) {
318 sequence_var_assignment_proto->add_unperformed(unperformed);
319 }
320}
321
323 if (Activated()) {
324 return absl::StrFormat("[forward %s, backward %s, unperformed [%s]]",
325 absl::StrJoin(forward_sequence_, " -> "),
326 absl::StrJoin(backward_sequence_, " -> "),
327 absl::StrJoin(unperformed_, ", "));
328 } else {
329 return "(...)";
330 }
331}
332
334 if (var_ != element.var_) {
335 return false;
336 }
337 if (Activated() != element.Activated()) {
338 return false;
339 }
340 if (!Activated() && !element.Activated()) {
341 // If both elements are deactivated, then they are equal, regardless of
342 // their other fields.
343 return true;
344 }
345 return forward_sequence_ == element.forward_sequence_ &&
346 backward_sequence_ == element.backward_sequence_ &&
347 unperformed_ == element.unperformed_;
348}
349
350const std::vector<int>& SequenceVarElement::ForwardSequence() const {
351 return forward_sequence_;
352}
353
354const std::vector<int>& SequenceVarElement::BackwardSequence() const {
355 return backward_sequence_;
356}
357
358const std::vector<int>& SequenceVarElement::Unperformed() const {
359 return unperformed_;
360}
361
362void SequenceVarElement::SetSequence(const std::vector<int>& forward_sequence,
363 const std::vector<int>& backward_sequence,
364 const std::vector<int>& unperformed) {
365 forward_sequence_ = forward_sequence;
366 backward_sequence_ = backward_sequence;
367 unperformed_ = unperformed;
368 DCHECK(CheckClassInvariants());
369}
370
372 const std::vector<int>& forward_sequence) {
373 forward_sequence_ = forward_sequence;
374}
375
377 const std::vector<int>& backward_sequence) {
378 backward_sequence_ = backward_sequence;
379}
380
381void SequenceVarElement::SetUnperformed(const std::vector<int>& unperformed) {
382 unperformed_ = unperformed;
383}
384
385bool SequenceVarElement::CheckClassInvariants() {
386 absl::flat_hash_set<int> visited;
387 for (const int forward_sequence : forward_sequence_) {
388 if (visited.contains(forward_sequence)) {
389 return false;
390 }
391 visited.insert(forward_sequence);
392 }
393 for (const int backward_sequence : backward_sequence_) {
394 if (visited.contains(backward_sequence)) {
395 return false;
396 }
397 visited.insert(backward_sequence);
398 }
399 for (const int unperformed : unperformed_) {
400 if (visited.contains(unperformed)) {
401 return false;
402 }
403 visited.insert(unperformed);
404 }
405 return true;
406}
407
408// ----- Assignment -----
409
411 : PropagationBaseObject(copy->solver()),
412 int_var_container_(copy->int_var_container_),
413 interval_var_container_(copy->interval_var_container_),
414 sequence_var_container_(copy->sequence_var_container_),
415 objective_elements_(copy->objective_elements_) {}
416
419
421 objective_elements_.clear();
422 int_var_container_.Clear();
423 interval_var_container_.Clear();
424 sequence_var_container_.Clear();
425}
426
428 int_var_container_.Store();
429 interval_var_container_.Store();
430 sequence_var_container_.Store();
431 for (IntVarElement& objective_element : objective_elements_) {
432 objective_element.Store();
433 }
434}
435
437 FreezeQueue();
438 int_var_container_.Restore();
439 interval_var_container_.Restore();
440 sequence_var_container_.Restore();
442}
443
444namespace {
445
446template <class V, class E>
447void IdToElementMap(AssignmentContainer<V, E>* container,
448 absl::flat_hash_map<std::string, E*>* id_to_element_map) {
449 CHECK(id_to_element_map != nullptr);
450 id_to_element_map->clear();
451 for (int i = 0; i < container->Size(); ++i) {
452 E* const element = container->MutableElement(i);
453 const V* const var = element->Var();
454 const std::string& name = var->name();
455 if (name.empty()) {
456 LOG(INFO) << "Cannot save/load variables with empty name"
457 << "; variable will be ignored";
458 } else if (id_to_element_map->contains(name)) {
459 LOG(INFO) << "Cannot save/load variables with duplicate names: " << name
460 << "; variable will be ignored";
461 } else {
462 (*id_to_element_map)[name] = element;
463 }
464 }
465}
466
467template <class E, class P>
468void LoadElement(const absl::flat_hash_map<std::string, E*>& id_to_element_map,
469 const P& proto) {
470 const std::string& var_id = proto.var_id();
471 CHECK(!var_id.empty());
472 E* element = nullptr;
473 if (gtl::FindCopy(id_to_element_map, var_id, &element)) {
474 element->LoadFromProto(proto);
475 } else {
476 LOG(INFO) << "Variable " << var_id
477 << " not in assignment; skipping variable";
478 }
479}
480
481} // namespace
482
483bool Assignment::Load(const std::string& filename) {
484 File* file;
485 if (!file::Open(filename, "r", &file, file::Defaults()).ok()) {
486 LOG(INFO) << "Cannot open " << filename;
487 return false;
488 }
489 return Load(file);
490}
491
493 CHECK(file != nullptr);
494 AssignmentProto assignment_proto;
496 if (!reader.ReadProtocolMessage(&assignment_proto)) {
497 LOG(INFO) << "No assignment found in " << file->filename();
498 return false;
499 }
500 Load(assignment_proto);
501 return reader.Close();
502}
503
504template <class Var, class Element, class Proto, class Container>
505void RealLoad(const AssignmentProto& assignment_proto,
506 Container* const container,
507 int (AssignmentProto::*GetSize)() const,
508 const Proto& (AssignmentProto::*GetElem)(int) const) {
509 bool fast_load = (container->Size() == (assignment_proto.*GetSize)());
510 for (int i = 0; fast_load && i < (assignment_proto.*GetSize)(); ++i) {
511 Element* const element = container->MutableElement(i);
512 const Proto& proto = (assignment_proto.*GetElem)(i);
513 if (element->Var()->name() == proto.var_id()) {
514 element->LoadFromProto(proto);
515 } else {
516 fast_load = false;
517 }
518 }
519 if (!fast_load) {
520 absl::flat_hash_map<std::string, Element*> id_to_element_map;
521 IdToElementMap<Var, Element>(container, &id_to_element_map);
522 for (int i = 0; i < (assignment_proto.*GetSize)(); ++i) {
523 LoadElement<Element, Proto>(id_to_element_map,
524 (assignment_proto.*GetElem)(i));
525 }
526 }
527}
528
529void Assignment::Load(const AssignmentProto& assignment_proto) {
531 assignment_proto, &int_var_container_,
532 &AssignmentProto::int_var_assignment_size,
533 &AssignmentProto::int_var_assignment);
534 RealLoad<IntervalVar, IntervalVarElement, IntervalVarAssignment,
535 IntervalContainer>(assignment_proto, &interval_var_container_,
536 &AssignmentProto::interval_var_assignment_size,
537 &AssignmentProto::interval_var_assignment);
538 RealLoad<SequenceVar, SequenceVarElement, SequenceVarAssignment,
539 SequenceContainer>(assignment_proto, &sequence_var_container_,
540 &AssignmentProto::sequence_var_assignment_size,
541 &AssignmentProto::sequence_var_assignment);
542 for (int i = 0; i < assignment_proto.objective_size(); ++i) {
543 const IntVarAssignment& objective = assignment_proto.objective(i);
544 const std::string& objective_id = objective.var_id();
545 DCHECK(!objective_id.empty());
546 if (HasObjectiveFromIndex(i) &&
547 objective_id == ObjectiveFromIndex(i)->name()) {
548 const int64_t obj_min = objective.min();
549 const int64_t obj_max = objective.max();
550 SetObjectiveRangeFromIndex(i, obj_min, obj_max);
551 if (objective.active()) {
553 } else {
555 }
556 }
557 }
558}
559
560bool Assignment::Save(const std::string& filename) const {
561 File* file;
562 if (!file::Open(filename, "w", &file, file::Defaults()).ok()) {
563 LOG(INFO) << "Cannot open " << filename;
564 return false;
565 }
566 return Save(file);
567}
568
570 CHECK(file != nullptr);
571 AssignmentProto assignment_proto;
572 Save(&assignment_proto);
574 return writer.WriteProtocolMessage(assignment_proto) && writer.Close();
575}
576
577template <class Var, class Element, class Proto, class Container>
578void RealSave(AssignmentProto* const assignment_proto,
579 const Container& container, Proto* (AssignmentProto::*Add)()) {
580 for (const Element& element : container.elements()) {
581 const Var* const var = element.Var();
582 const std::string& name = var->name();
583 if (!name.empty()) {
584 Proto* const var_assignment_proto = (assignment_proto->*Add)();
585 element.WriteToProto(var_assignment_proto);
586 }
587 }
588}
589
590void Assignment::Save(AssignmentProto* const assignment_proto) const {
591 assignment_proto->Clear();
593 assignment_proto, int_var_container_,
594 &AssignmentProto::add_int_var_assignment);
595 RealSave<IntervalVar, IntervalVarElement, IntervalVarAssignment,
596 IntervalContainer>(assignment_proto, interval_var_container_,
597 &AssignmentProto::add_interval_var_assignment);
598 RealSave<SequenceVar, SequenceVarElement, SequenceVarAssignment,
599 SequenceContainer>(assignment_proto, sequence_var_container_,
600 &AssignmentProto::add_sequence_var_assignment);
601 for (int i = 0; i < objective_elements_.size(); ++i) {
602 const std::string& name = ObjectiveFromIndex(i)->name();
603 if (!name.empty()) {
604 IntVarAssignment* objective = assignment_proto->add_objective();
605 objective->set_var_id(name);
606 objective->set_min(ObjectiveMinFromIndex(i));
607 objective->set_max(ObjectiveMaxFromIndex(i));
608 objective->set_active(ActivatedObjectiveFromIndex(i));
609 }
610 }
611}
612
613template <class Container, class Element>
614void RealDebugString(const Container& container, std::string* const out) {
615 for (const Element& element : container.elements()) {
616 if (element.Var() != nullptr) {
617 absl::StrAppendFormat(out, "%s %s | ", element.Var()->name(),
618 element.DebugString());
619 }
620 }
621}
622
623std::string Assignment::DebugString() const {
624 std::string out = "Assignment(";
625 RealDebugString<IntContainer, IntVarElement>(int_var_container_, &out);
627 interval_var_container_, &out);
629 sequence_var_container_, &out);
630 std::vector<std::string> objective_str;
631 for (const IntVarElement& objective_element : objective_elements_) {
632 if (objective_element.Activated()) {
633 objective_str.push_back(objective_element.DebugString());
634 }
635 }
636 absl::StrAppendFormat(&out, "%s)", absl::StrJoin(objective_str, ", "));
637 return out;
638}
639
641 return int_var_container_.Add(var);
642}
643
644void Assignment::Add(const std::vector<IntVar*>& vars) {
645 for (IntVar* const var : vars) {
646 Add(var);
647 }
648}
649
651 return int_var_container_.FastAdd(var);
652}
653
654int64_t Assignment::Min(const IntVar* const var) const {
655 return int_var_container_.Element(var).Min();
656}
657
658int64_t Assignment::Max(const IntVar* const var) const {
659 return int_var_container_.Element(var).Max();
660}
661
662int64_t Assignment::Value(const IntVar* const var) const {
663 return int_var_container_.Element(var).Value();
664}
665
666bool Assignment::Bound(const IntVar* const var) const {
667 return int_var_container_.Element(var).Bound();
668}
669
670void Assignment::SetMin(const IntVar* const var, int64_t m) {
671 int_var_container_.MutableElement(var)->SetMin(m);
672}
673
674void Assignment::SetMax(const IntVar* const var, int64_t m) {
675 int_var_container_.MutableElement(var)->SetMax(m);
676}
677
678void Assignment::SetRange(const IntVar* const var, int64_t l, int64_t u) {
679 int_var_container_.MutableElement(var)->SetRange(l, u);
680}
681
682void Assignment::SetValue(const IntVar* const var, int64_t value) {
683 int_var_container_.MutableElement(var)->SetValue(value);
684}
685
686// ----- Interval Var -----
687
689 return interval_var_container_.Add(var);
690}
691
692void Assignment::Add(const std::vector<IntervalVar*>& vars) {
693 for (IntervalVar* const var : vars) {
694 Add(var);
695 }
696}
697
699 return interval_var_container_.FastAdd(var);
700}
701
702int64_t Assignment::StartMin(const IntervalVar* const var) const {
703 return interval_var_container_.Element(var).StartMin();
704}
705
706int64_t Assignment::StartMax(const IntervalVar* const var) const {
707 return interval_var_container_.Element(var).StartMax();
708}
709
710int64_t Assignment::StartValue(const IntervalVar* const var) const {
711 return interval_var_container_.Element(var).StartValue();
712}
713
714int64_t Assignment::DurationMin(const IntervalVar* const var) const {
715 return interval_var_container_.Element(var).DurationMin();
716}
717
718int64_t Assignment::DurationMax(const IntervalVar* const var) const {
719 return interval_var_container_.Element(var).DurationMax();
720}
721
722int64_t Assignment::DurationValue(const IntervalVar* const var) const {
723 return interval_var_container_.Element(var).DurationValue();
724}
725
726int64_t Assignment::EndMin(const IntervalVar* const var) const {
727 return interval_var_container_.Element(var).EndMin();
728}
729
730int64_t Assignment::EndMax(const IntervalVar* const var) const {
731 return interval_var_container_.Element(var).EndMax();
732}
733
734int64_t Assignment::EndValue(const IntervalVar* const var) const {
735 return interval_var_container_.Element(var).EndValue();
736}
737
738int64_t Assignment::PerformedMin(const IntervalVar* const var) const {
739 return interval_var_container_.Element(var).PerformedMin();
740}
741
742int64_t Assignment::PerformedMax(const IntervalVar* const var) const {
743 return interval_var_container_.Element(var).PerformedMax();
744}
745
746int64_t Assignment::PerformedValue(const IntervalVar* const var) const {
747 return interval_var_container_.Element(var).PerformedValue();
748}
749
750void Assignment::SetStartMin(const IntervalVar* const var, int64_t m) {
751 interval_var_container_.MutableElement(var)->SetStartMin(m);
752}
753
754void Assignment::SetStartMax(const IntervalVar* const var, int64_t m) {
755 interval_var_container_.MutableElement(var)->SetStartMax(m);
756}
757
758void Assignment::SetStartRange(const IntervalVar* const var, int64_t mi,
759 int64_t ma) {
760 interval_var_container_.MutableElement(var)->SetStartRange(mi, ma);
761}
762
763void Assignment::SetStartValue(const IntervalVar* const var, int64_t value) {
764 interval_var_container_.MutableElement(var)->SetStartValue(value);
765}
766
767void Assignment::SetDurationMin(const IntervalVar* const var, int64_t m) {
768 interval_var_container_.MutableElement(var)->SetDurationMin(m);
769}
770
771void Assignment::SetDurationMax(const IntervalVar* const var, int64_t m) {
772 interval_var_container_.MutableElement(var)->SetDurationMax(m);
773}
774
775void Assignment::SetDurationRange(const IntervalVar* const var, int64_t mi,
776 int64_t ma) {
777 interval_var_container_.MutableElement(var)->SetDurationRange(mi, ma);
778}
779
781 interval_var_container_.MutableElement(var)->SetDurationValue(value);
782}
783
784void Assignment::SetEndMin(const IntervalVar* const var, int64_t m) {
785 interval_var_container_.MutableElement(var)->SetEndMin(m);
786}
787
788void Assignment::SetEndMax(const IntervalVar* const var, int64_t m) {
789 interval_var_container_.MutableElement(var)->SetEndMax(m);
790}
791
792void Assignment::SetEndRange(const IntervalVar* const var, int64_t mi,
793 int64_t ma) {
794 interval_var_container_.MutableElement(var)->SetEndRange(mi, ma);
795}
796
797void Assignment::SetEndValue(const IntervalVar* const var, int64_t value) {
798 interval_var_container_.MutableElement(var)->SetEndValue(value);
799}
800
801void Assignment::SetPerformedMin(const IntervalVar* const var, int64_t m) {
802 interval_var_container_.MutableElement(var)->SetPerformedMin(m);
803}
804
805void Assignment::SetPerformedMax(const IntervalVar* const var, int64_t m) {
806 interval_var_container_.MutableElement(var)->SetPerformedMax(m);
807}
808
809void Assignment::SetPerformedRange(const IntervalVar* const var, int64_t mi,
810 int64_t ma) {
811 interval_var_container_.MutableElement(var)->SetPerformedRange(mi, ma);
812}
813
815 int64_t value) {
816 interval_var_container_.MutableElement(var)->SetPerformedValue(value);
817}
818
819// ----- Sequence Var -----
820
822 return sequence_var_container_.Add(var);
823}
824
825void Assignment::Add(const std::vector<SequenceVar*>& vars) {
826 for (SequenceVar* const var : vars) {
827 Add(var);
828 }
829}
830
832 return sequence_var_container_.FastAdd(var);
833}
834
835const std::vector<int>& Assignment::ForwardSequence(
836 const SequenceVar* const var) const {
837 return sequence_var_container_.Element(var).ForwardSequence();
838}
839
840const std::vector<int>& Assignment::BackwardSequence(
841 const SequenceVar* const var) const {
842 return sequence_var_container_.Element(var).BackwardSequence();
843}
844
845const std::vector<int>& Assignment::Unperformed(
846 const SequenceVar* const var) const {
847 return sequence_var_container_.Element(var).Unperformed();
848}
849
851 const std::vector<int>& forward_sequence,
852 const std::vector<int>& backward_sequence,
853 const std::vector<int>& unperformed) {
854 sequence_var_container_.MutableElement(var)->SetSequence(
855 forward_sequence, backward_sequence, unperformed);
856}
857
859 const std::vector<int>& forward_sequence) {
860 sequence_var_container_.MutableElement(var)->SetForwardSequence(
861 forward_sequence);
862}
863
865 const SequenceVar* const var, const std::vector<int>& backward_sequence) {
866 sequence_var_container_.MutableElement(var)->SetBackwardSequence(
867 backward_sequence);
868}
869
871 const std::vector<int>& unperformed) {
872 sequence_var_container_.MutableElement(var)->SetUnperformed(unperformed);
873}
874
875void Assignment::Activate(const IntVar* const var) {
876 int_var_container_.MutableElement(var)->Activate();
877}
878
880 int_var_container_.MutableElement(var)->Deactivate();
881}
882
883bool Assignment::Activated(const IntVar* const var) const {
884 return int_var_container_.Element(var).Activated();
885}
886
888 interval_var_container_.MutableElement(var)->Activate();
889}
890
892 interval_var_container_.MutableElement(var)->Deactivate();
893}
894
895bool Assignment::Activated(const IntervalVar* const var) const {
896 return interval_var_container_.Element(var).Activated();
897}
898
900 sequence_var_container_.MutableElement(var)->Activate();
901}
902
904 sequence_var_container_.MutableElement(var)->Deactivate();
905}
906
907bool Assignment::Activated(const SequenceVar* const var) const {
908 return sequence_var_container_.Element(var).Activated();
909}
910
911bool Assignment::Contains(const IntVar* const var) const {
912 return int_var_container_.Contains(var);
913}
914
915bool Assignment::Contains(const IntervalVar* const var) const {
916 return interval_var_container_.Contains(var);
917}
918
919bool Assignment::Contains(const SequenceVar* const var) const {
920 return sequence_var_container_.Contains(var);
921}
922
924 int_var_container_.CopyIntersection(assignment->int_var_container_);
925 interval_var_container_.CopyIntersection(assignment->interval_var_container_);
926 sequence_var_container_.CopyIntersection(assignment->sequence_var_container_);
927 for (int i = 0; i < objective_elements_.size(); i++) {
928 if (i >= assignment->objective_elements_.size() ||
929 // TODO(user): The current behavior is to copy the objective "prefix"
930 // which fits the notion of lexicographic objectives well. Reconsider if
931 // multiple objectives are used in another context.
932 objective_elements_[i].Var() !=
933 assignment->objective_elements_[i].Var()) {
934 break;
935 }
936 objective_elements_[i] = assignment->objective_elements_[i];
937 }
938}
939
940void Assignment::Copy(const Assignment* assignment) {
941 Clear();
942 int_var_container_.Copy(assignment->int_var_container_);
943 interval_var_container_.Copy(assignment->interval_var_container_);
944 sequence_var_container_.Copy(assignment->sequence_var_container_);
945 objective_elements_ = assignment->objective_elements_;
946}
947
949 const std::vector<IntVar*>& target_vars,
950 const Assignment* source_assignment,
951 const std::vector<IntVar*>& source_vars) {
952 const int vars_size = target_vars.size();
953 CHECK_EQ(source_vars.size(), vars_size);
954 CHECK(target_assignment != nullptr);
955
956 target_assignment->Clear();
957 const Solver* const target_solver = target_assignment->solver();
958 const Solver* const source_solver = source_assignment->solver();
959 for (int index = 0; index < vars_size; index++) {
960 IntVar* target_var = target_vars[index];
961 CHECK_EQ(target_var->solver(), target_solver);
962 IntVar* source_var = source_vars[index];
963 CHECK_EQ(source_var->solver(), source_solver);
964 target_assignment->Add(target_var)
965 ->SetValue(source_assignment->Value(source_var));
966 }
967}
968
970
972 return RevAlloc(new Assignment(a));
973}
974
975// ----- Storing and Restoring assignments -----
976namespace {
977class RestoreAssignment : public DecisionBuilder {
978 public:
979 explicit RestoreAssignment(Assignment* assignment)
980 : assignment_(assignment) {}
981
982 ~RestoreAssignment() override {}
983
984 Decision* Next(Solver* const /*solver*/) override {
985 assignment_->Restore();
986 return nullptr;
987 }
988
989 std::string DebugString() const override { return "RestoreAssignment"; }
990
991 private:
992 Assignment* const assignment_;
993};
994
995class StoreAssignment : public DecisionBuilder {
996 public:
997 explicit StoreAssignment(Assignment* assignment) : assignment_(assignment) {}
998
999 ~StoreAssignment() override {}
1000
1001 Decision* Next(Solver* const /*solver*/) override {
1002 assignment_->Store();
1003 return nullptr;
1004 }
1005
1006 std::string DebugString() const override { return "StoreAssignment"; }
1007
1008 private:
1009 Assignment* const assignment_;
1010};
1011} // namespace
1012
1014 return RevAlloc(new RestoreAssignment(assignment));
1015}
1016
1018 return RevAlloc(new StoreAssignment(assignment));
1019}
1020
1021std::ostream& operator<<(std::ostream& out, const Assignment& assignment) {
1022 return out << assignment.DebugString();
1023}
1024
1025} // namespace operations_research
Definition file.h:30
const E & Element(const V *const var) const
E * FastAdd(V *var)
Adds element without checking its presence in the container.
void Copy(const AssignmentContainer< V, E > &container)
void CopyIntersection(const AssignmentContainer< V, E > &container)
bool Contains(const V *const var) const
void Activate(const IntVar *var)
void SetPerformedRange(const IntervalVar *var, int64_t mi, int64_t ma)
int64_t Value(const IntVar *var) const
void SetStartMax(const IntervalVar *var, int64_t m)
void SetMax(const IntVar *var, int64_t m)
void SetForwardSequence(const SequenceVar *var, const std::vector< int > &forward_sequence)
int64_t EndMin(const IntervalVar *var) const
bool Activated(const IntVar *var) const
int64_t DurationMax(const IntervalVar *var) const
int64_t PerformedMin(const IntervalVar *var) const
int64_t Max(const IntVar *var) const
void SetBackwardSequence(const SequenceVar *var, const std::vector< int > &backward_sequence)
int64_t Min(const IntVar *var) const
void SetEndValue(const IntervalVar *var, int64_t value)
bool Contains(const IntVar *var) const
void SetValue(const IntVar *var, int64_t value)
void SetEndMin(const IntervalVar *var, int64_t m)
bool Load(const std::string &filename)
int64_t EndValue(const IntervalVar *var) const
void SetMin(const IntVar *var, int64_t m)
const std::vector< int > & Unperformed(const SequenceVar *var) const
void SetPerformedValue(const IntervalVar *var, int64_t value)
int64_t PerformedValue(const IntervalVar *var) const
int64_t StartValue(const IntervalVar *var) const
IntVarElement * Add(IntVar *var)
void SetPerformedMax(const IntervalVar *var, int64_t m)
int64_t ObjectiveMinFromIndex(int index) const
std::string DebugString() const override
int64_t EndMax(const IntervalVar *var) const
int64_t StartMin(const IntervalVar *var) const
IntVarElement * FastAdd(IntVar *var)
Adds without checking if variable has been previously added.
void Deactivate(const IntVar *var)
void Copy(const Assignment *assignment)
const std::vector< int > & ForwardSequence(const SequenceVar *var) const
void SetRange(const IntVar *var, int64_t l, int64_t u)
int64_t ObjectiveMaxFromIndex(int index) const
bool ActivatedObjectiveFromIndex(int index) const
int64_t DurationMin(const IntervalVar *var) const
bool Bound(const IntVar *var) const
int64_t DurationValue(const IntervalVar *var) const
void SetSequence(const SequenceVar *var, const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
void SetStartMin(const IntervalVar *var, int64_t m)
void SetDurationMin(const IntervalVar *var, int64_t m)
void SetStartValue(const IntervalVar *var, int64_t value)
void SetDurationMax(const IntervalVar *var, int64_t m)
void SetEndMax(const IntervalVar *var, int64_t m)
void SetStartRange(const IntervalVar *var, int64_t mi, int64_t ma)
void SetDurationValue(const IntervalVar *var, int64_t value)
void CopyIntersection(const Assignment *assignment)
void SetEndRange(const IntervalVar *var, int64_t mi, int64_t ma)
void SetDurationRange(const IntervalVar *var, int64_t mi, int64_t ma)
bool HasObjectiveFromIndex(int index) const
int64_t StartMax(const IntervalVar *var) const
IntVar * ObjectiveFromIndex(int index) const
bool Save(const std::string &filename) const
Saves the assignment to a file.
const std::vector< int > & BackwardSequence(const SequenceVar *var) const
void SetPerformedMin(const IntervalVar *var, int64_t m)
void SetObjectiveRangeFromIndex(int index, int64_t l, int64_t u)
void SetUnperformed(const SequenceVar *var, const std::vector< int > &unperformed)
int64_t PerformedMax(const IntervalVar *var) const
bool operator==(const IntVarElement &element) const
Definition assignment.cc:77
void SetRange(int64_t l, int64_t u)
IntVarElement()
--------------— Solutions ---------------------—
Definition assignment.cc:40
void Copy(const IntVarElement &element)
Definition assignment.cc:56
void WriteToProto(IntVarAssignment *int_var_assignment_proto) const
Definition assignment.cc:92
void LoadFromProto(const IntVarAssignment &int_var_assignment_proto)
Definition assignment.cc:66
IntVar * Var() override
Creates a variable from the expression.
void SetDurationRange(int64_t mi, int64_t ma)
void WriteToProto(IntervalVarAssignment *interval_var_assignment_proto) const
void Copy(const IntervalVarElement &element)
void SetEndRange(int64_t mi, int64_t ma)
IntervalVarElement()
--— IntervalVarElement --—
bool operator==(const IntervalVarElement &element) const
void SetStartRange(int64_t mi, int64_t ma)
void SetPerformedRange(int64_t mi, int64_t ma)
void LoadFromProto(const IntervalVarAssignment &interval_var_assignment_proto)
virtual int64_t DurationMax() const =0
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t EndMax() const =0
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
virtual void SetPerformed(bool val)=0
virtual void SetStartRange(int64_t mi, int64_t ma)=0
virtual int64_t StartMax() const =0
virtual bool MayBePerformed() const =0
virtual int64_t DurationMin() const =0
These methods query, set, and watch the duration of the interval var.
virtual void SetDurationRange(int64_t mi, int64_t ma)=0
virtual int64_t StartMin() const =0
virtual bool MustBePerformed() const =0
virtual std::string name() const
Object naming.
void WriteToProto(SequenceVarAssignment *sequence_var_assignment_proto) const
bool operator==(const SequenceVarElement &element) const
SequenceVarElement()
--— SequenceVarElement --—
void SetUnperformed(const std::vector< int > &unperformed)
const std::vector< int > & ForwardSequence() const
void Copy(const SequenceVarElement &element)
void SetBackwardSequence(const std::vector< int > &backward_sequence)
const std::vector< int > & BackwardSequence() const
void SetSequence(const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
void SetForwardSequence(const std::vector< int > &forward_sequence)
void LoadFromProto(const SequenceVarAssignment &sequence_var_assignment_proto)
const std::vector< int > & Unperformed() const
void RankSequence(const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)
void FillSequence(std::vector< int > *rank_first, std::vector< int > *rank_last, std::vector< int > *unperformed) const
For the time being, Solver is neither MT_SAFE nor MT_HOT.
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
DecisionBuilder * MakeStoreAssignment(Assignment *assignment)
Assignment * MakeAssignment()
This method creates an empty assignment.
bool Close()
Closes the underlying file.
Definition recordio.cc:54
bool ReadProtocolMessage(P *const proto)
Definition recordio.h:91
bool Close()
Closes the underlying file.
Definition recordio.cc:29
bool WriteProtocolMessage(const P &proto)
Definition recordio.h:41
int64_t a
Definition table.cc:44
CpModelProto proto
The output proto.
const std::string name
A name for logging purposes.
int64_t value
IntVar * var
int index
Definition file.cc:169
absl::Status Open(absl::string_view filename, absl::string_view mode, File **f, Options options)
As of 2016-01, these methods can only be used with flags = file::Defaults().
Definition file.cc:170
Options Defaults()
Definition file.h:109
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition map_util.h:190
void StoreAssignment(const VariablesAssignment &assignment, BooleanAssignment *output)
In SWIG mode, we don't want anything besides these top-level includes.
void RealLoad(const AssignmentProto &assignment_proto, Container *const container, int(AssignmentProto::*GetSize)() const, const Proto &(AssignmentProto::*GetElem)(int) const)
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
void RealDebugString(const Container &container, std::string *const out)
void SetAssignmentFromAssignment(Assignment *target_assignment, const std::vector< IntVar * > &target_vars, const Assignment *source_assignment, const std::vector< IntVar * > &source_vars)
NOLINT.
void RealSave(AssignmentProto *const assignment_proto, const Container &container, Proto *(AssignmentProto::*Add)())
bool Next()