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