OR-Tools  9.0
constraint_solver/assignment.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 
14 #include <stddef.h>
15 
16 #include <cstdint>
17 #include <limits>
18 #include <string>
19 #include <vector>
20 
21 #include "absl/container/flat_hash_map.h"
22 #include "absl/strings/str_format.h"
23 #include "absl/strings/str_join.h"
24 #include "ortools/base/file.h"
25 #include "ortools/base/hash.h"
27 #include "ortools/base/logging.h"
28 #include "ortools/base/map_util.h"
29 #include "ortools/base/recordio.h"
32 
33 namespace operations_research {
34 
35 // ----------------- Solutions ------------------------
36 
37 // ----- IntVarElement -----
38 
40 
42 
44  var_ = var;
47 }
48 
50  IntVarElement* element = new IntVarElement;
51  element->Copy(*this);
52  return element;
53 }
54 
55 void IntVarElement::Copy(const IntVarElement& element) {
56  SetRange(element.min_, element.max_);
57  var_ = element.var_;
58  if (element.Activated()) {
59  Activate();
60  } else {
61  Deactivate();
62  }
63 }
64 
66  const IntVarAssignment& int_var_assignment_proto) {
67  min_ = int_var_assignment_proto.min();
68  max_ = int_var_assignment_proto.max();
69  if (int_var_assignment_proto.active()) {
70  Activate();
71  } else {
72  Deactivate();
73  }
74 }
75 
76 bool IntVarElement::operator==(const IntVarElement& element) const {
77  if (var_ != element.var_) {
78  return false;
79  }
80  if (Activated() != element.Activated()) {
81  return false;
82  }
83  if (!Activated() && !element.Activated()) {
84  // If both elements are deactivated, then they are equal, regardless of
85  // their min and max.
86  return true;
87  }
88  return min_ == element.min_ && max_ == element.max_;
89 }
90 
92  IntVarAssignment* int_var_assignment_proto) const {
93  int_var_assignment_proto->set_var_id(var_->name());
94  int_var_assignment_proto->set_min(min_);
95  int_var_assignment_proto->set_max(max_);
96  int_var_assignment_proto->set_active(Activated());
97 }
98 
99 std::string IntVarElement::DebugString() const {
100  if (Activated()) {
101  if (min_ == max_) {
102  return absl::StrFormat("(%d)", min_);
103  } else {
104  return absl::StrFormat("(%d..%d)", min_, max_);
105  }
106  } else {
107  return "(...)";
108  }
109 }
110 
111 // ----- IntervalVarElement -----
112 
114 
116 
118  var_ = var;
119  start_min_ = std::numeric_limits<int64_t>::min();
120  start_max_ = std::numeric_limits<int64_t>::max();
121  duration_min_ = std::numeric_limits<int64_t>::min();
122  duration_max_ = std::numeric_limits<int64_t>::max();
125  performed_min_ = 0;
126  performed_max_ = 1;
127 }
128 
130  IntervalVarElement* element = new IntervalVarElement;
131  element->Copy(*this);
132  return element;
133 }
134 
136  SetStartRange(element.start_min_, element.start_max_);
137  SetDurationRange(element.duration_min_, element.duration_max_);
138  SetEndRange(element.end_min_, element.end_max_);
139  SetPerformedRange(element.performed_min_, element.performed_max_);
140  var_ = element.var_;
141  if (element.Activated()) {
142  Activate();
143  } else {
144  Deactivate();
145  }
146 }
147 
149  performed_min_ = static_cast<int64_t>(var_->MustBePerformed());
150  performed_max_ = static_cast<int64_t>(var_->MayBePerformed());
151  if (performed_max_ != 0LL) {
152  start_min_ = var_->StartMin();
153  start_max_ = var_->StartMax();
154  duration_min_ = var_->DurationMin();
155  duration_max_ = var_->DurationMax();
156  end_min_ = var_->EndMin();
157  end_max_ = var_->EndMax();
158  }
159 }
160 
162  if (performed_max_ == performed_min_) {
163  var_->SetPerformed(performed_min_);
164  }
165  if (performed_max_ != 0LL) {
166  var_->SetStartRange(start_min_, start_max_);
167  var_->SetDurationRange(duration_min_, duration_max_);
168  var_->SetEndRange(end_min_, end_max_);
169  }
170 }
171 
173  const IntervalVarAssignment& interval_var_assignment_proto) {
174  start_min_ = interval_var_assignment_proto.start_min();
175  start_max_ = interval_var_assignment_proto.start_max();
176  duration_min_ = interval_var_assignment_proto.duration_min();
177  duration_max_ = interval_var_assignment_proto.duration_max();
178  end_min_ = interval_var_assignment_proto.end_min();
179  end_max_ = interval_var_assignment_proto.end_max();
180  performed_min_ = interval_var_assignment_proto.performed_min();
181  performed_max_ = interval_var_assignment_proto.performed_max();
182  if (interval_var_assignment_proto.active()) {
183  Activate();
184  } else {
185  Deactivate();
186  }
187 }
188 
190  IntervalVarAssignment* interval_var_assignment_proto) const {
191  interval_var_assignment_proto->set_var_id(var_->name());
192  interval_var_assignment_proto->set_start_min(start_min_);
193  interval_var_assignment_proto->set_start_max(start_max_);
194  interval_var_assignment_proto->set_duration_min(duration_min_);
195  interval_var_assignment_proto->set_duration_max(duration_max_);
196  interval_var_assignment_proto->set_end_min(end_min_);
197  interval_var_assignment_proto->set_end_max(end_max_);
198  interval_var_assignment_proto->set_performed_min(performed_min_);
199  interval_var_assignment_proto->set_performed_max(performed_max_);
200  interval_var_assignment_proto->set_active(Activated());
201 }
202 
203 std::string IntervalVarElement::DebugString() const {
204  if (Activated()) {
205  std::string out;
206  absl::StrAppendFormat(&out, "(start = %d", start_min_);
207  if (start_max_ != start_min_) {
208  absl::StrAppendFormat(&out, "..%d", start_max_);
209  }
210  absl::StrAppendFormat(&out, ", duration = %d", duration_min_);
211  if (duration_max_ != duration_min_) {
212  absl::StrAppendFormat(&out, "..%d", duration_max_);
213  }
214  absl::StrAppendFormat(&out, ", status = %d", performed_min_);
215  if (performed_max_ != performed_min_) {
216  absl::StrAppendFormat(&out, "..%d", performed_max_);
217  }
218  out.append(")");
219  return out;
220  } else {
221  return "(...)";
222  }
223 }
224 
226  if (var_ != element.var_) {
227  return false;
228  }
229  if (Activated() != element.Activated()) {
230  return false;
231  }
232  if (!Activated() && !element.Activated()) {
233  // If both elements are deactivated, then they are equal, regardless of
234  // their other fields.
235  return true;
236  }
237  return start_min_ == element.start_min_ && start_max_ == element.start_max_ &&
238  duration_min_ == element.duration_min_ &&
239  duration_max_ == element.duration_max_ &&
240  end_min_ == element.end_min_ && end_max_ == element.end_max_ &&
241  performed_min_ == element.performed_min_ &&
242  performed_max_ == element.performed_max_ && var_ == element.var_;
243 }
244 
245 // ----- SequenceVarElement -----
246 
248 
250 
252  var_ = var;
253  forward_sequence_.clear();
254  backward_sequence_.clear();
255  unperformed_.clear();
256 }
257 
259  SequenceVarElement* const element = new SequenceVarElement;
260  element->Copy(*this);
261  return element;
262 }
263 
265  forward_sequence_ = element.forward_sequence_;
266  backward_sequence_ = element.backward_sequence_;
267  unperformed_ = element.unperformed_;
268  var_ = element.var_;
269  if (element.Activated()) {
270  Activate();
271  } else {
272  Deactivate();
273  }
274 }
275 
277  var_->FillSequence(&forward_sequence_, &backward_sequence_, &unperformed_);
278 }
279 
281  var_->RankSequence(forward_sequence_, backward_sequence_, unperformed_);
282 }
283 
285  const SequenceVarAssignment& sequence_var_assignment_proto) {
286  for (const int32_t forward_sequence :
287  sequence_var_assignment_proto.forward_sequence()) {
288  forward_sequence_.push_back(forward_sequence);
289  }
290  for (const int32_t backward_sequence :
291  sequence_var_assignment_proto.backward_sequence()) {
292  backward_sequence_.push_back(backward_sequence);
293  }
294  for (const int32_t unperformed :
295  sequence_var_assignment_proto.unperformed()) {
296  unperformed_.push_back(unperformed);
297  }
298  if (sequence_var_assignment_proto.active()) {
299  Activate();
300  } else {
301  Deactivate();
302  }
303  DCHECK(CheckClassInvariants());
304 }
305 
307  SequenceVarAssignment* sequence_var_assignment_proto) const {
308  sequence_var_assignment_proto->set_var_id(var_->name());
309  sequence_var_assignment_proto->set_active(Activated());
310  for (const int forward_sequence : forward_sequence_) {
311  sequence_var_assignment_proto->add_forward_sequence(forward_sequence);
312  }
313  for (const int backward_sequence : backward_sequence_) {
314  sequence_var_assignment_proto->add_backward_sequence(backward_sequence);
315  }
316  for (const int unperformed : unperformed_) {
317  sequence_var_assignment_proto->add_unperformed(unperformed);
318  }
319 }
320 
321 std::string SequenceVarElement::DebugString() const {
322  if (Activated()) {
323  return absl::StrFormat("[forward %s, backward %s, unperformed [%s]]",
324  absl::StrJoin(forward_sequence_, " -> "),
325  absl::StrJoin(backward_sequence_, " -> "),
326  absl::StrJoin(unperformed_, ", "));
327  } else {
328  return "(...)";
329  }
330 }
331 
333  if (var_ != element.var_) {
334  return false;
335  }
336  if (Activated() != element.Activated()) {
337  return false;
338  }
339  if (!Activated() && !element.Activated()) {
340  // If both elements are deactivated, then they are equal, regardless of
341  // their other fields.
342  return true;
343  }
344  return forward_sequence_ == element.forward_sequence_ &&
345  backward_sequence_ == element.backward_sequence_ &&
346  unperformed_ == element.unperformed_;
347 }
348 
349 const std::vector<int>& SequenceVarElement::ForwardSequence() const {
350  return forward_sequence_;
351 }
352 
353 const std::vector<int>& SequenceVarElement::BackwardSequence() const {
354  return backward_sequence_;
355 }
356 
357 const std::vector<int>& SequenceVarElement::Unperformed() const {
358  return unperformed_;
359 }
360 
361 void SequenceVarElement::SetSequence(const std::vector<int>& forward_sequence,
362  const std::vector<int>& backward_sequence,
363  const std::vector<int>& unperformed) {
364  forward_sequence_ = forward_sequence;
365  backward_sequence_ = backward_sequence;
366  unperformed_ = unperformed;
367  DCHECK(CheckClassInvariants());
368 }
369 
371  const std::vector<int>& forward_sequence) {
372  forward_sequence_ = forward_sequence;
373 }
374 
376  const std::vector<int>& backward_sequence) {
377  backward_sequence_ = backward_sequence;
378 }
379 
380 void SequenceVarElement::SetUnperformed(const std::vector<int>& unperformed) {
381  unperformed_ = unperformed;
382 }
383 
384 bool SequenceVarElement::CheckClassInvariants() {
385  absl::flat_hash_set<int> visited;
386  for (const int forward_sequence : forward_sequence_) {
387  if (gtl::ContainsKey(visited, forward_sequence)) {
388  return false;
389  }
390  visited.insert(forward_sequence);
391  }
392  for (const int backward_sequence : backward_sequence_) {
393  if (gtl::ContainsKey(visited, backward_sequence)) {
394  return false;
395  }
396  visited.insert(backward_sequence);
397  }
398  for (const int unperformed : unperformed_) {
399  if (gtl::ContainsKey(visited, unperformed)) {
400  return false;
401  }
402  visited.insert(unperformed);
403  }
404  return true;
405 }
406 
407 // ----- Assignment -----
408 
410  : PropagationBaseObject(copy->solver()),
411  int_var_container_(copy->int_var_container_),
412  interval_var_container_(copy->interval_var_container_),
413  sequence_var_container_(copy->sequence_var_container_),
414  objective_element_(copy->objective_element_) {}
415 
417  : PropagationBaseObject(s), objective_element_(nullptr) {}
418 
420 
422  objective_element_.Reset(nullptr);
423  int_var_container_.Clear();
424  interval_var_container_.Clear();
425  sequence_var_container_.Clear();
426 }
427 
429  int_var_container_.Store();
430  interval_var_container_.Store();
431  sequence_var_container_.Store();
432  if (HasObjective()) {
433  objective_element_.Store();
434  }
435 }
436 
438  FreezeQueue();
439  int_var_container_.Restore();
440  interval_var_container_.Restore();
441  sequence_var_container_.Restore();
442  UnfreezeQueue();
443 }
444 
445 namespace {
446 
447 template <class V, class E>
448 void IdToElementMap(AssignmentContainer<V, E>* container,
449  absl::flat_hash_map<std::string, E*>* id_to_element_map) {
450  CHECK(id_to_element_map != nullptr);
451  id_to_element_map->clear();
452  for (int i = 0; i < container->Size(); ++i) {
453  E* const element = container->MutableElement(i);
454  const V* const var = element->Var();
455  const std::string& name = var->name();
456  if (name.empty()) {
457  LOG(INFO) << "Cannot save/load variables with empty name"
458  << "; variable will be ignored";
459  } else if (gtl::ContainsKey(*id_to_element_map, name)) {
460  LOG(INFO) << "Cannot save/load variables with duplicate names: " << name
461  << "; variable will be ignored";
462  } else {
463  (*id_to_element_map)[name] = element;
464  }
465  }
466 }
467 
468 template <class E, class P>
469 void LoadElement(const absl::flat_hash_map<std::string, E*>& id_to_element_map,
470  const P& proto) {
471  const std::string& var_id = proto.var_id();
472  CHECK(!var_id.empty());
473  E* element = nullptr;
474  if (gtl::FindCopy(id_to_element_map, var_id, &element)) {
475  element->LoadFromProto(proto);
476  } else {
477  LOG(INFO) << "Variable " << var_id
478  << " not in assignment; skipping variable";
479  }
480 }
481 
482 } // namespace
483 
484 bool Assignment::Load(const std::string& filename) {
485  File* file;
486  if (!file::Open(filename, "r", &file, file::Defaults()).ok()) {
487  LOG(INFO) << "Cannot open " << filename;
488  return false;
489  }
490  return Load(file);
491 }
492 
494  CHECK(file != nullptr);
495  AssignmentProto assignment_proto;
497  if (!reader.ReadProtocolMessage(&assignment_proto)) {
498  LOG(INFO) << "No assignment found in " << file->filename();
499  return false;
500  }
501  Load(assignment_proto);
502  return reader.Close();
503 }
504 
505 template <class Var, class Element, class Proto, class Container>
506 void RealLoad(const AssignmentProto& assignment_proto,
507  Container* const container,
508  int (AssignmentProto::*GetSize)() const,
509  const Proto& (AssignmentProto::*GetElem)(int) const) {
510  bool fast_load = (container->Size() == (assignment_proto.*GetSize)());
511  for (int i = 0; fast_load && i < (assignment_proto.*GetSize)(); ++i) {
512  Element* const element = container->MutableElement(i);
513  const Proto& proto = (assignment_proto.*GetElem)(i);
514  if (element->Var()->name() == proto.var_id()) {
515  element->LoadFromProto(proto);
516  } else {
517  fast_load = false;
518  }
519  }
520  if (!fast_load) {
521  absl::flat_hash_map<std::string, Element*> id_to_element_map;
522  IdToElementMap<Var, Element>(container, &id_to_element_map);
523  for (int i = 0; i < (assignment_proto.*GetSize)(); ++i) {
524  LoadElement<Element, Proto>(id_to_element_map,
525  (assignment_proto.*GetElem)(i));
526  }
527  }
528 }
529 
530 void Assignment::Load(const AssignmentProto& assignment_proto) {
531  RealLoad<IntVar, IntVarElement, IntVarAssignment, IntContainer>(
532  assignment_proto, &int_var_container_,
533  &AssignmentProto::int_var_assignment_size,
534  &AssignmentProto::int_var_assignment);
535  RealLoad<IntervalVar, IntervalVarElement, IntervalVarAssignment,
536  IntervalContainer>(assignment_proto, &interval_var_container_,
537  &AssignmentProto::interval_var_assignment_size,
538  &AssignmentProto::interval_var_assignment);
539  RealLoad<SequenceVar, SequenceVarElement, SequenceVarAssignment,
540  SequenceContainer>(assignment_proto, &sequence_var_container_,
541  &AssignmentProto::sequence_var_assignment_size,
542  &AssignmentProto::sequence_var_assignment);
543  if (assignment_proto.has_objective()) {
544  const IntVarAssignment& objective = assignment_proto.objective();
545  const std::string& objective_id = objective.var_id();
546  CHECK(!objective_id.empty());
547  if (HasObjective() && objective_id == Objective()->name()) {
548  const int64_t obj_min = objective.min();
549  const int64_t obj_max = objective.max();
550  SetObjectiveRange(obj_min, obj_max);
551  if (objective.active()) {
553  } else {
555  }
556  }
557  }
558 }
559 
560 bool 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 
569 bool Assignment::Save(File* file) const {
570  CHECK(file != nullptr);
571  AssignmentProto assignment_proto;
572  Save(&assignment_proto);
574  return writer.WriteProtocolMessage(assignment_proto) && writer.Close();
575 }
576 
577 template <class Var, class Element, class Proto, class Container>
578 void 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 
590 void Assignment::Save(AssignmentProto* const assignment_proto) const {
591  assignment_proto->Clear();
592  RealSave<IntVar, IntVarElement, IntVarAssignment, IntContainer>(
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  if (HasObjective()) {
602  const IntVar* objective = Objective();
603  const std::string& name = objective->name();
604  if (!name.empty()) {
605  IntVarAssignment* objective = assignment_proto->mutable_objective();
606  objective->set_var_id(name);
607  const int64_t obj_min = ObjectiveMin();
608  const int64_t obj_max = ObjectiveMax();
609  objective->set_min(obj_min);
610  objective->set_max(obj_max);
611  objective->set_active(ActivatedObjective());
612  }
613  }
614 }
615 
616 template <class Container, class Element>
617 void RealDebugString(const Container& container, std::string* const out) {
618  for (const Element& element : container.elements()) {
619  if (element.Var() != nullptr) {
620  absl::StrAppendFormat(out, "%s %s | ", element.Var()->name(),
621  element.DebugString());
622  }
623  }
624 }
625 
626 std::string Assignment::DebugString() const {
627  std::string out = "Assignment(";
628  RealDebugString<IntContainer, IntVarElement>(int_var_container_, &out);
629  RealDebugString<IntervalContainer, IntervalVarElement>(
630  interval_var_container_, &out);
631  RealDebugString<SequenceContainer, SequenceVarElement>(
632  sequence_var_container_, &out);
633  if (HasObjective() && objective_element_.Activated()) {
634  out += objective_element_.DebugString();
635  }
636  out += ")";
637  return out;
638 }
639 
641  return int_var_container_.Add(var);
642 }
643 
644 void 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 
654 int64_t Assignment::Min(const IntVar* const var) const {
655  return int_var_container_.Element(var).Min();
656 }
657 
658 int64_t Assignment::Max(const IntVar* const var) const {
659  return int_var_container_.Element(var).Max();
660 }
661 
662 int64_t Assignment::Value(const IntVar* const var) const {
663  return int_var_container_.Element(var).Value();
664 }
665 
666 bool Assignment::Bound(const IntVar* const var) const {
667  return int_var_container_.Element(var).Bound();
668 }
669 
670 void Assignment::SetMin(const IntVar* const var, int64_t m) {
671  int_var_container_.MutableElement(var)->SetMin(m);
672 }
673 
674 void Assignment::SetMax(const IntVar* const var, int64_t m) {
675  int_var_container_.MutableElement(var)->SetMax(m);
676 }
677 
678 void Assignment::SetRange(const IntVar* const var, int64_t l, int64_t u) {
679  int_var_container_.MutableElement(var)->SetRange(l, u);
680 }
681 
682 void 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 
692 void 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 
702 int64_t Assignment::StartMin(const IntervalVar* const var) const {
703  return interval_var_container_.Element(var).StartMin();
704 }
705 
706 int64_t Assignment::StartMax(const IntervalVar* const var) const {
707  return interval_var_container_.Element(var).StartMax();
708 }
709 
710 int64_t Assignment::StartValue(const IntervalVar* const var) const {
711  return interval_var_container_.Element(var).StartValue();
712 }
713 
714 int64_t Assignment::DurationMin(const IntervalVar* const var) const {
715  return interval_var_container_.Element(var).DurationMin();
716 }
717 
718 int64_t Assignment::DurationMax(const IntervalVar* const var) const {
719  return interval_var_container_.Element(var).DurationMax();
720 }
721 
722 int64_t Assignment::DurationValue(const IntervalVar* const var) const {
723  return interval_var_container_.Element(var).DurationValue();
724 }
725 
726 int64_t Assignment::EndMin(const IntervalVar* const var) const {
727  return interval_var_container_.Element(var).EndMin();
728 }
729 
730 int64_t Assignment::EndMax(const IntervalVar* const var) const {
731  return interval_var_container_.Element(var).EndMax();
732 }
733 
734 int64_t Assignment::EndValue(const IntervalVar* const var) const {
735  return interval_var_container_.Element(var).EndValue();
736 }
737 
738 int64_t Assignment::PerformedMin(const IntervalVar* const var) const {
739  return interval_var_container_.Element(var).PerformedMin();
740 }
741 
742 int64_t Assignment::PerformedMax(const IntervalVar* const var) const {
743  return interval_var_container_.Element(var).PerformedMax();
744 }
745 
746 int64_t Assignment::PerformedValue(const IntervalVar* const var) const {
747  return interval_var_container_.Element(var).PerformedValue();
748 }
749 
750 void Assignment::SetStartMin(const IntervalVar* const var, int64_t m) {
751  interval_var_container_.MutableElement(var)->SetStartMin(m);
752 }
753 
754 void Assignment::SetStartMax(const IntervalVar* const var, int64_t m) {
755  interval_var_container_.MutableElement(var)->SetStartMax(m);
756 }
757 
758 void Assignment::SetStartRange(const IntervalVar* const var, int64_t mi,
759  int64_t ma) {
760  interval_var_container_.MutableElement(var)->SetStartRange(mi, ma);
761 }
762 
763 void Assignment::SetStartValue(const IntervalVar* const var, int64_t value) {
764  interval_var_container_.MutableElement(var)->SetStartValue(value);
765 }
766 
767 void Assignment::SetDurationMin(const IntervalVar* const var, int64_t m) {
768  interval_var_container_.MutableElement(var)->SetDurationMin(m);
769 }
770 
771 void Assignment::SetDurationMax(const IntervalVar* const var, int64_t m) {
772  interval_var_container_.MutableElement(var)->SetDurationMax(m);
773 }
774 
775 void Assignment::SetDurationRange(const IntervalVar* const var, int64_t mi,
776  int64_t ma) {
777  interval_var_container_.MutableElement(var)->SetDurationRange(mi, ma);
778 }
779 
780 void Assignment::SetDurationValue(const IntervalVar* const var, int64_t value) {
781  interval_var_container_.MutableElement(var)->SetDurationValue(value);
782 }
783 
784 void Assignment::SetEndMin(const IntervalVar* const var, int64_t m) {
785  interval_var_container_.MutableElement(var)->SetEndMin(m);
786 }
787 
788 void Assignment::SetEndMax(const IntervalVar* const var, int64_t m) {
789  interval_var_container_.MutableElement(var)->SetEndMax(m);
790 }
791 
792 void Assignment::SetEndRange(const IntervalVar* const var, int64_t mi,
793  int64_t ma) {
794  interval_var_container_.MutableElement(var)->SetEndRange(mi, ma);
795 }
796 
797 void Assignment::SetEndValue(const IntervalVar* const var, int64_t value) {
798  interval_var_container_.MutableElement(var)->SetEndValue(value);
799 }
800 
801 void Assignment::SetPerformedMin(const IntervalVar* const var, int64_t m) {
802  interval_var_container_.MutableElement(var)->SetPerformedMin(m);
803 }
804 
805 void Assignment::SetPerformedMax(const IntervalVar* const var, int64_t m) {
806  interval_var_container_.MutableElement(var)->SetPerformedMax(m);
807 }
808 
809 void 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 
825 void 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 
835 const std::vector<int>& Assignment::ForwardSequence(
836  const SequenceVar* const var) const {
837  return sequence_var_container_.Element(var).ForwardSequence();
838 }
839 
840 const std::vector<int>& Assignment::BackwardSequence(
841  const SequenceVar* const var) const {
842  return sequence_var_container_.Element(var).BackwardSequence();
843 }
844 
845 const 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 
875 // ----- Objective -----
876 
878  // Check if adding twice an objective to the solution.
879  CHECK(!HasObjective());
880  objective_element_.Reset(v);
881 }
882 
883 IntVar* Assignment::Objective() const { return objective_element_.Var(); }
884 
885 int64_t Assignment::ObjectiveMin() const {
886  if (HasObjective()) {
887  return objective_element_.Min();
888  }
889  return 0;
890 }
891 
892 int64_t Assignment::ObjectiveMax() const {
893  if (HasObjective()) {
894  return objective_element_.Max();
895  }
896  return 0;
897 }
898 
899 int64_t Assignment::ObjectiveValue() const {
900  if (HasObjective()) {
901  return objective_element_.Value();
902  }
903  return 0;
904 }
905 
907  if (HasObjective()) {
908  return objective_element_.Bound();
909  }
910  return true;
911 }
912 
914  if (HasObjective()) {
915  objective_element_.SetMin(m);
916  }
917 }
918 
920  if (HasObjective()) {
921  objective_element_.SetMax(m);
922  }
923 }
924 
925 void Assignment::SetObjectiveRange(int64_t l, int64_t u) {
926  if (HasObjective()) {
927  objective_element_.SetRange(l, u);
928  }
929 }
930 
932  if (HasObjective()) {
933  objective_element_.SetValue(value);
934  }
935 }
936 
937 void Assignment::Activate(const IntVar* const var) {
938  int_var_container_.MutableElement(var)->Activate();
939 }
940 
941 void Assignment::Deactivate(const IntVar* const var) {
942  int_var_container_.MutableElement(var)->Deactivate();
943 }
944 
945 bool Assignment::Activated(const IntVar* const var) const {
946  return int_var_container_.Element(var).Activated();
947 }
948 
950  interval_var_container_.MutableElement(var)->Activate();
951 }
952 
954  interval_var_container_.MutableElement(var)->Deactivate();
955 }
956 
957 bool Assignment::Activated(const IntervalVar* const var) const {
958  return interval_var_container_.Element(var).Activated();
959 }
960 
962  sequence_var_container_.MutableElement(var)->Activate();
963 }
964 
966  sequence_var_container_.MutableElement(var)->Deactivate();
967 }
968 
969 bool Assignment::Activated(const SequenceVar* const var) const {
970  return sequence_var_container_.Element(var).Activated();
971 }
972 
974  if (HasObjective()) {
975  objective_element_.Activate();
976  }
977 }
978 
980  if (HasObjective()) {
981  objective_element_.Deactivate();
982  }
983 }
984 
986  if (HasObjective()) {
987  return objective_element_.Activated();
988  }
989  return true;
990 }
991 
992 bool Assignment::Contains(const IntVar* const var) const {
993  return int_var_container_.Contains(var);
994 }
995 
996 bool Assignment::Contains(const IntervalVar* const var) const {
997  return interval_var_container_.Contains(var);
998 }
999 
1000 bool Assignment::Contains(const SequenceVar* const var) const {
1001  return sequence_var_container_.Contains(var);
1002 }
1003 
1004 void Assignment::CopyIntersection(const Assignment* assignment) {
1005  int_var_container_.CopyIntersection(assignment->int_var_container_);
1006  interval_var_container_.CopyIntersection(assignment->interval_var_container_);
1007  sequence_var_container_.CopyIntersection(assignment->sequence_var_container_);
1008  if (objective_element_.Var() == assignment->objective_element_.Var()) {
1009  objective_element_ = assignment->objective_element_;
1010  }
1011 }
1012 
1013 void Assignment::Copy(const Assignment* assignment) {
1014  Clear();
1015  int_var_container_.Copy(assignment->int_var_container_);
1016  interval_var_container_.Copy(assignment->interval_var_container_);
1017  sequence_var_container_.Copy(assignment->sequence_var_container_);
1018  objective_element_ = assignment->objective_element_;
1019 }
1020 
1021 void SetAssignmentFromAssignment(Assignment* target_assignment,
1022  const std::vector<IntVar*>& target_vars,
1023  const Assignment* source_assignment,
1024  const std::vector<IntVar*>& source_vars) {
1025  const int vars_size = target_vars.size();
1026  CHECK_EQ(source_vars.size(), vars_size);
1027  CHECK(target_assignment != nullptr);
1028 
1029  target_assignment->Clear();
1030  const Solver* const target_solver = target_assignment->solver();
1031  const Solver* const source_solver = source_assignment->solver();
1032  for (int index = 0; index < vars_size; index++) {
1033  IntVar* target_var = target_vars[index];
1034  CHECK_EQ(target_var->solver(), target_solver);
1035  IntVar* source_var = source_vars[index];
1036  CHECK_EQ(source_var->solver(), source_solver);
1037  target_assignment->Add(target_var)
1038  ->SetValue(source_assignment->Value(source_var));
1039  }
1040 }
1041 
1043 
1045  return RevAlloc(new Assignment(a));
1046 }
1047 
1048 // ----- Storing and Restoring assignments -----
1049 namespace {
1050 class RestoreAssignment : public DecisionBuilder {
1051  public:
1052  explicit RestoreAssignment(Assignment* assignment)
1053  : assignment_(assignment) {}
1054 
1055  ~RestoreAssignment() override {}
1056 
1057  Decision* Next(Solver* const solver) override {
1058  assignment_->Restore();
1059  return nullptr;
1060  }
1061 
1062  std::string DebugString() const override { return "RestoreAssignment"; }
1063 
1064  private:
1065  Assignment* const assignment_;
1066 };
1067 
1068 class StoreAssignment : public DecisionBuilder {
1069  public:
1070  explicit StoreAssignment(Assignment* assignment) : assignment_(assignment) {}
1071 
1072  ~StoreAssignment() override {}
1073 
1074  Decision* Next(Solver* const solver) override {
1075  assignment_->Store();
1076  return nullptr;
1077  }
1078 
1079  std::string DebugString() const override { return "StoreAssignment"; }
1080 
1081  private:
1082  Assignment* const assignment_;
1083 };
1084 } // namespace
1085 
1087  return RevAlloc(new RestoreAssignment(assignment));
1088 }
1089 
1091  return RevAlloc(new StoreAssignment(assignment));
1092 }
1093 
1094 std::ostream& operator<<(std::ostream& out, const Assignment& assignment) {
1095  return out << assignment.DebugString();
1096 }
1097 
1098 } // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define CHECK(condition)
Definition: base/logging.h:498
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:705
#define LOG(severity)
Definition: base/logging.h:423
#define DCHECK(condition)
Definition: base/logging.h:892
Definition: base/file.h:32
bool Contains(const V *const var) const
void Copy(const AssignmentContainer< V, E > &container)
Copies all the elements of 'container' to this container, clearing its previous content.
const E & Element(const V *const var) const
void CopyIntersection(const AssignmentContainer< V, E > &container)
Copies the elements of 'container' which are already in the calling container.
E * FastAdd(V *var)
Adds element without checking its presence in the container.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
const std::vector< int > & Unperformed(const SequenceVar *const var) const
void SetForwardSequence(const SequenceVar *const var, const std::vector< int > &forward_sequence)
void SetStartRange(const IntervalVar *const var, int64_t mi, int64_t ma)
void Deactivate(const IntVar *const var)
int64_t EndMin(const IntervalVar *const var) const
int64_t PerformedMin(const IntervalVar *const var) const
int64_t EndMax(const IntervalVar *const var) const
void SetBackwardSequence(const SequenceVar *const var, const std::vector< int > &backward_sequence)
int64_t StartMax(const IntervalVar *const var) const
const std::vector< int > & BackwardSequence(const SequenceVar *const var) const
void SetStartMin(const IntervalVar *const var, int64_t m)
int64_t DurationMin(const IntervalVar *const var) const
int64_t EndValue(const IntervalVar *const var) const
void SetRange(const IntVar *const var, int64_t l, int64_t u)
int64_t StartValue(const IntervalVar *const var) const
bool Load(const std::string &filename)
Loads an assignment from a file; does not add variables to the assignment (only the variables contain...
void SetMax(const IntVar *const var, int64_t m)
void SetDurationMin(const IntervalVar *const var, int64_t m)
int64_t PerformedValue(const IntervalVar *const var) const
int64_t DurationMax(const IntervalVar *const var) const
bool Contains(const IntVar *const var) const
void SetEndRange(const IntervalVar *const var, int64_t mi, int64_t ma)
bool Activated(const IntVar *const var) const
bool Save(const std::string &filename) const
Saves the assignment to a file.
void SetPerformedRange(const IntervalVar *const var, int64_t mi, int64_t ma)
int64_t DurationValue(const IntervalVar *const var) const
const std::vector< int > & ForwardSequence(const SequenceVar *const var) const
void SetDurationRange(const IntervalVar *const var, int64_t mi, int64_t ma)
void SetEndMin(const IntervalVar *const var, int64_t m)
void SetValue(const IntVar *const var, int64_t value)
void SetDurationMax(const IntervalVar *const var, int64_t m)
int64_t Max(const IntVar *const var) const
int64_t Value(const IntVar *const var) const
void SetStartMax(const IntervalVar *const var, int64_t m)
void SetPerformedMax(const IntervalVar *const var, int64_t m)
void SetUnperformed(const SequenceVar *const var, const std::vector< int > &unperformed)
void SetMin(const IntVar *const var, int64_t m)
int64_t PerformedMax(const IntervalVar *const var) const
void SetDurationValue(const IntervalVar *const var, int64_t value)
void CopyIntersection(const Assignment *assignment)
Copies the intersection of the two assignments to the current assignment.
void SetEndValue(const IntervalVar *const var, int64_t value)
void SetStartValue(const IntervalVar *const var, int64_t value)
void SetEndMax(const IntervalVar *const var, int64_t m)
void SetPerformedValue(const IntervalVar *const var, int64_t value)
void SetPerformedMin(const IntervalVar *const var, int64_t m)
void Copy(const Assignment *assignment)
Copies 'assignment' to the current assignment, clearing its previous content.
void SetSequence(const SequenceVar *const var, const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
IntVarElement * Add(IntVar *const var)
bool Bound(const IntVar *const var) const
int64_t Min(const IntVar *const var) const
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
int64_t StartMin(const IntervalVar *const var) const
A DecisionBuilder is responsible for creating the search tree.
void Copy(const IntVarElement &element)
bool operator==(const IntVarElement &element) const
void WriteToProto(IntVarAssignment *int_var_assignment_proto) const
void LoadFromProto(const IntVarAssignment &int_var_assignment_proto)
void SetRange(int64_t l, int64_t u)
The class IntVar is a subset of IntExpr.
IntVar * Var() override
Creates a variable from the expression.
void LoadFromProto(const IntervalVarAssignment &interval_var_assignment_proto)
void SetDurationRange(int64_t mi, int64_t ma)
void SetPerformedRange(int64_t mi, int64_t ma)
void SetEndRange(int64_t mi, int64_t ma)
void SetStartRange(int64_t mi, int64_t ma)
bool operator==(const IntervalVarElement &element) const
void Copy(const IntervalVarElement &element)
void WriteToProto(IntervalVarAssignment *interval_var_assignment_proto) const
Interval variables are often used in scheduling.
virtual int64_t DurationMax() const =0
virtual int64_t DurationMin() const =0
These methods query, set, and watch the duration of the interval var.
virtual void SetPerformed(bool val)=0
virtual void SetStartRange(int64_t mi, int64_t ma)=0
virtual bool MustBePerformed() const =0
These methods query, set, and watch the performed status of the interval var.
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
virtual int64_t StartMin() const =0
These methods query, set, and watch the start position of the interval var.
virtual void SetDurationRange(int64_t mi, int64_t ma)=0
virtual int64_t EndMax() const =0
virtual bool MayBePerformed() const =0
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t StartMax() const =0
virtual std::string name() const
Object naming.
void FreezeQueue()
This method freezes the propagation queue.
void UnfreezeQueue()
This method unfreezes the propagation queue.
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
void SetSequence(const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
bool operator==(const SequenceVarElement &element) const
const std::vector< int > & BackwardSequence() const
void SetBackwardSequence(const std::vector< int > &backward_sequence)
const std::vector< int > & Unperformed() const
void SetUnperformed(const std::vector< int > &unperformed)
const std::vector< int > & ForwardSequence() const
void Copy(const SequenceVarElement &element)
void LoadFromProto(const SequenceVarAssignment &sequence_var_assignment_proto)
void WriteToProto(SequenceVarAssignment *sequence_var_assignment_proto) const
void SetForwardSequence(const std::vector< int > &forward_sequence)
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
void FillSequence(std::vector< int > *const rank_first, std::vector< int > *const rank_last, std::vector< int > *const unperformed) const
Clears 'rank_first' and 'rank_last', and fills them with the intervals in the order of the ranks.
void RankSequence(const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)
Applies the following sequence of ranks, ranks first, then rank last.
T * RevAlloc(T *object)
Registers the given object as being reversible.
Assignment * MakeAssignment()
This method creates an empty assignment.
DecisionBuilder * MakeStoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())
bool ReadProtocolMessage(P *const proto)
Definition: recordio.h:91
bool WriteProtocolMessage(const P &proto)
Definition: recordio.h:41
int64_t a
CpModelProto proto
const std::string name
int64_t value
IntVar * var
Definition: expr_array.cc:1874
const int INFO
Definition: log_severity.h:31
int Defaults()
Definition: base/file.h:119
absl::Status Open(const absl::string_view &filename, const absl::string_view &mode, File **f, int flags)
Definition: base/file.cc:142
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition: map_util.h:185
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:200
void StoreAssignment(const VariablesAssignment &assignment, BooleanAssignment *output)
Collection of objects used to extend the Constraint Solver library.
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 SetAssignmentFromAssignment(Assignment *target_assignment, const std::vector< IntVar * > &target_vars, const Assignment *source_assignment, const std::vector< IntVar * > &source_vars)
NOLINT.
void RealDebugString(const Container &container, std::string *const out)
void RealSave(AssignmentProto *const assignment_proto, const Container &container, Proto *(AssignmentProto::*Add)())
int index
Definition: pack.cc:509