C++ Reference

C++ Reference: Routing

constraint_solveri.h
Go to the documentation of this file.
1 // Copyright 2010-2018 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 
48 
49 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
51 
52 #include <algorithm>
53 #include <cmath>
54 #include <cstddef>
55 #include <functional>
56 #include <memory>
57 #include <string>
58 #include <vector>
59 
60 #include "absl/container/flat_hash_map.h"
61 #include "absl/strings/str_cat.h"
62 #include "absl/strings/str_format.h"
63 #include "absl/strings/str_join.h"
64 #include "ortools/base/commandlineflags.h"
65 #include "ortools/base/hash.h"
66 #include "ortools/base/integral_types.h"
67 #include "ortools/base/logging.h"
68 #include "ortools/base/map_util.h"
69 #include "ortools/base/sysinfo.h"
70 #include "ortools/base/timer.h"
72 #include "ortools/util/bitset.h"
73 #include "ortools/util/tuple_set.h"
74 #include "ortools/util/vector_map.h"
75 
76 class WallTimer;
77 
78 namespace operations_research {
79 class CPArgumentProto;
80 class CPConstraintProto;
81 class CPIntegerExpressionProto;
82 class CPIntervalVariableProto;
83 
109 class BaseIntExpr : public IntExpr {
110  public:
111  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
112  ~BaseIntExpr() override {}
113 
114  IntVar* Var() override;
115  virtual IntVar* CastToVar();
116 
117  private:
118  IntVar* var_;
119 };
120 
123 enum VarTypes {
133 };
134 
143 #ifndef SWIG
144 template <class T>
145 class SimpleRevFIFO {
146  private:
147  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
148  struct Chunk {
149  T data_[CHUNK_SIZE];
150  const Chunk* const next_;
151  explicit Chunk(const Chunk* next) : next_(next) {}
152  };
153 
154  public:
156  class Iterator {
157  public:
158  explicit Iterator(const SimpleRevFIFO<T>* l)
159  : chunk_(l->chunks_), value_(l->Last()) {}
160  bool ok() const { return (value_ != nullptr); }
161  T operator*() const { return *value_; }
162  void operator++() {
163  ++value_;
164  if (value_ == chunk_->data_ + CHUNK_SIZE) {
165  chunk_ = chunk_->next_;
166  value_ = chunk_ ? chunk_->data_ : nullptr;
167  }
168  }
169 
170  private:
171  const Chunk* chunk_;
172  const T* value_;
173  };
174 
175  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
176 
177  void Push(Solver* const s, T val) {
178  if (pos_.Value() == 0) {
179  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
180  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
181  reinterpret_cast<void*>(chunk));
182  pos_.SetValue(s, CHUNK_SIZE - 1);
183  } else {
184  pos_.Decr(s);
185  }
186  chunks_->data_[pos_.Value()] = val;
187  }
188 
190  void PushIfNotTop(Solver* const s, T val) {
191  if (chunks_ == nullptr || LastValue() != val) {
192  Push(s, val);
193  }
194  }
195 
197  const T* Last() const {
198  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
199  }
200 
201  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
202 
204  const T& LastValue() const {
205  DCHECK(chunks_);
206  return chunks_->data_[pos_.Value()];
207  }
208 
210  void SetLastValue(const T& v) {
211  DCHECK(Last());
212  chunks_->data_[pos_.Value()] = v;
213  }
214 
215  private:
216  Chunk* chunks_;
217  NumericalRev<int> pos_;
218 };
219 
221 // TODO(user): use murmurhash.
222 inline uint64 Hash1(uint64 value) {
223  value = (~value) + (value << 21);
224  value ^= value >> 24;
225  value += (value << 3) + (value << 8);
226  value ^= value >> 14;
227  value += (value << 2) + (value << 4);
228  value ^= value >> 28;
229  value += (value << 31);
230  return value;
231 }
232 
233 inline uint64 Hash1(uint32 value) {
234  uint64 a = value;
235  a = (a + 0x7ed55d16) + (a << 12);
236  a = (a ^ 0xc761c23c) ^ (a >> 19);
237  a = (a + 0x165667b1) + (a << 5);
238  a = (a + 0xd3a2646c) ^ (a << 9);
239  a = (a + 0xfd7046c5) + (a << 3);
240  a = (a ^ 0xb55a4f09) ^ (a >> 16);
241  return a;
242 }
243 
244 inline uint64 Hash1(int64 value) { return Hash1(static_cast<uint64>(value)); }
245 
246 inline uint64 Hash1(int value) { return Hash1(static_cast<uint32>(value)); }
247 
248 inline uint64 Hash1(void* const ptr) {
249 #if defined(ARCH_K8) || defined(__powerpc64__) || defined(__aarch64__)
250  return Hash1(reinterpret_cast<uint64>(ptr));
251 #else
252  return Hash1(reinterpret_cast<uint32>(ptr));
253 #endif
254 }
255 
256 template <class T>
257 uint64 Hash1(const std::vector<T*>& ptrs) {
258  if (ptrs.empty()) {
259  return 0;
260  } else if (ptrs.size() == 1) {
261  return Hash1(ptrs[0]);
262  } else {
263  uint64 hash = Hash1(ptrs[0]);
264  for (int i = 1; i < ptrs.size(); ++i) {
265  hash = hash * i + Hash1(ptrs[i]);
266  }
267  return hash;
268  }
269 }
270 
271 inline uint64 Hash1(const std::vector<int64>& ptrs) {
272  if (ptrs.empty()) {
273  return 0;
274  } else if (ptrs.size() == 1) {
275  return Hash1(ptrs[0]);
276  } else {
277  uint64 hash = Hash1(ptrs[0]);
278  for (int i = 1; i < ptrs.size(); ++i) {
279  hash = hash * i + Hash1(ptrs[i]);
280  }
281  return hash;
282  }
283 }
284 
287 template <class K, class V>
289  public:
290  RevImmutableMultiMap(Solver* const solver, int initial_size)
291  : solver_(solver),
292  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
293  size_(initial_size),
294  num_items_(0) {
295  memset(array_, 0, sizeof(*array_) * size_.Value());
296  }
297 
299 
300  int num_items() const { return num_items_.Value(); }
301 
303  bool ContainsKey(const K& key) const {
304  uint64 code = Hash1(key) % size_.Value();
305  Cell* tmp = array_[code];
306  while (tmp) {
307  if (tmp->key() == key) {
308  return true;
309  }
310  tmp = tmp->next();
311  }
312  return false;
313  }
314 
318  const V& FindWithDefault(const K& key, const V& default_value) const {
319  uint64 code = Hash1(key) % size_.Value();
320  Cell* tmp = array_[code];
321  while (tmp) {
322  if (tmp->key() == key) {
323  return tmp->value();
324  }
325  tmp = tmp->next();
326  }
327  return default_value;
328  }
329 
331  void Insert(const K& key, const V& value) {
332  const int position = Hash1(key) % size_.Value();
333  Cell* const cell =
334  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
335  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
336  reinterpret_cast<void*>(cell));
337  num_items_.Incr(solver_);
338  if (num_items_.Value() > 2 * size_.Value()) {
339  Double();
340  }
341  }
342 
343  private:
344  class Cell {
345  public:
346  Cell(const K& key, const V& value, Cell* const next)
347  : key_(key), value_(value), next_(next) {}
348 
349  void SetRevNext(Solver* const solver, Cell* const next) {
350  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
351  reinterpret_cast<void*>(next));
352  }
353 
354  Cell* next() const { return next_; }
355 
356  const K& key() const { return key_; }
357 
358  const V& value() const { return value_; }
359 
360  private:
361  const K key_;
362  const V value_;
363  Cell* next_;
364  };
365 
366  void Double() {
367  Cell** const old_cell_array = array_;
368  const int old_size = size_.Value();
369  size_.SetValue(solver_, size_.Value() * 2);
370  solver_->SaveAndSetValue(
371  reinterpret_cast<void**>(&array_),
372  reinterpret_cast<void*>(
373  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
374  memset(array_, 0, size_.Value() * sizeof(*array_));
375  for (int i = 0; i < old_size; ++i) {
376  Cell* tmp = old_cell_array[i];
377  while (tmp != nullptr) {
378  Cell* const to_reinsert = tmp;
379  tmp = tmp->next();
380  const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value();
381  to_reinsert->SetRevNext(solver_, array_[new_position]);
382  solver_->SaveAndSetValue(
383  reinterpret_cast<void**>(&array_[new_position]),
384  reinterpret_cast<void*>(to_reinsert));
385  }
386  }
387  }
388 
389  Solver* const solver_;
390  Cell** array_;
391  NumericalRev<int> size_;
392  NumericalRev<int> num_items_;
393 };
394 
396 class RevSwitch {
397  public:
398  RevSwitch() : value_(false) {}
399 
400  bool Switched() const { return value_; }
401 
402  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
403 
404  private:
405  bool value_;
406 };
407 
411  public:
412  explicit SmallRevBitSet(int64 size);
414  void SetToOne(Solver* const solver, int64 pos);
416  void SetToZero(Solver* const solver, int64 pos);
418  int64 Cardinality() const;
420  bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); }
422  bool IsCardinalityOne() const {
423  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
424  }
427  int64 GetFirstOne() const;
428 
429  private:
430  Rev<uint64> bits_;
431 };
432 
435 class RevBitSet {
436  public:
437  explicit RevBitSet(int64 size);
438  ~RevBitSet();
439 
441  void SetToOne(Solver* const solver, int64 index);
443  void SetToZero(Solver* const solver, int64 index);
445  bool IsSet(int64 index) const;
447  int64 Cardinality() const;
449  bool IsCardinalityZero() const;
451  bool IsCardinalityOne() const;
454  int64 GetFirstBit(int start) const;
456  void ClearAll(Solver* const solver);
457 
458  friend class RevBitMatrix;
459 
460  private:
462  void Save(Solver* const solver, int offset);
463  const int64 size_;
464  const int64 length_;
465  uint64* bits_;
466  uint64* stamps_;
467 };
468 
470 class RevBitMatrix : private RevBitSet {
471  public:
472  RevBitMatrix(int64 rows, int64 columns);
473  ~RevBitMatrix();
474 
476  void SetToOne(Solver* const solver, int64 row, int64 column);
478  void SetToZero(Solver* const solver, int64 row, int64 column);
480  bool IsSet(int64 row, int64 column) const {
481  DCHECK_GE(row, 0);
482  DCHECK_LT(row, rows_);
483  DCHECK_GE(column, 0);
484  DCHECK_LT(column, columns_);
485  return RevBitSet::IsSet(row * columns_ + column);
486  }
488  int64 Cardinality(int row) const;
490  bool IsCardinalityZero(int row) const;
492  bool IsCardinalityOne(int row) const;
495  int64 GetFirstBit(int row, int start) const;
497  void ClearAll(Solver* const solver);
498 
499  private:
500  const int64 rows_;
501  const int64 columns_;
502 };
503 
509 
511 template <class T>
512 class CallMethod0 : public Demon {
513  public:
514  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
515  : constraint_(ct), method_(method), name_(name) {}
516 
517  ~CallMethod0() override {}
518 
519  void Run(Solver* const s) override { (constraint_->*method_)(); }
520 
521  std::string DebugString() const override {
522  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
523  }
524 
525  private:
526  T* const constraint_;
527  void (T::*const method_)();
528  const std::string name_;
529 };
530 
531 template <class T>
532 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
533  const std::string& name) {
534  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
535 }
536 
537 template <class P>
538 std::string ParameterDebugString(P param) {
539  return absl::StrCat(param);
540 }
541 
543 template <class P>
544 std::string ParameterDebugString(P* param) {
545  return param->DebugString();
546 }
547 
549 template <class T, class P>
550 class CallMethod1 : public Demon {
551  public:
552  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
553  P param1)
554  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
555 
556  ~CallMethod1() override {}
557 
558  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
559 
560  std::string DebugString() const override {
561  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
562  ", ", ParameterDebugString(param1_), ")");
563  }
564 
565  private:
566  T* const constraint_;
567  void (T::*const method_)(P);
568  const std::string name_;
569  P param1_;
570 };
571 
572 template <class T, class P>
573 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
574  const std::string& name, P param1) {
575  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
576 }
577 
579 template <class T, class P, class Q>
580 class CallMethod2 : public Demon {
581  public:
582  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
583  P param1, Q param2)
584  : constraint_(ct),
585  method_(method),
586  name_(name),
587  param1_(param1),
588  param2_(param2) {}
589 
590  ~CallMethod2() override {}
591 
592  void Run(Solver* const s) override {
593  (constraint_->*method_)(param1_, param2_);
594  }
595 
596  std::string DebugString() const override {
597  return absl::StrCat(absl::StrCat("CallMethod_", name_),
598  absl::StrCat("(", constraint_->DebugString()),
599  absl::StrCat(", ", ParameterDebugString(param1_)),
600  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
601  }
602 
603  private:
604  T* const constraint_;
605  void (T::*const method_)(P, Q);
606  const std::string name_;
607  P param1_;
608  Q param2_;
609 };
610 
611 template <class T, class P, class Q>
612 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
613  void (T::*method)(P, Q), const std::string& name,
614  P param1, Q param2) {
615  return s->RevAlloc(
616  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
617 }
619 template <class T, class P, class Q, class R>
620 class CallMethod3 : public Demon {
621  public:
622  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
623  P param1, Q param2, R param3)
624  : constraint_(ct),
625  method_(method),
626  name_(name),
627  param1_(param1),
628  param2_(param2),
629  param3_(param3) {}
630 
631  ~CallMethod3() override {}
632 
633  void Run(Solver* const s) override {
634  (constraint_->*method_)(param1_, param2_, param3_);
635  }
636 
637  std::string DebugString() const override {
638  return absl::StrCat(absl::StrCat("CallMethod_", name_),
639  absl::StrCat("(", constraint_->DebugString()),
640  absl::StrCat(", ", ParameterDebugString(param1_)),
641  absl::StrCat(", ", ParameterDebugString(param2_)),
642  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
643  }
644 
645  private:
646  T* const constraint_;
647  void (T::*const method_)(P, Q, R);
648  const std::string name_;
649  P param1_;
650  Q param2_;
651  R param3_;
652 };
653 
654 template <class T, class P, class Q, class R>
655 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
656  void (T::*method)(P, Q, R), const std::string& name,
657  P param1, Q param2, R param3) {
658  return s->RevAlloc(
659  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
660 }
662 
667 
669 template <class T>
670 class DelayedCallMethod0 : public Demon {
671  public:
672  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
673  : constraint_(ct), method_(method), name_(name) {}
674 
675  ~DelayedCallMethod0() override {}
676 
677  void Run(Solver* const s) override { (constraint_->*method_)(); }
678 
679  Solver::DemonPriority priority() const override {
681  }
682 
683  std::string DebugString() const override {
684  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
685  ")";
686  }
687 
688  private:
689  T* const constraint_;
690  void (T::*const method_)();
691  const std::string name_;
692 };
693 
694 template <class T>
695 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
696  void (T::*method)(),
697  const std::string& name) {
698  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
699 }
700 
702 template <class T, class P>
703 class DelayedCallMethod1 : public Demon {
704  public:
705  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
706  P param1)
707  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
708 
709  ~DelayedCallMethod1() override {}
710 
711  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
712 
713  Solver::DemonPriority priority() const override {
715  }
716 
717  std::string DebugString() const override {
718  return absl::StrCat("DelayedCallMethod_", name_, "(",
719  constraint_->DebugString(), ", ",
720  ParameterDebugString(param1_), ")");
721  }
722 
723  private:
724  T* const constraint_;
725  void (T::*const method_)(P);
726  const std::string name_;
727  P param1_;
728 };
729 
730 template <class T, class P>
731 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
732  void (T::*method)(P),
733  const std::string& name, P param1) {
734  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
735 }
736 
738 template <class T, class P, class Q>
739 class DelayedCallMethod2 : public Demon {
740  public:
741  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
742  const std::string& name, P param1, Q param2)
743  : constraint_(ct),
744  method_(method),
745  name_(name),
746  param1_(param1),
747  param2_(param2) {}
748 
749  ~DelayedCallMethod2() override {}
750 
751  void Run(Solver* const s) override {
752  (constraint_->*method_)(param1_, param2_);
753  }
754 
755  Solver::DemonPriority priority() const override {
757  }
758 
759  std::string DebugString() const override {
760  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
761  absl::StrCat("(", constraint_->DebugString()),
762  absl::StrCat(", ", ParameterDebugString(param1_)),
763  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
764  }
765 
766  private:
767  T* const constraint_;
768  void (T::*const method_)(P, Q);
769  const std::string name_;
770  P param1_;
771  Q param2_;
772 };
773 
774 template <class T, class P, class Q>
775 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
776  void (T::*method)(P, Q),
777  const std::string& name, P param1,
778  Q param2) {
779  return s->RevAlloc(
780  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
781 }
783 
784 #endif // !defined(SWIG)
785 
803 // TODO(user): rename Start to Synchronize ?
804 // TODO(user): decouple the iterating from the defining of a neighbor.
806  public:
808  ~LocalSearchOperator() override {}
809  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
810  virtual void Start(const Assignment* assignment) = 0;
811  virtual void Reset() {}
812 #ifndef SWIG
813  virtual const LocalSearchOperator* Self() const { return this; }
814 #endif // SWIG
815  virtual bool HasFragments() const { return false; }
816  virtual bool HoldsDelta() const { return false; }
817 };
818 
820 template <class V, class Val, class Handler>
822  public:
824  VarLocalSearchOperator(std::vector<V*> vars, Handler var_handler)
825  : activated_(),
826  was_activated_(),
827  cleared_(true),
828  var_handler_(var_handler) {}
830  bool HoldsDelta() const override { return true; }
833  void Start(const Assignment* assignment) override {
834  const int size = Size();
835  CHECK_LE(size, assignment->Size())
836  << "Assignment contains fewer variables than operator";
837  for (int i = 0; i < size; ++i) {
838  activated_.Set(i, var_handler_.ValueFromAssignent(*assignment, vars_[i],
839  i, &values_[i]));
840  }
843  was_activated_.SetContentFromBitsetOfSameSize(activated_);
844  OnStart();
845  }
846  virtual bool IsIncremental() const { return false; }
847  int Size() const { return vars_.size(); }
850  const Val& Value(int64 index) const {
851  DCHECK_LT(index, vars_.size());
852  return values_[index];
853  }
855  V* Var(int64 index) const { return vars_[index]; }
856  virtual bool SkipUnchanged(int index) const { return false; }
857  const Val& OldValue(int64 index) const { return old_values_[index]; }
858  void SetValue(int64 index, const Val& value) {
859  values_[index] = value;
860  MarkChange(index);
861  }
862  bool Activated(int64 index) const { return activated_[index]; }
863  void Activate(int64 index) {
864  activated_.Set(index);
865  MarkChange(index);
866  }
867  void Deactivate(int64 index) {
868  activated_.Clear(index);
869  MarkChange(index);
870  }
871  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
872  if (IsIncremental() && !cleared_) {
873  for (const int64 index : delta_changes_.PositionsSetAtLeastOnce()) {
874  V* var = Var(index);
875  const Val& value = Value(index);
876  const bool activated = activated_[index];
877  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
878  deltadelta);
879  var_handler_.AddToAssignment(var, value, activated,
880  &assignment_indices_, index, delta);
881  }
882  } else {
883  delta->Clear();
884  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
885  const Val& value = Value(index);
886  const bool activated = activated_[index];
887  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
888  var_handler_.AddToAssignment(Var(index), value, activated_[index],
889  &assignment_indices_, index, delta);
890  }
891  }
892  }
893  return true;
894  }
895  void RevertChanges(bool incremental) {
896  cleared_ = false;
897  delta_changes_.SparseClearAll();
898  if (incremental && IsIncremental()) return;
899  cleared_ = true;
900  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
901  values_[index] = old_values_[index];
902  var_handler_.OnRevertChanges(index);
903  activated_.CopyBucket(was_activated_, index);
904  assignment_indices_[index] = -1;
905  }
906  changes_.SparseClearAll();
907  }
908  void AddVars(const std::vector<V*>& vars) {
909  if (!vars.empty()) {
910  vars_.insert(vars_.end(), vars.begin(), vars.end());
911  const int64 size = Size();
912  values_.resize(size);
913  old_values_.resize(size);
914  prev_values_.resize(size);
915  assignment_indices_.resize(size, -1);
916  activated_.Resize(size);
917  was_activated_.Resize(size);
918  changes_.ClearAndResize(size);
919  delta_changes_.ClearAndResize(size);
920  var_handler_.OnAddVars();
921  }
922  }
923 
927  virtual void OnStart() {}
928 
931  protected:
932  void MarkChange(int64 index) {
933  delta_changes_.Set(index);
934  changes_.Set(index);
935  }
936 
937  std::vector<V*> vars_;
938  std::vector<Val> values_;
939  std::vector<Val> old_values_;
940  std::vector<Val> prev_values_;
941  mutable std::vector<int> assignment_indices_;
942  Bitset64<> activated_;
943  Bitset64<> was_activated_;
944  SparseBitset<> changes_;
945  SparseBitset<> delta_changes_;
946  bool cleared_;
947  Handler var_handler_;
948 };
949 
952  public:
953  void AddToAssignment(IntVar* var, int64 value, bool active,
954  std::vector<int>* assignment_indices, int64 index,
955  Assignment* assignment) const {
956  Assignment::IntContainer* const container =
957  assignment->MutableIntVarContainer();
958  IntVarElement* element = nullptr;
959  if (assignment_indices != nullptr) {
960  if ((*assignment_indices)[index] == -1) {
961  (*assignment_indices)[index] = container->Size();
962  element = assignment->FastAdd(var);
963  } else {
964  element = container->MutableElement((*assignment_indices)[index]);
965  }
966  } else {
967  element = assignment->FastAdd(var);
968  }
969  if (active) {
970  element->SetValue(value);
971  element->Activate();
972  } else {
973  element->Deactivate();
974  }
975  }
976  bool ValueFromAssignent(const Assignment& assignment, IntVar* var,
977  int64 index, int64* value) {
978  const Assignment::IntContainer& container = assignment.IntVarContainer();
979  const IntVarElement* element = &(container.Element(index));
980  if (element->Var() != var) {
981  CHECK(container.Contains(var))
982  << "Assignment does not contain operator variable " << var;
983  element = &(container.Element(var));
984  }
985  *value = element->Value();
986  return element->Activated();
987  }
988  void OnRevertChanges(int64 index) {}
989  void OnAddVars() {}
990 };
991 
997 
998 #ifdef SWIG
999 // TODO(user): find a way to move this code back to the .i file, where it
1006 #if defined(SWIGPYTHON)
1007 %unignore VarLocalSearchOperator<IntVar, int64,
1008  IntVarLocalSearchHandler>::Size;
1009 %unignore VarLocalSearchOperator<IntVar, int64,
1010  IntVarLocalSearchHandler>::Value;
1011 %unignore VarLocalSearchOperator<IntVar, int64,
1012  IntVarLocalSearchHandler>::OldValue;
1013 %unignore VarLocalSearchOperator<IntVar, int64,
1014  IntVarLocalSearchHandler>::SetValue;
1015 %feature("director") VarLocalSearchOperator<IntVar, int64,
1016  IntVarLocalSearchHandler>::IsIncremental;
1017 %feature("director") VarLocalSearchOperator<IntVar, int64,
1018  IntVarLocalSearchHandler>::OnStart;
1019 %unignore VarLocalSearchOperator<IntVar, int64,
1020  IntVarLocalSearchHandler>::IsIncremental;
1021 %unignore VarLocalSearchOperator<IntVar, int64,
1022  IntVarLocalSearchHandler>::OnStart;
1023 #endif // SWIGPYTHON
1024 
1025 // clang-format off
1026 %rename(IntVarLocalSearchOperatorTemplate)
1027  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1028 %template(IntVarLocalSearchOperatorTemplate)
1029  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1030 // clang-format on
1031 #endif // SWIG
1032 
1035  public:
1037  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars)
1039  vars, IntVarLocalSearchHandler()) {
1040  AddVars(vars);
1041  }
1049  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1050 
1051  protected:
1054  // TODO(user): make it pure virtual, implies porting all apps overriding
1056  virtual bool MakeOneNeighbor();
1057 };
1058 
1060 class SequenceVarLocalSearchOperator;
1061 
1063  public:
1064  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1066  : op_(other.op_) {}
1068  : op_(op) {}
1069  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1070  bool active, std::vector<int>* assignment_indices,
1071  int64 index, Assignment* assignment) const;
1072  bool ValueFromAssignent(const Assignment& assignment, SequenceVar* var,
1073  int64 index, std::vector<int>* value);
1074  void OnRevertChanges(int64 index);
1075  void OnAddVars();
1076 
1077  private:
1078  SequenceVarLocalSearchOperator* const op_;
1079 };
1080 
1081 #ifdef SWIG
1082 // TODO(user): find a way to move this code back to the .i file, where it
1087 // clang-format off
1088 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1089  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1090 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1091  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1092 // clang-format on
1093 #endif
1094 
1095 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1096  SequenceVarLocalSearchHandler>
1098 
1101  public:
1103  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1105  vars, SequenceVarLocalSearchHandler(this)) {
1106  AddVars(vars);
1107  }
1111  const std::vector<int>& Sequence(int64 index) const { return Value(index); }
1112  const std::vector<int>& OldSequence(int64 index) const {
1113  return OldValue(index);
1114  }
1115  void SetForwardSequence(int64 index, const std::vector<int>& value) {
1116  SetValue(index, value);
1117  }
1118  void SetBackwardSequence(int64 index, const std::vector<int>& value) {
1119  backward_values_[index] = value;
1120  MarkChange(index);
1121  }
1122 
1123  protected:
1125 
1126  std::vector<std::vector<int> > backward_values_;
1127 };
1128 
1130  SequenceVar* var, const std::vector<int>& value, bool active,
1131  std::vector<int>* assignment_indices, int64 index,
1132  Assignment* assignment) const {
1133  Assignment::SequenceContainer* const container =
1134  assignment->MutableSequenceVarContainer();
1135  SequenceVarElement* element = nullptr;
1136  if (assignment_indices != nullptr) {
1137  if ((*assignment_indices)[index] == -1) {
1138  (*assignment_indices)[index] = container->Size();
1139  element = assignment->FastAdd(var);
1140  } else {
1141  element = container->MutableElement((*assignment_indices)[index]);
1142  }
1143  } else {
1144  element = assignment->FastAdd(var);
1145  }
1146  if (active) {
1147  element->SetForwardSequence(value);
1148  element->SetBackwardSequence(op_->backward_values_[index]);
1149  element->Activate();
1150  } else {
1151  element->Deactivate();
1152  }
1153 }
1154 
1156  const Assignment& assignment, SequenceVar* var, int64 index,
1157  std::vector<int>* value) {
1158  const Assignment::SequenceContainer& container =
1159  assignment.SequenceVarContainer();
1160  const SequenceVarElement* element = &(container.Element(index));
1161  if (element->Var() != var) {
1162  CHECK(container.Contains(var))
1163  << "Assignment does not contain operator variable " << var;
1164  element = &(container.Element(var));
1165  }
1166  const std::vector<int>& element_value = element->ForwardSequence();
1167  CHECK_GE(var->size(), element_value.size());
1168  op_->backward_values_[index].clear();
1169  *value = element_value;
1170  return element->Activated();
1171 }
1172 
1174  op_->backward_values_[index].clear();
1175 }
1176 
1178  op_->backward_values_.resize(op_->Size());
1179 }
1180 
1209  public:
1210  explicit BaseLns(const std::vector<IntVar*>& vars);
1211  ~BaseLns() override;
1212  virtual void InitFragments();
1213  virtual bool NextFragment() = 0;
1214  void AppendToFragment(int index);
1215  int FragmentSize() const;
1216  bool HasFragments() const override { return true; }
1217 
1218  protected:
1220  bool MakeOneNeighbor() override;
1221 
1222  private:
1224  void OnStart() override;
1225  std::vector<int> fragment_;
1226 };
1227 
1233  public:
1234  explicit ChangeValue(const std::vector<IntVar*>& vars);
1235  ~ChangeValue() override;
1236  virtual int64 ModifyValue(int64 index, int64 value) = 0;
1237 
1238  protected:
1240  bool MakeOneNeighbor() override;
1241 
1242  private:
1243  void OnStart() override;
1244 
1245  int index_;
1246 };
1247 
1262  public:
1276  PathOperator(const std::vector<IntVar*>& next_vars,
1277  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1278  bool skip_locally_optimal_paths,
1279  std::function<int(int64)> start_empty_path_class);
1280  ~PathOperator() override {}
1281  virtual bool MakeNeighbor() = 0;
1282  void Reset() override;
1283 
1284  // TODO(user): Make the following methods protected.
1285  bool SkipUnchanged(int index) const override;
1286 
1289  int64 Next(int64 node_index) const {
1290  DCHECK(!IsPathEnd(node_index));
1291  return Value(node_index);
1292  }
1293 
1296  int64 Path(int64 node_index) const {
1297  return ignore_path_vars_ ? 0LL : Value(node_index + number_of_nexts_);
1298  }
1299 
1301  int number_of_nexts() const { return number_of_nexts_; }
1302 
1303  protected:
1305  bool MakeOneNeighbor() override;
1306 
1308  int64 BaseNode(int i) const { return base_nodes_[i]; }
1311  int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1313  const std::vector<int64>& path_starts() const { return path_starts_; }
1315  int PathClass(int i) const {
1316  return start_empty_path_class_ != nullptr
1317  ? start_empty_path_class_(StartNode(i))
1318  : StartNode(i);
1319  }
1320 
1327  // TODO(user): remove this when automatic detection of such cases in done.
1328  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1332  // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2);
1334  virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; }
1340  virtual int64 GetBaseNodeRestartPosition(int base_index) {
1341  return StartNode(base_index);
1342  }
1345  virtual void SetNextBaseToIncrement(int64 base_index) {
1346  next_base_to_increment_ = base_index;
1347  }
1348 
1349  int64 OldNext(int64 node_index) const {
1350  DCHECK(!IsPathEnd(node_index));
1351  return OldValue(node_index);
1352  }
1353 
1354  int64 OldPath(int64 node_index) const {
1355  return ignore_path_vars_ ? 0LL : OldValue(node_index + number_of_nexts_);
1356  }
1357 
1360  bool MoveChain(int64 before_chain, int64 chain_end, int64 destination);
1361 
1364  bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last);
1365 
1366  bool MakeActive(int64 node, int64 destination);
1367  bool MakeChainInactive(int64 before_chain, int64 chain_end);
1368 
1370  void SetNext(int64 from, int64 to, int64 path) {
1371  DCHECK_LT(from, number_of_nexts_);
1372  SetValue(from, to);
1373  if (!ignore_path_vars_) {
1374  DCHECK_LT(from + number_of_nexts_, Size());
1375  SetValue(from + number_of_nexts_, path);
1376  }
1377  }
1378 
1381  bool IsPathEnd(int64 i) const { return i >= number_of_nexts_; }
1382 
1384  bool IsInactive(int64 i) const { return !IsPathEnd(i) && inactives_[i]; }
1385 
1388  virtual bool InitPosition() const { return false; }
1392  void ResetPosition() { just_started_ = true; }
1393 
1394  const int number_of_nexts_;
1395  const bool ignore_path_vars_;
1397  int num_paths_ = 0;
1398  std::vector<int64> start_to_path_;
1399 
1400  private:
1401  void OnStart() override;
1405  virtual void OnNodeInitialization() {}
1407  bool OnSamePath(int64 node1, int64 node2) const;
1408 
1409  bool CheckEnds() const {
1410  const int base_node_size = base_nodes_.size();
1411  for (int i = base_node_size - 1; i >= 0; --i) {
1412  if (base_nodes_[i] != end_nodes_[i]) {
1413  return true;
1414  }
1415  }
1416  return false;
1417  }
1418  bool IncrementPosition();
1419  void InitializePathStarts();
1420  void InitializeInactives();
1421  void InitializeBaseNodes();
1422  bool CheckChainValidity(int64 before_chain, int64 chain_end,
1423  int64 exclude) const;
1424  void Synchronize();
1425 
1426  std::vector<int> base_nodes_;
1427  std::vector<int> end_nodes_;
1428  std::vector<int> base_paths_;
1429  std::vector<int64> path_starts_;
1430  std::vector<bool> inactives_;
1431  bool just_started_;
1432  bool first_start_;
1433  std::function<int(int64)> start_empty_path_class_;
1434  bool skip_locally_optimal_paths_;
1435  bool optimal_paths_enabled_;
1436  std::vector<int> path_basis_;
1437  std::vector<bool> optimal_paths_;
1438 };
1439 
1443  public:
1445  const std::vector<IntVar*>& vars,
1446  const std::vector<IntVar*>& secondary_vars, int number_of_base_nodes,
1447  std::function<int(int64)> start_empty_path_class);
1449 
1450  bool IsPathStart(int64 node_index) const { return prevs_[node_index] == -1; }
1451 
1452  int64 Prev(int64 node_index) const {
1453  DCHECK(!IsPathStart(node_index));
1454  return prevs_[node_index];
1455  }
1456 
1457  std::string DebugString() const override {
1458  return "PathWithPreviousNodesOperator";
1459  }
1460 
1461  protected:
1462  void OnNodeInitialization() override;
1463 
1464  private:
1465  std::vector<int64> prevs_;
1466 };
1467 
1469 template <class T>
1470 LocalSearchOperator* MakeLocalSearchOperator(
1471  Solver* solver, const std::vector<IntVar*>& vars,
1472  const std::vector<IntVar*>& secondary_vars,
1473  std::function<int(int64)> start_empty_path_class);
1474 
1477 class TwoOpt;
1478 class Relocate;
1479 class Exchange;
1480 class Cross;
1481 class MakeActiveOperator;
1482 class MakeInactiveOperator;
1483 class MakeChainInactiveOperator;
1484 class SwapActiveOperator;
1485 class ExtendedSwapActiveOperator;
1486 class MakeActiveAndRelocate;
1487 class RelocateAndMakeActiveOperator;
1488 class RelocateAndMakeInactiveOperator;
1489 
1492  public:
1501  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1502  int64 objective_min, int64 objective_max) = 0;
1503 
1509  virtual void Synchronize(const Assignment* assignment,
1510  const Assignment* delta) = 0;
1511  virtual bool IsIncremental() const { return false; }
1512 
1514  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1516  // If the last Accept() call returned false, returns an undefined value.
1517  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1518 };
1519 
1520 #if !defined(SWIG)
1521 class LocalSearchFilterManager : public LocalSearchFilter {
1525  public:
1526  LocalSearchFilterManager(Solver* const solver,
1527  const std::vector<LocalSearchFilter*>& filters);
1528  std::string DebugString() const override {
1529  return "LocalSearchFilterManager";
1530  }
1533  bool Accept(const Assignment* delta, const Assignment* deltadelta,
1534  int64 objective_min, int64 objective_max) override;
1536  void Synchronize(const Assignment* assignment,
1537  const Assignment* delta) override;
1538  bool IsIncremental() const override { return is_incremental_; }
1539  int64 GetSynchronizedObjectiveValue() const override {
1540  return synchronized_value_;
1541  }
1542  int64 GetAcceptedObjectiveValue() const override { return accepted_value_; }
1543 
1544  private:
1545  Solver* const solver_;
1546  std::vector<LocalSearchFilter*> filters_;
1547  bool is_incremental_;
1548  int64 synchronized_value_;
1549  int64 accepted_value_;
1550 };
1551 #endif
1552 
1554  public:
1555  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1556  ~IntVarLocalSearchFilter() override;
1559  void Synchronize(const Assignment* assignment,
1560  const Assignment* delta) override;
1561 
1562  bool FindIndex(IntVar* const var, int64* index) const {
1563  DCHECK(index != nullptr);
1564  const int var_index = var->index();
1565  *index = (var_index < var_index_to_index_.size())
1566  ? var_index_to_index_[var_index]
1567  : kUnassigned;
1568  return *index != kUnassigned;
1569  }
1570 
1572  void AddVars(const std::vector<IntVar*>& vars);
1573  int Size() const { return vars_.size(); }
1574  IntVar* Var(int index) const { return vars_[index]; }
1575  int64 Value(int index) const {
1576  DCHECK(IsVarSynced(index));
1577  return values_[index];
1578  }
1579  bool IsVarSynced(int index) const { return var_synced_[index]; }
1580 
1581  protected:
1582  virtual void OnSynchronize(const Assignment* delta) {}
1583  void SynchronizeOnAssignment(const Assignment* assignment);
1584 
1585  private:
1586  std::vector<IntVar*> vars_;
1587  std::vector<int64> values_;
1588  std::vector<bool> var_synced_;
1589  std::vector<int> var_index_to_index_;
1590  static const int kUnassigned;
1591 };
1592 
1594  public:
1595  explicit PropagationMonitor(Solver* const solver);
1596  ~PropagationMonitor() override;
1597  std::string DebugString() const override { return "PropagationMonitor"; }
1598 
1600  virtual void BeginConstraintInitialPropagation(
1601  Constraint* const constraint) = 0;
1602  virtual void EndConstraintInitialPropagation(
1603  Constraint* const constraint) = 0;
1605  Constraint* const parent, Constraint* const nested) = 0;
1607  Constraint* const parent, Constraint* const nested) = 0;
1608  virtual void RegisterDemon(Demon* const demon) = 0;
1609  virtual void BeginDemonRun(Demon* const demon) = 0;
1610  virtual void EndDemonRun(Demon* const demon) = 0;
1611  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1612  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1613  virtual void PushContext(const std::string& context) = 0;
1614  virtual void PopContext() = 0;
1616  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1617  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1618  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1620  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1621  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1622  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1623  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1624  virtual void SetValue(IntVar* const var, int64 value) = 0;
1625  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1626  virtual void SetValues(IntVar* const var,
1627  const std::vector<int64>& values) = 0;
1628  virtual void RemoveValues(IntVar* const var,
1629  const std::vector<int64>& values) = 0;
1631  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1632  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1633  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1634  int64 new_max) = 0;
1635  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1636  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1637  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1638  int64 new_max) = 0;
1639  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1640  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1641  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1642  int64 new_max) = 0;
1643  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1645  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1646  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1647  virtual void RankLast(SequenceVar* const var, int index) = 0;
1648  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1649  virtual void RankSequence(SequenceVar* const var,
1650  const std::vector<int>& rank_first,
1651  const std::vector<int>& rank_last,
1652  const std::vector<int>& unperformed) = 0;
1654  void Install() override;
1655 };
1656 
1658  // TODO(user): Add monitoring of local search filters.
1659  public:
1660  explicit LocalSearchMonitor(Solver* const solver);
1661  ~LocalSearchMonitor() override;
1662  std::string DebugString() const override { return "LocalSearchMonitor"; }
1663 
1665  virtual void BeginOperatorStart() = 0;
1666  virtual void EndOperatorStart() = 0;
1667  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1668  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1669  bool neighbor_found, const Assignment* delta,
1670  const Assignment* deltadelta) = 0;
1671  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1672  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1673  bool neighbor_found) = 0;
1674  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1675  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1676  bool neighbor_found) = 0;
1677  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1678  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1679 
1681  void Install() override;
1682 };
1683 
1684 class BooleanVar : public IntVar {
1685  public:
1686  static const int kUnboundBooleanVarValue;
1687 
1688  explicit BooleanVar(Solver* const s, const std::string& name = "")
1690 
1691  ~BooleanVar() override {}
1692 
1693  int64 Min() const override { return (value_ == 1); }
1694  void SetMin(int64 m) override;
1695  int64 Max() const override { return (value_ != 0); }
1696  void SetMax(int64 m) override;
1697  void SetRange(int64 mi, int64 ma) override;
1698  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1699  int64 Value() const override {
1700  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1701  return value_;
1702  }
1703  void RemoveValue(int64 v) override;
1704  void RemoveInterval(int64 l, int64 u) override;
1705  void WhenBound(Demon* d) override;
1706  void WhenRange(Demon* d) override { WhenBound(d); }
1707  void WhenDomain(Demon* d) override { WhenBound(d); }
1708  uint64 Size() const override;
1709  bool Contains(int64 v) const override;
1710  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1711  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1712  std::string DebugString() const override;
1713  int VarType() const override { return BOOLEAN_VAR; }
1714 
1715  IntVar* IsEqual(int64 constant) override;
1716  IntVar* IsDifferent(int64 constant) override;
1717  IntVar* IsGreaterOrEqual(int64 constant) override;
1718  IntVar* IsLessOrEqual(int64 constant) override;
1719 
1720  virtual void RestoreValue() = 0;
1721  std::string BaseName() const override { return "BooleanVar"; }
1722 
1723  int RawValue() const { return value_; }
1724 
1725  protected:
1726  int value_;
1729 };
1730 
1731 class SymmetryManager;
1732 
1737  public:
1739  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1740  ~SymmetryBreaker() override {}
1741 
1742  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
1744  int64 value);
1745  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
1746 
1747  private:
1748  friend class SymmetryManager;
1749  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
1750  CHECK(symmetry_manager_ == nullptr);
1751  CHECK_EQ(-1, index_in_symmetry_manager_);
1752  symmetry_manager_ = manager;
1753  index_in_symmetry_manager_ = index;
1754  }
1755  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
1756  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
1757 
1758  SymmetryManager* symmetry_manager_;
1760  int index_in_symmetry_manager_;
1761 };
1762 
1765 class SearchLog : public SearchMonitor {
1766  public:
1767  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
1768  double scaling_factor, double offset,
1769  std::function<std::string()> display_callback, int period);
1770  ~SearchLog() override;
1771  void EnterSearch() override;
1772  void ExitSearch() override;
1773  bool AtSolution() override;
1774  void BeginFail() override;
1775  void NoMoreSolutions() override;
1776  void AcceptUncheckedNeighbor() override;
1777  void ApplyDecision(Decision* const decision) override;
1778  void RefuteDecision(Decision* const decision) override;
1779  void OutputDecision();
1780  void Maintain();
1781  void BeginInitialPropagation() override;
1782  void EndInitialPropagation() override;
1783  std::string DebugString() const override;
1784 
1785  protected:
1786  /* Bottleneck function used for all UI related output. */
1787  virtual void OutputLine(const std::string& line);
1788 
1789  private:
1790  static std::string MemoryUsage();
1791 
1792  const int period_;
1793  std::unique_ptr<WallTimer> timer_;
1794  IntVar* const var_;
1795  OptimizeVar* const obj_;
1796  const double scaling_factor_;
1797  const double offset_;
1798  std::function<std::string()> display_callback_;
1799  int nsol_;
1800  int64 tick_;
1801  int64 objective_min_;
1802  int64 objective_max_;
1803  int min_right_depth_;
1804  int max_depth_;
1805  int sliding_min_depth_;
1806  int sliding_max_depth_;
1807 };
1808 
1813 class ModelCache {
1814  public:
1819  };
1820 
1827  };
1828 
1832  };
1833 
1842  };
1843 
1849  };
1850 
1863  };
1864 
1868  };
1869 
1882  };
1886  };
1887 
1891  };
1892 
1896  };
1897 
1903  };
1904 
1908  };
1909 
1910  explicit ModelCache(Solver* const solver);
1911  virtual ~ModelCache();
1912 
1913  virtual void Clear() = 0;
1914 
1916 
1917  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
1918 
1919  virtual void InsertVoidConstraint(Constraint* const ct,
1920  VoidConstraintType type) = 0;
1921 
1924  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
1925 
1926  virtual void InsertVarConstantConstraint(Constraint* const ct,
1927  IntVar* const var, int64 value,
1928  VarConstantConstraintType type) = 0;
1929 
1931 
1933  IntVar* const var, int64 value1, int64 value2,
1934  VarConstantConstantConstraintType type) const = 0;
1935 
1937  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
1939 
1941 
1943  IntExpr* const expr1, IntExpr* const expr2,
1944  ExprExprConstraintType type) const = 0;
1945 
1946  virtual void InsertExprExprConstraint(Constraint* const ct,
1947  IntExpr* const expr1,
1948  IntExpr* const expr2,
1949  ExprExprConstraintType type) = 0;
1950 
1952 
1953  virtual IntExpr* FindExprExpression(IntExpr* const expr,
1954  ExprExpressionType type) const = 0;
1955 
1956  virtual void InsertExprExpression(IntExpr* const expression,
1957  IntExpr* const expr,
1958  ExprExpressionType type) = 0;
1959 
1961 
1963  IntExpr* const expr, int64 value,
1964  ExprConstantExpressionType type) const = 0;
1965 
1966  virtual void InsertExprConstantExpression(
1967  IntExpr* const expression, IntExpr* const var, int64 value,
1968  ExprConstantExpressionType type) = 0;
1969 
1971 
1973  IntExpr* const var1, IntExpr* const var2,
1974  ExprExprExpressionType type) const = 0;
1975 
1976  virtual void InsertExprExprExpression(IntExpr* const expression,
1977  IntExpr* const var1,
1978  IntExpr* const var2,
1979  ExprExprExpressionType type) = 0;
1980 
1982 
1984  IntExpr* const var1, IntExpr* const var2, int64 constant,
1985  ExprExprConstantExpressionType type) const = 0;
1986 
1987  virtual void InsertExprExprConstantExpression(
1988  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
1989  int64 constant, ExprExprConstantExpressionType type) = 0;
1990 
1992 
1994  IntVar* const var, int64 value1, int64 value2,
1995  VarConstantConstantExpressionType type) const = 0;
1996 
1998  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2000 
2002 
2004  IntVar* const var, const std::vector<int64>& values,
2005  VarConstantArrayExpressionType type) const = 0;
2006 
2007  virtual void InsertVarConstantArrayExpression(
2008  IntExpr* const expression, IntVar* const var,
2009  const std::vector<int64>& values,
2011 
2013 
2015  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2016 
2017  virtual void InsertVarArrayExpression(IntExpr* const expression,
2018  const std::vector<IntVar*>& vars,
2019  VarArrayExpressionType type) = 0;
2020 
2022 
2024  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2025  VarArrayConstantArrayExpressionType type) const = 0;
2026 
2028  IntExpr* const expression, const std::vector<IntVar*>& var,
2029  const std::vector<int64>& values,
2031 
2033 
2035  const std::vector<IntVar*>& vars, int64 value,
2036  VarArrayConstantExpressionType type) const = 0;
2037 
2038  virtual void InsertVarArrayConstantExpression(
2039  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2041 
2042  Solver* solver() const;
2043 
2044  private:
2045  Solver* const solver_;
2046 };
2047 
2049 #if !defined(SWIG)
2051  public:
2053  const std::string& TypeName() const;
2054  void SetTypeName(const std::string& type_name);
2055 
2057  void SetIntegerArgument(const std::string& arg_name, int64 value);
2058  void SetIntegerArrayArgument(const std::string& arg_name,
2059  const std::vector<int64>& values);
2060  void SetIntegerMatrixArgument(const std::string& arg_name,
2061  const IntTupleSet& values);
2062  void SetIntegerExpressionArgument(const std::string& arg_name,
2063  IntExpr* const expr);
2064  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2065  const std::vector<IntVar*>& vars);
2066  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2067  void SetIntervalArrayArgument(const std::string& arg_name,
2068  const std::vector<IntervalVar*>& vars);
2069  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2070  void SetSequenceArrayArgument(const std::string& arg_name,
2071  const std::vector<SequenceVar*>& vars);
2072 
2074  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2075  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2076 
2078  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2079  int64 def) const;
2080  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2081  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2082  const std::string& arg_name) const;
2083  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2084  const std::string& arg_name) const;
2085 
2087  const std::string& arg_name) const;
2088  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2089  const std::string& arg_name) const;
2090 
2091  private:
2092  std::string type_name_;
2093  absl::flat_hash_map<std::string, int64> integer_argument_;
2094  absl::flat_hash_map<std::string, std::vector<int64> > integer_array_argument_;
2095  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2096  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2097  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2098  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2099  absl::flat_hash_map<std::string, std::vector<IntVar*> >
2100  integer_variable_array_argument_;
2101  absl::flat_hash_map<std::string, std::vector<IntervalVar*> >
2102  interval_array_argument_;
2103  absl::flat_hash_map<std::string, std::vector<SequenceVar*> >
2104  sequence_array_argument_;
2105 };
2106 
2108 class ModelParser : public ModelVisitor {
2109  public:
2110  ModelParser();
2111 
2112  ~ModelParser() override;
2113 
2115  void BeginVisitModel(const std::string& solver_name) override;
2116  void EndVisitModel(const std::string& solver_name) override;
2117  void BeginVisitConstraint(const std::string& type_name,
2118  const Constraint* const constraint) override;
2119  void EndVisitConstraint(const std::string& type_name,
2120  const Constraint* const constraint) override;
2121  void BeginVisitIntegerExpression(const std::string& type_name,
2122  const IntExpr* const expr) override;
2123  void EndVisitIntegerExpression(const std::string& type_name,
2124  const IntExpr* const expr) override;
2125  void VisitIntegerVariable(const IntVar* const variable,
2126  IntExpr* const delegate) override;
2127  void VisitIntegerVariable(const IntVar* const variable,
2128  const std::string& operation, int64 value,
2129  IntVar* const delegate) override;
2130  void VisitIntervalVariable(const IntervalVar* const variable,
2131  const std::string& operation, int64 value,
2132  IntervalVar* const delegate) override;
2133  void VisitSequenceVariable(const SequenceVar* const variable) override;
2135  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2136  void VisitIntegerArrayArgument(const std::string& arg_name,
2137  const std::vector<int64>& values) override;
2138  void VisitIntegerMatrixArgument(const std::string& arg_name,
2139  const IntTupleSet& values) override;
2141  void VisitIntegerExpressionArgument(const std::string& arg_name,
2142  IntExpr* const argument) override;
2144  const std::string& arg_name,
2145  const std::vector<IntVar*>& arguments) override;
2147  void VisitIntervalArgument(const std::string& arg_name,
2148  IntervalVar* const argument) override;
2150  const std::string& arg_name,
2151  const std::vector<IntervalVar*>& arguments) override;
2153  void VisitSequenceArgument(const std::string& arg_name,
2154  SequenceVar* const argument) override;
2156  const std::string& arg_name,
2157  const std::vector<SequenceVar*>& arguments) override;
2158 
2159  protected:
2160  void PushArgumentHolder();
2161  void PopArgumentHolder();
2162  ArgumentHolder* Top() const;
2163 
2164  private:
2165  std::vector<ArgumentHolder*> holders_;
2166 };
2167 
2168 template <class T>
2169 class ArrayWithOffset : public BaseObject {
2170  public:
2171  ArrayWithOffset(int64 index_min, int64 index_max)
2172  : index_min_(index_min),
2173  index_max_(index_max),
2174  values_(new T[index_max - index_min + 1]) {
2175  DCHECK_LE(index_min, index_max);
2176  }
2177 
2178  ~ArrayWithOffset() override {}
2179 
2180  virtual T Evaluate(int64 index) const {
2181  DCHECK_GE(index, index_min_);
2182  DCHECK_LE(index, index_max_);
2183  return values_[index - index_min_];
2184  }
2185 
2186  void SetValue(int64 index, T value) {
2187  DCHECK_GE(index, index_min_);
2188  DCHECK_LE(index, index_max_);
2189  values_[index - index_min_] = value;
2190  }
2191 
2192  std::string DebugString() const override { return "ArrayWithOffset"; }
2193 
2194  private:
2195  const int64 index_min_;
2196  const int64 index_max_;
2197  std::unique_ptr<T[]> values_;
2198 };
2199 #endif // SWIG
2200 
2205 template <class T, class C>
2207  public:
2208  explicit RevGrowingArray(int64 block_size)
2209  : block_size_(block_size), block_offset_(0) {
2210  CHECK_GT(block_size, 0);
2211  }
2212 
2214  for (int i = 0; i < elements_.size(); ++i) {
2215  delete[] elements_[i];
2216  }
2217  }
2218 
2219  T At(int64 index) const {
2220  const int64 block_index = ComputeBlockIndex(index);
2221  const int64 relative_index = block_index - block_offset_;
2222  if (relative_index < 0 || relative_index >= elements_.size()) {
2223  return T();
2224  }
2225  const T* block = elements_[relative_index];
2226  return block != nullptr ? block[index - block_index * block_size_] : T();
2227  }
2228 
2229  void RevInsert(Solver* const solver, int64 index, T value) {
2230  const int64 block_index = ComputeBlockIndex(index);
2231  T* const block = GetOrCreateBlock(block_index);
2232  const int64 residual = index - block_index * block_size_;
2233  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2234  reinterpret_cast<C>(value));
2235  }
2236 
2237  private:
2238  T* NewBlock() const {
2239  T* const result = new T[block_size_];
2240  for (int i = 0; i < block_size_; ++i) {
2241  result[i] = T();
2242  }
2243  return result;
2244  }
2245 
2246  T* GetOrCreateBlock(int block_index) {
2247  if (elements_.size() == 0) {
2248  block_offset_ = block_index;
2249  GrowUp(block_index);
2250  } else if (block_index < block_offset_) {
2251  GrowDown(block_index);
2252  } else if (block_index - block_offset_ >= elements_.size()) {
2253  GrowUp(block_index);
2254  }
2255  T* block = elements_[block_index - block_offset_];
2256  if (block == nullptr) {
2257  block = NewBlock();
2258  elements_[block_index - block_offset_] = block;
2259  }
2260  return block;
2261  }
2262 
2263  int64 ComputeBlockIndex(int64 value) const {
2264  return value >= 0 ? value / block_size_
2265  : (value - block_size_ + 1) / block_size_;
2266  }
2267 
2268  void GrowUp(int64 block_index) {
2269  elements_.resize(block_index - block_offset_ + 1);
2270  }
2271 
2272  void GrowDown(int64 block_index) {
2273  const int64 delta = block_offset_ - block_index;
2274  block_offset_ = block_index;
2275  DCHECK_GT(delta, 0);
2276  elements_.insert(elements_.begin(), delta, nullptr);
2277  }
2278 
2279  const int64 block_size_;
2280  std::vector<T*> elements_;
2281  int block_offset_;
2282 };
2283 
2288 template <class T>
2289 class RevIntSet {
2290  public:
2291  static const int kNoInserted = -1;
2292 
2294  explicit RevIntSet(int capacity)
2295  : elements_(new T[capacity]),
2296  num_elements_(0),
2297  capacity_(capacity),
2298  position_(new int[capacity]),
2299  delete_position_(true) {
2300  for (int i = 0; i < capacity; ++i) {
2301  position_[i] = kNoInserted;
2302  }
2303  }
2304 
2306  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2307  : elements_(new T[capacity]),
2308  num_elements_(0),
2309  capacity_(capacity),
2310  position_(shared_positions),
2311  delete_position_(false) {
2312  for (int i = 0; i < shared_positions_size; ++i) {
2313  position_[i] = kNoInserted;
2314  }
2315  }
2316 
2318  if (delete_position_) {
2319  delete[] position_;
2320  }
2321  }
2322 
2323  int Size() const { return num_elements_.Value(); }
2324 
2325  int Capacity() const { return capacity_; }
2326 
2327  T Element(int i) const {
2328  DCHECK_GE(i, 0);
2329  DCHECK_LT(i, num_elements_.Value());
2330  return elements_[i];
2331  }
2332 
2333  T RemovedElement(int i) const {
2334  DCHECK_GE(i, 0);
2335  DCHECK_LT(i + num_elements_.Value(), capacity_);
2336  return elements_[i + num_elements_.Value()];
2337  }
2338 
2339  void Insert(Solver* const solver, const T& elt) {
2340  const int position = num_elements_.Value();
2341  DCHECK_LT(position, capacity_);
2342  DCHECK(NotAlreadyInserted(elt));
2343  elements_[position] = elt;
2344  position_[elt] = position;
2345  num_elements_.Incr(solver);
2346  }
2347 
2348  void Remove(Solver* const solver, const T& value_index) {
2349  num_elements_.Decr(solver);
2350  SwapTo(value_index, num_elements_.Value());
2351  }
2352 
2353  void Restore(Solver* const solver, const T& value_index) {
2354  SwapTo(value_index, num_elements_.Value());
2355  num_elements_.Incr(solver);
2356  }
2357 
2358  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2359 
2361  typedef const T* const_iterator;
2362  const_iterator begin() const { return elements_.get(); }
2363  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2364 
2365  private:
2367  bool NotAlreadyInserted(const T& elt) {
2368  for (int i = 0; i < num_elements_.Value(); ++i) {
2369  if (elt == elements_[i]) {
2370  return false;
2371  }
2372  }
2373  return true;
2374  }
2375 
2376  void SwapTo(T value_index, int next_position) {
2377  const int current_position = position_[value_index];
2378  if (current_position != next_position) {
2379  const T next_value_index = elements_[next_position];
2380  elements_[current_position] = next_value_index;
2381  elements_[next_position] = value_index;
2382  position_[value_index] = next_position;
2383  position_[next_value_index] = current_position;
2384  }
2385  }
2386 
2388  std::unique_ptr<T[]> elements_;
2390  NumericalRev<int> num_elements_;
2392  const int capacity_;
2394  int* position_;
2396  const bool delete_position_;
2397 };
2398 
2400 
2402  public:
2403  explicit RevPartialSequence(const std::vector<int>& items)
2404  : elements_(items),
2405  first_ranked_(0),
2406  last_ranked_(items.size() - 1),
2407  size_(items.size()),
2408  position_(new int[size_]) {
2409  for (int i = 0; i < size_; ++i) {
2410  elements_[i] = items[i];
2411  position_[i] = i;
2412  }
2413  }
2414 
2415  explicit RevPartialSequence(int size)
2416  : elements_(size),
2417  first_ranked_(0),
2418  last_ranked_(size - 1),
2419  size_(size),
2420  position_(new int[size_]) {
2421  for (int i = 0; i < size_; ++i) {
2422  elements_[i] = i;
2423  position_[i] = i;
2424  }
2425  }
2426 
2428 
2429  int NumFirstRanked() const { return first_ranked_.Value(); }
2430 
2431  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2432 
2433  int Size() const { return size_; }
2434 
2435 #if !defined(SWIG)
2436  const int& operator[](int index) const {
2437  DCHECK_GE(index, 0);
2438  DCHECK_LT(index, size_);
2439  return elements_[index];
2440  }
2441 #endif
2442 
2443  void RankFirst(Solver* const solver, int elt) {
2444  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2445  SwapTo(elt, first_ranked_.Value());
2446  first_ranked_.Incr(solver);
2447  }
2448 
2449  void RankLast(Solver* const solver, int elt) {
2450  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2451  SwapTo(elt, last_ranked_.Value());
2452  last_ranked_.Decr(solver);
2453  }
2454 
2455  bool IsRanked(int elt) const {
2456  const int position = position_[elt];
2457  return (position < first_ranked_.Value() ||
2458  position > last_ranked_.Value());
2459  }
2460 
2461  std::string DebugString() const {
2462  std::string result = "[";
2463  for (int i = 0; i < first_ranked_.Value(); ++i) {
2464  absl::StrAppend(&result, elements_[i]);
2465  if (i != first_ranked_.Value() - 1) {
2466  result.append("-");
2467  }
2468  }
2469  result.append("|");
2470  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2471  absl::StrAppend(&result, elements_[i]);
2472  if (i != last_ranked_.Value()) {
2473  result.append("-");
2474  }
2475  }
2476  result.append("|");
2477  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2478  absl::StrAppend(&result, elements_[i]);
2479  if (i != size_ - 1) {
2480  result.append("-");
2481  }
2482  }
2483  result.append("]");
2484  return result;
2485  }
2486 
2487  private:
2488  void SwapTo(int elt, int next_position) {
2489  const int current_position = position_[elt];
2490  if (current_position != next_position) {
2491  const int next_elt = elements_[next_position];
2492  elements_[current_position] = next_elt;
2493  elements_[next_position] = elt;
2494  position_[elt] = next_position;
2495  position_[next_elt] = current_position;
2496  }
2497  }
2498 
2500  std::vector<int> elements_;
2502  NumericalRev<int> first_ranked_;
2504  NumericalRev<int> last_ranked_;
2506  const int size_;
2508  std::unique_ptr<int[]> position_;
2509 };
2510 
2516  public:
2518  explicit UnsortedNullableRevBitset(int bit_size);
2519 
2521 
2524  void Init(Solver* const solver, const std::vector<uint64>& mask);
2525 
2528  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2529 
2532  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2533 
2536  int ActiveWordSize() const { return active_words_.Size(); }
2537 
2539  bool Empty() const { return active_words_.Size() == 0; }
2540 
2548  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2549 
2551  int64 bit_size() const { return bit_size_; }
2553  int64 word_size() const { return word_size_; }
2555  const RevIntSet<int>& active_words() const { return active_words_; }
2556 
2557  private:
2558  void CleanUpActives(Solver* const solver);
2559 
2560  const int64 bit_size_;
2561  const int64 word_size_;
2562  RevArray<uint64> bits_;
2563  RevIntSet<int> active_words_;
2564  std::vector<int> to_remove_;
2565 };
2566 
2567 template <class T>
2568 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2569  for (int i = 0; i < values.size(); ++i) {
2570  if (values[i] != value) {
2571  return false;
2572  }
2573  }
2574  return true;
2575 }
2576 
2577 template <class T>
2578 bool IsArrayBoolean(const std::vector<T>& values) {
2579  for (int i = 0; i < values.size(); ++i) {
2580  if (values[i] != 0 && values[i] != 1) {
2581  return false;
2582  }
2583  }
2584  return true;
2585 }
2586 
2587 template <class T>
2588 bool AreAllOnes(const std::vector<T>& values) {
2589  return IsArrayConstant(values, T(1));
2590 }
2591 
2592 template <class T>
2593 bool AreAllNull(const std::vector<T>& values) {
2594  return IsArrayConstant(values, T(0));
2595 }
2596 
2597 template <class T>
2598 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2599  for (const T& current_value : values) {
2600  if (current_value < value) {
2601  return false;
2602  }
2603  }
2604  return true;
2605 }
2606 
2607 template <class T>
2608 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2609  for (const T& current_value : values) {
2610  if (current_value > value) {
2611  return false;
2612  }
2613  }
2614  return true;
2615 }
2616 
2617 template <class T>
2618 bool AreAllPositive(const std::vector<T>& values) {
2619  return AreAllGreaterOrEqual(values, T(0));
2620 }
2621 
2622 template <class T>
2623 bool AreAllNegative(const std::vector<T>& values) {
2624  return AreAllLessOrEqual(values, T(0));
2625 }
2626 
2627 template <class T>
2628 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2629  return AreAllGreaterOrEqual(values, T(1));
2630 }
2631 
2632 template <class T>
2633 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2634  return AreAllLessOrEqual(values, T(-1));
2635 }
2636 
2637 template <class T>
2638 bool IsIncreasingContiguous(const std::vector<T>& values) {
2639  for (int i = 0; i < values.size() - 1; ++i) {
2640  if (values[i + 1] != values[i] + 1) {
2641  return false;
2642  }
2643  }
2644  return true;
2645 }
2646 
2647 template <class T>
2648 bool IsIncreasing(const std::vector<T>& values) {
2649  for (int i = 0; i < values.size() - 1; ++i) {
2650  if (values[i + 1] < values[i]) {
2651  return false;
2652  }
2653  }
2654  return true;
2655 }
2656 
2657 template <class T>
2658 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2659  T range_max) {
2660  for (int i = 0; i < vars.size(); ++i) {
2661  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2662  return false;
2663  }
2664  }
2665  return true;
2666 }
2667 
2668 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2669  for (int i = 0; i < vars.size(); ++i) {
2670  if (!vars[i]->Bound()) {
2671  return false;
2672  }
2673  }
2674  return true;
2675 }
2676 
2677 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2678  return IsArrayInRange(vars, 0, 1);
2679 }
2680 
2683 template <class T>
2684 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2685  const std::vector<T>& values) {
2686  for (int i = 0; i < vars.size(); ++i) {
2687  if (values[i] != 0 && !vars[i]->Bound()) {
2688  return false;
2689  }
2690  }
2691  return true;
2692 }
2693 
2695 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2696  for (int i = 0; i < vars.size(); ++i) {
2697  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2698  return false;
2699  }
2700  }
2701  return true;
2702 }
2703 
2704 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2705  DCHECK(!vars.empty());
2706  int64 result = kint64min;
2707  for (int i = 0; i < vars.size(); ++i) {
2709  result = std::max<int64>(result, vars[i]->Max());
2710  }
2711  return result;
2712 }
2713 
2714 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2715  DCHECK(!vars.empty());
2716  int64 result = kint64max;
2717  for (int i = 0; i < vars.size(); ++i) {
2719  result = std::min<int64>(result, vars[i]->Min());
2720  }
2721  return result;
2722 }
2723 
2724 inline void FillValues(const std::vector<IntVar*>& vars,
2725  std::vector<int64>* const values) {
2726  values->clear();
2727  values->resize(vars.size());
2728  for (int i = 0; i < vars.size(); ++i) {
2729  (*values)[i] = vars[i]->Value();
2730  }
2731 }
2732 
2733 inline int64 PosIntDivUp(int64 e, int64 v) {
2734  DCHECK_GT(v, 0);
2735  if (e >= 0) {
2736  return e % v == 0 ? e / v : e / v + 1;
2737  } else {
2738  return e / v;
2739  }
2740 }
2741 
2742 inline int64 PosIntDivDown(int64 e, int64 v) {
2743  DCHECK_GT(v, 0);
2744  if (e >= 0) {
2745  return e / v;
2746  } else {
2747  return e % v == 0 ? e / v : e / v - 1;
2748  }
2749 }
2750 
2751 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
2752 } // namespace operations_research
2753 
2754 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
Implements a complete cache for model elements: expressions and constraints.
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
void SetBackwardSequence(const std::vector< int > &backward_sequence)
bool ValueFromAssignent(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type)=0
void NoMoreSolutions() override
When the search tree is finished.
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
void Synchronize(const Assignment *assignment, const Assignment *delta) override
Synchronizes all filters to assignment.
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values) override
void Remove(Solver *const solver, const T &value_index)
void OnNodeInitialization() override
Called by OnStart() after initializing node information.
virtual void OnSynchronize(const Assignment *delta)
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
void RemoveValue(int64 v) override
This method removes the value 'v' from the domain of the variable.
int64 StartNode(int i) const
Returns the index of the variable corresponding to the current path of the ith base node.
bool IsPathEnd(int64 i) const
Returns true if i is the last node on the path; defined by the fact that i outside the range of the v...
IntVar * Var() override
Creates a variable from the expression.
int64 size() const
Returns the number of interval vars in the sequence.
bool AreAllBoundOrNull(const std::vector< IntVar * > &vars, const std::vector< T > &values)
Returns true if all the variables are assigned to a single value, or if their corresponding value is ...
const T * const_iterator
Iterators on the indices.
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars)
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
std::string DebugString() const override
Low-priority demon proxy to a method on the constraint with two arguments.
bool FindIndex(IntVar *const var, int64 *index) const
void SetBackwardSequence(int64 index, const std::vector< int > &value)
void SetLastValue(const T &v)
Sets the last value in the FIFO.
const std::vector< int > & Sequence(int64 index) const
Returns the value in the current assignment of the variable of given index.
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
void SetTypeName(const std::string &type_name)
std::string DebugString() const override
This class represent a reversible FIFO structure.
Matrix version of the RevBitSet class.
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
bool IsInactive(int64 i) const
Returns true if node is inactive.
bool IsArrayBoolean(const std::vector< T > &values)
const std::string & TypeName() const
Type of the argument.
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
PathWithPreviousNodesOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, int number_of_base_nodes, std::function< int(int64)> start_empty_path_class)
bool MakeActive(int64 node, int64 destination)
void EnterSearch() override
Beginning of the search.
virtual void SetValue(IntVar *const var, int64 value)=0
bool AreAllStrictlyNegative(const std::vector< T > &values)
Base operator class for operators manipulating variables.
void SetNext(int64 from, int64 to, int64 path)
Sets the to to be the node after from.
bool Empty() const
This method returns true if the active bitset is null.
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
IntVarIterator * MakeDomainIterator(bool reversible) const override
Creates a domain iterator.
void SetToOne(Solver *const solver, int64 row, int64 column)
Sets the 'column' bit in the 'row' row.
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type)=0
virtual void PushContext(const std::string &context)=0
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
const V & FindWithDefault(const K &key, const V &default_value) const
Returns one value attached to 'key', or 'default_value' if 'key' is not in the multi-map.
void VisitIntegerArgument(const std::string &arg_name, int64 value) override
Integer arguments.
void ClearAll(Solver *const solver)
Cleans all bits.
int index() const
Returns the index of the variable.
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
virtual int64 GetBaseNodeRestartPosition(int base_index)
Returns the index of the node to which the base node of index base_index must be set to when it reach...
Demon proxy to a method on the constraint with no arguments.
void Push(Solver *const s, T val)
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
void Restore(Solver *const solver, const T &value_index)
void SetToOne(Solver *const solver, int64 index)
Sets the 'index' bit.
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, std::function< int(int64)> start_empty_path_class)
Builds an instance of PathOperator from next and path variables.
void Run(Solver *const s) override
This is the main callback of the demon.
const SequenceContainer & SequenceVarContainer() const
virtual bool OnSamePathAsPreviousBase(int64 base_index)
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
virtual void RankLast(SequenceVar *const var, int index)=0
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type)=0
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
This class encapsulates an objective.
bool Contains(int64 v) const override
This method returns whether the value 'v' is in the domain of the variable.
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, double offset, std::function< std::string()> display_callback, int period)
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
void VisitSequenceVariable(const SequenceVar *const variable) override
This is the base class for all expressions that are not variables.
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
The base class of all search logs that periodically outputs information when the search is running.
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
virtual void EndDemonRun(Demon *const demon)=0
void RankFirst(Solver *const solver, int elt)
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
void Clear(Solver *const solver)
void EndVisitModel(const std::string &solver_name) override
const T & LastValue() const
Returns the last value in the FIFO.
std::string DebugString() const override
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
int64 PosIntDivUp(int64 e, int64 v)
int64 Path(int64 node_index) const
Returns the index of the path to which the node of index node_index belongs in the current assignment...
std::string DebugString() const override
Demon proxy to a method on the constraint with three arguments.
void SetToZero(Solver *const solver, int64 index)
Erases the 'index' bit.
A Demon is the base element of a propagation queue.
bool RevSubtract(Solver *const solver, const std::vector< uint64 > &mask)
This method subtracts the mask from the active bitset.
Low-priority demon proxy to a method on the constraint with one argument.
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
bool ValueFromAssignent(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
void Run(Solver *const s) override
This is the main callback of the demon.
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
IntVar * IsGreaterOrEqual(int64 constant) override
uint64 Hash1(uint64 value)
Hash functions.
void AddVars(const std::vector< V * > &vars)
BaseLns(const std::vector< IntVar * > &vars)
std::string DebugString() const override
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
virtual int64 GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
std::string BaseName() const override
Returns a base name for automatic naming.
virtual void BeginOperatorStart()=0
Local search operator events.
bool SkipUnchanged(int index) const override
int64 word_size() const
Returns the number of 64 bit words used to store the bitset.
bool RevAnd(Solver *const solver, const std::vector< uint64 > &mask)
This method ANDs the mask with the active bitset.
void SetForwardSequence(int64 index, const std::vector< int > &value)
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
bool HasFragments() const override
virtual void SetMax(IntExpr *const expr, int64 new_max)=0
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
bool IsCardinalityZero() const
Is bitset null?
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
void SetToZero(Solver *const solver, int64 pos)
Erases the 'pos' bit.
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type)=0
void Run(Solver *const s) override
This is the main callback of the demon.
const std::vector< int > & ForwardSequence() const
This iterator is not stable with respect to deletion.
virtual void SetValues(IntVar *const var, const std::vector< int64 > &values)=0
bool AreAllBooleans(const std::vector< IntVar * > &vars)
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void SetMin(int64 m) override
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64 value, VarConstantConstraintType type) const =0
Var Constant Constraints.
const E & Element(const V *const var) const
virtual T Evaluate(int64 index) const
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
int64 OldPath(int64 node_index) const
int64 Next(int64 node_index) const
Returns the index of the node after the node of index node_index in the current assignment.
LocalSearchFilterManager(Solver *const solver, const std::vector< LocalSearchFilter * > &filters)
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
RevImmutableMultiMap(Solver *const solver, int initial_size)
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
Argument Holder: useful when visiting a model.
const T * Last() const
Returns the last item of the FIFO.
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
void SetValue(Solver *const s, const T &val)
SimpleRevFIFO< Demon * > delayed_bound_demons_
ModelCache(Solver *const solver)
virtual void RankNotLast(SequenceVar *const var, int index)=0
void RemoveInterval(int64 l, int64 u) override
This method removes the interval 'l' .
bool IsCardinalityZero() const
Is bitset null?
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
int64 GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
int64 Value() const override
This method returns the value of the variable.
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
void EndInitialPropagation() override
After the initial propagation.
virtual int64 GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
ArgumentHolder * Top() const
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
VarTypes
This enum is used internally to do dynamic typing on subclasses of integer variables.
virtual void RankNotFirst(SequenceVar *const var, int index)=0
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
virtual void RemoveValue(IntVar *const var, int64 value)=0
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
void BeginFail() override
Just when the failure occurs.
const std::vector< int64 > & path_starts() const
Returns the vector of path start nodes.
int64 OldNext(int64 node_index) const
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
RevPartialSequence(const std::vector< int > &items)
void Run(Solver *const s) override
This is the main callback of the demon.
int64 Cardinality() const
Returns the number of bits set to one.
std::string DebugString() const override
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64 value)
Simple PathOperator wrapper that also stores the current previous nodes, and is thus able to provide ...
void Init(Solver *const solver, const std::vector< uint64 > &mask)
This methods overwrites the active bitset with the mask.
bool AreAllStrictlyPositive(const std::vector< T > &values)
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
std::string ParameterDebugString(P param)
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64 value, ExprConstantExpressionType type)=0
This is a special class to represent a 'residual' set of T.
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
const IntContainer & IntVarContainer() const
virtual bool SkipUnchanged(int index) const
void Install() override
Install itself on the solver.
bool IsCardinalityOne() const
Does it contains only one bit set?
SimpleRevFIFO< Demon * > bound_demons_
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64 value, IntervalVar *const delegate) override
bool ReverseChain(int64 before_chain, int64 after_chain, int64 *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
V * Var(int64 index) const
Returns the variable of given index.
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0
bool IsIncreasingContiguous(const std::vector< T > &values)
Local Search Filters are used for fast neighbor pruning.
virtual void Start(const Assignment *assignment)=0
SequenceContainer * MutableSequenceVarContainer()
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
int64 MinVarArray(const std::vector< IntVar * > &vars)
std::string DebugString() const override
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
bool MoveChain(int64 before_chain, int64 chain_end, int64 destination)
Moves the chain starting after the node before_chain and ending at the node chain_end after the node ...
A constraint is the main modeling object.
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
virtual void SetMin(IntExpr *const expr, int64 new_min)=0
IntExpr modifiers.
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
bool IsArrayConstant(const std::vector< T > &values, const T &value)
std::vector< int64 > ToInt64Vector(const std::vector< int > &input)
bool AreAllOnes(const std::vector< T > &values)
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
virtual std::string name() const
Object naming.
This class represents a small reversible bitset (size <= 64).
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
void Run(Solver *const s) override
This is the main callback of the demon.
Demon proxy to a method on the constraint with two arguments.
bool AreAllNegative(const std::vector< T > &values)
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
virtual bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
const int & operator[](int index) const
Low-priority demon proxy to a method on the constraint with no arguments.
void ExitSearch() override
End of the search.
A DecisionVisitor is used to inspect a decision.
int64 bit_size() const
Returns the number of bits given in the constructor of the bitset.
VarLocalSearchOperator(std::vector< V * > vars, Handler var_handler)
void SetToZero(Solver *const solver, int64 row, int64 column)
Erases the 'column' bit in the 'row' row.
void BeginInitialPropagation() override
Before the initial propagation.
void SetValue(int64 index, const Val &value)
virtual void OutputLine(const std::string &line)
IntVar * IsDifferent(int64 constant) override
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
std::string DebugString() const override
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
LocalSearchMonitor(Solver *const solver)
void RefuteDecision(Decision *const decision) override
Before refuting the decision.
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
virtual const LocalSearchOperator * Self() const
This class is a reversible growing array.
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
bool AreAllBound(const std::vector< IntVar * > &vars)
void MarkChange(int64 index)
OnStart() should really be protected, but then SWIG doesn't see it.
int64 BaseNode(int i) const
Returns the index of the variable corresponding to the ith base node.
RevBitMatrix(int64 rows, int64 columns)
int PathClass(int i) const
Returns the class of the current path of the ith base node.
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
virtual void BeginDemonRun(Demon *const demon)=0
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
void Run(Solver *const s) override
This is the main callback of the demon.
bool MakeChainInactive(int64 before_chain, int64 chain_end)
std::string DebugString() const override
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64 value, VarArrayConstantExpressionType type)=0
virtual bool InitPosition() const
Returns true if operator needs to restart its initial position at each call to Start()
int number_of_nexts() const
Number of next variables.
void SetForwardSequence(const std::vector< int > &forward_sequence)
A BaseObject is the root of all reversibly allocated objects.
bool IsCardinalityOne() const
Does it contains only one bit set?
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
The class IntExpr is the base of all integer expressions in constraint programming.
int64 GetSynchronizedObjectiveValue() const override
Objective value from last time Synchronize() was called.
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
A reversible switch that can switch once from false to true.
A search monitor is a simple set of callbacks to monitor all search events.
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
IntVar * IsEqual(int64 constant) override
IsEqual.
virtual void SetNextBaseToIncrement(int64 base_index)
Set the next base to increment on next iteration.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
void WhenDomain(Demon *d) override
This method attaches a demon that will watch any domain modification of the domain of the variable.
int64 GetFirstOne() const
Gets the index of the first bit set starting from 0.
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
std::string DebugString() const override
void SynchronizeOnAssignment(const Assignment *assignment)
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
IntVar * IsLessOrEqual(int64 constant) override
The class IntVar is a subset of IntExpr.
--— RevPartialSequence --—
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
int64 GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
void Switch(Solver *const solver)
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
int64 GetAcceptedObjectiveValue() const override
Objective value from the last time Accept() was called and returned true.
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64 value, VarConstantConstraintType type)=0
bool Contains(const V *const var) const
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Returns true iff all filters return true, and the sum of their accepted objectives is between objecti...
The class Iterator has two direct subclasses.
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
void RankLast(Solver *const solver, int elt)
ArrayWithOffset(int64 index_min, int64 index_max)
bool AreAllNull(const std::vector< T > &values)
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64 value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64 value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
const std::vector< int > & OldSequence(int64 index) const
Demon proxy to a method on the constraint with one argument.
virtual int64 ModifyValue(int64 index, int64 value)=0
PropagationMonitor(Solver *const solver)
bool AreAllPositive(const std::vector< T > &values)
int64 MaxVarArray(const std::vector< IntVar * > &vars)
const Val & Value(int64 index) const
Returns the value in the current assignment of the variable of given index.
virtual void RegisterDemon(Demon *const demon)=0
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
void Run(Solver *const s) override
This is the main callback of the demon.
void Insert(Solver *const solver, const T &elt)
void SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
This class represents a reversible bitset.
A Decision represents a choice point in the search tree.
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void AppendToFragment(int index)
void SetMax(int64 m) override
Base operator class for operators manipulating IntVars.
Interval variables are often used in scheduling.
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
virtual void Synchronize(const Assignment *assignment, const Assignment *delta)=0
Synchronizes the filter with the current solution, delta being the difference with the solution passe...
bool Intersects(const std::vector< uint64 > &mask, int *support_index)
This method returns true iff the mask and the active bitset have a non null intersection.
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
virtual bool NextFragment()=0
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64 value)
Returns true if all variables are assigned to 'value'.
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
void Install() override
Install itself on the solver.
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
int64 PosIntDivDown(int64 e, int64 v)
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64 value)
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
This class represents a reversible bitset.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
void RevInsert(Solver *const solver, int64 index, T value)
This is the base class for building an Lns operator.
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
T * RevAlloc(T *object)
Registers the given object as being reversible.
void Start(const Assignment *assignment) override
This method should not be overridden.
std::string DebugString() const override
uint64 Size() const override
This method returns the number of values in the domain of the variable.
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
int64 Cardinality() const
Returns the number of bits set to one.
bool AtSolution() override
This method is called when a valid solution is found.
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
An Assignment is a variable -> domains mapping, used to report solutions to the user.
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
void ClearAll(Solver *const solver)
Cleans all bits.
The base class for all local search operators.
void SetRange(int64 mi, int64 ma) override
This method sets both the min and the max of the expression.
int64 FindIntegerArgumentWithDefault(const std::string &arg_name, int64 def) const
Getters.
Reversible Immutable MultiMap class.
BooleanVar(Solver *const s, const std::string &name="")
ChangeValue(const std::vector< IntVar * > &vars)
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
std::string DebugString() const override
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64)> start_empty_path_class)
Operator Factories.
virtual void SetPerformed(IntervalVar *const var, bool value)=0
int64 FindIntegerArgumentOrDie(const std::string &arg_name) const
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64 > *const values)
bool IsIncreasing(const std::vector< T > &values)