OR-Tools  9.6
constraint_solver/assignment.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 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"
28 #include "ortools/base/logging.h"
29 #include "ortools/base/map_util.h"
30 #include "ortools/base/recordio.h"
31 #include "ortools/constraint_solver/assignment.pb.h"
33 
34 namespace operations_research {
35 
36 // ----------------- Solutions ------------------------
37 
38 // ----- IntVarElement -----
39 
41 
43 
45  var_ = var;
48 }
49 
51  IntVarElement* element = new IntVarElement;
52  element->Copy(*this);
53  return element;
54 }
55 
56 void 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 
77 bool 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 
100 std::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();
126  performed_min_ = 0;
127  performed_max_ = 1;
128 }
129 
131  IntervalVarElement* element = new IntervalVarElement;
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 
204 std::string IntervalVarElement::DebugString() const {
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 
322 std::string SequenceVarElement::DebugString() const {
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 
350 const std::vector<int>& SequenceVarElement::ForwardSequence() const {
351  return forward_sequence_;
352 }
353 
354 const std::vector<int>& SequenceVarElement::BackwardSequence() const {
355  return backward_sequence_;
356 }
357 
358 const std::vector<int>& SequenceVarElement::Unperformed() const {
359  return unperformed_;
360 }
361 
362 void 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 
381 void SequenceVarElement::SetUnperformed(const std::vector<int>& unperformed) {
382  unperformed_ = unperformed;
383 }
384 
385 bool 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_element_(copy->objective_element_) {}
416 
418  : PropagationBaseObject(s), objective_element_(nullptr) {}
419 
421 
423  objective_element_.Reset(nullptr);
424  int_var_container_.Clear();
425  interval_var_container_.Clear();
426  sequence_var_container_.Clear();
427 }
428 
430  int_var_container_.Store();
431  interval_var_container_.Store();
432  sequence_var_container_.Store();
433  if (HasObjective()) {
434  objective_element_.Store();
435  }
436 }
437 
439  FreezeQueue();
440  int_var_container_.Restore();
441  interval_var_container_.Restore();
442  sequence_var_container_.Restore();
443  UnfreezeQueue();
444 }
445 
446 namespace {
447 
448 template <class V, class E>
449 void IdToElementMap(AssignmentContainer<V, E>* container,
450  absl::flat_hash_map<std::string, E*>* id_to_element_map) {
451  CHECK(id_to_element_map != nullptr);
452  id_to_element_map->clear();
453  for (int i = 0; i < container->Size(); ++i) {
454  E* const element = container->MutableElement(i);
455  const V* const var = element->Var();
456  const std::string& name = var->name();
457  if (name.empty()) {
458  LOG(INFO) << "Cannot save/load variables with empty name"
459  << "; variable will be ignored";
460  } else if (id_to_element_map->contains(name)) {
461  LOG(INFO) << "Cannot save/load variables with duplicate names: " << name
462  << "; variable will be ignored";
463  } else {
464  (*id_to_element_map)[name] = element;
465  }
466  }
467 }
468 
469 template <class E, class P>
470 void LoadElement(const absl::flat_hash_map<std::string, E*>& id_to_element_map,
471  const P& proto) {
472  const std::string& var_id = proto.var_id();
473  CHECK(!var_id.empty());
474  E* element = nullptr;
475  if (gtl::FindCopy(id_to_element_map, var_id, &element)) {
476  element->LoadFromProto(proto);
477  } else {
478  LOG(INFO) << "Variable " << var_id
479  << " not in assignment; skipping variable";
480  }
481 }
482 
483 } // namespace
484 
485 bool Assignment::Load(const std::string& filename) {
486  File* file;
487  if (!file::Open(filename, "r", &file, file::Defaults()).ok()) {
488  LOG(INFO) << "Cannot open " << filename;
489  return false;
490  }
491  return Load(file);
492 }
493 
495  CHECK(file != nullptr);
496  AssignmentProto assignment_proto;
498  if (!reader.ReadProtocolMessage(&assignment_proto)) {
499  LOG(INFO) << "No assignment found in " << file->filename();
500  return false;
501  }
502  Load(assignment_proto);
503  return reader.Close();
504 }
505 
506 template <class Var, class Element, class Proto, class Container>
507 void RealLoad(const AssignmentProto& assignment_proto,
508  Container* const container,
509  int (AssignmentProto::*GetSize)() const,
510  const Proto& (AssignmentProto::*GetElem)(int) const) {
511  bool fast_load = (container->Size() == (assignment_proto.*GetSize)());
512  for (int i = 0; fast_load && i < (assignment_proto.*GetSize)(); ++i) {
513  Element* const element = container->MutableElement(i);
514  const Proto& proto = (assignment_proto.*GetElem)(i);
515  if (element->Var()->name() == proto.var_id()) {
516  element->LoadFromProto(proto);
517  } else {
518  fast_load = false;
519  }
520  }
521  if (!fast_load) {
522  absl::flat_hash_map<std::string, Element*> id_to_element_map;
523  IdToElementMap<Var, Element>(container, &id_to_element_map);
524  for (int i = 0; i < (assignment_proto.*GetSize)(); ++i) {
525  LoadElement<Element, Proto>(id_to_element_map,
526  (assignment_proto.*GetElem)(i));
527  }
528  }
529 }
530 
531 void Assignment::Load(const AssignmentProto& assignment_proto) {
532  RealLoad<IntVar, IntVarElement, IntVarAssignment, IntContainer>(
533  assignment_proto, &int_var_container_,
534  &AssignmentProto::int_var_assignment_size,
535  &AssignmentProto::int_var_assignment);
536  RealLoad<IntervalVar, IntervalVarElement, IntervalVarAssignment,
537  IntervalContainer>(assignment_proto, &interval_var_container_,
538  &AssignmentProto::interval_var_assignment_size,
539  &AssignmentProto::interval_var_assignment);
540  RealLoad<SequenceVar, SequenceVarElement, SequenceVarAssignment,
541  SequenceContainer>(assignment_proto, &sequence_var_container_,
542  &AssignmentProto::sequence_var_assignment_size,
543  &AssignmentProto::sequence_var_assignment);
544  if (assignment_proto.has_objective()) {
545  const IntVarAssignment& objective = assignment_proto.objective();
546  const std::string& objective_id = objective.var_id();
547  CHECK(!objective_id.empty());
548  if (HasObjective() && objective_id == Objective()->name()) {
549  const int64_t obj_min = objective.min();
550  const int64_t obj_max = objective.max();
551  SetObjectiveRange(obj_min, obj_max);
552  if (objective.active()) {
554  } else {
556  }
557  }
558  }
559 }
560 
561 bool Assignment::Save(const std::string& filename) const {
562  File* file;
563  if (!file::Open(filename, "w", &file, file::Defaults()).ok()) {
564  LOG(INFO) << "Cannot open " << filename;
565  return false;
566  }
567  return Save(file);
568 }
569 
570 bool Assignment::Save(File* file) const {
571  CHECK(file != nullptr);
572  AssignmentProto assignment_proto;
573  Save(&assignment_proto);
575  return writer.WriteProtocolMessage(assignment_proto) && writer.Close();
576 }
577 
578 template <class Var, class Element, class Proto, class Container>
579 void RealSave(AssignmentProto* const assignment_proto,
580  const Container& container, Proto* (AssignmentProto::*Add)()) {
581  for (const Element& element : container.elements()) {
582  const Var* const var = element.Var();
583  const std::string& name = var->name();
584  if (!name.empty()) {
585  Proto* const var_assignment_proto = (assignment_proto->*Add)();
586  element.WriteToProto(var_assignment_proto);
587  }
588  }
589 }
590 
591 void Assignment::Save(AssignmentProto* const assignment_proto) const {
592  assignment_proto->Clear();
593  RealSave<IntVar, IntVarElement, IntVarAssignment, IntContainer>(
594  assignment_proto, int_var_container_,
595  &AssignmentProto::add_int_var_assignment);
596  RealSave<IntervalVar, IntervalVarElement, IntervalVarAssignment,
597  IntervalContainer>(assignment_proto, interval_var_container_,
598  &AssignmentProto::add_interval_var_assignment);
599  RealSave<SequenceVar, SequenceVarElement, SequenceVarAssignment,
600  SequenceContainer>(assignment_proto, sequence_var_container_,
601  &AssignmentProto::add_sequence_var_assignment);
602  if (HasObjective()) {
603  const IntVar* objective = Objective();
604  const std::string& name = objective->name();
605  if (!name.empty()) {
606  IntVarAssignment* objective = assignment_proto->mutable_objective();
607  objective->set_var_id(name);
608  const int64_t obj_min = ObjectiveMin();
609  const int64_t obj_max = ObjectiveMax();
610  objective->set_min(obj_min);
611  objective->set_max(obj_max);
612  objective->set_active(ActivatedObjective());
613  }
614  }
615 }
616 
617 template <class Container, class Element>
618 void RealDebugString(const Container& container, std::string* const out) {
619  for (const Element& element : container.elements()) {
620  if (element.Var() != nullptr) {
621  absl::StrAppendFormat(out, "%s %s | ", element.Var()->name(),
622  element.DebugString());
623  }
624  }
625 }
626 
627 std::string Assignment::DebugString() const {
628  std::string out = "Assignment(";
629  RealDebugString<IntContainer, IntVarElement>(int_var_container_, &out);
630  RealDebugString<IntervalContainer, IntervalVarElement>(
631  interval_var_container_, &out);
632  RealDebugString<SequenceContainer, SequenceVarElement>(
633  sequence_var_container_, &out);
634  if (HasObjective() && objective_element_.Activated()) {
635  out += objective_element_.DebugString();
636  }
637  out += ")";
638  return out;
639 }
640 
642  return int_var_container_.Add(var);
643 }
644 
645 void Assignment::Add(const std::vector<IntVar*>& vars) {
646  for (IntVar* const var : vars) {
647  Add(var);
648  }
649 }
650 
652  return int_var_container_.FastAdd(var);
653 }
654 
655 int64_t Assignment::Min(const IntVar* const var) const {
656  return int_var_container_.Element(var).Min();
657 }
658 
659 int64_t Assignment::Max(const IntVar* const var) const {
660  return int_var_container_.Element(var).Max();
661 }
662 
663 int64_t Assignment::Value(const IntVar* const var) const {
664  return int_var_container_.Element(var).Value();
665 }
666 
667 bool Assignment::Bound(const IntVar* const var) const {
668  return int_var_container_.Element(var).Bound();
669 }
670 
671 void Assignment::SetMin(const IntVar* const var, int64_t m) {
672  int_var_container_.MutableElement(var)->SetMin(m);
673 }
674 
675 void Assignment::SetMax(const IntVar* const var, int64_t m) {
676  int_var_container_.MutableElement(var)->SetMax(m);
677 }
678 
679 void Assignment::SetRange(const IntVar* const var, int64_t l, int64_t u) {
680  int_var_container_.MutableElement(var)->SetRange(l, u);
681 }
682 
683 void Assignment::SetValue(const IntVar* const var, int64_t value) {
684  int_var_container_.MutableElement(var)->SetValue(value);
685 }
686 
687 // ----- Interval Var -----
688 
690  return interval_var_container_.Add(var);
691 }
692 
693 void Assignment::Add(const std::vector<IntervalVar*>& vars) {
694  for (IntervalVar* const var : vars) {
695  Add(var);
696  }
697 }
698 
700  return interval_var_container_.FastAdd(var);
701 }
702 
703 int64_t Assignment::StartMin(const IntervalVar* const var) const {
704  return interval_var_container_.Element(var).StartMin();
705 }
706 
707 int64_t Assignment::StartMax(const IntervalVar* const var) const {
708  return interval_var_container_.Element(var).StartMax();
709 }
710 
711 int64_t Assignment::StartValue(const IntervalVar* const var) const {
712  return interval_var_container_.Element(var).StartValue();
713 }
714 
715 int64_t Assignment::DurationMin(const IntervalVar* const var) const {
716  return interval_var_container_.Element(var).DurationMin();
717 }
718 
719 int64_t Assignment::DurationMax(const IntervalVar* const var) const {
720  return interval_var_container_.Element(var).DurationMax();
721 }
722 
723 int64_t Assignment::DurationValue(const IntervalVar* const var) const {
724  return interval_var_container_.Element(var).DurationValue();
725 }
726 
727 int64_t Assignment::EndMin(const IntervalVar* const var) const {
728  return interval_var_container_.Element(var).EndMin();
729 }
730 
731 int64_t Assignment::EndMax(const IntervalVar* const var) const {
732  return interval_var_container_.Element(var).EndMax();
733 }
734 
735 int64_t Assignment::EndValue(const IntervalVar* const var) const {
736  return interval_var_container_.Element(var).EndValue();
737 }
738 
739 int64_t Assignment::PerformedMin(const IntervalVar* const var) const {
740  return interval_var_container_.Element(var).PerformedMin();
741 }
742 
743 int64_t Assignment::PerformedMax(const IntervalVar* const var) const {
744  return interval_var_container_.Element(var).PerformedMax();
745 }
746 
747 int64_t Assignment::PerformedValue(const IntervalVar* const var) const {
748  return interval_var_container_.Element(var).PerformedValue();
749 }
750 
751 void Assignment::SetStartMin(const IntervalVar* const var, int64_t m) {
752  interval_var_container_.MutableElement(var)->SetStartMin(m);
753 }
754 
755 void Assignment::SetStartMax(const IntervalVar* const var, int64_t m) {
756  interval_var_container_.MutableElement(var)->SetStartMax(m);
757 }
758 
759 void Assignment::SetStartRange(const IntervalVar* const var, int64_t mi,
760  int64_t ma) {
761  interval_var_container_.MutableElement(var)->SetStartRange(mi, ma);
762 }
763 
764 void Assignment::SetStartValue(const IntervalVar* const var, int64_t value) {
765  interval_var_container_.MutableElement(var)->SetStartValue(value);
766 }
767 
768 void Assignment::SetDurationMin(const IntervalVar* const var, int64_t m) {
769  interval_var_container_.MutableElement(var)->SetDurationMin(m);
770 }
771 
772 void Assignment::SetDurationMax(const IntervalVar* const var, int64_t m) {
773  interval_var_container_.MutableElement(var)->SetDurationMax(m);
774 }
775 
776 void Assignment::SetDurationRange(const IntervalVar* const var, int64_t mi,
777  int64_t ma) {
778  interval_var_container_.MutableElement(var)->SetDurationRange(mi, ma);
779 }
780 
781 void Assignment::SetDurationValue(const IntervalVar* const var, int64_t value) {
782  interval_var_container_.MutableElement(var)->SetDurationValue(value);
783 }
784 
785 void Assignment::SetEndMin(const IntervalVar* const var, int64_t m) {
786  interval_var_container_.MutableElement(var)->SetEndMin(m);
787 }
788 
789 void Assignment::SetEndMax(const IntervalVar* const var, int64_t m) {
790  interval_var_container_.MutableElement(var)->SetEndMax(m);
791 }
792 
793 void Assignment::SetEndRange(const IntervalVar* const var, int64_t mi,
794  int64_t ma) {
795  interval_var_container_.MutableElement(var)->SetEndRange(mi, ma);
796 }
797 
798 void Assignment::SetEndValue(const IntervalVar* const var, int64_t value) {
799  interval_var_container_.MutableElement(var)->SetEndValue(value);
800 }
801 
802 void Assignment::SetPerformedMin(const IntervalVar* const var, int64_t m) {
803  interval_var_container_.MutableElement(var)->SetPerformedMin(m);
804 }
805 
806 void Assignment::SetPerformedMax(const IntervalVar* const var, int64_t m) {
807  interval_var_container_.MutableElement(var)->SetPerformedMax(m);
808 }
809 
810 void Assignment::SetPerformedRange(const IntervalVar* const var, int64_t mi,
811  int64_t ma) {
812  interval_var_container_.MutableElement(var)->SetPerformedRange(mi, ma);
813 }
814 
816  int64_t value) {
817  interval_var_container_.MutableElement(var)->SetPerformedValue(value);
818 }
819 
820 // ----- Sequence Var -----
821 
823  return sequence_var_container_.Add(var);
824 }
825 
826 void Assignment::Add(const std::vector<SequenceVar*>& vars) {
827  for (SequenceVar* const var : vars) {
828  Add(var);
829  }
830 }
831 
833  return sequence_var_container_.FastAdd(var);
834 }
835 
836 const std::vector<int>& Assignment::ForwardSequence(
837  const SequenceVar* const var) const {
838  return sequence_var_container_.Element(var).ForwardSequence();
839 }
840 
841 const std::vector<int>& Assignment::BackwardSequence(
842  const SequenceVar* const var) const {
843  return sequence_var_container_.Element(var).BackwardSequence();
844 }
845 
846 const std::vector<int>& Assignment::Unperformed(
847  const SequenceVar* const var) const {
848  return sequence_var_container_.Element(var).Unperformed();
849 }
850 
852  const std::vector<int>& forward_sequence,
853  const std::vector<int>& backward_sequence,
854  const std::vector<int>& unperformed) {
855  sequence_var_container_.MutableElement(var)->SetSequence(
856  forward_sequence, backward_sequence, unperformed);
857 }
858 
860  const std::vector<int>& forward_sequence) {
861  sequence_var_container_.MutableElement(var)->SetForwardSequence(
862  forward_sequence);
863 }
864 
866  const SequenceVar* const var, const std::vector<int>& backward_sequence) {
867  sequence_var_container_.MutableElement(var)->SetBackwardSequence(
868  backward_sequence);
869 }
870 
872  const std::vector<int>& unperformed) {
873  sequence_var_container_.MutableElement(var)->SetUnperformed(unperformed);
874 }
875 
876 // ----- Objective -----
877 
878 int64_t Assignment::ObjectiveMin() const {
879  if (HasObjective()) {
880  return objective_element_.Min();
881  }
882  return 0;
883 }
884 
885 int64_t Assignment::ObjectiveMax() const {
886  if (HasObjective()) {
887  return objective_element_.Max();
888  }
889  return 0;
890 }
891 
892 int64_t Assignment::ObjectiveValue() const {
893  if (HasObjective()) {
894  return objective_element_.Value();
895  }
896  return 0;
897 }
898 
900  if (HasObjective()) {
901  return objective_element_.Bound();
902  }
903  return true;
904 }
905 
907  if (HasObjective()) {
908  objective_element_.SetMin(m);
909  }
910 }
911 
913  if (HasObjective()) {
914  objective_element_.SetMax(m);
915  }
916 }
917 
918 void Assignment::SetObjectiveRange(int64_t l, int64_t u) {
919  if (HasObjective()) {
920  objective_element_.SetRange(l, u);
921  }
922 }
923 
925  if (HasObjective()) {
926  objective_element_.SetValue(value);
927  }
928 }
929 
930 void Assignment::Activate(const IntVar* const var) {
931  int_var_container_.MutableElement(var)->Activate();
932 }
933 
934 void Assignment::Deactivate(const IntVar* const var) {
935  int_var_container_.MutableElement(var)->Deactivate();
936 }
937 
938 bool Assignment::Activated(const IntVar* const var) const {
939  return int_var_container_.Element(var).Activated();
940 }
941 
943  interval_var_container_.MutableElement(var)->Activate();
944 }
945 
947  interval_var_container_.MutableElement(var)->Deactivate();
948 }
949 
950 bool Assignment::Activated(const IntervalVar* const var) const {
951  return interval_var_container_.Element(var).Activated();
952 }
953 
955  sequence_var_container_.MutableElement(var)->Activate();
956 }
957 
959  sequence_var_container_.MutableElement(var)->Deactivate();
960 }
961 
962 bool Assignment::Activated(const SequenceVar* const var) const {
963  return sequence_var_container_.Element(var).Activated();
964 }
965 
967  if (HasObjective()) {
968  objective_element_.Activate();
969  }
970 }
971 
973  if (HasObjective()) {
974  objective_element_.Deactivate();
975  }
976 }
977 
979  if (HasObjective()) {
980  return objective_element_.Activated();
981  }
982  return true;
983 }
984 
985 bool Assignment::Contains(const IntVar* const var) const {
986  return int_var_container_.Contains(var);
987 }
988 
989 bool Assignment::Contains(const IntervalVar* const var) const {
990  return interval_var_container_.Contains(var);
991 }
992 
993 bool Assignment::Contains(const SequenceVar* const var) const {
994  return sequence_var_container_.Contains(var);
995 }
996 
997 void Assignment::CopyIntersection(const Assignment* assignment) {
998  int_var_container_.CopyIntersection(assignment->int_var_container_);
999  interval_var_container_.CopyIntersection(assignment->interval_var_container_);
1000  sequence_var_container_.CopyIntersection(assignment->sequence_var_container_);
1001  if (objective_element_.Var() == assignment->objective_element_.Var()) {
1002  objective_element_ = assignment->objective_element_;
1003  }
1004 }
1005 
1006 void Assignment::Copy(const Assignment* assignment) {
1007  Clear();
1008  int_var_container_.Copy(assignment->int_var_container_);
1009  interval_var_container_.Copy(assignment->interval_var_container_);
1010  sequence_var_container_.Copy(assignment->sequence_var_container_);
1011  objective_element_ = assignment->objective_element_;
1012 }
1013 
1014 void SetAssignmentFromAssignment(Assignment* target_assignment,
1015  const std::vector<IntVar*>& target_vars,
1016  const Assignment* source_assignment,
1017  const std::vector<IntVar*>& source_vars) {
1018  const int vars_size = target_vars.size();
1019  CHECK_EQ(source_vars.size(), vars_size);
1020  CHECK(target_assignment != nullptr);
1021 
1022  target_assignment->Clear();
1023  const Solver* const target_solver = target_assignment->solver();
1024  const Solver* const source_solver = source_assignment->solver();
1025  for (int index = 0; index < vars_size; index++) {
1026  IntVar* target_var = target_vars[index];
1027  CHECK_EQ(target_var->solver(), target_solver);
1028  IntVar* source_var = source_vars[index];
1029  CHECK_EQ(source_var->solver(), source_solver);
1030  target_assignment->Add(target_var)
1031  ->SetValue(source_assignment->Value(source_var));
1032  }
1033 }
1034 
1036 
1038  return RevAlloc(new Assignment(a));
1039 }
1040 
1041 // ----- Storing and Restoring assignments -----
1042 namespace {
1043 class RestoreAssignment : public DecisionBuilder {
1044  public:
1045  explicit RestoreAssignment(Assignment* assignment)
1046  : assignment_(assignment) {}
1047 
1048  ~RestoreAssignment() override {}
1049 
1050  Decision* Next(Solver* const /*solver*/) override {
1051  assignment_->Restore();
1052  return nullptr;
1053  }
1054 
1055  std::string DebugString() const override { return "RestoreAssignment"; }
1056 
1057  private:
1058  Assignment* const assignment_;
1059 };
1060 
1061 class StoreAssignment : public DecisionBuilder {
1062  public:
1063  explicit StoreAssignment(Assignment* assignment) : assignment_(assignment) {}
1064 
1065  ~StoreAssignment() override {}
1066 
1067  Decision* Next(Solver* const /*solver*/) override {
1068  assignment_->Store();
1069  return nullptr;
1070  }
1071 
1072  std::string DebugString() const override { return "StoreAssignment"; }
1073 
1074  private:
1075  Assignment* const assignment_;
1076 };
1077 } // namespace
1078 
1080  return RevAlloc(new RestoreAssignment(assignment));
1081 }
1082 
1084  return RevAlloc(new StoreAssignment(assignment));
1085 }
1086 
1087 std::ostream& operator<<(std::ostream& out, const Assignment& assignment) {
1088  return out << assignment.DebugString();
1089 }
1090 
1091 } // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
Definition: base/file.h:33
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
int index
Options Defaults()
Definition: base/file.h:123
absl::Status Open(const absl::string_view &filename, const absl::string_view &mode, File **f, int flags)
Definition: base/file.cc:143
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition: map_util.h:185
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)())