OR-Tools  9.2
constraint_solveri.h
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
48 
49 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
51 
52 #include <stdint.h>
53 #include <string.h>
54 
55 #include <algorithm>
56 #include <functional>
57 #include <initializer_list>
58 #include <memory>
59 #include <string>
60 #include <utility>
61 #include <vector>
62 
63 #include "absl/container/flat_hash_map.h"
64 #include "absl/strings/str_cat.h"
66 #include "ortools/base/logging.h"
67 #include "ortools/base/timer.h"
69 #include "ortools/util/bitset.h"
70 #include "ortools/util/tuple_set.h"
71 
72 namespace operations_research {
73 
99 class LocalSearchMonitor;
100 
101 class BaseIntExpr : public IntExpr {
102  public:
103  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
104  ~BaseIntExpr() override {}
105 
106  IntVar* Var() override;
107  virtual IntVar* CastToVar();
108 
109  private:
110  IntVar* var_;
111 };
112 
115 enum VarTypes {
125 };
126 
135 #ifndef SWIG
136 template <class T>
137 class SimpleRevFIFO {
138  private:
139  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
140  struct Chunk {
141  T data_[CHUNK_SIZE];
142  const Chunk* const next_;
143  explicit Chunk(const Chunk* next) : next_(next) {}
144  };
145 
146  public:
148  class Iterator {
149  public:
150  explicit Iterator(const SimpleRevFIFO<T>* l)
151  : chunk_(l->chunks_), value_(l->Last()) {}
152  bool ok() const { return (value_ != nullptr); }
153  T operator*() const { return *value_; }
154  void operator++() {
155  ++value_;
156  if (value_ == chunk_->data_ + CHUNK_SIZE) {
157  chunk_ = chunk_->next_;
158  value_ = chunk_ ? chunk_->data_ : nullptr;
159  }
160  }
161 
162  private:
163  const Chunk* chunk_;
164  const T* value_;
165  };
166 
167  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
168 
169  void Push(Solver* const s, T val) {
170  if (pos_.Value() == 0) {
171  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
172  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
173  reinterpret_cast<void*>(chunk));
174  pos_.SetValue(s, CHUNK_SIZE - 1);
175  } else {
176  pos_.Decr(s);
177  }
178  chunks_->data_[pos_.Value()] = val;
179  }
180 
182  void PushIfNotTop(Solver* const s, T val) {
183  if (chunks_ == nullptr || LastValue() != val) {
184  Push(s, val);
185  }
186  }
187 
189  const T* Last() const {
190  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
191  }
192 
193  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
194 
196  const T& LastValue() const {
197  DCHECK(chunks_);
198  return chunks_->data_[pos_.Value()];
199  }
200 
202  void SetLastValue(const T& v) {
203  DCHECK(Last());
204  chunks_->data_[pos_.Value()] = v;
205  }
206 
207  private:
208  Chunk* chunks_;
209  NumericalRev<int> pos_;
210 };
211 
213 // TODO(user): use murmurhash.
214 inline uint64_t Hash1(uint64_t value) {
215  value = (~value) + (value << 21);
216  value ^= value >> 24;
217  value += (value << 3) + (value << 8);
218  value ^= value >> 14;
219  value += (value << 2) + (value << 4);
220  value ^= value >> 28;
221  value += (value << 31);
222  return value;
223 }
224 
225 inline uint64_t Hash1(uint32_t value) {
226  uint64_t a = value;
227  a = (a + 0x7ed55d16) + (a << 12);
228  a = (a ^ 0xc761c23c) ^ (a >> 19);
229  a = (a + 0x165667b1) + (a << 5);
230  a = (a + 0xd3a2646c) ^ (a << 9);
231  a = (a + 0xfd7046c5) + (a << 3);
232  a = (a ^ 0xb55a4f09) ^ (a >> 16);
233  return a;
234 }
235 
236 inline uint64_t Hash1(int64_t value) {
237  return Hash1(static_cast<uint64_t>(value));
238 }
239 
240 inline uint64_t Hash1(int value) { return Hash1(static_cast<uint32_t>(value)); }
241 
242 inline uint64_t Hash1(void* const ptr) {
243 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
244  defined(__aarch64__)
245  return Hash1(reinterpret_cast<uint64_t>(ptr));
246 #else
247  return Hash1(reinterpret_cast<uint32_t>(ptr));
248 #endif
249 }
250 
251 template <class T>
252 uint64_t Hash1(const std::vector<T*>& ptrs) {
253  if (ptrs.empty()) return 0;
254  if (ptrs.size() == 1) return Hash1(ptrs[0]);
255  uint64_t hash = Hash1(ptrs[0]);
256  for (int i = 1; i < ptrs.size(); ++i) {
257  hash = hash * i + Hash1(ptrs[i]);
258  }
259  return hash;
260 }
261 
262 inline uint64_t Hash1(const std::vector<int64_t>& ptrs) {
263  if (ptrs.empty()) return 0;
264  if (ptrs.size() == 1) return Hash1(ptrs[0]);
265  uint64_t hash = Hash1(ptrs[0]);
266  for (int i = 1; i < ptrs.size(); ++i) {
267  hash = hash * i + Hash1(ptrs[i]);
268  }
269  return hash;
270 }
271 
274 template <class K, class V>
276  public:
277  RevImmutableMultiMap(Solver* const solver, int initial_size)
278  : solver_(solver),
279  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
280  size_(initial_size),
281  num_items_(0) {
282  memset(array_, 0, sizeof(*array_) * size_.Value());
283  }
284 
286 
287  int num_items() const { return num_items_.Value(); }
288 
290  bool ContainsKey(const K& key) const {
291  uint64_t code = Hash1(key) % size_.Value();
292  Cell* tmp = array_[code];
293  while (tmp) {
294  if (tmp->key() == key) {
295  return true;
296  }
297  tmp = tmp->next();
298  }
299  return false;
300  }
301 
305  const V& FindWithDefault(const K& key, const V& default_value) const {
306  uint64_t code = Hash1(key) % size_.Value();
307  Cell* tmp = array_[code];
308  while (tmp) {
309  if (tmp->key() == key) {
310  return tmp->value();
311  }
312  tmp = tmp->next();
313  }
314  return default_value;
315  }
316 
318  void Insert(const K& key, const V& value) {
319  const int position = Hash1(key) % size_.Value();
320  Cell* const cell =
321  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
322  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
323  reinterpret_cast<void*>(cell));
324  num_items_.Incr(solver_);
325  if (num_items_.Value() > 2 * size_.Value()) {
326  Double();
327  }
328  }
329 
330  private:
331  class Cell {
332  public:
333  Cell(const K& key, const V& value, Cell* const next)
334  : key_(key), value_(value), next_(next) {}
335 
336  void SetRevNext(Solver* const solver, Cell* const next) {
337  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
338  reinterpret_cast<void*>(next));
339  }
340 
341  Cell* next() const { return next_; }
342 
343  const K& key() const { return key_; }
344 
345  const V& value() const { return value_; }
346 
347  private:
348  const K key_;
349  const V value_;
350  Cell* next_;
351  };
352 
353  void Double() {
354  Cell** const old_cell_array = array_;
355  const int old_size = size_.Value();
356  size_.SetValue(solver_, size_.Value() * 2);
357  solver_->SaveAndSetValue(
358  reinterpret_cast<void**>(&array_),
359  reinterpret_cast<void*>(
360  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
361  memset(array_, 0, size_.Value() * sizeof(*array_));
362  for (int i = 0; i < old_size; ++i) {
363  Cell* tmp = old_cell_array[i];
364  while (tmp != nullptr) {
365  Cell* const to_reinsert = tmp;
366  tmp = tmp->next();
367  const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value();
368  to_reinsert->SetRevNext(solver_, array_[new_position]);
369  solver_->SaveAndSetValue(
370  reinterpret_cast<void**>(&array_[new_position]),
371  reinterpret_cast<void*>(to_reinsert));
372  }
373  }
374  }
375 
376  Solver* const solver_;
377  Cell** array_;
378  NumericalRev<int> size_;
379  NumericalRev<int> num_items_;
380 };
381 
383 class RevSwitch {
384  public:
385  RevSwitch() : value_(false) {}
386 
387  bool Switched() const { return value_; }
388 
389  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
390 
391  private:
392  bool value_;
393 };
394 
398  public:
399  explicit SmallRevBitSet(int64_t size);
401  void SetToOne(Solver* const solver, int64_t pos);
403  void SetToZero(Solver* const solver, int64_t pos);
405  int64_t Cardinality() const;
407  bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; }
409  bool IsCardinalityOne() const {
410  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
411  }
414  int64_t GetFirstOne() const;
415 
416  private:
417  Rev<uint64_t> bits_;
418 };
419 
422 class RevBitSet {
423  public:
424  explicit RevBitSet(int64_t size);
425  ~RevBitSet();
426 
428  void SetToOne(Solver* const solver, int64_t index);
430  void SetToZero(Solver* const solver, int64_t index);
432  bool IsSet(int64_t index) const;
434  int64_t Cardinality() const;
436  bool IsCardinalityZero() const;
438  bool IsCardinalityOne() const;
441  int64_t GetFirstBit(int start) const;
443  void ClearAll(Solver* const solver);
444 
445  friend class RevBitMatrix;
446 
447  private:
449  void Save(Solver* const solver, int offset);
450  const int64_t size_;
451  const int64_t length_;
452  uint64_t* bits_;
453  uint64_t* stamps_;
454 };
455 
457 class RevBitMatrix : private RevBitSet {
458  public:
459  RevBitMatrix(int64_t rows, int64_t columns);
460  ~RevBitMatrix();
461 
463  void SetToOne(Solver* const solver, int64_t row, int64_t column);
465  void SetToZero(Solver* const solver, int64_t row, int64_t column);
467  bool IsSet(int64_t row, int64_t column) const {
468  DCHECK_GE(row, 0);
469  DCHECK_LT(row, rows_);
470  DCHECK_GE(column, 0);
471  DCHECK_LT(column, columns_);
472  return RevBitSet::IsSet(row * columns_ + column);
473  }
475  int64_t Cardinality(int row) const;
477  bool IsCardinalityZero(int row) const;
479  bool IsCardinalityOne(int row) const;
482  int64_t GetFirstBit(int row, int start) const;
484  void ClearAll(Solver* const solver);
485 
486  private:
487  const int64_t rows_;
488  const int64_t columns_;
489 };
490 
496 
498 template <class T>
499 class CallMethod0 : public Demon {
500  public:
501  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
502  : constraint_(ct), method_(method), name_(name) {}
503 
504  ~CallMethod0() override {}
505 
506  void Run(Solver* const s) override { (constraint_->*method_)(); }
507 
508  std::string DebugString() const override {
509  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
510  }
511 
512  private:
513  T* const constraint_;
514  void (T::*const method_)();
515  const std::string name_;
516 };
517 
518 template <class T>
519 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
520  const std::string& name) {
521  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
522 }
523 
524 template <class P>
525 std::string ParameterDebugString(P param) {
526  return absl::StrCat(param);
527 }
528 
530 template <class P>
531 std::string ParameterDebugString(P* param) {
532  return param->DebugString();
533 }
534 
536 template <class T, class P>
537 class CallMethod1 : public Demon {
538  public:
539  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
540  P param1)
541  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
542 
543  ~CallMethod1() override {}
544 
545  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
546 
547  std::string DebugString() const override {
548  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
549  ", ", ParameterDebugString(param1_), ")");
550  }
551 
552  private:
553  T* const constraint_;
554  void (T::*const method_)(P);
555  const std::string name_;
556  P param1_;
557 };
558 
559 template <class T, class P>
560 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
561  const std::string& name, P param1) {
562  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
563 }
564 
566 template <class T, class P, class Q>
567 class CallMethod2 : public Demon {
568  public:
569  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
570  P param1, Q param2)
571  : constraint_(ct),
572  method_(method),
573  name_(name),
574  param1_(param1),
575  param2_(param2) {}
576 
577  ~CallMethod2() override {}
578 
579  void Run(Solver* const s) override {
580  (constraint_->*method_)(param1_, param2_);
581  }
582 
583  std::string DebugString() const override {
584  return absl::StrCat(absl::StrCat("CallMethod_", name_),
585  absl::StrCat("(", constraint_->DebugString()),
586  absl::StrCat(", ", ParameterDebugString(param1_)),
587  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
588  }
589 
590  private:
591  T* const constraint_;
592  void (T::*const method_)(P, Q);
593  const std::string name_;
594  P param1_;
595  Q param2_;
596 };
597 
598 template <class T, class P, class Q>
599 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
600  void (T::*method)(P, Q), const std::string& name,
601  P param1, Q param2) {
602  return s->RevAlloc(
603  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
604 }
606 template <class T, class P, class Q, class R>
607 class CallMethod3 : public Demon {
608  public:
609  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
610  P param1, Q param2, R param3)
611  : constraint_(ct),
612  method_(method),
613  name_(name),
614  param1_(param1),
615  param2_(param2),
616  param3_(param3) {}
617 
618  ~CallMethod3() override {}
619 
620  void Run(Solver* const s) override {
621  (constraint_->*method_)(param1_, param2_, param3_);
622  }
623 
624  std::string DebugString() const override {
625  return absl::StrCat(absl::StrCat("CallMethod_", name_),
626  absl::StrCat("(", constraint_->DebugString()),
627  absl::StrCat(", ", ParameterDebugString(param1_)),
628  absl::StrCat(", ", ParameterDebugString(param2_)),
629  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
630  }
631 
632  private:
633  T* const constraint_;
634  void (T::*const method_)(P, Q, R);
635  const std::string name_;
636  P param1_;
637  Q param2_;
638  R param3_;
639 };
640 
641 template <class T, class P, class Q, class R>
642 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
643  void (T::*method)(P, Q, R), const std::string& name,
644  P param1, Q param2, R param3) {
645  return s->RevAlloc(
646  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
647 }
649 
654 
656 template <class T>
657 class DelayedCallMethod0 : public Demon {
658  public:
659  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
660  : constraint_(ct), method_(method), name_(name) {}
661 
662  ~DelayedCallMethod0() override {}
663 
664  void Run(Solver* const s) override { (constraint_->*method_)(); }
665 
666  Solver::DemonPriority priority() const override {
668  }
669 
670  std::string DebugString() const override {
671  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
672  ")";
673  }
674 
675  private:
676  T* const constraint_;
677  void (T::*const method_)();
678  const std::string name_;
679 };
680 
681 template <class T>
683  void (T::*method)(),
684  const std::string& name) {
685  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
686 }
687 
689 template <class T, class P>
690 class DelayedCallMethod1 : public Demon {
691  public:
692  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
693  P param1)
694  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
695 
696  ~DelayedCallMethod1() override {}
697 
698  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
699 
700  Solver::DemonPriority priority() const override {
702  }
703 
704  std::string DebugString() const override {
705  return absl::StrCat("DelayedCallMethod_", name_, "(",
706  constraint_->DebugString(), ", ",
707  ParameterDebugString(param1_), ")");
708  }
709 
710  private:
711  T* const constraint_;
712  void (T::*const method_)(P);
713  const std::string name_;
714  P param1_;
715 };
716 
717 template <class T, class P>
719  void (T::*method)(P),
720  const std::string& name, P param1) {
721  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
722 }
723 
725 template <class T, class P, class Q>
726 class DelayedCallMethod2 : public Demon {
727  public:
728  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
729  const std::string& name, P param1, Q param2)
730  : constraint_(ct),
731  method_(method),
732  name_(name),
733  param1_(param1),
734  param2_(param2) {}
735 
736  ~DelayedCallMethod2() override {}
737 
738  void Run(Solver* const s) override {
739  (constraint_->*method_)(param1_, param2_);
740  }
741 
742  Solver::DemonPriority priority() const override {
744  }
745 
746  std::string DebugString() const override {
747  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
748  absl::StrCat("(", constraint_->DebugString()),
749  absl::StrCat(", ", ParameterDebugString(param1_)),
750  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
751  }
752 
753  private:
754  T* const constraint_;
755  void (T::*const method_)(P, Q);
756  const std::string name_;
757  P param1_;
758  Q param2_;
759 };
760 
761 template <class T, class P, class Q>
763  void (T::*method)(P, Q),
764  const std::string& name, P param1,
765  Q param2) {
766  return s->RevAlloc(
767  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
768 }
770 
771 #endif // !defined(SWIG)
772 
790 // TODO(user): rename Start to Synchronize ?
791 // TODO(user): decouple the iterating from the defining of a neighbor.
793  public:
795  ~LocalSearchOperator() override {}
796  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
797  virtual void Start(const Assignment* assignment) = 0;
798  virtual void Reset() {}
799 #ifndef SWIG
800  virtual const LocalSearchOperator* Self() const { return this; }
801 #endif // SWIG
802  virtual bool HasFragments() const { return false; }
803  virtual bool HoldsDelta() const { return false; }
804 };
805 
807 template <class V, class Val, class Handler>
809  public:
811  explicit VarLocalSearchOperator(Handler var_handler)
812  : activated_(),
813  was_activated_(),
814  cleared_(true),
815  var_handler_(var_handler) {}
817  bool HoldsDelta() const override { return true; }
820  void Start(const Assignment* assignment) override {
821  const int size = Size();
822  CHECK_LE(size, assignment->Size())
823  << "Assignment contains fewer variables than operator";
824  for (int i = 0; i < size; ++i) {
825  activated_.Set(i, var_handler_.ValueFromAssignment(*assignment, vars_[i],
826  i, &values_[i]));
827  }
831  OnStart();
832  }
833  virtual bool IsIncremental() const { return false; }
834  int Size() const { return vars_.size(); }
837  const Val& Value(int64_t index) const {
838  DCHECK_LT(index, vars_.size());
839  return values_[index];
840  }
842  V* Var(int64_t index) const { return vars_[index]; }
843  virtual bool SkipUnchanged(int index) const { return false; }
844  const Val& OldValue(int64_t index) const { return old_values_[index]; }
845  void SetValue(int64_t index, const Val& value) {
846  values_[index] = value;
847  MarkChange(index);
848  }
849  bool Activated(int64_t index) const { return activated_[index]; }
850  void Activate(int64_t index) {
852  MarkChange(index);
853  }
854  void Deactivate(int64_t index) {
856  MarkChange(index);
857  }
858  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
859  if (IsIncremental() && !cleared_) {
860  for (const int64_t index : delta_changes_.PositionsSetAtLeastOnce()) {
861  V* var = Var(index);
862  const Val& value = Value(index);
863  const bool activated = activated_[index];
864  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
865  deltadelta);
866  var_handler_.AddToAssignment(var, value, activated,
868  }
869  } else {
870  delta->Clear();
871  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
872  const Val& value = Value(index);
873  const bool activated = activated_[index];
874  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
875  var_handler_.AddToAssignment(Var(index), value, activated_[index],
877  }
878  }
879  }
880  return true;
881  }
882  void RevertChanges(bool incremental) {
883  cleared_ = false;
885  if (incremental && IsIncremental()) return;
886  cleared_ = true;
887  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
889  var_handler_.OnRevertChanges(index, values_[index]);
892  }
894  }
895  void AddVars(const std::vector<V*>& vars) {
896  if (!vars.empty()) {
897  vars_.insert(vars_.end(), vars.begin(), vars.end());
898  const int64_t size = Size();
899  values_.resize(size);
900  old_values_.resize(size);
901  prev_values_.resize(size);
902  assignment_indices_.resize(size, -1);
903  activated_.Resize(size);
904  was_activated_.Resize(size);
905  changes_.ClearAndResize(size);
907  var_handler_.OnAddVars();
908  }
909  }
910 
914  virtual void OnStart() {}
915 
918  protected:
919  void MarkChange(int64_t index) {
921  changes_.Set(index);
922  }
923 
924  std::vector<V*> vars_;
925  std::vector<Val> values_;
926  std::vector<Val> old_values_;
927  std::vector<Val> prev_values_;
928  mutable std::vector<int> assignment_indices_;
933  bool cleared_;
934  Handler var_handler_;
935 };
936 
939 
941  public:
942  IntVarLocalSearchHandler() : op_(nullptr) {}
944  : op_(other.op_) {}
946  void AddToAssignment(IntVar* var, int64_t value, bool active,
947  std::vector<int>* assignment_indices, int64_t index,
948  Assignment* assignment) const {
949  Assignment::IntContainer* const container =
950  assignment->MutableIntVarContainer();
951  IntVarElement* element = nullptr;
952  if (assignment_indices != nullptr) {
953  if ((*assignment_indices)[index] == -1) {
954  (*assignment_indices)[index] = container->Size();
955  element = assignment->FastAdd(var);
956  } else {
957  element = container->MutableElement((*assignment_indices)[index]);
958  }
959  } else {
960  element = assignment->FastAdd(var);
961  }
962  if (active) {
963  element->SetValue(value);
964  element->Activate();
965  } else {
966  element->Deactivate();
967  }
968  }
969  bool ValueFromAssignment(const Assignment& assignment, IntVar* var,
970  int64_t index, int64_t* value);
971  void OnRevertChanges(int64_t index, int64_t value);
972  void OnAddVars() {}
973 
974  private:
975  IntVarLocalSearchOperator* const op_;
976 };
977 
983 
984 #ifdef SWIG
985 // TODO(user): find a way to move this code back to the .i file, where it
992 #if defined(SWIGPYTHON)
993 // clang-format off
994 %unignore VarLocalSearchOperator<IntVar, int64_t,
995  IntVarLocalSearchHandler>::Size;
996 %unignore VarLocalSearchOperator<IntVar, int64_t,
997  IntVarLocalSearchHandler>::Value;
998 %unignore VarLocalSearchOperator<IntVar, int64_t,
999  IntVarLocalSearchHandler>::OldValue;
1000 %unignore VarLocalSearchOperator<IntVar, int64_t,
1001  IntVarLocalSearchHandler>::SetValue;
1002 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1003  IntVarLocalSearchHandler>::IsIncremental;
1004 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1005  IntVarLocalSearchHandler>::OnStart;
1006 %unignore VarLocalSearchOperator<IntVar, int64_t,
1007  IntVarLocalSearchHandler>::IsIncremental;
1008 %unignore VarLocalSearchOperator<IntVar, int64_t,
1009  IntVarLocalSearchHandler>::OnStart;
1010 // clang-format on
1011 #endif // SWIGPYTHON
1012 
1013 // clang-format off
1014 %rename(IntVarLocalSearchOperatorTemplate)
1015  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1016 %template(IntVarLocalSearchOperatorTemplate)
1017  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1018 // clang-format on
1019 #endif // SWIG
1020 
1023  public:
1024  IntVarLocalSearchOperator() : max_inverse_value_(-1) {}
1025  // If keep_inverse_values is true, assumes that vars models an injective
1026  // function f with domain [0, vars.size()) in which case the operator will
1027  // maintain the inverse function.
1028  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1029  bool keep_inverse_values = false)
1031  IntVarLocalSearchHandler(this)),
1032  max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) {
1033  AddVars(vars);
1034  if (keep_inverse_values) {
1035  int64_t max_value = -1;
1036  for (const IntVar* const var : vars) {
1037  max_value = std::max(max_value, var->Max());
1038  }
1039  inverse_values_.resize(max_value + 1, -1);
1040  old_inverse_values_.resize(max_value + 1, -1);
1041  }
1042  }
1050  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1051 
1052  protected:
1054 
1057  // TODO(user): make it pure virtual, implies porting all apps overriding
1059  virtual bool MakeOneNeighbor();
1060 
1061  bool IsInverseValue(int64_t index) const {
1062  DCHECK_GE(index, 0);
1063  return index <= max_inverse_value_;
1064  }
1065 
1066  int64_t InverseValue(int64_t index) const { return inverse_values_[index]; }
1067 
1068  int64_t OldInverseValue(int64_t index) const {
1069  return old_inverse_values_[index];
1070  }
1071 
1072  void SetInverseValue(int64_t index, int64_t value) {
1073  inverse_values_[index] = value;
1074  }
1075 
1076  void SetOldInverseValue(int64_t index, int64_t value) {
1077  old_inverse_values_[index] = value;
1078  }
1079 
1080  private:
1081  const int64_t max_inverse_value_;
1082  std::vector<int64_t> old_inverse_values_;
1083  std::vector<int64_t> inverse_values_;
1084 };
1085 
1087  const Assignment& assignment, IntVar* var, int64_t index, int64_t* value) {
1088  const Assignment::IntContainer& container = assignment.IntVarContainer();
1089  const IntVarElement* element = &(container.Element(index));
1090  if (element->Var() != var) {
1091  CHECK(container.Contains(var))
1092  << "Assignment does not contain operator variable " << var;
1093  element = &(container.Element(var));
1094  }
1095  *value = element->Value();
1096  if (op_->IsInverseValue(index)) {
1097  op_->SetInverseValue(*value, index);
1098  op_->SetOldInverseValue(*value, index);
1099  }
1100  return element->Activated();
1101 }
1102 
1104  int64_t value) {
1105  if (op_->IsInverseValue(index)) {
1106  op_->SetInverseValue(value, index);
1107  }
1108 }
1109 
1112 
1114  public:
1115  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1117  : op_(other.op_) {}
1119  : op_(op) {}
1120  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1121  bool active, std::vector<int>* assignment_indices,
1122  int64_t index, Assignment* assignment) const;
1123  bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var,
1124  int64_t index, std::vector<int>* value);
1125  void OnRevertChanges(int64_t index, const std::vector<int>& value);
1126  void OnAddVars();
1127 
1128  private:
1129  SequenceVarLocalSearchOperator* const op_;
1130 };
1131 
1132 #ifdef SWIG
1133 // TODO(user): find a way to move this code back to the .i file, where it
1138 // clang-format off
1139 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1140  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1141 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1142  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1143 // clang-format on
1144 #endif
1145 
1146 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1147  SequenceVarLocalSearchHandler>
1149 
1152  public:
1154  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1157  AddVars(vars);
1158  }
1162  const std::vector<int>& Sequence(int64_t index) const { return Value(index); }
1163  const std::vector<int>& OldSequence(int64_t index) const {
1164  return OldValue(index);
1165  }
1166  void SetForwardSequence(int64_t index, const std::vector<int>& value) {
1167  SetValue(index, value);
1168  }
1169  void SetBackwardSequence(int64_t index, const std::vector<int>& value) {
1171  MarkChange(index);
1172  }
1173 
1174  protected:
1176 
1177  std::vector<std::vector<int>> backward_values_;
1178 };
1179 
1181  SequenceVar* var, const std::vector<int>& value, bool active,
1182  std::vector<int>* assignment_indices, int64_t index,
1183  Assignment* assignment) const {
1184  Assignment::SequenceContainer* const container =
1185  assignment->MutableSequenceVarContainer();
1186  SequenceVarElement* element = nullptr;
1187  if (assignment_indices != nullptr) {
1188  if ((*assignment_indices)[index] == -1) {
1189  (*assignment_indices)[index] = container->Size();
1190  element = assignment->FastAdd(var);
1191  } else {
1192  element = container->MutableElement((*assignment_indices)[index]);
1193  }
1194  } else {
1195  element = assignment->FastAdd(var);
1196  }
1197  if (active) {
1198  element->SetForwardSequence(value);
1199  element->SetBackwardSequence(op_->backward_values_[index]);
1200  element->Activate();
1201  } else {
1202  element->Deactivate();
1203  }
1204 }
1205 
1207  const Assignment& assignment, SequenceVar* var, int64_t index,
1208  std::vector<int>* value) {
1209  const Assignment::SequenceContainer& container =
1210  assignment.SequenceVarContainer();
1211  const SequenceVarElement* element = &(container.Element(index));
1212  if (element->Var() != var) {
1213  CHECK(container.Contains(var))
1214  << "Assignment does not contain operator variable " << var;
1215  element = &(container.Element(var));
1216  }
1217  const std::vector<int>& element_value = element->ForwardSequence();
1218  CHECK_GE(var->size(), element_value.size());
1219  op_->backward_values_[index].clear();
1220  *value = element_value;
1221  return element->Activated();
1222 }
1223 
1225  int64_t index, const std::vector<int>& value) {
1226  op_->backward_values_[index].clear();
1227 }
1228 
1230  op_->backward_values_.resize(op_->Size());
1231 }
1232 
1261  public:
1262  explicit BaseLns(const std::vector<IntVar*>& vars);
1263  ~BaseLns() override;
1264  virtual void InitFragments();
1265  virtual bool NextFragment() = 0;
1266  void AppendToFragment(int index);
1267  int FragmentSize() const;
1268  bool HasFragments() const override { return true; }
1269 
1270  protected:
1272  bool MakeOneNeighbor() override;
1273 
1274  private:
1276  void OnStart() override;
1277  std::vector<int> fragment_;
1278 };
1279 
1285  public:
1286  explicit ChangeValue(const std::vector<IntVar*>& vars);
1287  ~ChangeValue() override;
1288  virtual int64_t ModifyValue(int64_t index, int64_t value) = 0;
1289 
1290  protected:
1292  bool MakeOneNeighbor() override;
1293 
1294  private:
1295  void OnStart() override;
1296 
1297  int index_;
1298 };
1299 
1314  public:
1334  std::function<int(int64_t)> start_empty_path_class;
1335  };
1337  PathOperator(const std::vector<IntVar*>& next_vars,
1338  const std::vector<IntVar*>& path_vars,
1339  IterationParameters iteration_parameters);
1340  PathOperator(const std::vector<IntVar*>& next_vars,
1341  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1342  bool skip_locally_optimal_paths, bool accept_path_end_base,
1343  std::function<int(int64_t)> start_empty_path_class)
1344  : PathOperator(
1345  next_vars, path_vars,
1346  {number_of_base_nodes, skip_locally_optimal_paths,
1347  accept_path_end_base, std::move(start_empty_path_class)}) {}
1348  ~PathOperator() override {}
1349  virtual bool MakeNeighbor() = 0;
1350  void Reset() override;
1351 
1352  // TODO(user): Make the following methods protected.
1353  bool SkipUnchanged(int index) const override;
1354 
1356  int64_t Next(int64_t node) const {
1357  DCHECK(!IsPathEnd(node));
1358  return Value(node);
1359  }
1360 
1362  int64_t Prev(int64_t node) const {
1363  DCHECK(!IsPathStart(node));
1364  DCHECK_EQ(Next(InverseValue(node)), node);
1365  return InverseValue(node);
1366  }
1367 
1370  int64_t Path(int64_t node) const {
1371  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1372  }
1373 
1375  int number_of_nexts() const { return number_of_nexts_; }
1376 
1377  protected:
1379  bool MakeOneNeighbor() override;
1383  virtual void OnNodeInitialization() {}
1384 
1386  int64_t BaseNode(int i) const { return base_nodes_[i]; }
1388  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1390  int64_t BaseAlternativeNode(int i) const {
1391  if (!ConsiderAlternatives(i)) return BaseNode(i);
1392  const int alternative_index = alternative_index_[BaseNode(i)];
1393  return alternative_index >= 0
1394  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1395  : BaseNode(i);
1396  }
1398  int BaseSiblingAlternative(int i) const {
1399  return base_sibling_alternatives_[i];
1400  }
1402  int64_t BaseSiblingAlternativeNode(int i) const {
1403  if (!ConsiderAlternatives(i)) return BaseNode(i);
1404  const int sibling_alternative_index =
1406  return sibling_alternative_index >= 0
1407  ? alternative_sets_[sibling_alternative_index]
1408  [base_sibling_alternatives_[i]]
1409  : BaseNode(i);
1410  }
1412  int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1414  const std::vector<int64_t>& path_starts() const { return path_starts_; }
1416  int PathClass(int i) const {
1417  return iteration_parameters_.start_empty_path_class != nullptr
1418  ? iteration_parameters_.start_empty_path_class(StartNode(i))
1419  : StartNode(i);
1420  }
1421 
1428  // TODO(user): remove this when automatic detection of such cases in done.
1429  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1433  // TODO(user): ideally this should be OnSamePath(int64_t node1, int64_t
1434  // node2);
1436  virtual bool OnSamePathAsPreviousBase(int64_t base_index) { return false; }
1442  virtual int64_t GetBaseNodeRestartPosition(int base_index) {
1443  return StartNode(base_index);
1444  }
1447  virtual void SetNextBaseToIncrement(int64_t base_index) {
1448  next_base_to_increment_ = base_index;
1449  }
1452  virtual bool ConsiderAlternatives(int64_t base_index) const { return false; }
1453 
1454  int64_t OldNext(int64_t node) const {
1455  DCHECK(!IsPathEnd(node));
1456  return OldValue(node);
1457  }
1458 
1459  int64_t OldPrev(int64_t node) const {
1460  DCHECK(!IsPathStart(node));
1461  return OldInverseValue(node);
1462  }
1463 
1464  int64_t OldPath(int64_t node) const {
1465  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1466  }
1467 
1470  bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination);
1471 
1474  bool ReverseChain(int64_t before_chain, int64_t after_chain,
1475  int64_t* chain_last);
1476 
1478  bool MakeActive(int64_t node, int64_t destination);
1481  bool MakeChainInactive(int64_t before_chain, int64_t chain_end);
1483  bool SwapActiveAndInactive(int64_t active, int64_t inactive);
1484 
1486  void SetNext(int64_t from, int64_t to, int64_t path) {
1487  DCHECK_LT(from, number_of_nexts_);
1488  SetValue(from, to);
1489  SetInverseValue(to, from);
1490  if (!ignore_path_vars_) {
1491  DCHECK_LT(from + number_of_nexts_, Size());
1492  SetValue(from + number_of_nexts_, path);
1493  }
1494  }
1495 
1498  bool IsPathEnd(int64_t node) const { return node >= number_of_nexts_; }
1499 
1501  bool IsPathStart(int64_t node) const { return OldInverseValue(node) == -1; }
1502 
1504  bool IsInactive(int64_t node) const {
1505  return !IsPathEnd(node) && inactives_[node];
1506  }
1507 
1510  virtual bool InitPosition() const { return false; }
1514  void ResetPosition() { just_started_ = true; }
1515 
1519  int AddAlternativeSet(const std::vector<int64_t>& alternative_set) {
1520  const int alternative = alternative_sets_.size();
1521  for (int64_t node : alternative_set) {
1522  DCHECK_EQ(-1, alternative_index_[node]);
1523  alternative_index_[node] = alternative;
1524  }
1525  alternative_sets_.push_back(alternative_set);
1526  sibling_alternative_.push_back(-1);
1527  return alternative;
1528  }
1529 #ifndef SWIG
1533  const std::vector<std::pair<std::vector<int64_t>, std::vector<int64_t>>>&
1534  pair_alternative_sets) {
1535  for (const auto& pair_alternative_set : pair_alternative_sets) {
1536  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1537  sibling_alternative_.back() = alternative + 1;
1538  AddAlternativeSet(pair_alternative_set.second);
1539  }
1540  }
1541 #endif // SWIG
1542  int64_t GetActiveInAlternativeSet(int alternative_index) const {
1544  return alternative_index >= 0
1545  ? active_in_alternative_set_[alternative_index]
1546  : -1;
1547  }
1549  int64_t GetActiveAlternativeNode(int node) const {
1550  return GetActiveInAlternativeSet(alternative_index_[node]);
1551  }
1553  int GetSiblingAlternativeIndex(int node) const {
1554  if (node >= alternative_index_.size()) return -1;
1555  const int alternative = alternative_index_[node];
1556  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1557  }
1560  int64_t GetActiveAlternativeSibling(int node) const {
1561  if (node >= alternative_index_.size()) return -1;
1562  const int alternative = alternative_index_[node];
1563  const int sibling_alternative =
1564  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1565  return GetActiveInAlternativeSet(sibling_alternative);
1566  }
1569  bool CheckChainValidity(int64_t before_chain, int64_t chain_end,
1570  int64_t exclude) const;
1571 
1572  const int number_of_nexts_;
1573  const bool ignore_path_vars_;
1575  int num_paths_ = 0;
1576  std::vector<int64_t> start_to_path_;
1577 
1578  private:
1579  void OnStart() override;
1581  bool OnSamePath(int64_t node1, int64_t node2) const;
1582 
1583  bool CheckEnds() const {
1584  const int base_node_size = base_nodes_.size();
1585  for (int i = base_node_size - 1; i >= 0; --i) {
1586  if (base_nodes_[i] != end_nodes_[i]) {
1587  return true;
1588  }
1589  }
1590  return false;
1591  }
1592  bool IncrementPosition();
1593  void InitializePathStarts();
1594  void InitializeInactives();
1595  void InitializeBaseNodes();
1596  void InitializeAlternatives();
1597  void Synchronize();
1598 
1599  std::vector<int> base_nodes_;
1600  std::vector<int> base_alternatives_;
1601  std::vector<int> base_sibling_alternatives_;
1602  std::vector<int> end_nodes_;
1603  std::vector<int> base_paths_;
1604  std::vector<int64_t> path_starts_;
1605  std::vector<bool> inactives_;
1606  bool just_started_;
1607  bool first_start_;
1608  IterationParameters iteration_parameters_;
1609  bool optimal_paths_enabled_;
1610  std::vector<int> path_basis_;
1611  std::vector<bool> optimal_paths_;
1613 #ifndef SWIG
1614  std::vector<std::vector<int64_t>> alternative_sets_;
1615 #endif // SWIG
1616  std::vector<int> alternative_index_;
1617  std::vector<int64_t> active_in_alternative_set_;
1618  std::vector<int> sibling_alternative_;
1619 };
1620 
1622 template <class T>
1623 LocalSearchOperator* MakeLocalSearchOperator(
1624  Solver* solver, const std::vector<IntVar*>& vars,
1625  const std::vector<IntVar*>& secondary_vars,
1626  std::function<int(int64_t)> start_empty_path_class);
1627 
1642 
1643 #if !defined(SWIG)
1644 // A LocalSearchState is a container for variables with bounds that can be
1645 // relaxed and tightened, saved and restored. It represents the solution state
1646 // of a local search engine, and allows it to go from solution to solution by
1647 // relaxing some variables to form a new subproblem, then tightening those
1648 // variables to move to a new solution representation. That state may be saved
1649 // to an internal copy, or reverted to the last saved internal copy.
1650 // Relaxing a variable returns its bounds to their initial state.
1651 // Tightening a variable's bounds may make its min larger than its max,
1652 // in that case, the tightening function will return false, and the state will
1653 // be marked as invalid. No other operations than Revert() can be called on an
1654 // invalid state: in particular, an invalid state cannot be saved.
1655 class LocalSearchVariable;
1656 
1658  public:
1659  LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max);
1660  void Commit();
1661  void Revert();
1662  bool StateIsValid() const { return state_is_valid_; }
1663 
1664  private:
1665  friend class LocalSearchVariable;
1666 
1667  struct Bounds {
1668  int64_t min;
1669  int64_t max;
1670  };
1671 
1672  void RelaxVariableBounds(int variable_index);
1673  bool TightenVariableMin(int variable_index, int64_t value);
1674  bool TightenVariableMax(int variable_index, int64_t value);
1675  int64_t VariableMin(int variable_index) const;
1676  int64_t VariableMax(int variable_index) const;
1677 
1678  std::vector<Bounds> initial_variable_bounds_;
1679  std::vector<Bounds> variable_bounds_;
1680  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1681  std::vector<bool> variable_is_relaxed_;
1682  bool state_is_valid_ = true;
1683 };
1684 
1685 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1686 // meant to be passed by copy. If at some point the duplication of
1687 // LocalSearchState pointers is too expensive, we could switch to index only,
1688 // and the user would have to know the relevant state. The present setup allows
1689 // to ensure that variable users will not misuse the state.
1691  public:
1692  int64_t Min() const { return state_->VariableMin(variable_index_); }
1693  int64_t Max() const { return state_->VariableMax(variable_index_); }
1694  bool SetMin(int64_t new_min) {
1695  return state_->TightenVariableMin(variable_index_, new_min);
1696  }
1697  bool SetMax(int64_t new_max) {
1698  return state_->TightenVariableMax(variable_index_, new_max);
1699  }
1700  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1701 
1702  private:
1703  // Only LocalSearchState can construct LocalSearchVariables.
1704  friend class LocalSearchState;
1705 
1706  LocalSearchVariable(LocalSearchState* state, int variable_index)
1707  : state_(state), variable_index_(variable_index) {}
1708 
1709  LocalSearchState* const state_;
1710  const int variable_index_;
1711 };
1712 #endif // !defined(SWIG)
1713 
1731  public:
1734  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1736  virtual void Commit(const Assignment* delta, const Assignment* deltadelta) {}
1737 
1747  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1748  int64_t objective_min, int64_t objective_max) = 0;
1749  virtual bool IsIncremental() const { return false; }
1750 
1756  virtual void Synchronize(const Assignment* assignment,
1757  const Assignment* delta) = 0;
1759  virtual void Revert() {}
1760 
1762  virtual void Reset() {}
1763 
1765  virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; }
1767  // If the last Accept() call returned false, returns an undefined value.
1768  virtual int64_t GetAcceptedObjectiveValue() const { return 0LL; }
1769 };
1770 
1775  public:
1776  // This class is responsible for calling filters methods in a correct order.
1777  // For now, an order is specified explicitly by the user.
1779  struct FilterEvent {
1782  };
1783 
1784  std::string DebugString() const override {
1785  return "LocalSearchFilterManager";
1786  }
1787  // Builds a manager that calls filter methods using an explicit ordering.
1788  explicit LocalSearchFilterManager(std::vector<FilterEvent> filter_events);
1789  // Builds a manager that calls filter methods using the following ordering:
1790  // first Relax() in vector order, then Accept() in vector order.
1791  // Note that some filters might appear only once, if their Relax() or Accept()
1792  // are trivial.
1793  explicit LocalSearchFilterManager(std::vector<LocalSearchFilter*> filters);
1794 
1795  // Calls Revert() of filters, in reverse order of Relax events.
1796  void Revert();
1800  bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta,
1801  const Assignment* deltadelta, int64_t objective_min,
1802  int64_t objective_max);
1804  void Synchronize(const Assignment* assignment, const Assignment* delta);
1805  int64_t GetSynchronizedObjectiveValue() const { return synchronized_value_; }
1806  int64_t GetAcceptedObjectiveValue() const { return accepted_value_; }
1807 
1808  private:
1809  void InitializeForcedEvents();
1810 
1811  std::vector<FilterEvent> filter_events_;
1812  int last_event_called_ = -1;
1813  // If a filter is incremental, its Relax() and Accept() must be called for
1814  // every candidate, even if a previous Accept() rejected it.
1815  // To ensure that those filters have consistent inputs, all intermediate
1816  // Relax events are also triggered. All those events are called 'forced'.
1817  std::vector<int> next_forced_events_;
1818  int64_t synchronized_value_;
1819  int64_t accepted_value_;
1820 };
1821 
1823  public:
1824  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1825  ~IntVarLocalSearchFilter() override;
1828  void Synchronize(const Assignment* assignment,
1829  const Assignment* delta) override;
1830 
1831  bool FindIndex(IntVar* const var, int64_t* index) const {
1832  DCHECK(index != nullptr);
1833  const int var_index = var->index();
1834  *index = (var_index < var_index_to_index_.size())
1835  ? var_index_to_index_[var_index]
1836  : kUnassigned;
1837  return *index != kUnassigned;
1838  }
1839 
1841  void AddVars(const std::vector<IntVar*>& vars);
1842  int Size() const { return vars_.size(); }
1843  IntVar* Var(int index) const { return vars_[index]; }
1844  int64_t Value(int index) const {
1846  return values_[index];
1847  }
1848  bool IsVarSynced(int index) const { return var_synced_[index]; }
1849 
1850  protected:
1851  virtual void OnSynchronize(const Assignment* delta) {}
1852  void SynchronizeOnAssignment(const Assignment* assignment);
1853 
1854  private:
1855  std::vector<IntVar*> vars_;
1856  std::vector<int64_t> values_;
1857  std::vector<bool> var_synced_;
1858  std::vector<int> var_index_to_index_;
1859  static const int kUnassigned;
1860 };
1861 
1863  public:
1864  explicit PropagationMonitor(Solver* const solver);
1865  ~PropagationMonitor() override;
1866  std::string DebugString() const override { return "PropagationMonitor"; }
1867 
1869  virtual void BeginConstraintInitialPropagation(
1870  Constraint* const constraint) = 0;
1871  virtual void EndConstraintInitialPropagation(
1872  Constraint* const constraint) = 0;
1874  Constraint* const parent, Constraint* const nested) = 0;
1876  Constraint* const parent, Constraint* const nested) = 0;
1877  virtual void RegisterDemon(Demon* const demon) = 0;
1878  virtual void BeginDemonRun(Demon* const demon) = 0;
1879  virtual void EndDemonRun(Demon* const demon) = 0;
1880  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1881  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1882  virtual void PushContext(const std::string& context) = 0;
1883  virtual void PopContext() = 0;
1885  virtual void SetMin(IntExpr* const expr, int64_t new_min) = 0;
1886  virtual void SetMax(IntExpr* const expr, int64_t new_max) = 0;
1887  virtual void SetRange(IntExpr* const expr, int64_t new_min,
1888  int64_t new_max) = 0;
1890  virtual void SetMin(IntVar* const var, int64_t new_min) = 0;
1891  virtual void SetMax(IntVar* const var, int64_t new_max) = 0;
1892  virtual void SetRange(IntVar* const var, int64_t new_min,
1893  int64_t new_max) = 0;
1894  virtual void RemoveValue(IntVar* const var, int64_t value) = 0;
1895  virtual void SetValue(IntVar* const var, int64_t value) = 0;
1896  virtual void RemoveInterval(IntVar* const var, int64_t imin,
1897  int64_t imax) = 0;
1898  virtual void SetValues(IntVar* const var,
1899  const std::vector<int64_t>& values) = 0;
1900  virtual void RemoveValues(IntVar* const var,
1901  const std::vector<int64_t>& values) = 0;
1903  virtual void SetStartMin(IntervalVar* const var, int64_t new_min) = 0;
1904  virtual void SetStartMax(IntervalVar* const var, int64_t new_max) = 0;
1905  virtual void SetStartRange(IntervalVar* const var, int64_t new_min,
1906  int64_t new_max) = 0;
1907  virtual void SetEndMin(IntervalVar* const var, int64_t new_min) = 0;
1908  virtual void SetEndMax(IntervalVar* const var, int64_t new_max) = 0;
1909  virtual void SetEndRange(IntervalVar* const var, int64_t new_min,
1910  int64_t new_max) = 0;
1911  virtual void SetDurationMin(IntervalVar* const var, int64_t new_min) = 0;
1912  virtual void SetDurationMax(IntervalVar* const var, int64_t new_max) = 0;
1913  virtual void SetDurationRange(IntervalVar* const var, int64_t new_min,
1914  int64_t new_max) = 0;
1915  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1917  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1918  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1919  virtual void RankLast(SequenceVar* const var, int index) = 0;
1920  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1921  virtual void RankSequence(SequenceVar* const var,
1922  const std::vector<int>& rank_first,
1923  const std::vector<int>& rank_last,
1924  const std::vector<int>& unperformed) = 0;
1926  void Install() override;
1927 };
1928 
1930  // TODO(user): Add monitoring of local search filters.
1931  public:
1932  explicit LocalSearchMonitor(Solver* const solver);
1933  ~LocalSearchMonitor() override;
1934  std::string DebugString() const override { return "LocalSearchMonitor"; }
1935 
1937  virtual void BeginOperatorStart() = 0;
1938  virtual void EndOperatorStart() = 0;
1939  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1940  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1941  bool neighbor_found, const Assignment* delta,
1942  const Assignment* deltadelta) = 0;
1943  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1944  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1945  bool neighbor_found) = 0;
1946  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1947  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1948  bool neighbor_found) = 0;
1949  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1950  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1951 
1953  void Install() override;
1954 };
1955 
1956 class BooleanVar : public IntVar {
1957  public:
1958  static const int kUnboundBooleanVarValue;
1959 
1960  explicit BooleanVar(Solver* const s, const std::string& name = "")
1962 
1963  ~BooleanVar() override {}
1964 
1965  int64_t Min() const override { return (value_ == 1); }
1966  void SetMin(int64_t m) override;
1967  int64_t Max() const override { return (value_ != 0); }
1968  void SetMax(int64_t m) override;
1969  void SetRange(int64_t mi, int64_t ma) override;
1970  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1971  int64_t Value() const override {
1972  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1973  return value_;
1974  }
1975  void RemoveValue(int64_t v) override;
1976  void RemoveInterval(int64_t l, int64_t u) override;
1977  void WhenBound(Demon* d) override;
1978  void WhenRange(Demon* d) override { WhenBound(d); }
1979  void WhenDomain(Demon* d) override { WhenBound(d); }
1980  uint64_t Size() const override;
1981  bool Contains(int64_t v) const override;
1982  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1983  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1984  std::string DebugString() const override;
1985  int VarType() const override { return BOOLEAN_VAR; }
1986 
1987  IntVar* IsEqual(int64_t constant) override;
1988  IntVar* IsDifferent(int64_t constant) override;
1989  IntVar* IsGreaterOrEqual(int64_t constant) override;
1990  IntVar* IsLessOrEqual(int64_t constant) override;
1991 
1992  virtual void RestoreValue() = 0;
1993  std::string BaseName() const override { return "BooleanVar"; }
1994 
1995  int RawValue() const { return value_; }
1996 
1997  protected:
1998  int value_;
2001 };
2002 
2003 class SymmetryManager;
2004 
2009  public:
2011  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
2012  ~SymmetryBreaker() override {}
2013 
2014  void AddIntegerVariableEqualValueClause(IntVar* const var, int64_t value);
2016  int64_t value);
2018  int64_t value);
2019 
2020  private:
2021  friend class SymmetryManager;
2022  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
2023  CHECK(symmetry_manager_ == nullptr);
2024  CHECK_EQ(-1, index_in_symmetry_manager_);
2025  symmetry_manager_ = manager;
2026  index_in_symmetry_manager_ = index;
2027  }
2028  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
2029  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
2030 
2031  SymmetryManager* symmetry_manager_;
2033  int index_in_symmetry_manager_;
2034 };
2035 
2038 class SearchLog : public SearchMonitor {
2039  public:
2040  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2041  double scaling_factor, double offset,
2042  std::function<std::string()> display_callback,
2043  bool display_on_new_solutions_only, int period);
2044  ~SearchLog() override;
2045  void EnterSearch() override;
2046  void ExitSearch() override;
2047  bool AtSolution() override;
2048  void BeginFail() override;
2049  void NoMoreSolutions() override;
2050  void AcceptUncheckedNeighbor() override;
2051  void ApplyDecision(Decision* const decision) override;
2052  void RefuteDecision(Decision* const decision) override;
2053  void OutputDecision();
2054  void Maintain();
2055  void BeginInitialPropagation() override;
2056  void EndInitialPropagation() override;
2057  std::string DebugString() const override;
2058 
2059  protected:
2060  /* Bottleneck function used for all UI related output. */
2061  virtual void OutputLine(const std::string& line);
2062 
2063  private:
2064  static std::string MemoryUsage();
2065 
2066  const int period_;
2067  std::unique_ptr<WallTimer> timer_;
2068  IntVar* const var_;
2069  OptimizeVar* const obj_;
2070  const double scaling_factor_;
2071  const double offset_;
2072  std::function<std::string()> display_callback_;
2073  const bool display_on_new_solutions_only_;
2074  int nsol_;
2075  int64_t tick_;
2076  int64_t objective_min_;
2077  int64_t objective_max_;
2078  int min_right_depth_;
2079  int max_depth_;
2080  int sliding_min_depth_;
2081  int sliding_max_depth_;
2082 };
2083 
2088 class ModelCache {
2089  public:
2094  };
2095 
2102  };
2103 
2107  };
2108 
2117  };
2118 
2124  };
2125 
2138  };
2139 
2143  };
2144 
2157  };
2161  };
2162 
2166  };
2167 
2171  };
2172 
2178  };
2179 
2183  };
2184 
2185  explicit ModelCache(Solver* const solver);
2186  virtual ~ModelCache();
2187 
2188  virtual void Clear() = 0;
2189 
2191 
2192  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
2193 
2194  virtual void InsertVoidConstraint(Constraint* const ct,
2195  VoidConstraintType type) = 0;
2196 
2199  IntVar* const var, int64_t value,
2200  VarConstantConstraintType type) const = 0;
2201 
2202  virtual void InsertVarConstantConstraint(Constraint* const ct,
2203  IntVar* const var, int64_t value,
2204  VarConstantConstraintType type) = 0;
2205 
2207 
2209  IntVar* const var, int64_t value1, int64_t value2,
2210  VarConstantConstantConstraintType type) const = 0;
2211 
2213  Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2,
2215 
2217 
2219  IntExpr* const expr1, IntExpr* const expr2,
2220  ExprExprConstraintType type) const = 0;
2221 
2222  virtual void InsertExprExprConstraint(Constraint* const ct,
2223  IntExpr* const expr1,
2224  IntExpr* const expr2,
2225  ExprExprConstraintType type) = 0;
2226 
2228 
2229  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2230  ExprExpressionType type) const = 0;
2231 
2232  virtual void InsertExprExpression(IntExpr* const expression,
2233  IntExpr* const expr,
2234  ExprExpressionType type) = 0;
2235 
2237 
2239  IntExpr* const expr, int64_t value,
2240  ExprConstantExpressionType type) const = 0;
2241 
2242  virtual void InsertExprConstantExpression(
2243  IntExpr* const expression, IntExpr* const var, int64_t value,
2244  ExprConstantExpressionType type) = 0;
2245 
2247 
2249  IntExpr* const var1, IntExpr* const var2,
2250  ExprExprExpressionType type) const = 0;
2251 
2252  virtual void InsertExprExprExpression(IntExpr* const expression,
2253  IntExpr* const var1,
2254  IntExpr* const var2,
2255  ExprExprExpressionType type) = 0;
2256 
2258 
2260  IntExpr* const var1, IntExpr* const var2, int64_t constant,
2261  ExprExprConstantExpressionType type) const = 0;
2262 
2263  virtual void InsertExprExprConstantExpression(
2264  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2265  int64_t constant, ExprExprConstantExpressionType type) = 0;
2266 
2268 
2270  IntVar* const var, int64_t value1, int64_t value2,
2271  VarConstantConstantExpressionType type) const = 0;
2272 
2274  IntExpr* const expression, IntVar* const var, int64_t value1,
2275  int64_t value2, VarConstantConstantExpressionType type) = 0;
2276 
2278 
2280  IntVar* const var, const std::vector<int64_t>& values,
2281  VarConstantArrayExpressionType type) const = 0;
2282 
2283  virtual void InsertVarConstantArrayExpression(
2284  IntExpr* const expression, IntVar* const var,
2285  const std::vector<int64_t>& values,
2287 
2289 
2291  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2292 
2293  virtual void InsertVarArrayExpression(IntExpr* const expression,
2294  const std::vector<IntVar*>& vars,
2295  VarArrayExpressionType type) = 0;
2296 
2298 
2300  const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
2301  VarArrayConstantArrayExpressionType type) const = 0;
2302 
2304  IntExpr* const expression, const std::vector<IntVar*>& var,
2305  const std::vector<int64_t>& values,
2307 
2309 
2311  const std::vector<IntVar*>& vars, int64_t value,
2312  VarArrayConstantExpressionType type) const = 0;
2313 
2314  virtual void InsertVarArrayConstantExpression(
2315  IntExpr* const expression, const std::vector<IntVar*>& var, int64_t value,
2317 
2318  Solver* solver() const;
2319 
2320  private:
2321  Solver* const solver_;
2322 };
2323 
2325 #if !defined(SWIG)
2327  public:
2329  const std::string& TypeName() const;
2330  void SetTypeName(const std::string& type_name);
2331 
2333  void SetIntegerArgument(const std::string& arg_name, int64_t value);
2334  void SetIntegerArrayArgument(const std::string& arg_name,
2335  const std::vector<int64_t>& values);
2336  void SetIntegerMatrixArgument(const std::string& arg_name,
2337  const IntTupleSet& values);
2338  void SetIntegerExpressionArgument(const std::string& arg_name,
2339  IntExpr* const expr);
2340  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2341  const std::vector<IntVar*>& vars);
2342  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2343  void SetIntervalArrayArgument(const std::string& arg_name,
2344  const std::vector<IntervalVar*>& vars);
2345  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2346  void SetSequenceArrayArgument(const std::string& arg_name,
2347  const std::vector<SequenceVar*>& vars);
2348 
2350  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2351  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2352 
2354  int64_t FindIntegerArgumentWithDefault(const std::string& arg_name,
2355  int64_t def) const;
2356  int64_t FindIntegerArgumentOrDie(const std::string& arg_name) const;
2357  const std::vector<int64_t>& FindIntegerArrayArgumentOrDie(
2358  const std::string& arg_name) const;
2360  const std::string& arg_name) const;
2361 
2363  const std::string& arg_name) const;
2364  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2365  const std::string& arg_name) const;
2366 
2367  private:
2368  std::string type_name_;
2369  absl::flat_hash_map<std::string, int64_t> integer_argument_;
2370  absl::flat_hash_map<std::string, std::vector<int64_t>>
2371  integer_array_argument_;
2372  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2373  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2374  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2375  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2376  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2377  integer_variable_array_argument_;
2378  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2379  interval_array_argument_;
2380  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2381  sequence_array_argument_;
2382 };
2383 
2385 class ModelParser : public ModelVisitor {
2386  public:
2387  ModelParser();
2388 
2389  ~ModelParser() override;
2390 
2392  void BeginVisitModel(const std::string& solver_name) override;
2393  void EndVisitModel(const std::string& solver_name) override;
2394  void BeginVisitConstraint(const std::string& type_name,
2395  const Constraint* const constraint) override;
2396  void EndVisitConstraint(const std::string& type_name,
2397  const Constraint* const constraint) override;
2398  void BeginVisitIntegerExpression(const std::string& type_name,
2399  const IntExpr* const expr) override;
2400  void EndVisitIntegerExpression(const std::string& type_name,
2401  const IntExpr* const expr) override;
2402  void VisitIntegerVariable(const IntVar* const variable,
2403  IntExpr* const delegate) override;
2404  void VisitIntegerVariable(const IntVar* const variable,
2405  const std::string& operation, int64_t value,
2406  IntVar* const delegate) override;
2407  void VisitIntervalVariable(const IntervalVar* const variable,
2408  const std::string& operation, int64_t value,
2409  IntervalVar* const delegate) override;
2410  void VisitSequenceVariable(const SequenceVar* const variable) override;
2412  void VisitIntegerArgument(const std::string& arg_name,
2413  int64_t value) override;
2414  void VisitIntegerArrayArgument(const std::string& arg_name,
2415  const std::vector<int64_t>& values) override;
2416  void VisitIntegerMatrixArgument(const std::string& arg_name,
2417  const IntTupleSet& values) override;
2419  void VisitIntegerExpressionArgument(const std::string& arg_name,
2420  IntExpr* const argument) override;
2422  const std::string& arg_name,
2423  const std::vector<IntVar*>& arguments) override;
2425  void VisitIntervalArgument(const std::string& arg_name,
2426  IntervalVar* const argument) override;
2428  const std::string& arg_name,
2429  const std::vector<IntervalVar*>& arguments) override;
2431  void VisitSequenceArgument(const std::string& arg_name,
2432  SequenceVar* const argument) override;
2434  const std::string& arg_name,
2435  const std::vector<SequenceVar*>& arguments) override;
2436 
2437  protected:
2438  void PushArgumentHolder();
2439  void PopArgumentHolder();
2440  ArgumentHolder* Top() const;
2441 
2442  private:
2443  std::vector<ArgumentHolder*> holders_;
2444 };
2445 
2446 template <class T>
2447 class ArrayWithOffset : public BaseObject {
2448  public:
2449  ArrayWithOffset(int64_t index_min, int64_t index_max)
2450  : index_min_(index_min),
2451  index_max_(index_max),
2452  values_(new T[index_max - index_min + 1]) {
2453  DCHECK_LE(index_min, index_max);
2454  }
2455 
2456  ~ArrayWithOffset() override {}
2457 
2458  virtual T Evaluate(int64_t index) const {
2459  DCHECK_GE(index, index_min_);
2460  DCHECK_LE(index, index_max_);
2461  return values_[index - index_min_];
2462  }
2463 
2464  void SetValue(int64_t index, T value) {
2465  DCHECK_GE(index, index_min_);
2466  DCHECK_LE(index, index_max_);
2467  values_[index - index_min_] = value;
2468  }
2469 
2470  std::string DebugString() const override { return "ArrayWithOffset"; }
2471 
2472  private:
2473  const int64_t index_min_;
2474  const int64_t index_max_;
2475  std::unique_ptr<T[]> values_;
2476 };
2477 #endif // SWIG
2478 
2483 template <class T, class C>
2485  public:
2486  explicit RevGrowingArray(int64_t block_size)
2487  : block_size_(block_size), block_offset_(0) {
2488  CHECK_GT(block_size, 0);
2489  }
2490 
2492  for (int i = 0; i < elements_.size(); ++i) {
2493  delete[] elements_[i];
2494  }
2495  }
2496 
2497  T At(int64_t index) const {
2498  const int64_t block_index = ComputeBlockIndex(index);
2499  const int64_t relative_index = block_index - block_offset_;
2500  if (relative_index < 0 || relative_index >= elements_.size()) {
2501  return T();
2502  }
2503  const T* block = elements_[relative_index];
2504  return block != nullptr ? block[index - block_index * block_size_] : T();
2505  }
2506 
2507  void RevInsert(Solver* const solver, int64_t index, T value) {
2508  const int64_t block_index = ComputeBlockIndex(index);
2509  T* const block = GetOrCreateBlock(block_index);
2510  const int64_t residual = index - block_index * block_size_;
2511  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2512  reinterpret_cast<C>(value));
2513  }
2514 
2515  private:
2516  T* NewBlock() const {
2517  T* const result = new T[block_size_];
2518  for (int i = 0; i < block_size_; ++i) {
2519  result[i] = T();
2520  }
2521  return result;
2522  }
2523 
2524  T* GetOrCreateBlock(int block_index) {
2525  if (elements_.size() == 0) {
2526  block_offset_ = block_index;
2527  GrowUp(block_index);
2528  } else if (block_index < block_offset_) {
2529  GrowDown(block_index);
2530  } else if (block_index - block_offset_ >= elements_.size()) {
2531  GrowUp(block_index);
2532  }
2533  T* block = elements_[block_index - block_offset_];
2534  if (block == nullptr) {
2535  block = NewBlock();
2536  elements_[block_index - block_offset_] = block;
2537  }
2538  return block;
2539  }
2540 
2541  int64_t ComputeBlockIndex(int64_t value) const {
2542  return value >= 0 ? value / block_size_
2543  : (value - block_size_ + 1) / block_size_;
2544  }
2545 
2546  void GrowUp(int64_t block_index) {
2547  elements_.resize(block_index - block_offset_ + 1);
2548  }
2549 
2550  void GrowDown(int64_t block_index) {
2551  const int64_t delta = block_offset_ - block_index;
2552  block_offset_ = block_index;
2553  DCHECK_GT(delta, 0);
2554  elements_.insert(elements_.begin(), delta, nullptr);
2555  }
2556 
2557  const int64_t block_size_;
2558  std::vector<T*> elements_;
2559  int block_offset_;
2560 };
2561 
2566 template <class T>
2567 class RevIntSet {
2568  public:
2569  static constexpr int kNoInserted = -1;
2570 
2572  explicit RevIntSet(int capacity)
2573  : elements_(new T[capacity]),
2574  num_elements_(0),
2575  capacity_(capacity),
2576  position_(new int[capacity]),
2577  delete_position_(true) {
2578  for (int i = 0; i < capacity; ++i) {
2579  position_[i] = kNoInserted;
2580  }
2581  }
2582 
2584  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2585  : elements_(new T[capacity]),
2586  num_elements_(0),
2587  capacity_(capacity),
2588  position_(shared_positions),
2589  delete_position_(false) {
2590  for (int i = 0; i < shared_positions_size; ++i) {
2591  position_[i] = kNoInserted;
2592  }
2593  }
2594 
2596  if (delete_position_) {
2597  delete[] position_;
2598  }
2599  }
2600 
2601  int Size() const { return num_elements_.Value(); }
2602 
2603  int Capacity() const { return capacity_; }
2604 
2605  T Element(int i) const {
2606  DCHECK_GE(i, 0);
2607  DCHECK_LT(i, num_elements_.Value());
2608  return elements_[i];
2609  }
2610 
2611  T RemovedElement(int i) const {
2612  DCHECK_GE(i, 0);
2613  DCHECK_LT(i + num_elements_.Value(), capacity_);
2614  return elements_[i + num_elements_.Value()];
2615  }
2616 
2617  void Insert(Solver* const solver, const T& elt) {
2618  const int position = num_elements_.Value();
2619  DCHECK_LT(position, capacity_);
2620  DCHECK(NotAlreadyInserted(elt));
2621  elements_[position] = elt;
2622  position_[elt] = position;
2623  num_elements_.Incr(solver);
2624  }
2625 
2626  void Remove(Solver* const solver, const T& value_index) {
2627  num_elements_.Decr(solver);
2628  SwapTo(value_index, num_elements_.Value());
2629  }
2630 
2631  void Restore(Solver* const solver, const T& value_index) {
2632  SwapTo(value_index, num_elements_.Value());
2633  num_elements_.Incr(solver);
2634  }
2635 
2636  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2637 
2639  typedef const T* const_iterator;
2640  const_iterator begin() const { return elements_.get(); }
2641  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2642 
2643  private:
2645  bool NotAlreadyInserted(const T& elt) {
2646  for (int i = 0; i < num_elements_.Value(); ++i) {
2647  if (elt == elements_[i]) {
2648  return false;
2649  }
2650  }
2651  return true;
2652  }
2653 
2654  void SwapTo(T value_index, int next_position) {
2655  const int current_position = position_[value_index];
2656  if (current_position != next_position) {
2657  const T next_value_index = elements_[next_position];
2658  elements_[current_position] = next_value_index;
2659  elements_[next_position] = value_index;
2660  position_[value_index] = next_position;
2661  position_[next_value_index] = current_position;
2662  }
2663  }
2664 
2666  std::unique_ptr<T[]> elements_;
2668  NumericalRev<int> num_elements_;
2670  const int capacity_;
2672  int* position_;
2674  const bool delete_position_;
2675 };
2676 
2678 
2680  public:
2681  explicit RevPartialSequence(const std::vector<int>& items)
2682  : elements_(items),
2683  first_ranked_(0),
2684  last_ranked_(items.size() - 1),
2685  size_(items.size()),
2686  position_(new int[size_]) {
2687  for (int i = 0; i < size_; ++i) {
2688  elements_[i] = items[i];
2689  position_[i] = i;
2690  }
2691  }
2692 
2693  explicit RevPartialSequence(int size)
2694  : elements_(size),
2695  first_ranked_(0),
2696  last_ranked_(size - 1),
2697  size_(size),
2698  position_(new int[size_]) {
2699  for (int i = 0; i < size_; ++i) {
2700  elements_[i] = i;
2701  position_[i] = i;
2702  }
2703  }
2704 
2706 
2707  int NumFirstRanked() const { return first_ranked_.Value(); }
2708 
2709  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2710 
2711  int Size() const { return size_; }
2712 
2713 #if !defined(SWIG)
2714  const int& operator[](int index) const {
2715  DCHECK_GE(index, 0);
2716  DCHECK_LT(index, size_);
2717  return elements_[index];
2718  }
2719 #endif
2720 
2721  void RankFirst(Solver* const solver, int elt) {
2722  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2723  SwapTo(elt, first_ranked_.Value());
2724  first_ranked_.Incr(solver);
2725  }
2726 
2727  void RankLast(Solver* const solver, int elt) {
2728  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2729  SwapTo(elt, last_ranked_.Value());
2730  last_ranked_.Decr(solver);
2731  }
2732 
2733  bool IsRanked(int elt) const {
2734  const int position = position_[elt];
2735  return (position < first_ranked_.Value() ||
2736  position > last_ranked_.Value());
2737  }
2738 
2739  std::string DebugString() const {
2740  std::string result = "[";
2741  for (int i = 0; i < first_ranked_.Value(); ++i) {
2742  absl::StrAppend(&result, elements_[i]);
2743  if (i != first_ranked_.Value() - 1) {
2744  result.append("-");
2745  }
2746  }
2747  result.append("|");
2748  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2749  absl::StrAppend(&result, elements_[i]);
2750  if (i != last_ranked_.Value()) {
2751  result.append("-");
2752  }
2753  }
2754  result.append("|");
2755  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2756  absl::StrAppend(&result, elements_[i]);
2757  if (i != size_ - 1) {
2758  result.append("-");
2759  }
2760  }
2761  result.append("]");
2762  return result;
2763  }
2764 
2765  private:
2766  void SwapTo(int elt, int next_position) {
2767  const int current_position = position_[elt];
2768  if (current_position != next_position) {
2769  const int next_elt = elements_[next_position];
2770  elements_[current_position] = next_elt;
2771  elements_[next_position] = elt;
2772  position_[elt] = next_position;
2773  position_[next_elt] = current_position;
2774  }
2775  }
2776 
2778  std::vector<int> elements_;
2780  NumericalRev<int> first_ranked_;
2782  NumericalRev<int> last_ranked_;
2784  const int size_;
2786  std::unique_ptr<int[]> position_;
2787 };
2788 
2794  public:
2796  explicit UnsortedNullableRevBitset(int bit_size);
2797 
2799 
2802  void Init(Solver* const solver, const std::vector<uint64_t>& mask);
2803 
2806  bool RevSubtract(Solver* const solver, const std::vector<uint64_t>& mask);
2807 
2810  bool RevAnd(Solver* const solver, const std::vector<uint64_t>& mask);
2811 
2814  int ActiveWordSize() const { return active_words_.Size(); }
2815 
2817  bool Empty() const { return active_words_.Size() == 0; }
2818 
2826  bool Intersects(const std::vector<uint64_t>& mask, int* support_index);
2827 
2829  int64_t bit_size() const { return bit_size_; }
2831  int64_t word_size() const { return word_size_; }
2833  const RevIntSet<int>& active_words() const { return active_words_; }
2834 
2835  private:
2836  void CleanUpActives(Solver* const solver);
2837 
2838  const int64_t bit_size_;
2839  const int64_t word_size_;
2840  RevArray<uint64_t> bits_;
2841  RevIntSet<int> active_words_;
2842  std::vector<int> to_remove_;
2843 };
2844 
2845 template <class T>
2846 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2847  for (int i = 0; i < values.size(); ++i) {
2848  if (values[i] != value) {
2849  return false;
2850  }
2851  }
2852  return true;
2853 }
2854 
2855 template <class T>
2856 bool IsArrayBoolean(const std::vector<T>& values) {
2857  for (int i = 0; i < values.size(); ++i) {
2858  if (values[i] != 0 && values[i] != 1) {
2859  return false;
2860  }
2861  }
2862  return true;
2863 }
2864 
2865 template <class T>
2866 bool AreAllOnes(const std::vector<T>& values) {
2867  return IsArrayConstant(values, T(1));
2868 }
2869 
2870 template <class T>
2871 bool AreAllNull(const std::vector<T>& values) {
2872  return IsArrayConstant(values, T(0));
2873 }
2874 
2875 template <class T>
2876 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2877  for (const T& current_value : values) {
2878  if (current_value < value) {
2879  return false;
2880  }
2881  }
2882  return true;
2883 }
2884 
2885 template <class T>
2886 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2887  for (const T& current_value : values) {
2888  if (current_value > value) {
2889  return false;
2890  }
2891  }
2892  return true;
2893 }
2894 
2895 template <class T>
2896 bool AreAllPositive(const std::vector<T>& values) {
2897  return AreAllGreaterOrEqual(values, T(0));
2898 }
2899 
2900 template <class T>
2901 bool AreAllNegative(const std::vector<T>& values) {
2902  return AreAllLessOrEqual(values, T(0));
2903 }
2904 
2905 template <class T>
2906 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2907  return AreAllGreaterOrEqual(values, T(1));
2908 }
2909 
2910 template <class T>
2911 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2912  return AreAllLessOrEqual(values, T(-1));
2913 }
2914 
2915 template <class T>
2916 bool IsIncreasingContiguous(const std::vector<T>& values) {
2917  for (int i = 0; i < values.size() - 1; ++i) {
2918  if (values[i + 1] != values[i] + 1) {
2919  return false;
2920  }
2921  }
2922  return true;
2923 }
2924 
2925 template <class T>
2926 bool IsIncreasing(const std::vector<T>& values) {
2927  for (int i = 0; i < values.size() - 1; ++i) {
2928  if (values[i + 1] < values[i]) {
2929  return false;
2930  }
2931  }
2932  return true;
2933 }
2934 
2935 template <class T>
2936 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2937  T range_max) {
2938  for (int i = 0; i < vars.size(); ++i) {
2939  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2940  return false;
2941  }
2942  }
2943  return true;
2944 }
2945 
2946 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2947  for (int i = 0; i < vars.size(); ++i) {
2948  if (!vars[i]->Bound()) {
2949  return false;
2950  }
2951  }
2952  return true;
2953 }
2954 
2955 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2956  return IsArrayInRange(vars, 0, 1);
2957 }
2958 
2961 template <class T>
2962 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2963  const std::vector<T>& values) {
2964  for (int i = 0; i < vars.size(); ++i) {
2965  if (values[i] != 0 && !vars[i]->Bound()) {
2966  return false;
2967  }
2968  }
2969  return true;
2970 }
2971 
2973 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64_t value) {
2974  for (int i = 0; i < vars.size(); ++i) {
2975  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2976  return false;
2977  }
2978  }
2979  return true;
2980 }
2981 
2982 inline int64_t MaxVarArray(const std::vector<IntVar*>& vars) {
2983  DCHECK(!vars.empty());
2984  int64_t result = kint64min;
2985  for (int i = 0; i < vars.size(); ++i) {
2987  result = std::max<int64_t>(result, vars[i]->Max());
2988  }
2989  return result;
2990 }
2991 
2992 inline int64_t MinVarArray(const std::vector<IntVar*>& vars) {
2993  DCHECK(!vars.empty());
2994  int64_t result = kint64max;
2995  for (int i = 0; i < vars.size(); ++i) {
2997  result = std::min<int64_t>(result, vars[i]->Min());
2998  }
2999  return result;
3000 }
3001 
3002 inline void FillValues(const std::vector<IntVar*>& vars,
3003  std::vector<int64_t>* const values) {
3004  values->clear();
3005  values->resize(vars.size());
3006  for (int i = 0; i < vars.size(); ++i) {
3007  (*values)[i] = vars[i]->Value();
3008  }
3009 }
3010 
3011 inline int64_t PosIntDivUp(int64_t e, int64_t v) {
3012  DCHECK_GT(v, 0);
3013  return (e < 0 || e % v == 0) ? e / v : e / v + 1;
3014 }
3015 
3016 inline int64_t PosIntDivDown(int64_t e, int64_t v) {
3017  DCHECK_GT(v, 0);
3018  return (e >= 0 || e % v == 0) ? e / v : e / v - 1;
3019 }
3020 
3021 std::vector<int64_t> ToInt64Vector(const std::vector<int>& input);
3022 
3023 #if !defined(SWIG)
3024 // A PathState represents a set of paths and changes made on it.
3025 //
3026 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
3027 // directed graphs with nodes [0, num_nodes) whose connected components are
3028 // paths from starts[i] to ends[i] (for the same i) and loops.
3029 // Let us fix num_nodes, starts and ends, so we call these P-graphs.
3030 //
3031 // A P-graph can be described by the sequence of nodes of each of its paths,
3032 // and its set of loops. To describe a change made on a given P-graph G0 that
3033 // yields another P-graph G1, we choose to describe G1 in terms of G0. When
3034 // the difference between G0 and G1 is small, as is almost always the case in a
3035 // local search setting, the description is compact, allowing for incremental
3036 // filters to be efficient.
3037 //
3038 // In order to describe G1 in terms of G0 succintly, we describe each path of
3039 // G1 as a sequence of chains of G0. A chain of G0 is either a nonempty sequence
3040 // of consecutive nodes of a path of G0, or a node that was a loop in G0.
3041 // For instance, a path that was not modified from G0 to G1 has one chain,
3042 // the sequence of all nodes in the path. Typically, local search operators
3043 // modify one or two paths, and the resulting paths can described as sequences
3044 // of two to four chains of G0. Paths that were modified are listed explicitly,
3045 // allowing to iterate only on changed paths.
3046 // The loops of G1 are described more implicitly: the loops of G1 not in G0
3047 // are listed explicitly, but those in both G1 and G0 are not listed.
3048 //
3049 // A PathState object can be in two states: committed or changed.
3050 // At construction, the object is committed, G0.
3051 // To enter a changed state G1, one can pass modifications with ChangePath() and
3052 // ChangeLoops(). For reasons of efficiency, a chain is described as a range of
3053 // node indices in the representation of the committed graph G0. To that effect,
3054 // the nodes of a path of G0 are guaranteed to have consecutive indices.
3055 //
3056 // Filters can then browse the change efficiently using ChangedPaths(),
3057 // Chains(), Nodes() and ChangedLoops().
3058 //
3059 // Then Commit() or Revert() can be called: Commit() sets the changed state G1
3060 // as the new committed state, Revert() erases all changes.
3061 class PathState {
3062  public:
3063  // A Chain allows to iterate on all nodes of a chain, and access some data:
3064  // first node, last node, number of nodes in the chain.
3065  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3066  // Chains are returned by PathChainIterator's operator*().
3067  class Chain;
3068  // A ChainRange allows to iterate on all chains of a path.
3069  // ChainRange is a range, its iterator Chain*, its value type Chain.
3070  class ChainRange;
3071  // A NodeRange allows to iterate on all nodes of a path.
3072  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3073  class NodeRange;
3074 
3075  // Path constructor: path_start and path_end must be disjoint,
3076  // their values in [0, num_nodes).
3077  PathState(int num_nodes, std::vector<int> path_start,
3078  std::vector<int> path_end);
3079 
3080  // Instance-constant accessors.
3081 
3082  // Returns the number of nodes in the underlying graph.
3083  int NumNodes() const { return num_nodes_; }
3084  // Returns the number of paths (empty paths included).
3085  int NumPaths() const { return num_paths_; }
3086  // Returns the start of a path.
3087  int Start(int path) const { return path_start_end_[path].start; }
3088  // Returns the end of a path.
3089  int End(int path) const { return path_start_end_[path].end; }
3090 
3091  // State-dependent accessors.
3092 
3093  // Returns the committed path of a given node, -1 if it is a loop.
3094  int Path(int node) const {
3095  return committed_nodes_[committed_index_[node]].path;
3096  }
3097  // Returns the set of arcs that have been added,
3098  // i.e. that were changed and were not in the committed state.
3099  const std::vector<std::pair<int, int>>& ChangedArcs() const {
3100  return changed_arcs_;
3101  }
3102  // Returns the set of paths that actually changed,
3103  // i.e. that have an arc in ChangedArcs().
3104  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3105  // Returns the current range of chains of path.
3106  ChainRange Chains(int path) const;
3107  // Returns the current range of nodes of path.
3108  NodeRange Nodes(int path) const;
3109 
3110  // State modifiers.
3111 
3112  // Adds arc (node, new_next) to the changed state, more formally,
3113  // changes the state from (P0, D) to (P0, D + (node, new_next)).
3114  void ChangeNext(int node, int new_next) {
3115  changed_arcs_.emplace_back(node, new_next);
3116  }
3117  // Marks the end of ChangeNext() sequence, more formally,
3118  // changes the state from (P0, D) to (P0 |> D, D).
3119  void CutChains();
3120  // Makes the current temporary state permanent, more formally,
3121  // changes the state from (P0 |> D, D) to (P0 + D, \emptyset),
3122  void Commit();
3123  // Erase incremental changes made by ChangeNext() and CutChains(),
3124  // more formally, changes the state from (P0 |> D, D) to (P0, \emptyset).
3125  void Revert();
3126 
3127  // LNS Operators may not fix variables,
3128  // in which case we mark the candidate invalid.
3129  void SetInvalid() { is_invalid_ = true; }
3130  bool IsInvalid() const { return is_invalid_; }
3131 
3132  private:
3133  // Most structs below are named pairs of ints, for typing purposes.
3134 
3135  // Start and end are stored together to optimize (likely) simultaneous access.
3136  struct PathStartEnd {
3137  PathStartEnd(int start, int end) : start(start), end(end) {}
3138  int start;
3139  int end;
3140  };
3141  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3142  struct PathBounds {
3143  int begin_index;
3144  int end_index;
3145  };
3146  struct ChainBounds {
3147  ChainBounds() = default;
3148  ChainBounds(int begin_index, int end_index)
3149  : begin_index(begin_index), end_index(end_index) {}
3150  int begin_index;
3151  int end_index;
3152  };
3153  struct CommittedNode {
3154  CommittedNode(int node, int path) : node(node), path(path) {}
3155  int node;
3156  // Path of node in the committed state, -1 for loop nodes.
3157  // TODO(user): check if path would be better stored
3158  // with committed_index_, or in its own vector, or just recomputed.
3159  int path;
3160  };
3161  // Used in temporary structures, see below.
3162  struct TailHeadIndices {
3163  int tail_index;
3164  int head_index;
3165  };
3166  struct IndexArc {
3167  int index;
3168  int arc;
3169  bool operator<(const IndexArc& other) const { return index < other.index; }
3170  };
3171 
3172  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3173  // Selection-based algorithm in O(n^2), to use for small change sets.
3174  void MakeChainsFromChangedPathsAndArcsWithSelectionAlgorithm();
3175  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3176  // Generic algorithm in O(std::sort(n)+n), to use for larger change sets.
3177  void MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm();
3178 
3179  // Copies nodes in chains of path at the end of nodes,
3180  // and sets those nodes' path member to value path.
3181  void CopyNewPathAtEndOfNodes(int path);
3182  // Commits paths in O(#{changed paths' nodes}) time,
3183  // increasing this object's space usage by O(|changed path nodes|).
3184  void IncrementalCommit();
3185  // Commits paths in O(num_nodes + num_paths) time,
3186  // reducing this object's space usage to O(num_nodes + num_paths).
3187  void FullCommit();
3188 
3189  // Instance-constant data.
3190  const int num_nodes_;
3191  const int num_paths_;
3192  std::vector<PathStartEnd> path_start_end_;
3193 
3194  // Representation of the committed and changed paths.
3195  // A path is a range of chains, which is a range of nodes.
3196  // Ranges are represented internally by indices in vectors:
3197  // ChainBounds are indices in committed_nodes_. PathBounds are indices in
3198  // chains_. When committed (after construction, Revert() or Commit()):
3199  // - path ranges are [path, path+1): they have one chain.
3200  // - chain ranges don't overlap, chains_ has an empty sentinel at the end.
3201  // - committed_nodes_ contains all nodes and old duplicates may appear,
3202  // the current version of a node is at the index given by
3203  // committed_index_[node]. A Commit() can add nodes at the end of
3204  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3205  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3206  // space by rewriting the path/chain/nodes structure.
3207  // When changed (after CutChains()), new chains are computed,
3208  // and the structure is updated accordingly:
3209  // - path ranges that were changed have nonoverlapping values [begin, end)
3210  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3211  // committed state.
3212  // - additional chain ranges are stored after the committed chains
3213  // to represent the new chains resulting from the changes.
3214  // Those chains do not overlap with each other or with unchanged chains.
3215  // An empty sentinel chain is added at the end of additional chains.
3216  // - committed_nodes_ are not modified, and still represent the committed
3217  // paths.
3218  // committed_index_ is not modified either.
3219  std::vector<CommittedNode> committed_nodes_;
3220  std::vector<int> committed_index_;
3221  const int num_nodes_threshold_;
3222  std::vector<ChainBounds> chains_;
3223  std::vector<PathBounds> paths_;
3224 
3225  // Incremental information: indices of nodes whose successor have changed,
3226  // path that have changed nodes.
3227  std::vector<std::pair<int, int>> changed_arcs_;
3228  std::vector<int> changed_paths_;
3229  std::vector<bool> path_has_changed_;
3230 
3231  // Temporary structures, since they will be reused heavily,
3232  // those are members in order to be allocated once and for all.
3233  std::vector<TailHeadIndices> tail_head_indices_;
3234  std::vector<IndexArc> arcs_by_tail_index_;
3235  std::vector<IndexArc> arcs_by_head_index_;
3236  std::vector<int> next_arc_;
3237 
3238  // See IsInvalid() and SetInvalid().
3239  bool is_invalid_ = false;
3240 };
3241 
3242 // A Chain is a range of committed nodes.
3244  public:
3245  class Iterator {
3246  public:
3248  ++current_node_;
3249  return *this;
3250  }
3251  int operator*() const { return current_node_->node; }
3252  bool operator!=(Iterator other) const {
3253  return current_node_ != other.current_node_;
3254  }
3255 
3256  private:
3257  // Only a Chain can construct its iterator.
3258  friend class PathState::Chain;
3259  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3260  const CommittedNode* current_node_;
3261  };
3262 
3263  // Chains hold CommittedNode* values, a Chain may be invalidated
3264  // if the underlying vector is modified.
3265  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3266  : begin_(begin_node), end_(end_node) {}
3267 
3268  int NumNodes() const { return end_ - begin_; }
3269  int First() const { return begin_->node; }
3270  int Last() const { return (end_ - 1)->node; }
3271  Iterator begin() const { return Iterator(begin_); }
3272  Iterator end() const { return Iterator(end_); }
3273 
3274  private:
3275  const CommittedNode* const begin_;
3276  const CommittedNode* const end_;
3277 };
3278 
3279 // A ChainRange is a range of Chains, committed or not.
3281  public:
3282  class Iterator {
3283  public:
3285  ++current_chain_;
3286  return *this;
3287  }
3288  Chain operator*() const {
3289  return {first_node_ + current_chain_->begin_index,
3290  first_node_ + current_chain_->end_index};
3291  }
3292  bool operator!=(Iterator other) const {
3293  return current_chain_ != other.current_chain_;
3294  }
3295 
3296  private:
3297  // Only a ChainRange can construct its Iterator.
3298  friend class ChainRange;
3299  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3300  : current_chain_(chain), first_node_(first_node) {}
3301  const ChainBounds* current_chain_;
3302  const CommittedNode* const first_node_;
3303  };
3304 
3305  // ChainRanges hold ChainBounds* and CommittedNode*,
3306  // a ChainRange may be invalidated if on of the underlying vector is modified.
3307  ChainRange(const ChainBounds* const begin_chain,
3308  const ChainBounds* const end_chain,
3309  const CommittedNode* const first_node)
3310  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3311 
3312  Iterator begin() const { return {begin_, first_node_}; }
3313  Iterator end() const { return {end_, first_node_}; }
3314 
3315  private:
3316  const ChainBounds* const begin_;
3317  const ChainBounds* const end_;
3318  const CommittedNode* const first_node_;
3319 };
3320 
3321 // A NodeRange allows to iterate on all nodes of a path,
3322 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3324  public:
3325  class Iterator {
3326  public:
3328  ++current_node_;
3329  if (current_node_ == end_node_) {
3330  ++current_chain_;
3331  // Note: dereferencing bounds is valid because there is a sentinel
3332  // value at the end of PathState::chains_ to that intent.
3333  const ChainBounds bounds = *current_chain_;
3334  current_node_ = first_node_ + bounds.begin_index;
3335  end_node_ = first_node_ + bounds.end_index;
3336  }
3337  return *this;
3338  }
3339  int operator*() const { return current_node_->node; }
3340  bool operator!=(Iterator other) const {
3341  return current_chain_ != other.current_chain_;
3342  }
3343 
3344  private:
3345  // Only a NodeRange can construct its Iterator.
3346  friend class NodeRange;
3347  Iterator(const ChainBounds* current_chain,
3348  const CommittedNode* const first_node)
3349  : current_node_(first_node + current_chain->begin_index),
3350  end_node_(first_node + current_chain->end_index),
3351  current_chain_(current_chain),
3352  first_node_(first_node) {}
3353  const CommittedNode* current_node_;
3354  const CommittedNode* end_node_;
3355  const ChainBounds* current_chain_;
3356  const CommittedNode* const first_node_;
3357  };
3358 
3359  // NodeRanges hold ChainBounds* and CommittedNode*,
3360  // a NodeRange may be invalidated if on of the underlying vector is modified.
3361  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3362  const CommittedNode* first_node)
3363  : begin_chain_(begin_chain),
3364  end_chain_(end_chain),
3365  first_node_(first_node) {}
3366  Iterator begin() const { return {begin_chain_, first_node_}; }
3367  // Note: there is a sentinel value at the end of PathState::chains_,
3368  // so dereferencing chain_range_.end()->begin_ is always valid.
3369  Iterator end() const { return {end_chain_, first_node_}; }
3370 
3371  private:
3372  const ChainBounds* begin_chain_;
3373  const ChainBounds* end_chain_;
3374  const CommittedNode* const first_node_;
3375 };
3376 
3377 // This checker enforces unary dimension requirements.
3378 // A unary dimension requires that there is some valuation of
3379 // node_capacity and demand such that for all paths,
3380 // if arc A -> B is on a path of path_class p,
3381 // then node_capacity[A] + demand[p][A] = node_capacity[B].
3382 // Moreover, all node_capacities of a path must be inside interval
3383 // path_capacity[path].
3384 // Note that Intervals have two meanings:
3385 // - for demand and node_capacity, those are values allowed for each associated
3386 // decision variable.
3387 // - for path_capacity, those are set of values that node_capacities of the path
3388 // must respect.
3389 // If the path capacity of a path is [kint64min, kint64max],
3390 // then the unary dimension requirements are not enforced on this path.
3392  public:
3393  struct Interval {
3394  int64_t min;
3395  int64_t max;
3396  };
3397 
3398  UnaryDimensionChecker(const PathState* path_state,
3399  std::vector<Interval> path_capacity,
3400  std::vector<int> path_class,
3401  std::vector<std::vector<Interval>> demand,
3402  std::vector<Interval> node_capacity);
3403 
3404  // Given the change made in PathState, checks that the unary dimension
3405  // constraint is still feasible.
3406  bool Check() const;
3407 
3408  // Commits to the changes made in PathState,
3409  // must be called before PathState::Commit().
3410  void Commit();
3411 
3412  private:
3413  // Range min/max query on partial_demand_sums_.
3414  // The first_node and last_node MUST form a subpath in the committed state.
3415  // Nodes first_node and last_node are passed by their index in precomputed
3416  // data, they must be committed in some path, and it has to be the same path.
3417  // See partial_demand_sums_.
3418  Interval GetMinMaxPartialDemandSum(int first_node_index,
3419  int last_node_index) const;
3420 
3421  // Queries whether all nodes in the committed subpath [first_node, last_node]
3422  // have fixed demands and trivial node_capacity [kint64min, kint64max].
3423  // first_node and last_node MUST form a subpath in the committed state.
3424  // Nodes are passed by their index in precomputed data.
3425  bool SubpathOnlyHasTrivialNodes(int first_node_index,
3426  int last_node_index) const;
3427 
3428  // Commits to the current solution and rebuilds structures from scratch.
3429  void FullCommit();
3430  // Commits to the current solution and only build structures for paths that
3431  // changed, using additional space to do so in a time-memory tradeoff.
3432  void IncrementalCommit();
3433  // Adds sums of given path to the bottom layer of the RMQ structure,
3434  // updates index_ and previous_nontrivial_index_.
3435  void AppendPathDemandsToSums(int path);
3436  // Updates the RMQ structure from its bottom layer,
3437  // with [begin_index, end_index) the range of the change,
3438  // which must be at the end of the bottom layer.
3439  // Supposes that requests overlapping the range will be inside the range,
3440  // to avoid updating all layers.
3441  void UpdateRMQStructure(int begin_index, int end_index);
3442 
3443  const PathState* const path_state_;
3444  const std::vector<Interval> path_capacity_;
3445  const std::vector<int> path_class_;
3446  const std::vector<std::vector<Interval>> demand_;
3447  const std::vector<Interval> node_capacity_;
3448 
3449  // Precomputed data.
3450  // Maps nodes to their pre-computed data, except for isolated nodes,
3451  // which do not have precomputed data.
3452  // Only valid for nodes that are in some path in the committed state.
3453  std::vector<int> index_;
3454  // Implementation of a <O(n log n), O(1)> range min/max query, n = #nodes.
3455  // partial_demand_sums_rmq_[0][index_[node]] contains the sum of demands
3456  // from the start of the node's path to the node.
3457  // If node is the start of path, the sum is demand_[path_class_[path]][node],
3458  // moreover partial_demand_sums_rmq_[0][index_[node]-1] is {0, 0}.
3459  // partial_demand_sums_rmq_[layer][index] contains an interval
3460  // [min_value, max_value] such that min_value is
3461  // min(partial_demand_sums_rmq_[0][index+i].min | i in [0, 2^layer)),
3462  // similarly max_value is the maximum of .max on the same range.
3463  std::vector<std::vector<Interval>> partial_demand_sums_rmq_;
3464  // The incremental branch of Commit() may waste space in the layers of the
3465  // RMQ structure. This is the upper limit of a layer's size.
3466  const int maximum_partial_demand_layer_size_;
3467  // previous_nontrivial_index_[index_[node]] has the index of the previous
3468  // node on its committed path that has nonfixed demand or nontrivial node
3469  // capacity. This allows for O(1) queries that all nodes on a subpath
3470  // are nonfixed and nontrivial.
3471  std::vector<int> previous_nontrivial_index_;
3472 };
3473 
3474 // Make a filter that takes ownership of a PathState and synchronizes it with
3475 // solver events. The solver represents a graph with array of variables 'nexts'.
3476 // Solver events are embodied by Assignment* deltas, that are translated to node
3477 // changes during Relax(), committed during Synchronize(), and reverted on
3478 // Revert().
3480  std::unique_ptr<PathState> path_state,
3481  const std::vector<IntVar*>& nexts);
3482 
3483 // Make a filter that translates solver events to the input checker's interface.
3484 // Since UnaryDimensionChecker has a PathState, the filter returned by this
3485 // must be synchronized to the corresponding PathStateFilter:
3486 // - Relax() must be called after the PathStateFilter's.
3487 // - Accept() must be called after.
3488 // - Synchronize() must be called before.
3489 // - Revert() must be called before.
3491  Solver* solver, std::unique_ptr<UnaryDimensionChecker> checker,
3492  const std::string& dimension_name);
3493 
3494 #endif // !defined(SWIG)
3495 
3496 } // namespace operations_research
3497 
3498 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
Definition: visitor.cc:140
Low-priority demon proxy to a method on the constraint with two arguments.
IntVar * Var() override
Creates a variable from the expression.
Base operator class for operators manipulating variables.
#define CHECK(condition)
Definition: base/logging.h:495
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
Definition: visitor.cc:85
This is the base class for building an Lns operator.
void AddIntegerVariableEqualValueClause(IntVar *const var, int64_t value)
Definition: search.cc:4881
bool IsPathEnd(int64_t node) const
Returns true if node is the last node on the path; defined by the fact that node is outside the range...
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
Definition: visitor.cc:220
This is a special class to represent a 'residual' set of T.
void SetContentFromBitsetOfSameSize(const Bitset64< OtherIndexType > &other)
Definition: bitset.h:535
SequenceContainer * MutableSequenceVarContainer()
const std::vector< int64_t > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
Definition: visitor.cc:105
std::string DebugString() const override
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.
LocalSearchFilter * MakeUnaryDimensionFilter(Solver *solver, std::unique_ptr< UnaryDimensionChecker > checker, const std::string &dimension_name)
IntVar * IsDifferent(int64_t constant) override
Definition: expressions.cc:145
bool FindIndex(IntVar *const var, int64_t *index) const
bool IsCardinalityOne() const
Does it contains only one bit set?
Set of parameters used to configure how the neighnorhood is traversed.
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 ...
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64_t value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
void Run(Solver *const s) override
This is the main callback of the demon.
void RankFirst(Solver *const solver, int elt)
void SetToZero(Solver *const solver, int64_t pos)
Erases the 'pos' bit.
Definition: utilities.cc:43
void SetBackwardSequence(const std::vector< int > &backward_sequence)
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
Definition: expressions.cc:116
The base class for all local search operators.
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
Operator Factories.
int64_t min
Definition: alldiff_cst.cc:139
const SequenceContainer & SequenceVarContainer() const
virtual void Relax(const Assignment *delta, const Assignment *deltadelta)
Lets the filter know what delta and deltadelta will be passed in the next Accept().
void AddVars(const std::vector< V * > &vars)
int64_t GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
Definition: utilities.cc:204
int64_t BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
void Set(IntegerType index)
Definition: bitset.h:804
std::string DebugString() const override
Definition: expressions.cc:176
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
Definition: visitor.cc:145
int64_t PosIntDivDown(int64_t e, int64_t v)
int64_t BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
--— RevPartialSequence --—
void EndVisitModel(const std::string &solver_name) override
Definition: visitor.cc:136
const std::vector< int > & ForwardSequence() const
#define CHECK_GE(val1, val2)
Definition: base/logging.h:706
virtual bool NextFragment()=0
bool IsArrayBoolean(const std::vector< T > &values)
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
Definition: visitor.cc:211
void SetValue(int64_t index, const Val &value)
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
Definition: visitor.cc:116
IntVarLocalSearchHandler(IntVarLocalSearchOperator *op)
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
Definition: utilities.cc:106
void VisitSequenceVariable(const SequenceVar *const variable) override
Definition: visitor.cc:184
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
void Restore(Solver *const solver, const T &value_index)
int64_t PosIntDivUp(int64_t e, int64_t v)
bool RevSubtract(Solver *const solver, const std::vector< uint64_t > &mask)
This method subtracts the mask from the active bitset.
Definition: utilities.cc:243
void SetToOne(Solver *const solver, int64_t index)
Sets the 'index' bit.
Definition: utilities.cc:84
uint64_t Size() const override
This method returns the number of values in the domain of the variable.
Definition: expressions.cc:126
virtual void SetEndMax(IntervalVar *const var, int64_t new_max)=0
bool AreAllStrictlyNegative(const std::vector< T > &values)
Matrix version of the RevBitSet class.
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, double offset, std::function< std::string()> display_callback, bool display_on_new_solutions_only, int period)
Definition: search.cc:58
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate) override
Definition: visitor.cc:174
void SetNext(int64_t from, int64_t to, int64_t path)
Sets 'to' to be the node after 'from' on the given path.
int64_t StartNode(int i) const
Returns the start node of the ith base node.
#define CHECK_GT(val1, val2)
Definition: base/logging.h:707
LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max)
bool IsCardinalityOne() const
Does it contains only one bit set?
Definition: utilities.cc:129
const std::string & TypeName() const
Type of the argument.
Definition: visitor.cc:32
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
Definition: visitor.cc:151
const std::string name
ChainRange Chains(int path) const
void EndInitialPropagation() override
After the initial propagation.
Definition: search.cc:252
int64_t BaseNode(int i) const
Returns the ith base node of the operator.
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
bool skip_locally_optimal_paths
Skip paths which have been proven locally optimal.
int PathClass(int i) const
Returns the class of the path of the ith base node.
bool SkipUnchanged(int index) const override
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
void SetInverseValue(int64_t index, int64_t value)
bool Contains(int64_t v) const override
This method returns whether the value 'v' is in the domain of the variable.
Definition: expressions.cc:130
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64_t constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
A Demon is the base element of a propagation queue.
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
Definition: visitor.cc:80
virtual void SetDurationMax(IntervalVar *const var, int64_t new_max)=0
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
A DecisionVisitor is used to inspect a decision.
void ExitSearch() override
End of the search.
Definition: search.cc:95
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
std::string DebugString() const override
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, bool accept_path_end_base, std::function< int(int64_t)> start_empty_path_class)
std::string DebugString() const override
virtual std::string name() const
Object naming.
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
Definition: visitor.cc:199
virtual void OnSynchronize(const Assignment *delta)
virtual void SetPerformed(IntervalVar *const var, bool value)=0
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64_t value, VarConstantConstraintType type)=0
Low-priority demon proxy to a method on the constraint with one argument.
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values) override
Definition: visitor.cc:194
void ClearAll(Solver *const solver)
Cleans all bits.
Definition: utilities.cc:220
int64_t OldPrev(int64_t node) const
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
This class represents a reversible bitset.
const std::vector< std::pair< int, int > > & ChangedArcs() const
A constraint is the main modeling object.
V * Var(int64_t index) const
Returns the variable of given index.
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
This class is a reversible growing array.
void RankLast(Solver *const solver, int elt)
bool IsInactive(int64_t node) const
Returns true if node is inactive.
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
Definition: visitor.cc:121
void OnRevertChanges(int64_t index, const std::vector< int > &value)
#define DCHECK_GT(val1, val2)
Definition: base/logging.h:895
bool IsSet(int64_t row, int64_t column) const
Returns whether the 'column' bit in the 'row' row is set.
void Install() override
Install itself on the solver.
virtual void RankNotLast(SequenceVar *const var, int index)=0
RowIndex row
Definition: markowitz.cc:182
void Run(Solver *const s) override
This is the main callback of the demon.
void ClearAll(Solver *const solver)
Cleans all bits.
Definition: utilities.cc:151
int64_t GetActiveAlternativeSibling(int node) const
Returns the active node in the alternative set of the sibling of the given node.
const E & Element(const V *const var) const
virtual int64_t ModifyValue(int64_t index, int64_t value)=0
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
const std::vector< int > & OldSequence(int64_t index) const
void Run(Solver *const s) override
This is the main callback of the demon.
void AddToAssignment(IntVar *var, int64_t value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
virtual void EndDemonRun(Demon *const demon)=0
void WhenDomain(Demon *d) override
This method attaches a demon that will watch any domain modification of the domain of the variable.
void SetToOne(Solver *const solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
Definition: utilities.cc:170
virtual void OnNodeInitialization()
Called by OnStart() after initializing node information.
void BeginFail() override
Just when the failure occurs.
Definition: search.cc:180
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
virtual void RankLast(SequenceVar *const var, int index)=0
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
Definition: visitor.cc:55
void SetForwardSequence(const std::vector< int > &forward_sequence)
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64_t > *const values)
void BeginInitialPropagation() override
Before the initial propagation.
Definition: search.cc:250
void RemoveValue(int64_t v) override
This method removes the value 'v' from the domain of the variable.
Definition: expressions.cc:93
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64_t constant, ExprExprConstantExpressionType type)=0
virtual void SetValue(IntVar *const var, int64_t value)=0
virtual void RegisterDemon(Demon *const demon)=0
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type)=0
void Push(Solver *const s, T val)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1673
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
Definition: visitor.cc:43
void SetOldInverseValue(int64_t index, int64_t value)
virtual void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
int number_of_nexts() const
Number of next variables.
BaseLns(const std::vector< IntVar * > &vars)
BooleanVar(Solver *const s, const std::string &name="")
Interval variables are often used in scheduling.
virtual void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max)=0
virtual void Start(const Assignment *assignment)=0
This class represents a reversible bitset.
std::string DebugString() const override
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
virtual void PushContext(const std::string &context)=0
bool Contains(const V *const var) const
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
void OnRevertChanges(int64_t index, int64_t value)
std::string DebugString() const override
const std::vector< int64_t > & path_starts() const
Returns the vector of path start nodes.
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64_t value)
Returns true if all variables are assigned to 'value'.
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
IntVarLocalSearchHandler(const IntVarLocalSearchHandler &other)
int64_t max
Definition: alldiff_cst.cc:140
Block * next
int64_t Next(int64_t node) const
Returns the node after node in the current delta.
bool IsCardinalityZero() const
Is bitset null?
static const int64_t kint64min
int64_t Cardinality() const
Returns the number of bits set to one.
Definition: utilities.cc:112
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
virtual void BeginOperatorStart()=0
Local search operator events.
bool AreAllBooleans(const std::vector< IntVar * > &vars)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
Definition: utilities.cc:828
int64_t bit_size() const
Returns the number of bits given in the constructor of the bitset.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
Definition: search.cc:202
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
Implements a complete cache for model elements: expressions and constraints.
int64_t GetFirstOne() const
Gets the index of the first bit set starting from 0.
Definition: utilities.cc:52
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
Definition: bitset.h:511
void SetToZero(Solver *const solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
Definition: utilities.cc:178
void NoMoreSolutions() override
When the search tree is finished.
Definition: search.cc:182
static const int64_t kint64max
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
void Remove(Solver *const solver, const T &value_index)
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
Reversible Immutable MultiMap class.
void SetRange(int64_t mi, int64_t ma) override
This method sets both the min and the max of the expression.
Definition: expressions.cc:82
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
This class encapsulates an objective.
void Run(Solver *const s) override
This is the main callback of the demon.
int64_t word_size() const
Returns the number of 64 bit words used to store the bitset.
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64_t value)
Definition: search.cc:4889
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
Definition: visitor.cc:110
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
virtual void RemoveValues(IntVar *const var, const std::vector< int64_t > &values)=0
const std::vector< int > & ChangedPaths() const
The class Iterator has two direct subclasses.
bool CheckChainValidity(int64_t before_chain, int64_t chain_end, int64_t exclude) const
Returns true if the chain is a valid path without cycles from before_chain to chain_end and does not ...
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
Demon proxy to a method on the constraint with no arguments.
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64_t value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
void SynchronizeOnAssignment(const Assignment *assignment)
const int & operator[](int index) const
bool accept_path_end_base
True if path ends should be considered when iterating over neighbors.
The base class of all search logs that periodically outputs information when the search is running.
bool RevAnd(Solver *const solver, const std::vector< uint64_t > &mask)
This method ANDs the mask with the active bitset.
Definition: utilities.cc:270
#define CHECK_LE(val1, val2)
Definition: base/logging.h:704
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
const Val & Value(int64_t index) const
Returns the value in the current assignment of the variable of given index.
UnaryDimensionChecker(const PathState *path_state, std::vector< Interval > path_capacity, std::vector< int > path_class, std::vector< std::vector< Interval >> demand, std::vector< Interval > node_capacity)
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
bool Empty() const
This method returns true if the active bitset is null.
void AppendToFragment(int index)
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64_t value, VarArrayConstantExpressionType type)=0
int64_t OldPath(int64_t node) const
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
VarTypes
This enum is used internally to do dynamic typing on subclasses of integer variables.
void SetToOne(Solver *const solver, int64_t pos)
Sets the 'pos' bit.
Definition: utilities.cc:38
int64_t demand
Definition: resource.cc:125
int64_t Path(int64_t node) const
Returns the index of the path to which node belongs in the current delta.
SimpleRevFIFO< Demon * > delayed_bound_demons_
virtual void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
int64_t hash
Definition: matrix_utils.cc:61
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
bool HasFragments() const override
bool IsCardinalityZero() const
Is bitset null?
Definition: utilities.cc:120
virtual void SetEndMin(IntervalVar *const var, int64_t new_min)=0
bool AreAllStrictlyPositive(const std::vector< T > &values)
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
std::string ParameterDebugString(P param)
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
static int input(yyscan_t yyscanner)
int64_t capacity
A reversible switch that can switch once from false to true.
bool SwapActiveAndInactive(int64_t active, int64_t inactive)
Replaces active by inactive in the current path, making active inactive.
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type)=0
int index
Definition: pack.cc:509
ModelCache(Solver *const solver)
Definition: model_cache.cc:31
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
Definition: visitor.cc:156
int64_t Value() const override
This method returns the value of the variable.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
void SetBackwardSequence(int64_t index, const std::vector< int > &value)
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
Definition: visitor.cc:65
bool IsIncreasingContiguous(const std::vector< T > &values)
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
Definition: visitor.cc:241
std::string DebugString() const override
void RemoveInterval(int64_t l, int64_t u) override
This method removes the interval 'l' .
Definition: expressions.cc:105
Low-priority demon proxy to a method on the constraint with no arguments.
Argument Holder: useful when visiting a model.
virtual void SetMin(IntExpr *const expr, int64_t new_min)=0
IntExpr modifiers.
A BaseObject is the root of all reversibly allocated objects.
virtual void SetStartMax(IntervalVar *const var, int64_t new_max)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
The class IntVar is a subset of IntExpr.
int64_t FindIntegerArgumentOrDie(const std::string &arg_name) const
Definition: visitor.cc:100
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:894
void EnterSearch() override
Beginning of the search.
Definition: search.cc:87
void RevInsert(Solver *const solver, int64_t index, T value)
int64_t GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
Definition: utilities.cc:147
ChainRange(const ChainBounds *const begin_chain, const ChainBounds *const end_chain, const CommittedNode *const first_node)
virtual void SetValues(IntVar *const var, const std::vector< int64_t > &values)=0
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64_t value)
Definition: search.cc:4897
The class IntExpr is the base of all integer expressions in constraint programming.
const T * const_iterator
Iterators on the indices.
bool ValueFromAssignment(const Assignment &assignment, SequenceVar *var, int64_t index, std::vector< int > *value)
bool IsArrayConstant(const std::vector< T > &values, const T &value)
int number_of_base_nodes
Number of nodes needed to define a neighbor.
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
bool AreAllOnes(const std::vector< T > &values)
NodeRange(const ChainBounds *begin_chain, const ChainBounds *end_chain, const CommittedNode *first_node)
virtual void SetNextBaseToIncrement(int64_t base_index)
Set the next base to increment on next iteration.
virtual void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax)=0
virtual bool ConsiderAlternatives(int64_t base_index) const
Indicates if alternatives should be considered when iterating over base nodes.
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:702
std::string DebugString() const override
int64_t MaxVarArray(const std::vector< IntVar * > &vars)
bool AreAllNegative(const std::vector< T > &values)
uint64_t Hash1(uint64_t value)
Hash functions.
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
Definition: visitor.cc:235
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
Definition: utilities.cc:226
void RefuteDecision(Decision *const decision) override
Before refuting the decision.
Definition: search.cc:210
int64_t delta
Definition: resource.cc:1692
virtual void SetStartMin(IntervalVar *const var, int64_t new_min)=0
IntervalVar modifiers.
int BaseSiblingAlternative(int i) const
Returns the alternative for the sibling of the ith base node.
bool Accept(LocalSearchMonitor *const monitor, const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)
Returns true iff all filters return true, and the sum of their accepted objectives is between objecti...
This class represent a reversible FIFO structure.
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64_t value, ExprConstantExpressionType type)=0
T * RevAlloc(T *object)
Registers the given object as being reversible.
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
void Run(Solver *const s) override
This is the main callback of the demon.
void VisitIntegerArgument(const std::string &arg_name, int64_t value) override
Integer arguments.
Definition: visitor.cc:189
ChangeValue(const std::vector< IntVar * > &vars)
Demon proxy to a method on the constraint with three arguments.
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
void SetMax(int64_t m) override
Definition: expressions.cc:76
IntVar * IsLessOrEqual(int64_t constant) override
Definition: expressions.cc:166
#define DCHECK(condition)
Definition: base/logging.h:889
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
bool AreAllBound(const std::vector< IntVar * > &vars)
virtual void BeginDemonRun(Demon *const demon)=0
Demon proxy to a method on the constraint with one argument.
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
virtual bool InitPosition() const
Returns true if the operator needs to restart its initial position at each call to Start()
SimpleRevFIFO< Demon * > bound_demons_
int64_t OldNext(int64_t node) const
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
int64_t GetActiveInAlternativeSet(int alternative_index) const
Returns the active node in the given alternative set.
std::string BaseName() const override
Returns a base name for automatic naming.
int AddAlternativeSet(const std::vector< int64_t > &alternative_set)
Handling node alternatives.
virtual int64_t GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
bool Bound() const override
Returns true if the min and the max of the expression are equal.
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
Definition: visitor.cc:90
const std::vector< int > & Sequence(int64_t index) const
Returns the value in the current assignment of the variable of given index.
virtual void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
const T * Last() const
Returns the last item of the FIFO.
int64_t Prev(int64_t node) const
Returns the node before node in the current delta.
RevImmutableMultiMap(Solver *const solver, int initial_size)
virtual void SetDurationMin(IntervalVar *const var, int64_t new_min)=0
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:890
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
RevBitMatrix(int64_t rows, int64_t columns)
Definition: utilities.cc:162
void ClearAndResize(IntegerType size)
Definition: bitset.h:779
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 AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
virtual const LocalSearchOperator * Self() const
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
Definition: visitor.cc:60
void Insert(Solver *const solver, const T &elt)
virtual bool SkipUnchanged(int index) const
int64_t MinVarArray(const std::vector< IntVar * > &vars)
void SetValue(Solver *const s, const T &val)
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
A Decision represents a choice point in the search tree.
virtual int64_t GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
Definition: visitor.cc:132
void Start(const Assignment *assignment) override
This method should not be overridden.
void Init(Solver *const solver, const std::vector< uint64_t > &mask)
This methods overwrites the active bitset with the mask.
Definition: utilities.cc:232
std::string DebugString() const override
Definition: search.cc:85
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
void Clear(Solver *const solver)
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
This method returns true iff the mask and the active bitset have a non null intersection.
Definition: utilities.cc:295
void Run(Solver *const s) override
This is the main callback of the demon.
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:892
A search monitor is a simple set of callbacks to monitor all search events.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
void Clear(IndexType i)
Definition: bitset.h:457
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
Definition: search.cc:178
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
Definition: bitset.h:814
bool AtSolution() override
This method is called when a valid solution is found.
Definition: search.cc:108
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64_t value, VarConstantConstraintType type) const =0
Var Constant Constraints.
SharedBoundsManager * bounds
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
This iterator is not stable with respect to deletion.
void Switch(Solver *const solver)
Collection of objects used to extend the Constraint Solver library.
virtual void SetMax(IntExpr *const expr, int64_t new_max)=0
RevPartialSequence(const std::vector< int > &items)
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
Definition: visitor.cc:226
std::string DebugString() const override
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, IterationParameters iteration_parameters)
Builds an instance of PathOperator from next and path variables.
IntVar * IsGreaterOrEqual(int64_t constant) override
Definition: expressions.cc:156
virtual T Evaluate(int64_t index) const
virtual bool Accept(const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
bool AreAllNull(const std::vector< T > &values)
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
void SetMin(int64_t m) override
Definition: expressions.cc:70
int64_t GetActiveAlternativeNode(int node) const
Returns the active node in the alternative set of the given node.
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
Definition: visitor.cc:75
void SetLastValue(const T &v)
Sets the last value in the FIFO.
void Synchronize(const Assignment *assignment, const Assignment *delta)
Synchronizes all filters to assignment.
virtual void RemoveValue(IntVar *const var, int64_t value)=0
int64_t FindIntegerArgumentWithDefault(const std::string &arg_name, int64_t def) const
Getters.
Definition: visitor.cc:95
int64_t Cardinality() const
Returns the number of bits set to one.
Definition: utilities.cc:48
void Run(Solver *const s) override
This is the main callback of the demon.
bool AreAllPositive(const std::vector< T > &values)
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type)=0
bool MakeActive(int64_t node, int64_t destination)
Insert the inactive node after destination.
Chain(const CommittedNode *begin_node, const CommittedNode *end_node)
void SetValue(int64_t index, T value)
ArrayWithOffset(int64_t index_min, int64_t index_max)
IntVar * var
Definition: expr_array.cc:1874
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type)=0
bool ReverseChain(int64_t before_chain, int64_t after_chain, int64_t *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void ChangeNext(int node, int new_next)
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
Definition: visitor.cc:205
NodeRange Nodes(int path) const
LocalSearchFilterManager(std::vector< FilterEvent > filter_events)
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
Definition: visitor.cc:48
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
Definition: visitor.cc:162
virtual int64_t 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 IsPathStart(int64_t node) const
Returns true if node is the first node on the path.
bool ValueFromAssignment(const Assignment &assignment, IntVar *var, int64_t index, int64_t *value)
void SetIntegerArgument(const std::string &arg_name, int64_t value)
Setters.
Definition: visitor.cc:38
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination)
Moves the chain starting after the node before_chain and ending at the node chain_end after the node ...
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
void Resize(IndexType size)
Definition: bitset.h:433
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
void AddPairAlternativeSets(const std::vector< std::pair< std::vector< int64_t >, std::vector< int64_t >>> &pair_alternative_sets)
Adds all sets of node alternatives of a vector of alternative pairs.
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
std::string DebugString() const override
GurobiMPCallbackContext * context
Demon proxy to a method on the constraint with two arguments.
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
bool MakeChainInactive(int64_t before_chain, int64_t chain_end)
Makes the nodes on the chain starting after before_chain and ending at chain_end inactive.
IntVarIterator * MakeDomainIterator(bool reversible) const override
Creates a domain iterator.
virtual void OutputLine(const std::string &line)
Definition: search.cc:260
const T & LastValue() const
Returns the last value in the FIFO.
std::function< int(int64_t)> start_empty_path_class
Callback returning an index such that if c1 = start_empty_path_class(StartNode(p1)),...
const IntContainer & IntVarContainer() const
void Install() override
Install itself on the solver.
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
virtual void Commit(const Assignment *delta, const Assignment *deltadelta)
Dual of Relax(), lets the filter know that the delta was accepted.
const Val & OldValue(int64_t index) const
void SetForwardSequence(int64_t index, const std::vector< int > &value)
Local Search Filters are used for fast neighbor pruning.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
This class represents a small reversible bitset (size <= 64).
int64_t value
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
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 Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
void MarkChange(int64_t index)
OnStart() should really be protected, but then SWIG doesn't see it.
#define CHECK_NE(val1, val2)
Definition: base/logging.h:703
std::string DebugString() const override
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
Definition: visitor.cc:70
void SetTypeName(const std::string &type_name)
Definition: visitor.cc:34
virtual bool OnSamePathAsPreviousBase(int64_t 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 int64_t Max() const =0
const Constraint * ct
void Set(IndexType i)
Definition: bitset.h:495
ArgumentHolder * Top() const
Definition: visitor.cc:259
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:893
virtual void RankNotFirst(SequenceVar *const var, int index)=0
IntVar * IsEqual(int64_t constant) override
IsEqual.
Definition: expressions.cc:134
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
void SetToZero(Solver *const solver, int64_t index)
Erases the 'index' bit.
Definition: utilities.cc:95
virtual void Reset()
Sets the filter to empty solution.
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...
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
int64_t a
bool IsIncreasing(const std::vector< T > &values)
PathState(int num_nodes, std::vector< int > path_start, std::vector< int > path_end)
Solver::DemonPriority priority() const override
This method returns the priority of the demon.