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:
1499  virtual bool Accept(Assignment* delta, Assignment* deltadelta) = 0;
1500 
1506  virtual void Synchronize(const Assignment* assignment,
1507  const Assignment* delta) = 0;
1508  virtual bool IsIncremental() const { return false; }
1509 
1511  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1515  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1516 };
1517 
1518 #if !defined(SWIG)
1519 class LocalSearchFilterManager : public LocalSearchFilter {
1523  public:
1524  LocalSearchFilterManager(Solver* const solver,
1525  const std::vector<LocalSearchFilter*>& filters,
1526  IntVar* objective);
1527  std::string DebugString() const override {
1528  return "LocalSearchFilterManager";
1529  }
1538  bool Accept(Assignment* delta, Assignment* deltadelta) override;
1540  void Synchronize(const Assignment* assignment,
1541  const Assignment* delta) override;
1542  bool IsIncremental() const override { return is_incremental_; }
1543  int64 GetSynchronizedObjectiveValue() const override {
1544  return synchronized_value_;
1545  }
1546  int64 GetAcceptedObjectiveValue() const override { return accepted_value_; }
1547 
1548  private:
1549  Solver* const solver_;
1550  std::vector<LocalSearchFilter*> filters_;
1551  IntVar* const objective_;
1552  bool is_incremental_;
1553  int64 synchronized_value_;
1554  int64 accepted_value_;
1555 };
1556 #endif
1557 
1559  public:
1560  IntVarLocalSearchFilter(const std::vector<IntVar*>& vars,
1561  Solver::ObjectiveWatcher objective_callback);
1562  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1563  ~IntVarLocalSearchFilter() override;
1566  void Synchronize(const Assignment* assignment,
1567  const Assignment* delta) override;
1568 
1569  bool FindIndex(IntVar* const var, int64* index) const {
1570  DCHECK(index != nullptr);
1571  const int var_index = var->index();
1572  *index = (var_index < var_index_to_index_.size())
1573  ? var_index_to_index_[var_index]
1574  : kUnassigned;
1575  return *index != kUnassigned;
1576  }
1577 
1578  virtual void InjectObjectiveValue(int64 objective_value) {
1579  injected_objective_value_ = objective_value;
1580  }
1581 
1583  void AddVars(const std::vector<IntVar*>& vars);
1584  int Size() const { return vars_.size(); }
1585  IntVar* Var(int index) const { return vars_[index]; }
1586  int64 Value(int index) const {
1587  DCHECK(IsVarSynced(index));
1588  return values_[index];
1589  }
1590  bool IsVarSynced(int index) const { return var_synced_[index]; }
1591 
1592  protected:
1593  virtual void OnSynchronize(const Assignment* delta) {}
1594  void SynchronizeOnAssignment(const Assignment* assignment);
1595 
1597  return objective_callback_ != nullptr;
1598  }
1599  void PropagateObjectiveValue(int64 objective_value) {
1600  if (objective_callback_ != nullptr) {
1601  objective_callback_(objective_value);
1602  }
1603  }
1605 
1606  private:
1607  std::vector<IntVar*> vars_;
1608  std::vector<int64> values_;
1609  std::vector<bool> var_synced_;
1610  std::vector<int> var_index_to_index_;
1611  static const int kUnassigned;
1612  Solver::ObjectiveWatcher objective_callback_;
1613 };
1614 
1616  public:
1617  explicit PropagationMonitor(Solver* const solver);
1618  ~PropagationMonitor() override;
1619  std::string DebugString() const override { return "PropagationMonitor"; }
1620 
1622  virtual void BeginConstraintInitialPropagation(
1623  Constraint* const constraint) = 0;
1624  virtual void EndConstraintInitialPropagation(
1625  Constraint* const constraint) = 0;
1627  Constraint* const parent, Constraint* const nested) = 0;
1629  Constraint* const parent, Constraint* const nested) = 0;
1630  virtual void RegisterDemon(Demon* const demon) = 0;
1631  virtual void BeginDemonRun(Demon* const demon) = 0;
1632  virtual void EndDemonRun(Demon* const demon) = 0;
1633  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1634  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1635  virtual void PushContext(const std::string& context) = 0;
1636  virtual void PopContext() = 0;
1638  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1639  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1640  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1642  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1643  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1644  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1645  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1646  virtual void SetValue(IntVar* const var, int64 value) = 0;
1647  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1648  virtual void SetValues(IntVar* const var,
1649  const std::vector<int64>& values) = 0;
1650  virtual void RemoveValues(IntVar* const var,
1651  const std::vector<int64>& values) = 0;
1653  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1654  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1655  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1656  int64 new_max) = 0;
1657  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1658  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1659  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1660  int64 new_max) = 0;
1661  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1662  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1663  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1664  int64 new_max) = 0;
1665  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1667  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1668  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1669  virtual void RankLast(SequenceVar* const var, int index) = 0;
1670  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1671  virtual void RankSequence(SequenceVar* const var,
1672  const std::vector<int>& rank_first,
1673  const std::vector<int>& rank_last,
1674  const std::vector<int>& unperformed) = 0;
1676  void Install() override;
1677 };
1678 
1680  // TODO(user): Add monitoring of local search filters.
1681  public:
1682  explicit LocalSearchMonitor(Solver* const solver);
1683  ~LocalSearchMonitor() override;
1684  std::string DebugString() const override { return "LocalSearchMonitor"; }
1685 
1687  virtual void BeginOperatorStart() = 0;
1688  virtual void EndOperatorStart() = 0;
1689  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1690  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1691  bool neighbor_found, const Assignment* delta,
1692  const Assignment* deltadelta) = 0;
1693  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1694  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1695  bool neighbor_found) = 0;
1696  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1697  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1698  bool neighbor_found) = 0;
1699  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1700  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1701 
1703  void Install() override;
1704 };
1705 
1706 class BooleanVar : public IntVar {
1707  public:
1708  static const int kUnboundBooleanVarValue;
1709 
1710  explicit BooleanVar(Solver* const s, const std::string& name = "")
1712 
1713  ~BooleanVar() override {}
1714 
1715  int64 Min() const override { return (value_ == 1); }
1716  void SetMin(int64 m) override;
1717  int64 Max() const override { return (value_ != 0); }
1718  void SetMax(int64 m) override;
1719  void SetRange(int64 mi, int64 ma) override;
1720  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1721  int64 Value() const override {
1722  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1723  return value_;
1724  }
1725  void RemoveValue(int64 v) override;
1726  void RemoveInterval(int64 l, int64 u) override;
1727  void WhenBound(Demon* d) override;
1728  void WhenRange(Demon* d) override { WhenBound(d); }
1729  void WhenDomain(Demon* d) override { WhenBound(d); }
1730  uint64 Size() const override;
1731  bool Contains(int64 v) const override;
1732  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1733  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1734  std::string DebugString() const override;
1735  int VarType() const override { return BOOLEAN_VAR; }
1736 
1737  IntVar* IsEqual(int64 constant) override;
1738  IntVar* IsDifferent(int64 constant) override;
1739  IntVar* IsGreaterOrEqual(int64 constant) override;
1740  IntVar* IsLessOrEqual(int64 constant) override;
1741 
1742  virtual void RestoreValue() = 0;
1743  std::string BaseName() const override { return "BooleanVar"; }
1744 
1745  int RawValue() const { return value_; }
1746 
1747  protected:
1748  int value_;
1751 };
1752 
1753 class SymmetryManager;
1754 
1759  public:
1761  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1762  ~SymmetryBreaker() override {}
1763 
1764  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
1766  int64 value);
1767  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
1768 
1769  private:
1770  friend class SymmetryManager;
1771  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
1772  CHECK(symmetry_manager_ == nullptr);
1773  CHECK_EQ(-1, index_in_symmetry_manager_);
1774  symmetry_manager_ = manager;
1775  index_in_symmetry_manager_ = index;
1776  }
1777  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
1778  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
1779 
1780  SymmetryManager* symmetry_manager_;
1782  int index_in_symmetry_manager_;
1783 };
1784 
1787 class SearchLog : public SearchMonitor {
1788  public:
1789  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
1790  double scaling_factor,
1791  std::function<std::string()> display_callback, int period);
1792  ~SearchLog() override;
1793  void EnterSearch() override;
1794  void ExitSearch() override;
1795  bool AtSolution() override;
1796  void BeginFail() override;
1797  void NoMoreSolutions() override;
1798  void AcceptUncheckedNeighbor() override;
1799  void ApplyDecision(Decision* const decision) override;
1800  void RefuteDecision(Decision* const decision) override;
1801  void OutputDecision();
1802  void Maintain();
1803  void BeginInitialPropagation() override;
1804  void EndInitialPropagation() override;
1805  std::string DebugString() const override;
1806 
1807  protected:
1808  /* Bottleneck function used for all UI related output. */
1809  virtual void OutputLine(const std::string& line);
1810 
1811  private:
1812  static std::string MemoryUsage();
1813 
1814  const int period_;
1815  std::unique_ptr<WallTimer> timer_;
1816  IntVar* const var_;
1817  OptimizeVar* const obj_;
1818  const double scaling_factor_;
1819  std::function<std::string()> display_callback_;
1820  int nsol_;
1821  int64 tick_;
1822  int64 objective_min_;
1823  int64 objective_max_;
1824  int min_right_depth_;
1825  int max_depth_;
1826  int sliding_min_depth_;
1827  int sliding_max_depth_;
1828 };
1829 
1834 class ModelCache {
1835  public:
1840  };
1841 
1848  };
1849 
1853  };
1854 
1863  };
1864 
1870  };
1871 
1884  };
1885 
1889  };
1890 
1903  };
1907  };
1908 
1912  };
1913 
1917  };
1918 
1924  };
1925 
1929  };
1930 
1931  explicit ModelCache(Solver* const solver);
1932  virtual ~ModelCache();
1933 
1934  virtual void Clear() = 0;
1935 
1937 
1938  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
1939 
1940  virtual void InsertVoidConstraint(Constraint* const ct,
1941  VoidConstraintType type) = 0;
1942 
1945  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
1946 
1947  virtual void InsertVarConstantConstraint(Constraint* const ct,
1948  IntVar* const var, int64 value,
1949  VarConstantConstraintType type) = 0;
1950 
1952 
1954  IntVar* const var, int64 value1, int64 value2,
1955  VarConstantConstantConstraintType type) const = 0;
1956 
1958  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
1960 
1962 
1964  IntExpr* const expr1, IntExpr* const expr2,
1965  ExprExprConstraintType type) const = 0;
1966 
1967  virtual void InsertExprExprConstraint(Constraint* const ct,
1968  IntExpr* const expr1,
1969  IntExpr* const expr2,
1970  ExprExprConstraintType type) = 0;
1971 
1973 
1974  virtual IntExpr* FindExprExpression(IntExpr* const expr,
1975  ExprExpressionType type) const = 0;
1976 
1977  virtual void InsertExprExpression(IntExpr* const expression,
1978  IntExpr* const expr,
1979  ExprExpressionType type) = 0;
1980 
1982 
1984  IntExpr* const expr, int64 value,
1985  ExprConstantExpressionType type) const = 0;
1986 
1987  virtual void InsertExprConstantExpression(
1988  IntExpr* const expression, IntExpr* const var, int64 value,
1989  ExprConstantExpressionType type) = 0;
1990 
1992 
1994  IntExpr* const var1, IntExpr* const var2,
1995  ExprExprExpressionType type) const = 0;
1996 
1997  virtual void InsertExprExprExpression(IntExpr* const expression,
1998  IntExpr* const var1,
1999  IntExpr* const var2,
2000  ExprExprExpressionType type) = 0;
2001 
2003 
2005  IntExpr* const var1, IntExpr* const var2, int64 constant,
2006  ExprExprConstantExpressionType type) const = 0;
2007 
2008  virtual void InsertExprExprConstantExpression(
2009  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2010  int64 constant, ExprExprConstantExpressionType type) = 0;
2011 
2013 
2015  IntVar* const var, int64 value1, int64 value2,
2016  VarConstantConstantExpressionType type) const = 0;
2017 
2019  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2021 
2023 
2025  IntVar* const var, const std::vector<int64>& values,
2026  VarConstantArrayExpressionType type) const = 0;
2027 
2028  virtual void InsertVarConstantArrayExpression(
2029  IntExpr* const expression, IntVar* const var,
2030  const std::vector<int64>& values,
2032 
2034 
2036  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2037 
2038  virtual void InsertVarArrayExpression(IntExpr* const expression,
2039  const std::vector<IntVar*>& vars,
2040  VarArrayExpressionType type) = 0;
2041 
2043 
2045  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2046  VarArrayConstantArrayExpressionType type) const = 0;
2047 
2049  IntExpr* const expression, const std::vector<IntVar*>& var,
2050  const std::vector<int64>& values,
2052 
2054 
2056  const std::vector<IntVar*>& vars, int64 value,
2057  VarArrayConstantExpressionType type) const = 0;
2058 
2059  virtual void InsertVarArrayConstantExpression(
2060  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2062 
2063  Solver* solver() const;
2064 
2065  private:
2066  Solver* const solver_;
2067 };
2068 
2070 #if !defined(SWIG)
2072  public:
2074  const std::string& TypeName() const;
2075  void SetTypeName(const std::string& type_name);
2076 
2078  void SetIntegerArgument(const std::string& arg_name, int64 value);
2079  void SetIntegerArrayArgument(const std::string& arg_name,
2080  const std::vector<int64>& values);
2081  void SetIntegerMatrixArgument(const std::string& arg_name,
2082  const IntTupleSet& values);
2083  void SetIntegerExpressionArgument(const std::string& arg_name,
2084  IntExpr* const expr);
2085  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2086  const std::vector<IntVar*>& vars);
2087  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2088  void SetIntervalArrayArgument(const std::string& arg_name,
2089  const std::vector<IntervalVar*>& vars);
2090  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2091  void SetSequenceArrayArgument(const std::string& arg_name,
2092  const std::vector<SequenceVar*>& vars);
2093 
2095  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2096  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2097 
2099  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2100  int64 def) const;
2101  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2102  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2103  const std::string& arg_name) const;
2104  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2105  const std::string& arg_name) const;
2106 
2108  const std::string& arg_name) const;
2109  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2110  const std::string& arg_name) const;
2111 
2112  private:
2113  std::string type_name_;
2114  absl::flat_hash_map<std::string, int64> integer_argument_;
2115  absl::flat_hash_map<std::string, std::vector<int64> > integer_array_argument_;
2116  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2117  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2118  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2119  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2120  absl::flat_hash_map<std::string, std::vector<IntVar*> >
2121  integer_variable_array_argument_;
2122  absl::flat_hash_map<std::string, std::vector<IntervalVar*> >
2123  interval_array_argument_;
2124  absl::flat_hash_map<std::string, std::vector<SequenceVar*> >
2125  sequence_array_argument_;
2126 };
2127 
2129 class ModelParser : public ModelVisitor {
2130  public:
2131  ModelParser();
2132 
2133  ~ModelParser() override;
2134 
2136  void BeginVisitModel(const std::string& solver_name) override;
2137  void EndVisitModel(const std::string& solver_name) override;
2138  void BeginVisitConstraint(const std::string& type_name,
2139  const Constraint* const constraint) override;
2140  void EndVisitConstraint(const std::string& type_name,
2141  const Constraint* const constraint) override;
2142  void BeginVisitIntegerExpression(const std::string& type_name,
2143  const IntExpr* const expr) override;
2144  void EndVisitIntegerExpression(const std::string& type_name,
2145  const IntExpr* const expr) override;
2146  void VisitIntegerVariable(const IntVar* const variable,
2147  IntExpr* const delegate) override;
2148  void VisitIntegerVariable(const IntVar* const variable,
2149  const std::string& operation, int64 value,
2150  IntVar* const delegate) override;
2151  void VisitIntervalVariable(const IntervalVar* const variable,
2152  const std::string& operation, int64 value,
2153  IntervalVar* const delegate) override;
2154  void VisitSequenceVariable(const SequenceVar* const variable) override;
2156  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2157  void VisitIntegerArrayArgument(const std::string& arg_name,
2158  const std::vector<int64>& values) override;
2159  void VisitIntegerMatrixArgument(const std::string& arg_name,
2160  const IntTupleSet& values) override;
2162  void VisitIntegerExpressionArgument(const std::string& arg_name,
2163  IntExpr* const argument) override;
2165  const std::string& arg_name,
2166  const std::vector<IntVar*>& arguments) override;
2168  void VisitIntervalArgument(const std::string& arg_name,
2169  IntervalVar* const argument) override;
2171  const std::string& arg_name,
2172  const std::vector<IntervalVar*>& arguments) override;
2174  void VisitSequenceArgument(const std::string& arg_name,
2175  SequenceVar* const argument) override;
2177  const std::string& arg_name,
2178  const std::vector<SequenceVar*>& arguments) override;
2179 
2180  protected:
2181  void PushArgumentHolder();
2182  void PopArgumentHolder();
2183  ArgumentHolder* Top() const;
2184 
2185  private:
2186  std::vector<ArgumentHolder*> holders_;
2187 };
2188 
2189 template <class T>
2190 class ArrayWithOffset : public BaseObject {
2191  public:
2192  ArrayWithOffset(int64 index_min, int64 index_max)
2193  : index_min_(index_min),
2194  index_max_(index_max),
2195  values_(new T[index_max - index_min + 1]) {
2196  DCHECK_LE(index_min, index_max);
2197  }
2198 
2199  ~ArrayWithOffset() override {}
2200 
2201  virtual T Evaluate(int64 index) const {
2202  DCHECK_GE(index, index_min_);
2203  DCHECK_LE(index, index_max_);
2204  return values_[index - index_min_];
2205  }
2206 
2207  void SetValue(int64 index, T value) {
2208  DCHECK_GE(index, index_min_);
2209  DCHECK_LE(index, index_max_);
2210  values_[index - index_min_] = value;
2211  }
2212 
2213  std::string DebugString() const override { return "ArrayWithOffset"; }
2214 
2215  private:
2216  const int64 index_min_;
2217  const int64 index_max_;
2218  std::unique_ptr<T[]> values_;
2219 };
2220 #endif // SWIG
2221 
2226 template <class T, class C>
2228  public:
2229  explicit RevGrowingArray(int64 block_size)
2230  : block_size_(block_size), block_offset_(0) {
2231  CHECK_GT(block_size, 0);
2232  }
2233 
2235  for (int i = 0; i < elements_.size(); ++i) {
2236  delete[] elements_[i];
2237  }
2238  }
2239 
2240  T At(int64 index) const {
2241  const int64 block_index = ComputeBlockIndex(index);
2242  const int64 relative_index = block_index - block_offset_;
2243  if (relative_index < 0 || relative_index >= elements_.size()) {
2244  return T();
2245  }
2246  const T* block = elements_[relative_index];
2247  return block != nullptr ? block[index - block_index * block_size_] : T();
2248  }
2249 
2250  void RevInsert(Solver* const solver, int64 index, T value) {
2251  const int64 block_index = ComputeBlockIndex(index);
2252  T* const block = GetOrCreateBlock(block_index);
2253  const int64 residual = index - block_index * block_size_;
2254  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2255  reinterpret_cast<C>(value));
2256  }
2257 
2258  private:
2259  T* NewBlock() const {
2260  T* const result = new T[block_size_];
2261  for (int i = 0; i < block_size_; ++i) {
2262  result[i] = T();
2263  }
2264  return result;
2265  }
2266 
2267  T* GetOrCreateBlock(int block_index) {
2268  if (elements_.size() == 0) {
2269  block_offset_ = block_index;
2270  GrowUp(block_index);
2271  } else if (block_index < block_offset_) {
2272  GrowDown(block_index);
2273  } else if (block_index - block_offset_ >= elements_.size()) {
2274  GrowUp(block_index);
2275  }
2276  T* block = elements_[block_index - block_offset_];
2277  if (block == nullptr) {
2278  block = NewBlock();
2279  elements_[block_index - block_offset_] = block;
2280  }
2281  return block;
2282  }
2283 
2284  int64 ComputeBlockIndex(int64 value) const {
2285  return value >= 0 ? value / block_size_
2286  : (value - block_size_ + 1) / block_size_;
2287  }
2288 
2289  void GrowUp(int64 block_index) {
2290  elements_.resize(block_index - block_offset_ + 1);
2291  }
2292 
2293  void GrowDown(int64 block_index) {
2294  const int64 delta = block_offset_ - block_index;
2295  block_offset_ = block_index;
2296  DCHECK_GT(delta, 0);
2297  elements_.insert(elements_.begin(), delta, nullptr);
2298  }
2299 
2300  const int64 block_size_;
2301  std::vector<T*> elements_;
2302  int block_offset_;
2303 };
2304 
2309 template <class T>
2310 class RevIntSet {
2311  public:
2312  static const int kNoInserted = -1;
2313 
2315  explicit RevIntSet(int capacity)
2316  : elements_(new T[capacity]),
2317  num_elements_(0),
2318  capacity_(capacity),
2319  position_(new int[capacity]),
2320  delete_position_(true) {
2321  for (int i = 0; i < capacity; ++i) {
2322  position_[i] = kNoInserted;
2323  }
2324  }
2325 
2327  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2328  : elements_(new T[capacity]),
2329  num_elements_(0),
2330  capacity_(capacity),
2331  position_(shared_positions),
2332  delete_position_(false) {
2333  for (int i = 0; i < shared_positions_size; ++i) {
2334  position_[i] = kNoInserted;
2335  }
2336  }
2337 
2339  if (delete_position_) {
2340  delete[] position_;
2341  }
2342  }
2343 
2344  int Size() const { return num_elements_.Value(); }
2345 
2346  int Capacity() const { return capacity_; }
2347 
2348  T Element(int i) const {
2349  DCHECK_GE(i, 0);
2350  DCHECK_LT(i, num_elements_.Value());
2351  return elements_[i];
2352  }
2353 
2354  T RemovedElement(int i) const {
2355  DCHECK_GE(i, 0);
2356  DCHECK_LT(i + num_elements_.Value(), capacity_);
2357  return elements_[i + num_elements_.Value()];
2358  }
2359 
2360  void Insert(Solver* const solver, const T& elt) {
2361  const int position = num_elements_.Value();
2362  DCHECK_LT(position, capacity_);
2363  DCHECK(NotAlreadyInserted(elt));
2364  elements_[position] = elt;
2365  position_[elt] = position;
2366  num_elements_.Incr(solver);
2367  }
2368 
2369  void Remove(Solver* const solver, const T& value_index) {
2370  num_elements_.Decr(solver);
2371  SwapTo(value_index, num_elements_.Value());
2372  }
2373 
2374  void Restore(Solver* const solver, const T& value_index) {
2375  SwapTo(value_index, num_elements_.Value());
2376  num_elements_.Incr(solver);
2377  }
2378 
2379  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2380 
2382  typedef const T* const_iterator;
2383  const_iterator begin() const { return elements_.get(); }
2384  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2385 
2386  private:
2388  bool NotAlreadyInserted(const T& elt) {
2389  for (int i = 0; i < num_elements_.Value(); ++i) {
2390  if (elt == elements_[i]) {
2391  return false;
2392  }
2393  }
2394  return true;
2395  }
2396 
2397  void SwapTo(T value_index, int next_position) {
2398  const int current_position = position_[value_index];
2399  if (current_position != next_position) {
2400  const T next_value_index = elements_[next_position];
2401  elements_[current_position] = next_value_index;
2402  elements_[next_position] = value_index;
2403  position_[value_index] = next_position;
2404  position_[next_value_index] = current_position;
2405  }
2406  }
2407 
2409  std::unique_ptr<T[]> elements_;
2411  NumericalRev<int> num_elements_;
2413  const int capacity_;
2415  int* position_;
2417  const bool delete_position_;
2418 };
2419 
2421 
2423  public:
2424  explicit RevPartialSequence(const std::vector<int>& items)
2425  : elements_(items),
2426  first_ranked_(0),
2427  last_ranked_(items.size() - 1),
2428  size_(items.size()),
2429  position_(new int[size_]) {
2430  for (int i = 0; i < size_; ++i) {
2431  elements_[i] = items[i];
2432  position_[i] = i;
2433  }
2434  }
2435 
2436  explicit RevPartialSequence(int size)
2437  : elements_(size),
2438  first_ranked_(0),
2439  last_ranked_(size - 1),
2440  size_(size),
2441  position_(new int[size_]) {
2442  for (int i = 0; i < size_; ++i) {
2443  elements_[i] = i;
2444  position_[i] = i;
2445  }
2446  }
2447 
2449 
2450  int NumFirstRanked() const { return first_ranked_.Value(); }
2451 
2452  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2453 
2454  int Size() const { return size_; }
2455 
2456 #if !defined(SWIG)
2457  const int& operator[](int index) const {
2458  DCHECK_GE(index, 0);
2459  DCHECK_LT(index, size_);
2460  return elements_[index];
2461  }
2462 #endif
2463 
2464  void RankFirst(Solver* const solver, int elt) {
2465  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2466  SwapTo(elt, first_ranked_.Value());
2467  first_ranked_.Incr(solver);
2468  }
2469 
2470  void RankLast(Solver* const solver, int elt) {
2471  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2472  SwapTo(elt, last_ranked_.Value());
2473  last_ranked_.Decr(solver);
2474  }
2475 
2476  bool IsRanked(int elt) const {
2477  const int position = position_[elt];
2478  return (position < first_ranked_.Value() ||
2479  position > last_ranked_.Value());
2480  }
2481 
2482  std::string DebugString() const {
2483  std::string result = "[";
2484  for (int i = 0; i < first_ranked_.Value(); ++i) {
2485  absl::StrAppend(&result, elements_[i]);
2486  if (i != first_ranked_.Value() - 1) {
2487  result.append("-");
2488  }
2489  }
2490  result.append("|");
2491  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2492  absl::StrAppend(&result, elements_[i]);
2493  if (i != last_ranked_.Value()) {
2494  result.append("-");
2495  }
2496  }
2497  result.append("|");
2498  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2499  absl::StrAppend(&result, elements_[i]);
2500  if (i != size_ - 1) {
2501  result.append("-");
2502  }
2503  }
2504  result.append("]");
2505  return result;
2506  }
2507 
2508  private:
2509  void SwapTo(int elt, int next_position) {
2510  const int current_position = position_[elt];
2511  if (current_position != next_position) {
2512  const int next_elt = elements_[next_position];
2513  elements_[current_position] = next_elt;
2514  elements_[next_position] = elt;
2515  position_[elt] = next_position;
2516  position_[next_elt] = current_position;
2517  }
2518  }
2519 
2521  std::vector<int> elements_;
2523  NumericalRev<int> first_ranked_;
2525  NumericalRev<int> last_ranked_;
2527  const int size_;
2529  std::unique_ptr<int[]> position_;
2530 };
2531 
2537  public:
2539  explicit UnsortedNullableRevBitset(int bit_size);
2540 
2542 
2545  void Init(Solver* const solver, const std::vector<uint64>& mask);
2546 
2549  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2550 
2553  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2554 
2557  int ActiveWordSize() const { return active_words_.Size(); }
2558 
2560  bool Empty() const { return active_words_.Size() == 0; }
2561 
2569  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2570 
2572  int64 bit_size() const { return bit_size_; }
2574  int64 word_size() const { return word_size_; }
2576  const RevIntSet<int>& active_words() const { return active_words_; }
2577 
2578  private:
2579  void CleanUpActives(Solver* const solver);
2580 
2581  const int64 bit_size_;
2582  const int64 word_size_;
2583  RevArray<uint64> bits_;
2584  RevIntSet<int> active_words_;
2585  std::vector<int> to_remove_;
2586 };
2587 
2588 template <class T>
2589 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2590  for (int i = 0; i < values.size(); ++i) {
2591  if (values[i] != value) {
2592  return false;
2593  }
2594  }
2595  return true;
2596 }
2597 
2598 template <class T>
2599 bool IsArrayBoolean(const std::vector<T>& values) {
2600  for (int i = 0; i < values.size(); ++i) {
2601  if (values[i] != 0 && values[i] != 1) {
2602  return false;
2603  }
2604  }
2605  return true;
2606 }
2607 
2608 template <class T>
2609 bool AreAllOnes(const std::vector<T>& values) {
2610  return IsArrayConstant(values, T(1));
2611 }
2612 
2613 template <class T>
2614 bool AreAllNull(const std::vector<T>& values) {
2615  return IsArrayConstant(values, T(0));
2616 }
2617 
2618 template <class T>
2619 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2620  for (const T& current_value : values) {
2621  if (current_value < value) {
2622  return false;
2623  }
2624  }
2625  return true;
2626 }
2627 
2628 template <class T>
2629 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2630  for (const T& current_value : values) {
2631  if (current_value > value) {
2632  return false;
2633  }
2634  }
2635  return true;
2636 }
2637 
2638 template <class T>
2639 bool AreAllPositive(const std::vector<T>& values) {
2640  return AreAllGreaterOrEqual(values, T(0));
2641 }
2642 
2643 template <class T>
2644 bool AreAllNegative(const std::vector<T>& values) {
2645  return AreAllLessOrEqual(values, T(0));
2646 }
2647 
2648 template <class T>
2649 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2650  return AreAllGreaterOrEqual(values, T(1));
2651 }
2652 
2653 template <class T>
2654 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2655  return AreAllLessOrEqual(values, T(-1));
2656 }
2657 
2658 template <class T>
2659 bool IsIncreasingContiguous(const std::vector<T>& values) {
2660  for (int i = 0; i < values.size() - 1; ++i) {
2661  if (values[i + 1] != values[i] + 1) {
2662  return false;
2663  }
2664  }
2665  return true;
2666 }
2667 
2668 template <class T>
2669 bool IsIncreasing(const std::vector<T>& values) {
2670  for (int i = 0; i < values.size() - 1; ++i) {
2671  if (values[i + 1] < values[i]) {
2672  return false;
2673  }
2674  }
2675  return true;
2676 }
2677 
2678 template <class T>
2679 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2680  T range_max) {
2681  for (int i = 0; i < vars.size(); ++i) {
2682  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2683  return false;
2684  }
2685  }
2686  return true;
2687 }
2688 
2689 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2690  for (int i = 0; i < vars.size(); ++i) {
2691  if (!vars[i]->Bound()) {
2692  return false;
2693  }
2694  }
2695  return true;
2696 }
2697 
2698 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2699  return IsArrayInRange(vars, 0, 1);
2700 }
2701 
2704 template <class T>
2705 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2706  const std::vector<T>& values) {
2707  for (int i = 0; i < vars.size(); ++i) {
2708  if (values[i] != 0 && !vars[i]->Bound()) {
2709  return false;
2710  }
2711  }
2712  return true;
2713 }
2714 
2716 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2717  for (int i = 0; i < vars.size(); ++i) {
2718  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2719  return false;
2720  }
2721  }
2722  return true;
2723 }
2724 
2725 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2726  DCHECK(!vars.empty());
2727  int64 result = kint64min;
2728  for (int i = 0; i < vars.size(); ++i) {
2730  result = std::max<int64>(result, vars[i]->Max());
2731  }
2732  return result;
2733 }
2734 
2735 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2736  DCHECK(!vars.empty());
2737  int64 result = kint64max;
2738  for (int i = 0; i < vars.size(); ++i) {
2740  result = std::min<int64>(result, vars[i]->Min());
2741  }
2742  return result;
2743 }
2744 
2745 inline void FillValues(const std::vector<IntVar*>& vars,
2746  std::vector<int64>* const values) {
2747  values->clear();
2748  values->resize(vars.size());
2749  for (int i = 0; i < vars.size(); ++i) {
2750  (*values)[i] = vars[i]->Value();
2751  }
2752 }
2753 
2754 inline int64 PosIntDivUp(int64 e, int64 v) {
2755  DCHECK_GT(v, 0);
2756  if (e >= 0) {
2757  return e % v == 0 ? e / v : e / v + 1;
2758  } else {
2759  return e / v;
2760  }
2761 }
2762 
2763 inline int64 PosIntDivDown(int64 e, int64 v) {
2764  DCHECK_GT(v, 0);
2765  if (e >= 0) {
2766  return e / v;
2767  } else {
2768  return e % v == 0 ? e / v : e / v - 1;
2769  }
2770 }
2771 
2772 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
2773 } // namespace operations_research
2774 
2775 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
Implements a complete cache for model elements: expressions and constraints.
IntVar * IsGreaterOrEqual(int64 constant) override
void SetForwardSequence(int64 index, const std::vector< int > &value)
void SetToZero(Solver *const solver, int64 row, int64 column)
Erases the 'column' bit in the 'row' row.
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars, Solver::ObjectiveWatcher objective_callback)
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
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 std::vector< int > & ForwardSequence() const
void Switch(Solver *const solver)
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Low-priority demon proxy to a method on the constraint with two arguments.
virtual void SetPerformed(IntervalVar *const var, bool value)=0
bool SkipUnchanged(int index) const override
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
This class represent a reversible FIFO structure.
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
void VisitSequenceVariable(const SequenceVar *const variable) override
std::string DebugString() const override
Matrix version of the RevBitSet class.
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void ClearAll(Solver *const solver)
Cleans all bits.
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
virtual std::string name() const
Object naming.
bool IsArrayBoolean(const std::vector< T > &values)
std::string DebugString() const override
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
std::string BaseName() const override
Returns a base name for automatic naming.
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
const Val & Value(int64 index) const
Returns the value in the current assignment of the variable of given index.
virtual int64 ModifyValue(int64 index, int64 value)=0
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
virtual void RankLast(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.
bool MakeChainInactive(int64 before_chain, int64 chain_end)
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values) override
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
bool AreAllStrictlyNegative(const std::vector< T > &values)
Base operator class for operators manipulating variables.
int64 FindIntegerArgumentWithDefault(const std::string &arg_name, int64 def) const
Getters.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
VarTypes
This enum is used internally to do dynamic typing on subclasses of integer variables.
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64 value, ExprConstantExpressionType type)=0
void SetMax(int64 m) override
virtual void RemoveValue(IntVar *const var, int64 value)=0
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
ModelCache(Solver *const solver)
std::string DebugString() const override
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
virtual int64 GetSynchronizedObjectiveValue() const
DO NOT USE. Objective value from last time Synchronize() was called.
void AddVars(const std::vector< V * > &vars)
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
Demon proxy to a method on the constraint with no arguments.
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
const int & operator[](int index) const
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type)=0
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
RevBitMatrix(int64 rows, int64 columns)
SimpleRevFIFO< Demon * > bound_demons_
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
bool MakeActive(int64 node, int64 destination)
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.
LocalSearchFilterManager(Solver *const solver, const std::vector< LocalSearchFilter * > &filters, IntVar *objective)
IntVarIterator * MakeDomainIterator(bool reversible) const override
Creates a domain iterator.
bool FindIndex(IntVar *const var, int64 *index) const
void WhenDomain(Demon *d) override
This method attaches a demon that will watch any domain modification of the domain of the variable.
virtual void Start(const Assignment *assignment)=0
void SetLastValue(const T &v)
Sets the last value in the FIFO.
void ClearAll(Solver *const solver)
Cleans all bits.
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
virtual bool NextFragment()=0
void Synchronize(const Assignment *assignment, const Assignment *delta) override
Synchronizes all filters to assignment.
const T & LastValue() const
Returns the last value in the FIFO.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
bool HasFragments() const override
This class encapsulates an objective.
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
const T * Last() const
Returns the last item of the FIFO.
This is the base class for all expressions that are not variables.
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
The base class of all search logs that periodically outputs information when the search is running.
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
virtual const LocalSearchOperator * Self() const
int64 PosIntDivUp(int64 e, int64 v)
Demon proxy to a method on the constraint with three arguments.
A Demon is the base element of a propagation queue.
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
bool ValueFromAssignent(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
int64 Cardinality() const
Returns the number of bits set to one.
Low-priority demon proxy to a method on the constraint with one argument.
void Run(Solver *const s) override
This is the main callback of the demon.
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
bool IsCardinalityZero() const
Is bitset null?
bool Accept(Assignment *delta, Assignment *deltadelta) override
Returns true iff all filters return true, and the sum of their accepted objectives is smaller or equa...
virtual void BeginDemonRun(Demon *const demon)=0
void Init(Solver *const solver, const std::vector< uint64 > &mask)
This methods overwrites the active bitset with the mask.
void SetToOne(Solver *const solver, int64 row, int64 column)
Sets the 'column' bit in the 'row' row.
const std::vector< int > & OldSequence(int64 index) const
int64 BaseNode(int i) const
Returns the index of the variable corresponding to the ith base node.
std::string DebugString() const override
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.
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64 value, VarConstantConstraintType type)=0
uint64 Hash1(uint64 value)
Hash functions.
int number_of_nexts() const
Number of next variables.
bool Contains(int64 v) const override
This method returns whether the value 'v' is in the domain of the variable.
virtual bool Accept(Assignment *delta, Assignment *deltadelta)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
IntVar * IsDifferent(int64 constant) override
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
void RankFirst(Solver *const solver, int elt)
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
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...
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
void Start(const Assignment *assignment) override
This method should not be overridden.
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64 value, VarArrayConstantExpressionType type)=0
void Push(Solver *const s, T val)
std::string DebugString() const override
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
const std::vector< int > & Sequence(int64 index) const
Returns the value in the current assignment of the variable of given index.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
bool IsInactive(int64 i) const
Returns true if node is inactive.
void SetTypeName(const std::string &type_name)
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64 value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
int64 StartNode(int i) const
Returns the index of the variable corresponding to the current path of the ith base node.
void MarkChange(int64 index)
OnStart() should really be protected, but then SWIG doesn't see it.
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
bool IsCardinalityOne() const
Does it contains only one bit set?
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
int64 GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
This iterator is not stable with respect to deletion.
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
bool AreAllBooleans(const std::vector< IntVar * > &vars)
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
LocalSearchMonitor(Solver *const solver)
void OnNodeInitialization() override
Called by OnStart() after initializing node information.
virtual void SetMax(IntExpr *const expr, int64 new_max)=0
bool IsCardinalityOne() const
Does it contains only one bit set?
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
const IntContainer & IntVarContainer() const
int64 bit_size() const
Returns the number of bits given in the constructor of the bitset.
virtual void OnSynchronize(const Assignment *delta)
std::string DebugString() const override
RevPartialSequence(const std::vector< int > &items)
Argument Holder: useful when visiting a model.
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
void SynchronizeOnAssignment(const Assignment *assignment)
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
virtual void PushContext(const std::string &context)=0
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
virtual void SetValues(IntVar *const var, const std::vector< int64 > &values)=0
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0
virtual void BeginOperatorStart()=0
Local search operator events.
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...
void SetValue(Solver *const s, const T &val)
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
BooleanVar(Solver *const s, const std::string &name="")
void RankLast(Solver *const solver, int elt)
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
void BeginInitialPropagation() override
Before the initial propagation.
void SetNext(int64 from, int64 to, int64 path)
Sets the to to be the node after from.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
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)
void SetToOne(Solver *const solver, int64 index)
Sets the 'index' bit.
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64 value)
ArrayWithOffset(int64 index_min, int64 index_max)
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64 value, VarConstantConstraintType type) const =0
Var Constant Constraints.
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
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.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
Simple PathOperator wrapper that also stores the current previous nodes, and is thus able to provide ...
void EndVisitModel(const std::string &solver_name) override
bool AreAllStrictlyPositive(const std::vector< T > &values)
std::string ParameterDebugString(P param)
PropagationMonitor(Solver *const solver)
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 ...
This is a special class to represent a 'residual' set of T.
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
void ExitSearch() override
End of the search.
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars)
bool IsIncreasingContiguous(const std::vector< T > &values)
void Clear(Solver *const solver)
void RemoveInterval(int64 l, int64 u) override
This method removes the interval 'l' .
Local Search Filters are used for fast neighbor pruning.
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
bool ValueFromAssignent(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
uint64 Size() const override
This method returns the number of values in the domain of the variable.
IntVar * IsEqual(int64 constant) override
IsEqual.
int64 MinVarArray(const std::vector< IntVar * > &vars)
A constraint is the main modeling object.
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
void Run(Solver *const s) override
This is the main callback of the demon.
bool IsArrayConstant(const std::vector< T > &values, const T &value)
std::vector< int64 > ToInt64Vector(const std::vector< int > &input)
void Run(Solver *const s) override
This is the main callback of the demon.
bool AreAllOnes(const std::vector< T > &values)
const E & Element(const V *const var) const
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
This class represents a small reversible bitset (size <= 64).
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type)=0
void Run(Solver *const s) override
This is the main callback of the demon.
SequenceContainer * MutableSequenceVarContainer()
const SequenceContainer & SequenceVarContainer() const
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
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...
Demon proxy to a method on the constraint with two arguments.
bool AreAllNegative(const std::vector< T > &values)
void PropagateObjectiveValue(int64 objective_value)
Low-priority demon proxy to a method on the constraint with no arguments.
void SetBackwardSequence(int64 index, const std::vector< int > &value)
A DecisionVisitor is used to inspect a decision.
bool IsCardinalityZero() const
Is bitset null?
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
VarLocalSearchOperator(std::vector< V * > vars, Handler var_handler)
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, std::function< std::string()> display_callback, int period)
IntVar * Var() override
Creates a variable from the expression.
int64 GetFirstOne() const
Gets the index of the first bit set starting from 0.
virtual void EndDemonRun(Demon *const demon)=0
virtual bool SkipUnchanged(int index) const
void BeginFail() override
Just when the failure occurs.
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
int64 OldPath(int64 node_index) const
bool AtSolution() override
This method is called when a valid solution is found.
void VisitIntegerArgument(const std::string &arg_name, int64 value) override
Integer arguments.
virtual void SetNextBaseToIncrement(int64 base_index)
Set the next base to increment on next iteration.
void Run(Solver *const s) override
This is the main callback of the demon.
void Install() override
Install itself on the solver.
std::string DebugString() const override
This class is a reversible growing array.
void RemoveValue(int64 v) override
This method removes the value 'v' from the domain of the variable.
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
bool AreAllBound(const std::vector< IntVar * > &vars)
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
BaseLns(const std::vector< IntVar * > &vars)
void SetValue(int64 index, const Val &value)
ChangeValue(const std::vector< IntVar * > &vars)
virtual void OutputLine(const std::string &line)
std::string DebugString() const override
int64 OldNext(int64 node_index) const
V * Var(int64 index) const
Returns the variable of given index.
int64 FindIntegerArgumentOrDie(const std::string &arg_name) const
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
void Run(Solver *const s) override
This is the main callback of the demon.
int index() const
Returns the index of the variable.
void SetRange(int64 mi, int64 ma) override
This method sets both the min and the max of the expression.
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
void RevInsert(Solver *const solver, int64 index, T value)
int64 Value() const override
This method returns the value of the variable.
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
const T * const_iterator
Iterators on the indices.
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
int64 Cardinality() const
Returns the number of bits set to one.
bool RevAnd(Solver *const solver, const std::vector< uint64 > &mask)
This method ANDs the mask with the active bitset.
A BaseObject is the root of all reversibly allocated objects.
T * RevAlloc(T *object)
Registers the given object as being reversible.
The class IntExpr is the base of all integer expressions in constraint programming.
bool Empty() const
This method returns true if the active bitset is null.
ArgumentHolder * Top() const
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.
RevImmutableMultiMap(Solver *const solver, int initial_size)
int64 size() const
Returns the number of interval vars in the sequence.
virtual T Evaluate(int64 index) const
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64 value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
int64 word_size() const
Returns the number of 64 bit words used to store the bitset.
std::function< void(int64)> ObjectiveWatcher
The class IntVar is a subset of IntExpr.
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
void Insert(Solver *const solver, const T &elt)
The class Iterator has two direct subclasses.
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
std::string DebugString() const override
void SetBackwardSequence(const std::vector< int > &backward_sequence)
bool AreAllNull(const std::vector< T > &values)
void SetMin(int64 m) override
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
void EndInitialPropagation() override
After the initial propagation.
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
virtual bool InitPosition() const
Returns true if operator needs to restart its initial position at each call to Start()
void SetToZero(Solver *const solver, int64 pos)
Erases the 'pos' bit.
int64 GetAcceptedObjectiveValue() const override
DO NOT USE.
void SetForwardSequence(const std::vector< int > &forward_sequence)
std::string DebugString() const override
Demon proxy to a method on the constraint with one argument.
bool AreAllPositive(const std::vector< T > &values)
int64 MaxVarArray(const std::vector< IntVar * > &vars)
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
void RefuteDecision(Decision *const decision) override
Before refuting the decision.
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
std::string DebugString() const override
void SetToZero(Solver *const solver, int64 index)
Erases the 'index' bit.
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
virtual void RankNotLast(SequenceVar *const var, int index)=0
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
virtual int64 GetAcceptedObjectiveValue() const
DO NOT USE.
virtual void SetMin(IntExpr *const expr, int64 new_min)=0
IntExpr modifiers.
This class represents a reversible bitset.
void NoMoreSolutions() override
When the search tree is finished.
virtual void SetValue(IntVar *const var, int64 value)=0
void Install() override
Install itself on the solver.
A Decision represents a choice point in the search tree.
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
bool Contains(const V *const var) const
Base operator class for operators manipulating IntVars.
Interval variables are often used in scheduling.
const std::vector< int64 > & path_starts() const
Returns the vector of path start nodes.
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
int PathClass(int i) const
Returns the class of the current path of the ith base node.
SimpleRevFIFO< Demon * > delayed_bound_demons_
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64 value)
Returns true if all variables are assigned to 'value'.
std::string DebugString() const override
int64 PosIntDivDown(int64 e, int64 v)
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
int64 GetSynchronizedObjectiveValue() const override
DO NOT USE. Objective value from last time Synchronize() was called.
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
This class represents a reversible bitset.
This is the base class for building an Lns operator.
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 RegisterDemon(Demon *const demon)=0
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
bool ReverseChain(int64 before_chain, int64 after_chain, int64 *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
void EnterSearch() override
Beginning of the search.
bool RevSubtract(Solver *const solver, const std::vector< uint64 > &mask)
This method subtracts the mask from the active bitset.
void AppendToFragment(int index)
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64 value, IntervalVar *const delegate) override
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
int64 Next(int64 node_index) const
Returns the index of the node after the node of index node_index in the current assignment.
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 SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
void Remove(Solver *const solver, const T &value_index)
The base class for all local search operators.
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64 value)
virtual void InjectObjectiveValue(int64 objective_value)
Reversible Immutable MultiMap class.
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
int64 GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
IntVar * IsLessOrEqual(int64 constant) override
void Run(Solver *const s) override
This is the main callback of the demon.
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
void Restore(Solver *const solver, const T &value_index)
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.
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64 > *const values)
bool IsIncreasing(const std::vector< T > &values)
const std::string & TypeName() const
Type of the argument.
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...