OR-Tools  9.1
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 <memory>
58 #include <string>
59 #include <utility>
60 #include <vector>
61 
62 #include "absl/container/flat_hash_map.h"
63 #include "absl/strings/str_cat.h"
65 #include "ortools/base/logging.h"
66 #include "ortools/base/timer.h"
68 #include "ortools/util/bitset.h"
69 #include "ortools/util/tuple_set.h"
70 
71 namespace operations_research {
72 
98 class LocalSearchMonitor;
99 
100 class BaseIntExpr : public IntExpr {
101  public:
102  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
103  ~BaseIntExpr() override {}
104 
105  IntVar* Var() override;
106  virtual IntVar* CastToVar();
107 
108  private:
109  IntVar* var_;
110 };
111 
114 enum VarTypes {
124 };
125 
134 #ifndef SWIG
135 template <class T>
136 class SimpleRevFIFO {
137  private:
138  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
139  struct Chunk {
140  T data_[CHUNK_SIZE];
141  const Chunk* const next_;
142  explicit Chunk(const Chunk* next) : next_(next) {}
143  };
144 
145  public:
147  class Iterator {
148  public:
149  explicit Iterator(const SimpleRevFIFO<T>* l)
150  : chunk_(l->chunks_), value_(l->Last()) {}
151  bool ok() const { return (value_ != nullptr); }
152  T operator*() const { return *value_; }
153  void operator++() {
154  ++value_;
155  if (value_ == chunk_->data_ + CHUNK_SIZE) {
156  chunk_ = chunk_->next_;
157  value_ = chunk_ ? chunk_->data_ : nullptr;
158  }
159  }
160 
161  private:
162  const Chunk* chunk_;
163  const T* value_;
164  };
165 
166  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
167 
168  void Push(Solver* const s, T val) {
169  if (pos_.Value() == 0) {
170  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
171  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
172  reinterpret_cast<void*>(chunk));
173  pos_.SetValue(s, CHUNK_SIZE - 1);
174  } else {
175  pos_.Decr(s);
176  }
177  chunks_->data_[pos_.Value()] = val;
178  }
179 
181  void PushIfNotTop(Solver* const s, T val) {
182  if (chunks_ == nullptr || LastValue() != val) {
183  Push(s, val);
184  }
185  }
186 
188  const T* Last() const {
189  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
190  }
191 
192  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
193 
195  const T& LastValue() const {
196  DCHECK(chunks_);
197  return chunks_->data_[pos_.Value()];
198  }
199 
201  void SetLastValue(const T& v) {
202  DCHECK(Last());
203  chunks_->data_[pos_.Value()] = v;
204  }
205 
206  private:
207  Chunk* chunks_;
208  NumericalRev<int> pos_;
209 };
210 
212 // TODO(user): use murmurhash.
213 inline uint64_t Hash1(uint64_t value) {
214  value = (~value) + (value << 21);
215  value ^= value >> 24;
216  value += (value << 3) + (value << 8);
217  value ^= value >> 14;
218  value += (value << 2) + (value << 4);
219  value ^= value >> 28;
220  value += (value << 31);
221  return value;
222 }
223 
224 inline uint64_t Hash1(uint32_t value) {
225  uint64_t a = value;
226  a = (a + 0x7ed55d16) + (a << 12);
227  a = (a ^ 0xc761c23c) ^ (a >> 19);
228  a = (a + 0x165667b1) + (a << 5);
229  a = (a + 0xd3a2646c) ^ (a << 9);
230  a = (a + 0xfd7046c5) + (a << 3);
231  a = (a ^ 0xb55a4f09) ^ (a >> 16);
232  return a;
233 }
234 
235 inline uint64_t Hash1(int64_t value) {
236  return Hash1(static_cast<uint64_t>(value));
237 }
238 
239 inline uint64_t Hash1(int value) { return Hash1(static_cast<uint32_t>(value)); }
240 
241 inline uint64_t Hash1(void* const ptr) {
242 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
243  defined(__aarch64__)
244  return Hash1(reinterpret_cast<uint64_t>(ptr));
245 #else
246  return Hash1(reinterpret_cast<uint32_t>(ptr));
247 #endif
248 }
249 
250 template <class T>
251 uint64_t Hash1(const std::vector<T*>& ptrs) {
252  if (ptrs.empty()) return 0;
253  if (ptrs.size() == 1) return Hash1(ptrs[0]);
254  uint64_t hash = Hash1(ptrs[0]);
255  for (int i = 1; i < ptrs.size(); ++i) {
256  hash = hash * i + Hash1(ptrs[i]);
257  }
258  return hash;
259 }
260 
261 inline uint64_t Hash1(const std::vector<int64_t>& ptrs) {
262  if (ptrs.empty()) return 0;
263  if (ptrs.size() == 1) return Hash1(ptrs[0]);
264  uint64_t hash = Hash1(ptrs[0]);
265  for (int i = 1; i < ptrs.size(); ++i) {
266  hash = hash * i + Hash1(ptrs[i]);
267  }
268  return hash;
269 }
270 
273 template <class K, class V>
275  public:
276  RevImmutableMultiMap(Solver* const solver, int initial_size)
277  : solver_(solver),
278  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
279  size_(initial_size),
280  num_items_(0) {
281  memset(array_, 0, sizeof(*array_) * size_.Value());
282  }
283 
285 
286  int num_items() const { return num_items_.Value(); }
287 
289  bool ContainsKey(const K& key) const {
290  uint64_t code = Hash1(key) % size_.Value();
291  Cell* tmp = array_[code];
292  while (tmp) {
293  if (tmp->key() == key) {
294  return true;
295  }
296  tmp = tmp->next();
297  }
298  return false;
299  }
300 
304  const V& FindWithDefault(const K& key, const V& default_value) const {
305  uint64_t code = Hash1(key) % size_.Value();
306  Cell* tmp = array_[code];
307  while (tmp) {
308  if (tmp->key() == key) {
309  return tmp->value();
310  }
311  tmp = tmp->next();
312  }
313  return default_value;
314  }
315 
317  void Insert(const K& key, const V& value) {
318  const int position = Hash1(key) % size_.Value();
319  Cell* const cell =
320  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
321  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
322  reinterpret_cast<void*>(cell));
323  num_items_.Incr(solver_);
324  if (num_items_.Value() > 2 * size_.Value()) {
325  Double();
326  }
327  }
328 
329  private:
330  class Cell {
331  public:
332  Cell(const K& key, const V& value, Cell* const next)
333  : key_(key), value_(value), next_(next) {}
334 
335  void SetRevNext(Solver* const solver, Cell* const next) {
336  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
337  reinterpret_cast<void*>(next));
338  }
339 
340  Cell* next() const { return next_; }
341 
342  const K& key() const { return key_; }
343 
344  const V& value() const { return value_; }
345 
346  private:
347  const K key_;
348  const V value_;
349  Cell* next_;
350  };
351 
352  void Double() {
353  Cell** const old_cell_array = array_;
354  const int old_size = size_.Value();
355  size_.SetValue(solver_, size_.Value() * 2);
356  solver_->SaveAndSetValue(
357  reinterpret_cast<void**>(&array_),
358  reinterpret_cast<void*>(
359  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
360  memset(array_, 0, size_.Value() * sizeof(*array_));
361  for (int i = 0; i < old_size; ++i) {
362  Cell* tmp = old_cell_array[i];
363  while (tmp != nullptr) {
364  Cell* const to_reinsert = tmp;
365  tmp = tmp->next();
366  const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value();
367  to_reinsert->SetRevNext(solver_, array_[new_position]);
368  solver_->SaveAndSetValue(
369  reinterpret_cast<void**>(&array_[new_position]),
370  reinterpret_cast<void*>(to_reinsert));
371  }
372  }
373  }
374 
375  Solver* const solver_;
376  Cell** array_;
377  NumericalRev<int> size_;
378  NumericalRev<int> num_items_;
379 };
380 
382 class RevSwitch {
383  public:
384  RevSwitch() : value_(false) {}
385 
386  bool Switched() const { return value_; }
387 
388  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
389 
390  private:
391  bool value_;
392 };
393 
397  public:
398  explicit SmallRevBitSet(int64_t size);
400  void SetToOne(Solver* const solver, int64_t pos);
402  void SetToZero(Solver* const solver, int64_t pos);
404  int64_t Cardinality() const;
406  bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; }
408  bool IsCardinalityOne() const {
409  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
410  }
413  int64_t GetFirstOne() const;
414 
415  private:
416  Rev<uint64_t> bits_;
417 };
418 
421 class RevBitSet {
422  public:
423  explicit RevBitSet(int64_t size);
424  ~RevBitSet();
425 
427  void SetToOne(Solver* const solver, int64_t index);
429  void SetToZero(Solver* const solver, int64_t index);
431  bool IsSet(int64_t index) const;
433  int64_t Cardinality() const;
435  bool IsCardinalityZero() const;
437  bool IsCardinalityOne() const;
440  int64_t GetFirstBit(int start) const;
442  void ClearAll(Solver* const solver);
443 
444  friend class RevBitMatrix;
445 
446  private:
448  void Save(Solver* const solver, int offset);
449  const int64_t size_;
450  const int64_t length_;
451  uint64_t* bits_;
452  uint64_t* stamps_;
453 };
454 
456 class RevBitMatrix : private RevBitSet {
457  public:
458  RevBitMatrix(int64_t rows, int64_t columns);
459  ~RevBitMatrix();
460 
462  void SetToOne(Solver* const solver, int64_t row, int64_t column);
464  void SetToZero(Solver* const solver, int64_t row, int64_t column);
466  bool IsSet(int64_t row, int64_t column) const {
467  DCHECK_GE(row, 0);
468  DCHECK_LT(row, rows_);
469  DCHECK_GE(column, 0);
470  DCHECK_LT(column, columns_);
471  return RevBitSet::IsSet(row * columns_ + column);
472  }
474  int64_t Cardinality(int row) const;
476  bool IsCardinalityZero(int row) const;
478  bool IsCardinalityOne(int row) const;
481  int64_t GetFirstBit(int row, int start) const;
483  void ClearAll(Solver* const solver);
484 
485  private:
486  const int64_t rows_;
487  const int64_t columns_;
488 };
489 
495 
497 template <class T>
498 class CallMethod0 : public Demon {
499  public:
500  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
501  : constraint_(ct), method_(method), name_(name) {}
502 
503  ~CallMethod0() override {}
504 
505  void Run(Solver* const s) override { (constraint_->*method_)(); }
506 
507  std::string DebugString() const override {
508  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
509  }
510 
511  private:
512  T* const constraint_;
513  void (T::*const method_)();
514  const std::string name_;
515 };
516 
517 template <class T>
518 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
519  const std::string& name) {
520  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
521 }
522 
523 template <class P>
524 std::string ParameterDebugString(P param) {
525  return absl::StrCat(param);
526 }
527 
529 template <class P>
530 std::string ParameterDebugString(P* param) {
531  return param->DebugString();
532 }
533 
535 template <class T, class P>
536 class CallMethod1 : public Demon {
537  public:
538  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
539  P param1)
540  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
541 
542  ~CallMethod1() override {}
543 
544  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
545 
546  std::string DebugString() const override {
547  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
548  ", ", ParameterDebugString(param1_), ")");
549  }
550 
551  private:
552  T* const constraint_;
553  void (T::*const method_)(P);
554  const std::string name_;
555  P param1_;
556 };
557 
558 template <class T, class P>
559 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
560  const std::string& name, P param1) {
561  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
562 }
563 
565 template <class T, class P, class Q>
566 class CallMethod2 : public Demon {
567  public:
568  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
569  P param1, Q param2)
570  : constraint_(ct),
571  method_(method),
572  name_(name),
573  param1_(param1),
574  param2_(param2) {}
575 
576  ~CallMethod2() override {}
577 
578  void Run(Solver* const s) override {
579  (constraint_->*method_)(param1_, param2_);
580  }
581 
582  std::string DebugString() const override {
583  return absl::StrCat(absl::StrCat("CallMethod_", name_),
584  absl::StrCat("(", constraint_->DebugString()),
585  absl::StrCat(", ", ParameterDebugString(param1_)),
586  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
587  }
588 
589  private:
590  T* const constraint_;
591  void (T::*const method_)(P, Q);
592  const std::string name_;
593  P param1_;
594  Q param2_;
595 };
596 
597 template <class T, class P, class Q>
598 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
599  void (T::*method)(P, Q), const std::string& name,
600  P param1, Q param2) {
601  return s->RevAlloc(
602  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
603 }
605 template <class T, class P, class Q, class R>
606 class CallMethod3 : public Demon {
607  public:
608  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
609  P param1, Q param2, R param3)
610  : constraint_(ct),
611  method_(method),
612  name_(name),
613  param1_(param1),
614  param2_(param2),
615  param3_(param3) {}
616 
617  ~CallMethod3() override {}
618 
619  void Run(Solver* const s) override {
620  (constraint_->*method_)(param1_, param2_, param3_);
621  }
622 
623  std::string DebugString() const override {
624  return absl::StrCat(absl::StrCat("CallMethod_", name_),
625  absl::StrCat("(", constraint_->DebugString()),
626  absl::StrCat(", ", ParameterDebugString(param1_)),
627  absl::StrCat(", ", ParameterDebugString(param2_)),
628  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
629  }
630 
631  private:
632  T* const constraint_;
633  void (T::*const method_)(P, Q, R);
634  const std::string name_;
635  P param1_;
636  Q param2_;
637  R param3_;
638 };
639 
640 template <class T, class P, class Q, class R>
641 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
642  void (T::*method)(P, Q, R), const std::string& name,
643  P param1, Q param2, R param3) {
644  return s->RevAlloc(
645  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
646 }
648 
653 
655 template <class T>
656 class DelayedCallMethod0 : public Demon {
657  public:
658  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
659  : constraint_(ct), method_(method), name_(name) {}
660 
661  ~DelayedCallMethod0() override {}
662 
663  void Run(Solver* const s) override { (constraint_->*method_)(); }
664 
665  Solver::DemonPriority priority() const override {
667  }
668 
669  std::string DebugString() const override {
670  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
671  ")";
672  }
673 
674  private:
675  T* const constraint_;
676  void (T::*const method_)();
677  const std::string name_;
678 };
679 
680 template <class T>
682  void (T::*method)(),
683  const std::string& name) {
684  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
685 }
686 
688 template <class T, class P>
689 class DelayedCallMethod1 : public Demon {
690  public:
691  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
692  P param1)
693  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
694 
695  ~DelayedCallMethod1() override {}
696 
697  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
698 
699  Solver::DemonPriority priority() const override {
701  }
702 
703  std::string DebugString() const override {
704  return absl::StrCat("DelayedCallMethod_", name_, "(",
705  constraint_->DebugString(), ", ",
706  ParameterDebugString(param1_), ")");
707  }
708 
709  private:
710  T* const constraint_;
711  void (T::*const method_)(P);
712  const std::string name_;
713  P param1_;
714 };
715 
716 template <class T, class P>
718  void (T::*method)(P),
719  const std::string& name, P param1) {
720  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
721 }
722 
724 template <class T, class P, class Q>
725 class DelayedCallMethod2 : public Demon {
726  public:
727  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
728  const std::string& name, P param1, Q param2)
729  : constraint_(ct),
730  method_(method),
731  name_(name),
732  param1_(param1),
733  param2_(param2) {}
734 
735  ~DelayedCallMethod2() override {}
736 
737  void Run(Solver* const s) override {
738  (constraint_->*method_)(param1_, param2_);
739  }
740 
741  Solver::DemonPriority priority() const override {
743  }
744 
745  std::string DebugString() const override {
746  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
747  absl::StrCat("(", constraint_->DebugString()),
748  absl::StrCat(", ", ParameterDebugString(param1_)),
749  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
750  }
751 
752  private:
753  T* const constraint_;
754  void (T::*const method_)(P, Q);
755  const std::string name_;
756  P param1_;
757  Q param2_;
758 };
759 
760 template <class T, class P, class Q>
762  void (T::*method)(P, Q),
763  const std::string& name, P param1,
764  Q param2) {
765  return s->RevAlloc(
766  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
767 }
769 
770 #endif // !defined(SWIG)
771 
789 // TODO(user): rename Start to Synchronize ?
790 // TODO(user): decouple the iterating from the defining of a neighbor.
792  public:
794  ~LocalSearchOperator() override {}
795  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
796  virtual void Start(const Assignment* assignment) = 0;
797  virtual void Reset() {}
798 #ifndef SWIG
799  virtual const LocalSearchOperator* Self() const { return this; }
800 #endif // SWIG
801  virtual bool HasFragments() const { return false; }
802  virtual bool HoldsDelta() const { return false; }
803 };
804 
806 template <class V, class Val, class Handler>
808  public:
810  explicit VarLocalSearchOperator(Handler var_handler)
811  : activated_(),
812  was_activated_(),
813  cleared_(true),
814  var_handler_(var_handler) {}
816  bool HoldsDelta() const override { return true; }
819  void Start(const Assignment* assignment) override {
820  const int size = Size();
821  CHECK_LE(size, assignment->Size())
822  << "Assignment contains fewer variables than operator";
823  for (int i = 0; i < size; ++i) {
824  activated_.Set(i, var_handler_.ValueFromAssignment(*assignment, vars_[i],
825  i, &values_[i]));
826  }
830  OnStart();
831  }
832  virtual bool IsIncremental() const { return false; }
833  int Size() const { return vars_.size(); }
836  const Val& Value(int64_t index) const {
837  DCHECK_LT(index, vars_.size());
838  return values_[index];
839  }
841  V* Var(int64_t index) const { return vars_[index]; }
842  virtual bool SkipUnchanged(int index) const { return false; }
843  const Val& OldValue(int64_t index) const { return old_values_[index]; }
844  void SetValue(int64_t index, const Val& value) {
845  values_[index] = value;
846  MarkChange(index);
847  }
848  bool Activated(int64_t index) const { return activated_[index]; }
849  void Activate(int64_t index) {
851  MarkChange(index);
852  }
853  void Deactivate(int64_t index) {
855  MarkChange(index);
856  }
857  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
858  if (IsIncremental() && !cleared_) {
859  for (const int64_t index : delta_changes_.PositionsSetAtLeastOnce()) {
860  V* var = Var(index);
861  const Val& value = Value(index);
862  const bool activated = activated_[index];
863  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
864  deltadelta);
865  var_handler_.AddToAssignment(var, value, activated,
867  }
868  } else {
869  delta->Clear();
870  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
871  const Val& value = Value(index);
872  const bool activated = activated_[index];
873  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
874  var_handler_.AddToAssignment(Var(index), value, activated_[index],
876  }
877  }
878  }
879  return true;
880  }
881  void RevertChanges(bool incremental) {
882  cleared_ = false;
884  if (incremental && IsIncremental()) return;
885  cleared_ = true;
886  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
888  var_handler_.OnRevertChanges(index, values_[index]);
891  }
893  }
894  void AddVars(const std::vector<V*>& vars) {
895  if (!vars.empty()) {
896  vars_.insert(vars_.end(), vars.begin(), vars.end());
897  const int64_t size = Size();
898  values_.resize(size);
899  old_values_.resize(size);
900  prev_values_.resize(size);
901  assignment_indices_.resize(size, -1);
902  activated_.Resize(size);
903  was_activated_.Resize(size);
904  changes_.ClearAndResize(size);
906  var_handler_.OnAddVars();
907  }
908  }
909 
913  virtual void OnStart() {}
914 
917  protected:
918  void MarkChange(int64_t index) {
920  changes_.Set(index);
921  }
922 
923  std::vector<V*> vars_;
924  std::vector<Val> values_;
925  std::vector<Val> old_values_;
926  std::vector<Val> prev_values_;
927  mutable std::vector<int> assignment_indices_;
932  bool cleared_;
933  Handler var_handler_;
934 };
935 
938 
940  public:
941  IntVarLocalSearchHandler() : op_(nullptr) {}
943  : op_(other.op_) {}
945  void AddToAssignment(IntVar* var, int64_t value, bool active,
946  std::vector<int>* assignment_indices, int64_t index,
947  Assignment* assignment) const {
948  Assignment::IntContainer* const container =
949  assignment->MutableIntVarContainer();
950  IntVarElement* element = nullptr;
951  if (assignment_indices != nullptr) {
952  if ((*assignment_indices)[index] == -1) {
953  (*assignment_indices)[index] = container->Size();
954  element = assignment->FastAdd(var);
955  } else {
956  element = container->MutableElement((*assignment_indices)[index]);
957  }
958  } else {
959  element = assignment->FastAdd(var);
960  }
961  if (active) {
962  element->SetValue(value);
963  element->Activate();
964  } else {
965  element->Deactivate();
966  }
967  }
968  bool ValueFromAssignment(const Assignment& assignment, IntVar* var,
969  int64_t index, int64_t* value);
970  void OnRevertChanges(int64_t index, int64_t value);
971  void OnAddVars() {}
972 
973  private:
974  IntVarLocalSearchOperator* const op_;
975 };
976 
982 
983 #ifdef SWIG
984 // TODO(user): find a way to move this code back to the .i file, where it
991 #if defined(SWIGPYTHON)
992 // clang-format off
993 %unignore VarLocalSearchOperator<IntVar, int64_t,
994  IntVarLocalSearchHandler>::Size;
995 %unignore VarLocalSearchOperator<IntVar, int64_t,
996  IntVarLocalSearchHandler>::Value;
997 %unignore VarLocalSearchOperator<IntVar, int64_t,
998  IntVarLocalSearchHandler>::OldValue;
999 %unignore VarLocalSearchOperator<IntVar, int64_t,
1000  IntVarLocalSearchHandler>::SetValue;
1001 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1002  IntVarLocalSearchHandler>::IsIncremental;
1003 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1004  IntVarLocalSearchHandler>::OnStart;
1005 %unignore VarLocalSearchOperator<IntVar, int64_t,
1006  IntVarLocalSearchHandler>::IsIncremental;
1007 %unignore VarLocalSearchOperator<IntVar, int64_t,
1008  IntVarLocalSearchHandler>::OnStart;
1009 // clang-format on
1010 #endif // SWIGPYTHON
1011 
1012 // clang-format off
1013 %rename(IntVarLocalSearchOperatorTemplate)
1014  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1015 %template(IntVarLocalSearchOperatorTemplate)
1016  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1017 // clang-format on
1018 #endif // SWIG
1019 
1022  public:
1023  IntVarLocalSearchOperator() : max_inverse_value_(-1) {}
1024  // If keep_inverse_values is true, assumes that vars models an injective
1025  // function f with domain [0, vars.size()) in which case the operator will
1026  // maintain the inverse function.
1027  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1028  bool keep_inverse_values = false)
1030  IntVarLocalSearchHandler(this)),
1031  max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) {
1032  AddVars(vars);
1033  if (keep_inverse_values) {
1034  int64_t max_value = -1;
1035  for (const IntVar* const var : vars) {
1036  max_value = std::max(max_value, var->Max());
1037  }
1038  inverse_values_.resize(max_value + 1, -1);
1039  old_inverse_values_.resize(max_value + 1, -1);
1040  }
1041  }
1049  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1050 
1051  protected:
1053 
1056  // TODO(user): make it pure virtual, implies porting all apps overriding
1058  virtual bool MakeOneNeighbor();
1059 
1060  bool IsInverseValue(int64_t index) const {
1061  DCHECK_GE(index, 0);
1062  return index <= max_inverse_value_;
1063  }
1064 
1065  int64_t InverseValue(int64_t index) const { return inverse_values_[index]; }
1066 
1067  int64_t OldInverseValue(int64_t index) const {
1068  return old_inverse_values_[index];
1069  }
1070 
1071  void SetInverseValue(int64_t index, int64_t value) {
1072  inverse_values_[index] = value;
1073  }
1074 
1075  void SetOldInverseValue(int64_t index, int64_t value) {
1076  old_inverse_values_[index] = value;
1077  }
1078 
1079  private:
1080  const int64_t max_inverse_value_;
1081  std::vector<int64_t> old_inverse_values_;
1082  std::vector<int64_t> inverse_values_;
1083 };
1084 
1086  const Assignment& assignment, IntVar* var, int64_t index, int64_t* value) {
1087  const Assignment::IntContainer& container = assignment.IntVarContainer();
1088  const IntVarElement* element = &(container.Element(index));
1089  if (element->Var() != var) {
1090  CHECK(container.Contains(var))
1091  << "Assignment does not contain operator variable " << var;
1092  element = &(container.Element(var));
1093  }
1094  *value = element->Value();
1095  if (op_->IsInverseValue(index)) {
1096  op_->SetInverseValue(*value, index);
1097  op_->SetOldInverseValue(*value, index);
1098  }
1099  return element->Activated();
1100 }
1101 
1103  int64_t value) {
1104  if (op_->IsInverseValue(index)) {
1105  op_->SetInverseValue(value, index);
1106  }
1107 }
1108 
1111 
1113  public:
1114  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1116  : op_(other.op_) {}
1118  : op_(op) {}
1119  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1120  bool active, std::vector<int>* assignment_indices,
1121  int64_t index, Assignment* assignment) const;
1122  bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var,
1123  int64_t index, std::vector<int>* value);
1124  void OnRevertChanges(int64_t index, const std::vector<int>& value);
1125  void OnAddVars();
1126 
1127  private:
1128  SequenceVarLocalSearchOperator* const op_;
1129 };
1130 
1131 #ifdef SWIG
1132 // TODO(user): find a way to move this code back to the .i file, where it
1137 // clang-format off
1138 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1139  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1140 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1141  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1142 // clang-format on
1143 #endif
1144 
1145 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1146  SequenceVarLocalSearchHandler>
1148 
1151  public:
1153  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1156  AddVars(vars);
1157  }
1161  const std::vector<int>& Sequence(int64_t index) const { return Value(index); }
1162  const std::vector<int>& OldSequence(int64_t index) const {
1163  return OldValue(index);
1164  }
1165  void SetForwardSequence(int64_t index, const std::vector<int>& value) {
1166  SetValue(index, value);
1167  }
1168  void SetBackwardSequence(int64_t index, const std::vector<int>& value) {
1170  MarkChange(index);
1171  }
1172 
1173  protected:
1175 
1176  std::vector<std::vector<int>> backward_values_;
1177 };
1178 
1180  SequenceVar* var, const std::vector<int>& value, bool active,
1181  std::vector<int>* assignment_indices, int64_t index,
1182  Assignment* assignment) const {
1183  Assignment::SequenceContainer* const container =
1184  assignment->MutableSequenceVarContainer();
1185  SequenceVarElement* element = nullptr;
1186  if (assignment_indices != nullptr) {
1187  if ((*assignment_indices)[index] == -1) {
1188  (*assignment_indices)[index] = container->Size();
1189  element = assignment->FastAdd(var);
1190  } else {
1191  element = container->MutableElement((*assignment_indices)[index]);
1192  }
1193  } else {
1194  element = assignment->FastAdd(var);
1195  }
1196  if (active) {
1197  element->SetForwardSequence(value);
1198  element->SetBackwardSequence(op_->backward_values_[index]);
1199  element->Activate();
1200  } else {
1201  element->Deactivate();
1202  }
1203 }
1204 
1206  const Assignment& assignment, SequenceVar* var, int64_t index,
1207  std::vector<int>* value) {
1208  const Assignment::SequenceContainer& container =
1209  assignment.SequenceVarContainer();
1210  const SequenceVarElement* element = &(container.Element(index));
1211  if (element->Var() != var) {
1212  CHECK(container.Contains(var))
1213  << "Assignment does not contain operator variable " << var;
1214  element = &(container.Element(var));
1215  }
1216  const std::vector<int>& element_value = element->ForwardSequence();
1217  CHECK_GE(var->size(), element_value.size());
1218  op_->backward_values_[index].clear();
1219  *value = element_value;
1220  return element->Activated();
1221 }
1222 
1224  int64_t index, const std::vector<int>& value) {
1225  op_->backward_values_[index].clear();
1226 }
1227 
1229  op_->backward_values_.resize(op_->Size());
1230 }
1231 
1260  public:
1261  explicit BaseLns(const std::vector<IntVar*>& vars);
1262  ~BaseLns() override;
1263  virtual void InitFragments();
1264  virtual bool NextFragment() = 0;
1265  void AppendToFragment(int index);
1266  int FragmentSize() const;
1267  bool HasFragments() const override { return true; }
1268 
1269  protected:
1271  bool MakeOneNeighbor() override;
1272 
1273  private:
1275  void OnStart() override;
1276  std::vector<int> fragment_;
1277 };
1278 
1284  public:
1285  explicit ChangeValue(const std::vector<IntVar*>& vars);
1286  ~ChangeValue() override;
1287  virtual int64_t ModifyValue(int64_t index, int64_t value) = 0;
1288 
1289  protected:
1291  bool MakeOneNeighbor() override;
1292 
1293  private:
1294  void OnStart() override;
1295 
1296  int index_;
1297 };
1298 
1313  public:
1333  std::function<int(int64_t)> start_empty_path_class;
1334  };
1336  PathOperator(const std::vector<IntVar*>& next_vars,
1337  const std::vector<IntVar*>& path_vars,
1338  IterationParameters iteration_parameters);
1339  PathOperator(const std::vector<IntVar*>& next_vars,
1340  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1341  bool skip_locally_optimal_paths, bool accept_path_end_base,
1342  std::function<int(int64_t)> start_empty_path_class)
1343  : PathOperator(
1344  next_vars, path_vars,
1345  {number_of_base_nodes, skip_locally_optimal_paths,
1346  accept_path_end_base, std::move(start_empty_path_class)}) {}
1347  ~PathOperator() override {}
1348  virtual bool MakeNeighbor() = 0;
1349  void Reset() override;
1350 
1351  // TODO(user): Make the following methods protected.
1352  bool SkipUnchanged(int index) const override;
1353 
1355  int64_t Next(int64_t node) const {
1356  DCHECK(!IsPathEnd(node));
1357  return Value(node);
1358  }
1359 
1361  int64_t Prev(int64_t node) const {
1362  DCHECK(!IsPathStart(node));
1363  DCHECK_EQ(Next(InverseValue(node)), node);
1364  return InverseValue(node);
1365  }
1366 
1369  int64_t Path(int64_t node) const {
1370  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1371  }
1372 
1374  int number_of_nexts() const { return number_of_nexts_; }
1375 
1376  protected:
1378  bool MakeOneNeighbor() override;
1382  virtual void OnNodeInitialization() {}
1383 
1385  int64_t BaseNode(int i) const { return base_nodes_[i]; }
1387  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1389  int64_t BaseAlternativeNode(int i) const {
1390  if (!ConsiderAlternatives(i)) return BaseNode(i);
1391  const int alternative_index = alternative_index_[BaseNode(i)];
1392  return alternative_index >= 0
1393  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1394  : BaseNode(i);
1395  }
1397  int BaseSiblingAlternative(int i) const {
1398  return base_sibling_alternatives_[i];
1399  }
1401  int64_t BaseSiblingAlternativeNode(int i) const {
1402  if (!ConsiderAlternatives(i)) return BaseNode(i);
1403  const int sibling_alternative_index =
1405  return sibling_alternative_index >= 0
1406  ? alternative_sets_[sibling_alternative_index]
1407  [base_sibling_alternatives_[i]]
1408  : BaseNode(i);
1409  }
1411  int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1413  const std::vector<int64_t>& path_starts() const { return path_starts_; }
1415  int PathClass(int i) const {
1416  return iteration_parameters_.start_empty_path_class != nullptr
1417  ? iteration_parameters_.start_empty_path_class(StartNode(i))
1418  : StartNode(i);
1419  }
1420 
1427  // TODO(user): remove this when automatic detection of such cases in done.
1428  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1432  // TODO(user): ideally this should be OnSamePath(int64_t node1, int64_t
1433  // node2);
1435  virtual bool OnSamePathAsPreviousBase(int64_t base_index) { return false; }
1441  virtual int64_t GetBaseNodeRestartPosition(int base_index) {
1442  return StartNode(base_index);
1443  }
1446  virtual void SetNextBaseToIncrement(int64_t base_index) {
1447  next_base_to_increment_ = base_index;
1448  }
1451  virtual bool ConsiderAlternatives(int64_t base_index) const { return false; }
1452 
1453  int64_t OldNext(int64_t node) const {
1454  DCHECK(!IsPathEnd(node));
1455  return OldValue(node);
1456  }
1457 
1458  int64_t OldPrev(int64_t node) const {
1459  DCHECK(!IsPathStart(node));
1460  return OldInverseValue(node);
1461  }
1462 
1463  int64_t OldPath(int64_t node) const {
1464  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1465  }
1466 
1469  bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination);
1470 
1473  bool ReverseChain(int64_t before_chain, int64_t after_chain,
1474  int64_t* chain_last);
1475 
1477  bool MakeActive(int64_t node, int64_t destination);
1480  bool MakeChainInactive(int64_t before_chain, int64_t chain_end);
1482  bool SwapActiveAndInactive(int64_t active, int64_t inactive);
1483 
1485  void SetNext(int64_t from, int64_t to, int64_t path) {
1486  DCHECK_LT(from, number_of_nexts_);
1487  SetValue(from, to);
1488  SetInverseValue(to, from);
1489  if (!ignore_path_vars_) {
1490  DCHECK_LT(from + number_of_nexts_, Size());
1491  SetValue(from + number_of_nexts_, path);
1492  }
1493  }
1494 
1497  bool IsPathEnd(int64_t node) const { return node >= number_of_nexts_; }
1498 
1500  bool IsPathStart(int64_t node) const { return OldInverseValue(node) == -1; }
1501 
1503  bool IsInactive(int64_t node) const {
1504  return !IsPathEnd(node) && inactives_[node];
1505  }
1506 
1509  virtual bool InitPosition() const { return false; }
1513  void ResetPosition() { just_started_ = true; }
1514 
1518  int AddAlternativeSet(const std::vector<int64_t>& alternative_set) {
1519  const int alternative = alternative_sets_.size();
1520  for (int64_t node : alternative_set) {
1521  DCHECK_EQ(-1, alternative_index_[node]);
1522  alternative_index_[node] = alternative;
1523  }
1524  alternative_sets_.push_back(alternative_set);
1525  sibling_alternative_.push_back(-1);
1526  return alternative;
1527  }
1528 #ifndef SWIG
1532  const std::vector<std::pair<std::vector<int64_t>, std::vector<int64_t>>>&
1533  pair_alternative_sets) {
1534  for (const auto& pair_alternative_set : pair_alternative_sets) {
1535  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1536  sibling_alternative_.back() = alternative + 1;
1537  AddAlternativeSet(pair_alternative_set.second);
1538  }
1539  }
1540 #endif // SWIG
1541  int64_t GetActiveInAlternativeSet(int alternative_index) const {
1543  return alternative_index >= 0
1544  ? active_in_alternative_set_[alternative_index]
1545  : -1;
1546  }
1548  int64_t GetActiveAlternativeNode(int node) const {
1549  return GetActiveInAlternativeSet(alternative_index_[node]);
1550  }
1552  int GetSiblingAlternativeIndex(int node) const {
1553  if (node >= alternative_index_.size()) return -1;
1554  const int alternative = alternative_index_[node];
1555  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1556  }
1559  int64_t GetActiveAlternativeSibling(int node) const {
1560  if (node >= alternative_index_.size()) return -1;
1561  const int alternative = alternative_index_[node];
1562  const int sibling_alternative =
1563  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1564  return GetActiveInAlternativeSet(sibling_alternative);
1565  }
1568  bool CheckChainValidity(int64_t before_chain, int64_t chain_end,
1569  int64_t exclude) const;
1570 
1571  const int number_of_nexts_;
1572  const bool ignore_path_vars_;
1574  int num_paths_ = 0;
1575  std::vector<int64_t> start_to_path_;
1576 
1577  private:
1578  void OnStart() override;
1580  bool OnSamePath(int64_t node1, int64_t node2) const;
1581 
1582  bool CheckEnds() const {
1583  const int base_node_size = base_nodes_.size();
1584  for (int i = base_node_size - 1; i >= 0; --i) {
1585  if (base_nodes_[i] != end_nodes_[i]) {
1586  return true;
1587  }
1588  }
1589  return false;
1590  }
1591  bool IncrementPosition();
1592  void InitializePathStarts();
1593  void InitializeInactives();
1594  void InitializeBaseNodes();
1595  void InitializeAlternatives();
1596  void Synchronize();
1597 
1598  std::vector<int> base_nodes_;
1599  std::vector<int> base_alternatives_;
1600  std::vector<int> base_sibling_alternatives_;
1601  std::vector<int> end_nodes_;
1602  std::vector<int> base_paths_;
1603  std::vector<int64_t> path_starts_;
1604  std::vector<bool> inactives_;
1605  bool just_started_;
1606  bool first_start_;
1607  IterationParameters iteration_parameters_;
1608  bool optimal_paths_enabled_;
1609  std::vector<int> path_basis_;
1610  std::vector<bool> optimal_paths_;
1612 #ifndef SWIG
1613  std::vector<std::vector<int64_t>> alternative_sets_;
1614 #endif // SWIG
1615  std::vector<int> alternative_index_;
1616  std::vector<int64_t> active_in_alternative_set_;
1617  std::vector<int> sibling_alternative_;
1618 };
1619 
1621 template <class T>
1622 LocalSearchOperator* MakeLocalSearchOperator(
1623  Solver* solver, const std::vector<IntVar*>& vars,
1624  const std::vector<IntVar*>& secondary_vars,
1625  std::function<int(int64_t)> start_empty_path_class);
1626 
1641 
1642 #if !defined(SWIG)
1643 // A LocalSearchState is a container for variables with bounds that can be
1644 // relaxed and tightened, saved and restored. It represents the solution state
1645 // of a local search engine, and allows it to go from solution to solution by
1646 // relaxing some variables to form a new subproblem, then tightening those
1647 // variables to move to a new solution representation. That state may be saved
1648 // to an internal copy, or reverted to the last saved internal copy.
1649 // Relaxing a variable returns its bounds to their initial state.
1650 // Tightening a variable's bounds may make its min larger than its max,
1651 // in that case, the tightening function will return false, and the state will
1652 // be marked as invalid. No other operations than Revert() can be called on an
1653 // invalid state: in particular, an invalid state cannot be saved.
1654 class LocalSearchVariable;
1655 
1657  public:
1658  LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max);
1659  void Commit();
1660  void Revert();
1661  bool StateIsValid() const { return state_is_valid_; }
1662 
1663  private:
1664  friend class LocalSearchVariable;
1665 
1666  struct Bounds {
1667  int64_t min;
1668  int64_t max;
1669  };
1670 
1671  void RelaxVariableBounds(int variable_index);
1672  bool TightenVariableMin(int variable_index, int64_t value);
1673  bool TightenVariableMax(int variable_index, int64_t value);
1674  int64_t VariableMin(int variable_index) const;
1675  int64_t VariableMax(int variable_index) const;
1676 
1677  std::vector<Bounds> initial_variable_bounds_;
1678  std::vector<Bounds> variable_bounds_;
1679  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1680  std::vector<bool> variable_is_relaxed_;
1681  bool state_is_valid_ = true;
1682 };
1683 
1684 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1685 // meant to be passed by copy. If at some point the duplication of
1686 // LocalSearchState pointers is too expensive, we could switch to index only,
1687 // and the user would have to know the relevant state. The present setup allows
1688 // to ensure that variable users will not misuse the state.
1690  public:
1691  int64_t Min() const { return state_->VariableMin(variable_index_); }
1692  int64_t Max() const { return state_->VariableMax(variable_index_); }
1693  bool SetMin(int64_t new_min) {
1694  return state_->TightenVariableMin(variable_index_, new_min);
1695  }
1696  bool SetMax(int64_t new_max) {
1697  return state_->TightenVariableMax(variable_index_, new_max);
1698  }
1699  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1700 
1701  private:
1702  // Only LocalSearchState can construct LocalSearchVariables.
1703  friend class LocalSearchState;
1704 
1705  LocalSearchVariable(LocalSearchState* state, int variable_index)
1706  : state_(state), variable_index_(variable_index) {}
1707 
1708  LocalSearchState* const state_;
1709  const int variable_index_;
1710 };
1711 #endif // !defined(SWIG)
1712 
1730  public:
1733  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1735  virtual void Commit(const Assignment* delta, const Assignment* deltadelta) {}
1736 
1746  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1747  int64_t objective_min, int64_t objective_max) = 0;
1748  virtual bool IsIncremental() const { return false; }
1749 
1755  virtual void Synchronize(const Assignment* assignment,
1756  const Assignment* delta) = 0;
1758  virtual void Revert() {}
1759 
1761  virtual void Reset() {}
1762 
1764  virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; }
1766  // If the last Accept() call returned false, returns an undefined value.
1767  virtual int64_t GetAcceptedObjectiveValue() const { return 0LL; }
1768 };
1769 
1774  public:
1775  // This class is responsible for calling filters methods in a correct order.
1776  // For now, an order is specified explicitly by the user.
1778  struct FilterEvent {
1781  };
1782 
1783  std::string DebugString() const override {
1784  return "LocalSearchFilterManager";
1785  }
1786  // Builds a manager that calls filter methods using an explicit ordering.
1787  explicit LocalSearchFilterManager(std::vector<FilterEvent> filter_events);
1788  // Builds a manager that calls filter methods using the following ordering:
1789  // first Relax() in vector order, then Accept() in vector order.
1790  // Note that some filters might appear only once, if their Relax() or Accept()
1791  // are trivial.
1792  explicit LocalSearchFilterManager(std::vector<LocalSearchFilter*> filters);
1793 
1794  // Calls Revert() of filters, in reverse order of Relax events.
1795  void Revert();
1799  bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta,
1800  const Assignment* deltadelta, int64_t objective_min,
1801  int64_t objective_max);
1803  void Synchronize(const Assignment* assignment, const Assignment* delta);
1804  int64_t GetSynchronizedObjectiveValue() const { return synchronized_value_; }
1805  int64_t GetAcceptedObjectiveValue() const { return accepted_value_; }
1806 
1807  private:
1808  void InitializeForcedEvents();
1809 
1810  std::vector<FilterEvent> filter_events_;
1811  int last_event_called_ = -1;
1812  // If a filter is incremental, its Relax() and Accept() must be called for
1813  // every candidate, even if a previous Accept() rejected it.
1814  // To ensure that those filters have consistent inputs, all intermediate
1815  // Relax events are also triggered. All those events are called 'forced'.
1816  std::vector<int> next_forced_events_;
1817  int64_t synchronized_value_;
1818  int64_t accepted_value_;
1819 };
1820 
1822  public:
1823  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1824  ~IntVarLocalSearchFilter() override;
1827  void Synchronize(const Assignment* assignment,
1828  const Assignment* delta) override;
1829 
1830  bool FindIndex(IntVar* const var, int64_t* index) const {
1831  DCHECK(index != nullptr);
1832  const int var_index = var->index();
1833  *index = (var_index < var_index_to_index_.size())
1834  ? var_index_to_index_[var_index]
1835  : kUnassigned;
1836  return *index != kUnassigned;
1837  }
1838 
1840  void AddVars(const std::vector<IntVar*>& vars);
1841  int Size() const { return vars_.size(); }
1842  IntVar* Var(int index) const { return vars_[index]; }
1843  int64_t Value(int index) const {
1845  return values_[index];
1846  }
1847  bool IsVarSynced(int index) const { return var_synced_[index]; }
1848 
1849  protected:
1850  virtual void OnSynchronize(const Assignment* delta) {}
1851  void SynchronizeOnAssignment(const Assignment* assignment);
1852 
1853  private:
1854  std::vector<IntVar*> vars_;
1855  std::vector<int64_t> values_;
1856  std::vector<bool> var_synced_;
1857  std::vector<int> var_index_to_index_;
1858  static const int kUnassigned;
1859 };
1860 
1862  public:
1863  explicit PropagationMonitor(Solver* const solver);
1864  ~PropagationMonitor() override;
1865  std::string DebugString() const override { return "PropagationMonitor"; }
1866 
1868  virtual void BeginConstraintInitialPropagation(
1869  Constraint* const constraint) = 0;
1870  virtual void EndConstraintInitialPropagation(
1871  Constraint* const constraint) = 0;
1873  Constraint* const parent, Constraint* const nested) = 0;
1875  Constraint* const parent, Constraint* const nested) = 0;
1876  virtual void RegisterDemon(Demon* const demon) = 0;
1877  virtual void BeginDemonRun(Demon* const demon) = 0;
1878  virtual void EndDemonRun(Demon* const demon) = 0;
1879  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1880  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1881  virtual void PushContext(const std::string& context) = 0;
1882  virtual void PopContext() = 0;
1884  virtual void SetMin(IntExpr* const expr, int64_t new_min) = 0;
1885  virtual void SetMax(IntExpr* const expr, int64_t new_max) = 0;
1886  virtual void SetRange(IntExpr* const expr, int64_t new_min,
1887  int64_t new_max) = 0;
1889  virtual void SetMin(IntVar* const var, int64_t new_min) = 0;
1890  virtual void SetMax(IntVar* const var, int64_t new_max) = 0;
1891  virtual void SetRange(IntVar* const var, int64_t new_min,
1892  int64_t new_max) = 0;
1893  virtual void RemoveValue(IntVar* const var, int64_t value) = 0;
1894  virtual void SetValue(IntVar* const var, int64_t value) = 0;
1895  virtual void RemoveInterval(IntVar* const var, int64_t imin,
1896  int64_t imax) = 0;
1897  virtual void SetValues(IntVar* const var,
1898  const std::vector<int64_t>& values) = 0;
1899  virtual void RemoveValues(IntVar* const var,
1900  const std::vector<int64_t>& values) = 0;
1902  virtual void SetStartMin(IntervalVar* const var, int64_t new_min) = 0;
1903  virtual void SetStartMax(IntervalVar* const var, int64_t new_max) = 0;
1904  virtual void SetStartRange(IntervalVar* const var, int64_t new_min,
1905  int64_t new_max) = 0;
1906  virtual void SetEndMin(IntervalVar* const var, int64_t new_min) = 0;
1907  virtual void SetEndMax(IntervalVar* const var, int64_t new_max) = 0;
1908  virtual void SetEndRange(IntervalVar* const var, int64_t new_min,
1909  int64_t new_max) = 0;
1910  virtual void SetDurationMin(IntervalVar* const var, int64_t new_min) = 0;
1911  virtual void SetDurationMax(IntervalVar* const var, int64_t new_max) = 0;
1912  virtual void SetDurationRange(IntervalVar* const var, int64_t new_min,
1913  int64_t new_max) = 0;
1914  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1916  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1917  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1918  virtual void RankLast(SequenceVar* const var, int index) = 0;
1919  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1920  virtual void RankSequence(SequenceVar* const var,
1921  const std::vector<int>& rank_first,
1922  const std::vector<int>& rank_last,
1923  const std::vector<int>& unperformed) = 0;
1925  void Install() override;
1926 };
1927 
1929  // TODO(user): Add monitoring of local search filters.
1930  public:
1931  explicit LocalSearchMonitor(Solver* const solver);
1932  ~LocalSearchMonitor() override;
1933  std::string DebugString() const override { return "LocalSearchMonitor"; }
1934 
1936  virtual void BeginOperatorStart() = 0;
1937  virtual void EndOperatorStart() = 0;
1938  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1939  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1940  bool neighbor_found, const Assignment* delta,
1941  const Assignment* deltadelta) = 0;
1942  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1943  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1944  bool neighbor_found) = 0;
1945  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1946  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1947  bool neighbor_found) = 0;
1948  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1949  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1950 
1952  void Install() override;
1953 };
1954 
1955 class BooleanVar : public IntVar {
1956  public:
1957  static const int kUnboundBooleanVarValue;
1958 
1959  explicit BooleanVar(Solver* const s, const std::string& name = "")
1961 
1962  ~BooleanVar() override {}
1963 
1964  int64_t Min() const override { return (value_ == 1); }
1965  void SetMin(int64_t m) override;
1966  int64_t Max() const override { return (value_ != 0); }
1967  void SetMax(int64_t m) override;
1968  void SetRange(int64_t mi, int64_t ma) override;
1969  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1970  int64_t Value() const override {
1971  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1972  return value_;
1973  }
1974  void RemoveValue(int64_t v) override;
1975  void RemoveInterval(int64_t l, int64_t u) override;
1976  void WhenBound(Demon* d) override;
1977  void WhenRange(Demon* d) override { WhenBound(d); }
1978  void WhenDomain(Demon* d) override { WhenBound(d); }
1979  uint64_t Size() const override;
1980  bool Contains(int64_t v) const override;
1981  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1982  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1983  std::string DebugString() const override;
1984  int VarType() const override { return BOOLEAN_VAR; }
1985 
1986  IntVar* IsEqual(int64_t constant) override;
1987  IntVar* IsDifferent(int64_t constant) override;
1988  IntVar* IsGreaterOrEqual(int64_t constant) override;
1989  IntVar* IsLessOrEqual(int64_t constant) override;
1990 
1991  virtual void RestoreValue() = 0;
1992  std::string BaseName() const override { return "BooleanVar"; }
1993 
1994  int RawValue() const { return value_; }
1995 
1996  protected:
1997  int value_;
2000 };
2001 
2002 class SymmetryManager;
2003 
2008  public:
2010  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
2011  ~SymmetryBreaker() override {}
2012 
2013  void AddIntegerVariableEqualValueClause(IntVar* const var, int64_t value);
2015  int64_t value);
2017  int64_t value);
2018 
2019  private:
2020  friend class SymmetryManager;
2021  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
2022  CHECK(symmetry_manager_ == nullptr);
2023  CHECK_EQ(-1, index_in_symmetry_manager_);
2024  symmetry_manager_ = manager;
2025  index_in_symmetry_manager_ = index;
2026  }
2027  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
2028  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
2029 
2030  SymmetryManager* symmetry_manager_;
2032  int index_in_symmetry_manager_;
2033 };
2034 
2037 class SearchLog : public SearchMonitor {
2038  public:
2039  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2040  double scaling_factor, double offset,
2041  std::function<std::string()> display_callback,
2042  bool display_on_new_solutions_only, int period);
2043  ~SearchLog() override;
2044  void EnterSearch() override;
2045  void ExitSearch() override;
2046  bool AtSolution() override;
2047  void BeginFail() override;
2048  void NoMoreSolutions() override;
2049  void AcceptUncheckedNeighbor() override;
2050  void ApplyDecision(Decision* const decision) override;
2051  void RefuteDecision(Decision* const decision) override;
2052  void OutputDecision();
2053  void Maintain();
2054  void BeginInitialPropagation() override;
2055  void EndInitialPropagation() override;
2056  std::string DebugString() const override;
2057 
2058  protected:
2059  /* Bottleneck function used for all UI related output. */
2060  virtual void OutputLine(const std::string& line);
2061 
2062  private:
2063  static std::string MemoryUsage();
2064 
2065  const int period_;
2066  std::unique_ptr<WallTimer> timer_;
2067  IntVar* const var_;
2068  OptimizeVar* const obj_;
2069  const double scaling_factor_;
2070  const double offset_;
2071  std::function<std::string()> display_callback_;
2072  const bool display_on_new_solutions_only_;
2073  int nsol_;
2074  int64_t tick_;
2075  int64_t objective_min_;
2076  int64_t objective_max_;
2077  int min_right_depth_;
2078  int max_depth_;
2079  int sliding_min_depth_;
2080  int sliding_max_depth_;
2081 };
2082 
2087 class ModelCache {
2088  public:
2093  };
2094 
2101  };
2102 
2106  };
2107 
2116  };
2117 
2123  };
2124 
2137  };
2138 
2142  };
2143 
2156  };
2160  };
2161 
2165  };
2166 
2170  };
2171 
2177  };
2178 
2182  };
2183 
2184  explicit ModelCache(Solver* const solver);
2185  virtual ~ModelCache();
2186 
2187  virtual void Clear() = 0;
2188 
2190 
2191  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
2192 
2193  virtual void InsertVoidConstraint(Constraint* const ct,
2194  VoidConstraintType type) = 0;
2195 
2198  IntVar* const var, int64_t value,
2199  VarConstantConstraintType type) const = 0;
2200 
2201  virtual void InsertVarConstantConstraint(Constraint* const ct,
2202  IntVar* const var, int64_t value,
2203  VarConstantConstraintType type) = 0;
2204 
2206 
2208  IntVar* const var, int64_t value1, int64_t value2,
2209  VarConstantConstantConstraintType type) const = 0;
2210 
2212  Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2,
2214 
2216 
2218  IntExpr* const expr1, IntExpr* const expr2,
2219  ExprExprConstraintType type) const = 0;
2220 
2221  virtual void InsertExprExprConstraint(Constraint* const ct,
2222  IntExpr* const expr1,
2223  IntExpr* const expr2,
2224  ExprExprConstraintType type) = 0;
2225 
2227 
2228  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2229  ExprExpressionType type) const = 0;
2230 
2231  virtual void InsertExprExpression(IntExpr* const expression,
2232  IntExpr* const expr,
2233  ExprExpressionType type) = 0;
2234 
2236 
2238  IntExpr* const expr, int64_t value,
2239  ExprConstantExpressionType type) const = 0;
2240 
2241  virtual void InsertExprConstantExpression(
2242  IntExpr* const expression, IntExpr* const var, int64_t value,
2243  ExprConstantExpressionType type) = 0;
2244 
2246 
2248  IntExpr* const var1, IntExpr* const var2,
2249  ExprExprExpressionType type) const = 0;
2250 
2251  virtual void InsertExprExprExpression(IntExpr* const expression,
2252  IntExpr* const var1,
2253  IntExpr* const var2,
2254  ExprExprExpressionType type) = 0;
2255 
2257 
2259  IntExpr* const var1, IntExpr* const var2, int64_t constant,
2260  ExprExprConstantExpressionType type) const = 0;
2261 
2262  virtual void InsertExprExprConstantExpression(
2263  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2264  int64_t constant, ExprExprConstantExpressionType type) = 0;
2265 
2267 
2269  IntVar* const var, int64_t value1, int64_t value2,
2270  VarConstantConstantExpressionType type) const = 0;
2271 
2273  IntExpr* const expression, IntVar* const var, int64_t value1,
2274  int64_t value2, VarConstantConstantExpressionType type) = 0;
2275 
2277 
2279  IntVar* const var, const std::vector<int64_t>& values,
2280  VarConstantArrayExpressionType type) const = 0;
2281 
2282  virtual void InsertVarConstantArrayExpression(
2283  IntExpr* const expression, IntVar* const var,
2284  const std::vector<int64_t>& values,
2286 
2288 
2290  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2291 
2292  virtual void InsertVarArrayExpression(IntExpr* const expression,
2293  const std::vector<IntVar*>& vars,
2294  VarArrayExpressionType type) = 0;
2295 
2297 
2299  const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
2300  VarArrayConstantArrayExpressionType type) const = 0;
2301 
2303  IntExpr* const expression, const std::vector<IntVar*>& var,
2304  const std::vector<int64_t>& values,
2306 
2308 
2310  const std::vector<IntVar*>& vars, int64_t value,
2311  VarArrayConstantExpressionType type) const = 0;
2312 
2313  virtual void InsertVarArrayConstantExpression(
2314  IntExpr* const expression, const std::vector<IntVar*>& var, int64_t value,
2316 
2317  Solver* solver() const;
2318 
2319  private:
2320  Solver* const solver_;
2321 };
2322 
2324 #if !defined(SWIG)
2326  public:
2328  const std::string& TypeName() const;
2329  void SetTypeName(const std::string& type_name);
2330 
2332  void SetIntegerArgument(const std::string& arg_name, int64_t value);
2333  void SetIntegerArrayArgument(const std::string& arg_name,
2334  const std::vector<int64_t>& values);
2335  void SetIntegerMatrixArgument(const std::string& arg_name,
2336  const IntTupleSet& values);
2337  void SetIntegerExpressionArgument(const std::string& arg_name,
2338  IntExpr* const expr);
2339  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2340  const std::vector<IntVar*>& vars);
2341  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2342  void SetIntervalArrayArgument(const std::string& arg_name,
2343  const std::vector<IntervalVar*>& vars);
2344  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2345  void SetSequenceArrayArgument(const std::string& arg_name,
2346  const std::vector<SequenceVar*>& vars);
2347 
2349  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2350  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2351 
2353  int64_t FindIntegerArgumentWithDefault(const std::string& arg_name,
2354  int64_t def) const;
2355  int64_t FindIntegerArgumentOrDie(const std::string& arg_name) const;
2356  const std::vector<int64_t>& FindIntegerArrayArgumentOrDie(
2357  const std::string& arg_name) const;
2359  const std::string& arg_name) const;
2360 
2362  const std::string& arg_name) const;
2363  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2364  const std::string& arg_name) const;
2365 
2366  private:
2367  std::string type_name_;
2368  absl::flat_hash_map<std::string, int64_t> integer_argument_;
2369  absl::flat_hash_map<std::string, std::vector<int64_t>>
2370  integer_array_argument_;
2371  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2372  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2373  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2374  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2375  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2376  integer_variable_array_argument_;
2377  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2378  interval_array_argument_;
2379  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2380  sequence_array_argument_;
2381 };
2382 
2384 class ModelParser : public ModelVisitor {
2385  public:
2386  ModelParser();
2387 
2388  ~ModelParser() override;
2389 
2391  void BeginVisitModel(const std::string& solver_name) override;
2392  void EndVisitModel(const std::string& solver_name) override;
2393  void BeginVisitConstraint(const std::string& type_name,
2394  const Constraint* const constraint) override;
2395  void EndVisitConstraint(const std::string& type_name,
2396  const Constraint* const constraint) override;
2397  void BeginVisitIntegerExpression(const std::string& type_name,
2398  const IntExpr* const expr) override;
2399  void EndVisitIntegerExpression(const std::string& type_name,
2400  const IntExpr* const expr) override;
2401  void VisitIntegerVariable(const IntVar* const variable,
2402  IntExpr* const delegate) override;
2403  void VisitIntegerVariable(const IntVar* const variable,
2404  const std::string& operation, int64_t value,
2405  IntVar* const delegate) override;
2406  void VisitIntervalVariable(const IntervalVar* const variable,
2407  const std::string& operation, int64_t value,
2408  IntervalVar* const delegate) override;
2409  void VisitSequenceVariable(const SequenceVar* const variable) override;
2411  void VisitIntegerArgument(const std::string& arg_name,
2412  int64_t value) override;
2413  void VisitIntegerArrayArgument(const std::string& arg_name,
2414  const std::vector<int64_t>& values) override;
2415  void VisitIntegerMatrixArgument(const std::string& arg_name,
2416  const IntTupleSet& values) override;
2418  void VisitIntegerExpressionArgument(const std::string& arg_name,
2419  IntExpr* const argument) override;
2421  const std::string& arg_name,
2422  const std::vector<IntVar*>& arguments) override;
2424  void VisitIntervalArgument(const std::string& arg_name,
2425  IntervalVar* const argument) override;
2427  const std::string& arg_name,
2428  const std::vector<IntervalVar*>& arguments) override;
2430  void VisitSequenceArgument(const std::string& arg_name,
2431  SequenceVar* const argument) override;
2433  const std::string& arg_name,
2434  const std::vector<SequenceVar*>& arguments) override;
2435 
2436  protected:
2437  void PushArgumentHolder();
2438  void PopArgumentHolder();
2439  ArgumentHolder* Top() const;
2440 
2441  private:
2442  std::vector<ArgumentHolder*> holders_;
2443 };
2444 
2445 template <class T>
2446 class ArrayWithOffset : public BaseObject {
2447  public:
2448  ArrayWithOffset(int64_t index_min, int64_t index_max)
2449  : index_min_(index_min),
2450  index_max_(index_max),
2451  values_(new T[index_max - index_min + 1]) {
2452  DCHECK_LE(index_min, index_max);
2453  }
2454 
2455  ~ArrayWithOffset() override {}
2456 
2457  virtual T Evaluate(int64_t index) const {
2458  DCHECK_GE(index, index_min_);
2459  DCHECK_LE(index, index_max_);
2460  return values_[index - index_min_];
2461  }
2462 
2463  void SetValue(int64_t index, T value) {
2464  DCHECK_GE(index, index_min_);
2465  DCHECK_LE(index, index_max_);
2466  values_[index - index_min_] = value;
2467  }
2468 
2469  std::string DebugString() const override { return "ArrayWithOffset"; }
2470 
2471  private:
2472  const int64_t index_min_;
2473  const int64_t index_max_;
2474  std::unique_ptr<T[]> values_;
2475 };
2476 #endif // SWIG
2477 
2482 template <class T, class C>
2484  public:
2485  explicit RevGrowingArray(int64_t block_size)
2486  : block_size_(block_size), block_offset_(0) {
2487  CHECK_GT(block_size, 0);
2488  }
2489 
2491  for (int i = 0; i < elements_.size(); ++i) {
2492  delete[] elements_[i];
2493  }
2494  }
2495 
2496  T At(int64_t index) const {
2497  const int64_t block_index = ComputeBlockIndex(index);
2498  const int64_t relative_index = block_index - block_offset_;
2499  if (relative_index < 0 || relative_index >= elements_.size()) {
2500  return T();
2501  }
2502  const T* block = elements_[relative_index];
2503  return block != nullptr ? block[index - block_index * block_size_] : T();
2504  }
2505 
2506  void RevInsert(Solver* const solver, int64_t index, T value) {
2507  const int64_t block_index = ComputeBlockIndex(index);
2508  T* const block = GetOrCreateBlock(block_index);
2509  const int64_t residual = index - block_index * block_size_;
2510  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2511  reinterpret_cast<C>(value));
2512  }
2513 
2514  private:
2515  T* NewBlock() const {
2516  T* const result = new T[block_size_];
2517  for (int i = 0; i < block_size_; ++i) {
2518  result[i] = T();
2519  }
2520  return result;
2521  }
2522 
2523  T* GetOrCreateBlock(int block_index) {
2524  if (elements_.size() == 0) {
2525  block_offset_ = block_index;
2526  GrowUp(block_index);
2527  } else if (block_index < block_offset_) {
2528  GrowDown(block_index);
2529  } else if (block_index - block_offset_ >= elements_.size()) {
2530  GrowUp(block_index);
2531  }
2532  T* block = elements_[block_index - block_offset_];
2533  if (block == nullptr) {
2534  block = NewBlock();
2535  elements_[block_index - block_offset_] = block;
2536  }
2537  return block;
2538  }
2539 
2540  int64_t ComputeBlockIndex(int64_t value) const {
2541  return value >= 0 ? value / block_size_
2542  : (value - block_size_ + 1) / block_size_;
2543  }
2544 
2545  void GrowUp(int64_t block_index) {
2546  elements_.resize(block_index - block_offset_ + 1);
2547  }
2548 
2549  void GrowDown(int64_t block_index) {
2550  const int64_t delta = block_offset_ - block_index;
2551  block_offset_ = block_index;
2552  DCHECK_GT(delta, 0);
2553  elements_.insert(elements_.begin(), delta, nullptr);
2554  }
2555 
2556  const int64_t block_size_;
2557  std::vector<T*> elements_;
2558  int block_offset_;
2559 };
2560 
2565 template <class T>
2566 class RevIntSet {
2567  public:
2568  static constexpr int kNoInserted = -1;
2569 
2571  explicit RevIntSet(int capacity)
2572  : elements_(new T[capacity]),
2573  num_elements_(0),
2574  capacity_(capacity),
2575  position_(new int[capacity]),
2576  delete_position_(true) {
2577  for (int i = 0; i < capacity; ++i) {
2578  position_[i] = kNoInserted;
2579  }
2580  }
2581 
2583  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2584  : elements_(new T[capacity]),
2585  num_elements_(0),
2586  capacity_(capacity),
2587  position_(shared_positions),
2588  delete_position_(false) {
2589  for (int i = 0; i < shared_positions_size; ++i) {
2590  position_[i] = kNoInserted;
2591  }
2592  }
2593 
2595  if (delete_position_) {
2596  delete[] position_;
2597  }
2598  }
2599 
2600  int Size() const { return num_elements_.Value(); }
2601 
2602  int Capacity() const { return capacity_; }
2603 
2604  T Element(int i) const {
2605  DCHECK_GE(i, 0);
2606  DCHECK_LT(i, num_elements_.Value());
2607  return elements_[i];
2608  }
2609 
2610  T RemovedElement(int i) const {
2611  DCHECK_GE(i, 0);
2612  DCHECK_LT(i + num_elements_.Value(), capacity_);
2613  return elements_[i + num_elements_.Value()];
2614  }
2615 
2616  void Insert(Solver* const solver, const T& elt) {
2617  const int position = num_elements_.Value();
2618  DCHECK_LT(position, capacity_);
2619  DCHECK(NotAlreadyInserted(elt));
2620  elements_[position] = elt;
2621  position_[elt] = position;
2622  num_elements_.Incr(solver);
2623  }
2624 
2625  void Remove(Solver* const solver, const T& value_index) {
2626  num_elements_.Decr(solver);
2627  SwapTo(value_index, num_elements_.Value());
2628  }
2629 
2630  void Restore(Solver* const solver, const T& value_index) {
2631  SwapTo(value_index, num_elements_.Value());
2632  num_elements_.Incr(solver);
2633  }
2634 
2635  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2636 
2638  typedef const T* const_iterator;
2639  const_iterator begin() const { return elements_.get(); }
2640  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2641 
2642  private:
2644  bool NotAlreadyInserted(const T& elt) {
2645  for (int i = 0; i < num_elements_.Value(); ++i) {
2646  if (elt == elements_[i]) {
2647  return false;
2648  }
2649  }
2650  return true;
2651  }
2652 
2653  void SwapTo(T value_index, int next_position) {
2654  const int current_position = position_[value_index];
2655  if (current_position != next_position) {
2656  const T next_value_index = elements_[next_position];
2657  elements_[current_position] = next_value_index;
2658  elements_[next_position] = value_index;
2659  position_[value_index] = next_position;
2660  position_[next_value_index] = current_position;
2661  }
2662  }
2663 
2665  std::unique_ptr<T[]> elements_;
2667  NumericalRev<int> num_elements_;
2669  const int capacity_;
2671  int* position_;
2673  const bool delete_position_;
2674 };
2675 
2677 
2679  public:
2680  explicit RevPartialSequence(const std::vector<int>& items)
2681  : elements_(items),
2682  first_ranked_(0),
2683  last_ranked_(items.size() - 1),
2684  size_(items.size()),
2685  position_(new int[size_]) {
2686  for (int i = 0; i < size_; ++i) {
2687  elements_[i] = items[i];
2688  position_[i] = i;
2689  }
2690  }
2691 
2692  explicit RevPartialSequence(int size)
2693  : elements_(size),
2694  first_ranked_(0),
2695  last_ranked_(size - 1),
2696  size_(size),
2697  position_(new int[size_]) {
2698  for (int i = 0; i < size_; ++i) {
2699  elements_[i] = i;
2700  position_[i] = i;
2701  }
2702  }
2703 
2705 
2706  int NumFirstRanked() const { return first_ranked_.Value(); }
2707 
2708  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2709 
2710  int Size() const { return size_; }
2711 
2712 #if !defined(SWIG)
2713  const int& operator[](int index) const {
2714  DCHECK_GE(index, 0);
2715  DCHECK_LT(index, size_);
2716  return elements_[index];
2717  }
2718 #endif
2719 
2720  void RankFirst(Solver* const solver, int elt) {
2721  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2722  SwapTo(elt, first_ranked_.Value());
2723  first_ranked_.Incr(solver);
2724  }
2725 
2726  void RankLast(Solver* const solver, int elt) {
2727  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2728  SwapTo(elt, last_ranked_.Value());
2729  last_ranked_.Decr(solver);
2730  }
2731 
2732  bool IsRanked(int elt) const {
2733  const int position = position_[elt];
2734  return (position < first_ranked_.Value() ||
2735  position > last_ranked_.Value());
2736  }
2737 
2738  std::string DebugString() const {
2739  std::string result = "[";
2740  for (int i = 0; i < first_ranked_.Value(); ++i) {
2741  absl::StrAppend(&result, elements_[i]);
2742  if (i != first_ranked_.Value() - 1) {
2743  result.append("-");
2744  }
2745  }
2746  result.append("|");
2747  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2748  absl::StrAppend(&result, elements_[i]);
2749  if (i != last_ranked_.Value()) {
2750  result.append("-");
2751  }
2752  }
2753  result.append("|");
2754  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2755  absl::StrAppend(&result, elements_[i]);
2756  if (i != size_ - 1) {
2757  result.append("-");
2758  }
2759  }
2760  result.append("]");
2761  return result;
2762  }
2763 
2764  private:
2765  void SwapTo(int elt, int next_position) {
2766  const int current_position = position_[elt];
2767  if (current_position != next_position) {
2768  const int next_elt = elements_[next_position];
2769  elements_[current_position] = next_elt;
2770  elements_[next_position] = elt;
2771  position_[elt] = next_position;
2772  position_[next_elt] = current_position;
2773  }
2774  }
2775 
2777  std::vector<int> elements_;
2779  NumericalRev<int> first_ranked_;
2781  NumericalRev<int> last_ranked_;
2783  const int size_;
2785  std::unique_ptr<int[]> position_;
2786 };
2787 
2793  public:
2795  explicit UnsortedNullableRevBitset(int bit_size);
2796 
2798 
2801  void Init(Solver* const solver, const std::vector<uint64_t>& mask);
2802 
2805  bool RevSubtract(Solver* const solver, const std::vector<uint64_t>& mask);
2806 
2809  bool RevAnd(Solver* const solver, const std::vector<uint64_t>& mask);
2810 
2813  int ActiveWordSize() const { return active_words_.Size(); }
2814 
2816  bool Empty() const { return active_words_.Size() == 0; }
2817 
2825  bool Intersects(const std::vector<uint64_t>& mask, int* support_index);
2826 
2828  int64_t bit_size() const { return bit_size_; }
2830  int64_t word_size() const { return word_size_; }
2832  const RevIntSet<int>& active_words() const { return active_words_; }
2833 
2834  private:
2835  void CleanUpActives(Solver* const solver);
2836 
2837  const int64_t bit_size_;
2838  const int64_t word_size_;
2839  RevArray<uint64_t> bits_;
2840  RevIntSet<int> active_words_;
2841  std::vector<int> to_remove_;
2842 };
2843 
2844 template <class T>
2845 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2846  for (int i = 0; i < values.size(); ++i) {
2847  if (values[i] != value) {
2848  return false;
2849  }
2850  }
2851  return true;
2852 }
2853 
2854 template <class T>
2855 bool IsArrayBoolean(const std::vector<T>& values) {
2856  for (int i = 0; i < values.size(); ++i) {
2857  if (values[i] != 0 && values[i] != 1) {
2858  return false;
2859  }
2860  }
2861  return true;
2862 }
2863 
2864 template <class T>
2865 bool AreAllOnes(const std::vector<T>& values) {
2866  return IsArrayConstant(values, T(1));
2867 }
2868 
2869 template <class T>
2870 bool AreAllNull(const std::vector<T>& values) {
2871  return IsArrayConstant(values, T(0));
2872 }
2873 
2874 template <class T>
2875 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2876  for (const T& current_value : values) {
2877  if (current_value < value) {
2878  return false;
2879  }
2880  }
2881  return true;
2882 }
2883 
2884 template <class T>
2885 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2886  for (const T& current_value : values) {
2887  if (current_value > value) {
2888  return false;
2889  }
2890  }
2891  return true;
2892 }
2893 
2894 template <class T>
2895 bool AreAllPositive(const std::vector<T>& values) {
2896  return AreAllGreaterOrEqual(values, T(0));
2897 }
2898 
2899 template <class T>
2900 bool AreAllNegative(const std::vector<T>& values) {
2901  return AreAllLessOrEqual(values, T(0));
2902 }
2903 
2904 template <class T>
2905 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2906  return AreAllGreaterOrEqual(values, T(1));
2907 }
2908 
2909 template <class T>
2910 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2911  return AreAllLessOrEqual(values, T(-1));
2912 }
2913 
2914 template <class T>
2915 bool IsIncreasingContiguous(const std::vector<T>& values) {
2916  for (int i = 0; i < values.size() - 1; ++i) {
2917  if (values[i + 1] != values[i] + 1) {
2918  return false;
2919  }
2920  }
2921  return true;
2922 }
2923 
2924 template <class T>
2925 bool IsIncreasing(const std::vector<T>& values) {
2926  for (int i = 0; i < values.size() - 1; ++i) {
2927  if (values[i + 1] < values[i]) {
2928  return false;
2929  }
2930  }
2931  return true;
2932 }
2933 
2934 template <class T>
2935 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2936  T range_max) {
2937  for (int i = 0; i < vars.size(); ++i) {
2938  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2939  return false;
2940  }
2941  }
2942  return true;
2943 }
2944 
2945 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2946  for (int i = 0; i < vars.size(); ++i) {
2947  if (!vars[i]->Bound()) {
2948  return false;
2949  }
2950  }
2951  return true;
2952 }
2953 
2954 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2955  return IsArrayInRange(vars, 0, 1);
2956 }
2957 
2960 template <class T>
2961 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2962  const std::vector<T>& values) {
2963  for (int i = 0; i < vars.size(); ++i) {
2964  if (values[i] != 0 && !vars[i]->Bound()) {
2965  return false;
2966  }
2967  }
2968  return true;
2969 }
2970 
2972 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64_t value) {
2973  for (int i = 0; i < vars.size(); ++i) {
2974  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2975  return false;
2976  }
2977  }
2978  return true;
2979 }
2980 
2981 inline int64_t MaxVarArray(const std::vector<IntVar*>& vars) {
2982  DCHECK(!vars.empty());
2983  int64_t result = kint64min;
2984  for (int i = 0; i < vars.size(); ++i) {
2986  result = std::max<int64_t>(result, vars[i]->Max());
2987  }
2988  return result;
2989 }
2990 
2991 inline int64_t MinVarArray(const std::vector<IntVar*>& vars) {
2992  DCHECK(!vars.empty());
2993  int64_t result = kint64max;
2994  for (int i = 0; i < vars.size(); ++i) {
2996  result = std::min<int64_t>(result, vars[i]->Min());
2997  }
2998  return result;
2999 }
3000 
3001 inline void FillValues(const std::vector<IntVar*>& vars,
3002  std::vector<int64_t>* const values) {
3003  values->clear();
3004  values->resize(vars.size());
3005  for (int i = 0; i < vars.size(); ++i) {
3006  (*values)[i] = vars[i]->Value();
3007  }
3008 }
3009 
3010 inline int64_t PosIntDivUp(int64_t e, int64_t v) {
3011  DCHECK_GT(v, 0);
3012  return (e < 0 || e % v == 0) ? e / v : e / v + 1;
3013 }
3014 
3015 inline int64_t PosIntDivDown(int64_t e, int64_t v) {
3016  DCHECK_GT(v, 0);
3017  return (e >= 0 || e % v == 0) ? e / v : e / v - 1;
3018 }
3019 
3020 std::vector<int64_t> ToInt64Vector(const std::vector<int>& input);
3021 
3022 #if !defined(SWIG)
3023 // A PathState represents a set of paths and changed made on it.
3024 //
3025 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
3026 // directed graphs with nodes [0, num_nodes) whose connected components are
3027 // paths from starts[i] to ends[i] (for the same i) and loops.
3028 // Let us fix num_nodes, starts and ends so we call these P-graphs.
3029 //
3030 // Let us define some notions on graphs with the same set of nodes:
3031 // tails(D) is the set of nodes that are the tail of some arc of D.
3032 // P0 inter P1 is the graph of all arcs both in P0 and P1.
3033 // P0 union P1 is the graph of all arcs either in P0 or P1.
3034 // P1 - P0 is the graph with arcs in P1 and not in P0.
3035 // P0 |> D is the graph with arcs of P0 whose tail is not in tails(D).
3036 // P0 + D is (P0 |> D) union D.
3037 //
3038 // Now suppose P0 and P1 are P-graphs.
3039 // P0 + (P1 - P0) is exactly P1.
3040 // Moreover, note that P0 |> D is not a union of paths from some starts[i] to
3041 // ends[i] and loops like P0, because the operation removes arcs from P0.
3042 // P0 |> D is a union of generic paths, loops, and isolated nodes.
3043 // Let us call the generic paths and isolated nodes "chains".
3044 // Then the paths of P0 + D are chains linked by arcs of D.
3045 // Those chains are particularly interesting when examining a P-graph change.
3046 //
3047 // A PathState represents a P-graph for a fixed {num_nodes, starts, ends}.
3048 // The value of a PathState can be changed incrementally from P0 to P1
3049 // by passing the arcs of P1 - P0 to ChangeNext() and marking the end of the
3050 // change with a call to CutChains().
3051 // If P0 + D is not a P-graph, the behaviour is undefined.
3052 // TODO(user): check whether we want to have a DCHECK that P0 + D
3053 // is a P-graph or if CutChains() should return false.
3054 //
3055 // After CutChains(), tails(D) can be traversed using an iterator,
3056 // and the chains of P0 |> D can be browsed by chain-based iterators.
3057 // An iterator allows to browse the set of paths that have changed.
3058 // Then Commit() or Revert() can be called: Commit() changes the PathState to
3059 // represent P1 = P0 + D, all further changes are made from P1; Revert() changes
3060 // the PathState to forget D completely and return the state to P0.
3061 //
3062 // After a Commit(), Revert() or at initial state, the same iterators are
3063 // available and represent the change by an empty D: the set of changed paths
3064 // and the set of changed nodes is empty. Still, the chain-based iterator allows
3065 // to browse paths: each path has exactly one chain.
3066 class PathState {
3067  public:
3068  // A Chain allows to iterate on all nodes of a chain, and access some data:
3069  // first node, last node, number of nodes in the chain.
3070  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3071  // Chains are returned by PathChainIterator's operator*().
3072  class Chain;
3073  // A ChainRange allows to iterate on all chains of a path.
3074  // ChainRange is a range, its iterator Chain*, its value type Chain.
3075  class ChainRange;
3076  // A NodeRange allows to iterate on all nodes of a path.
3077  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3078  class NodeRange;
3079 
3080  // Path constructor: path_start and path_end must be disjoint,
3081  // their values in [0, num_nodes).
3082  PathState(int num_nodes, std::vector<int> path_start,
3083  std::vector<int> path_end);
3084 
3085  // Instance-constant accessors.
3086 
3087  // Returns the number of nodes in the underlying graph.
3088  int NumNodes() const { return num_nodes_; }
3089  // Returns the number of paths (empty paths included).
3090  int NumPaths() const { return num_paths_; }
3091  // Returns the start of a path.
3092  int Start(int path) const { return path_start_end_[path].start; }
3093  // Returns the end of a path.
3094  int End(int path) const { return path_start_end_[path].end; }
3095 
3096  // State-dependent accessors.
3097 
3098  // Returns the committed path of a given node, -1 if it is a loop.
3099  int Path(int node) const {
3100  return committed_nodes_[committed_index_[node]].path;
3101  }
3102  // Returns the set of arcs that have been added,
3103  // i.e. that were changed and were not in the committed state.
3104  const std::vector<std::pair<int, int>>& ChangedArcs() const {
3105  return changed_arcs_;
3106  }
3107  // Returns the set of paths that actually changed,
3108  // i.e. that have an arc in ChangedArcs().
3109  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3110  // Returns the current range of chains of path.
3111  ChainRange Chains(int path) const;
3112  // Returns the current range of nodes of path.
3113  NodeRange Nodes(int path) const;
3114 
3115  // State modifiers.
3116 
3117  // Adds arc (node, new_next) to the changed state, more formally,
3118  // changes the state from (P0, D) to (P0, D + (node, new_next)).
3119  void ChangeNext(int node, int new_next) {
3120  changed_arcs_.emplace_back(node, new_next);
3121  }
3122  // Marks the end of ChangeNext() sequence, more formally,
3123  // changes the state from (P0, D) to (P0 |> D, D).
3124  void CutChains();
3125  // Makes the current temporary state permanent, more formally,
3126  // changes the state from (P0 |> D, D) to (P0 + D, \emptyset),
3127  void Commit();
3128  // Erase incremental changes made by ChangeNext() and CutChains(),
3129  // more formally, changes the state from (P0 |> D, D) to (P0, \emptyset).
3130  void Revert();
3131 
3132  // LNS Operators may not fix variables,
3133  // in which case we mark the candidate invalid.
3134  void SetInvalid() { is_invalid_ = true; }
3135  bool IsInvalid() const { return is_invalid_; }
3136 
3137  private:
3138  // Most structs below are named pairs of ints, for typing purposes.
3139 
3140  // Start and end are stored together to optimize (likely) simultaneous access.
3141  struct PathStartEnd {
3142  PathStartEnd(int start, int end) : start(start), end(end) {}
3143  int start;
3144  int end;
3145  };
3146  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3147  struct PathBounds {
3148  int begin_index;
3149  int end_index;
3150  };
3151  struct ChainBounds {
3152  ChainBounds() = default;
3153  ChainBounds(int begin_index, int end_index)
3154  : begin_index(begin_index), end_index(end_index) {}
3155  int begin_index;
3156  int end_index;
3157  };
3158  struct CommittedNode {
3159  CommittedNode(int node, int path) : node(node), path(path) {}
3160  int node;
3161  // Path of node in the committed state, -1 for loop nodes.
3162  // TODO(user): check if path would be better stored
3163  // with committed_index_, or in its own vector, or just recomputed.
3164  int path;
3165  };
3166  // Used in temporary structures, see below.
3167  struct TailHeadIndices {
3168  int tail_index;
3169  int head_index;
3170  };
3171  struct IndexArc {
3172  int index;
3173  int arc;
3174  bool operator<(const IndexArc& other) const { return index < other.index; }
3175  };
3176 
3177  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3178  // Selection-based algorithm in O(n^2), to use for small change sets.
3179  void MakeChainsFromChangedPathsAndArcsWithSelectionAlgorithm();
3180  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3181  // Generic algorithm in O(std::sort(n)+n), to use for larger change sets.
3182  void MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm();
3183 
3184  // Copies nodes in chains of path at the end of nodes,
3185  // and sets those nodes' path member to value path.
3186  void CopyNewPathAtEndOfNodes(int path);
3187  // Commits paths in O(#{changed paths' nodes}) time,
3188  // increasing this object's space usage by O(|changed path nodes|).
3189  void IncrementalCommit();
3190  // Commits paths in O(num_nodes + num_paths) time,
3191  // reducing this object's space usage to O(num_nodes + num_paths).
3192  void FullCommit();
3193 
3194  // Instance-constant data.
3195  const int num_nodes_;
3196  const int num_paths_;
3197  std::vector<PathStartEnd> path_start_end_;
3198 
3199  // Representation of the committed and changed paths.
3200  // A path is a range of chains, which is a range of nodes.
3201  // Ranges are represented internally by indices in vectors:
3202  // ChainBounds are indices in committed_nodes_. PathBounds are indices in
3203  // chains_. When committed (after construction, Revert() or Commit()):
3204  // - path ranges are [path, path+1): they have one chain.
3205  // - chain ranges don't overlap, chains_ has an empty sentinel at the end.
3206  // - committed_nodes_ contains all nodes and old duplicates may appear,
3207  // the current version of a node is at the index given by
3208  // committed_index_[node]. A Commit() can add nodes at the end of
3209  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3210  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3211  // space by rewriting the path/chain/nodes structure.
3212  // When changed (after CutChains()), new chains are computed,
3213  // and the structure is updated accordingly:
3214  // - path ranges that were changed have nonoverlapping values [begin, end)
3215  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3216  // committed state.
3217  // - additional chain ranges are stored after the committed chains
3218  // to represent the new chains resulting from the changes.
3219  // Those chains do not overlap with each other or with unchanged chains.
3220  // An empty sentinel chain is added at the end of additional chains.
3221  // - committed_nodes_ are not modified, and still represent the committed
3222  // paths.
3223  // committed_index_ is not modified either.
3224  std::vector<CommittedNode> committed_nodes_;
3225  std::vector<int> committed_index_;
3226  const int num_nodes_threshold_;
3227  std::vector<ChainBounds> chains_;
3228  std::vector<PathBounds> paths_;
3229 
3230  // Incremental information: indices of nodes whose successor have changed,
3231  // path that have changed nodes.
3232  std::vector<std::pair<int, int>> changed_arcs_;
3233  std::vector<int> changed_paths_;
3234  std::vector<bool> path_has_changed_;
3235 
3236  // Temporary structures, since they will be reused heavily,
3237  // those are members in order to be allocated once and for all.
3238  std::vector<TailHeadIndices> tail_head_indices_;
3239  std::vector<IndexArc> arcs_by_tail_index_;
3240  std::vector<IndexArc> arcs_by_head_index_;
3241  std::vector<int> next_arc_;
3242 
3243  // See IsInvalid() and SetInvalid().
3244  bool is_invalid_ = false;
3245 };
3246 
3247 // A Chain is a range of committed nodes.
3249  public:
3250  class Iterator {
3251  public:
3253  ++current_node_;
3254  return *this;
3255  }
3256  int operator*() const { return current_node_->node; }
3257  bool operator!=(Iterator other) const {
3258  return current_node_ != other.current_node_;
3259  }
3260 
3261  private:
3262  // Only a Chain can construct its iterator.
3263  friend class PathState::Chain;
3264  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3265  const CommittedNode* current_node_;
3266  };
3267 
3268  // Chains hold CommittedNode* values, a Chain may be invalidated
3269  // if the underlying vector is modified.
3270  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3271  : begin_(begin_node), end_(end_node) {}
3272 
3273  int NumNodes() const { return end_ - begin_; }
3274  int First() const { return begin_->node; }
3275  int Last() const { return (end_ - 1)->node; }
3276  Iterator begin() const { return Iterator(begin_); }
3277  Iterator end() const { return Iterator(end_); }
3278 
3279  private:
3280  const CommittedNode* const begin_;
3281  const CommittedNode* const end_;
3282 };
3283 
3284 // A ChainRange is a range of Chains, committed or not.
3286  public:
3287  class Iterator {
3288  public:
3290  ++current_chain_;
3291  return *this;
3292  }
3293  Chain operator*() const {
3294  return {first_node_ + current_chain_->begin_index,
3295  first_node_ + current_chain_->end_index};
3296  }
3297  bool operator!=(Iterator other) const {
3298  return current_chain_ != other.current_chain_;
3299  }
3300 
3301  private:
3302  // Only a ChainRange can construct its Iterator.
3303  friend class ChainRange;
3304  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3305  : current_chain_(chain), first_node_(first_node) {}
3306  const ChainBounds* current_chain_;
3307  const CommittedNode* const first_node_;
3308  };
3309 
3310  // ChainRanges hold ChainBounds* and CommittedNode*,
3311  // a ChainRange may be invalidated if on of the underlying vector is modified.
3312  ChainRange(const ChainBounds* const begin_chain,
3313  const ChainBounds* const end_chain,
3314  const CommittedNode* const first_node)
3315  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3316 
3317  Iterator begin() const { return {begin_, first_node_}; }
3318  Iterator end() const { return {end_, first_node_}; }
3319 
3320  private:
3321  const ChainBounds* const begin_;
3322  const ChainBounds* const end_;
3323  const CommittedNode* const first_node_;
3324 };
3325 
3326 // A NodeRange allows to iterate on all nodes of a path,
3327 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3329  public:
3330  class Iterator {
3331  public:
3333  ++current_node_;
3334  if (current_node_ == end_node_) {
3335  ++current_chain_;
3336  // Note: dereferencing bounds is valid because there is a sentinel
3337  // value at the end of PathState::chains_ to that intent.
3338  const ChainBounds bounds = *current_chain_;
3339  current_node_ = first_node_ + bounds.begin_index;
3340  end_node_ = first_node_ + bounds.end_index;
3341  }
3342  return *this;
3343  }
3344  int operator*() const { return current_node_->node; }
3345  bool operator!=(Iterator other) const {
3346  return current_chain_ != other.current_chain_;
3347  }
3348 
3349  private:
3350  // Only a NodeRange can construct its Iterator.
3351  friend class NodeRange;
3352  Iterator(const ChainBounds* current_chain,
3353  const CommittedNode* const first_node)
3354  : current_node_(first_node + current_chain->begin_index),
3355  end_node_(first_node + current_chain->end_index),
3356  current_chain_(current_chain),
3357  first_node_(first_node) {}
3358  const CommittedNode* current_node_;
3359  const CommittedNode* end_node_;
3360  const ChainBounds* current_chain_;
3361  const CommittedNode* const first_node_;
3362  };
3363 
3364  // NodeRanges hold ChainBounds* and CommittedNode*,
3365  // a NodeRange may be invalidated if on of the underlying vector is modified.
3366  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3367  const CommittedNode* first_node)
3368  : begin_chain_(begin_chain),
3369  end_chain_(end_chain),
3370  first_node_(first_node) {}
3371  Iterator begin() const { return {begin_chain_, first_node_}; }
3372  // Note: there is a sentinel value at the end of PathState::chains_,
3373  // so dereferencing chain_range_.end()->begin_ is always valid.
3374  Iterator end() const { return {end_chain_, first_node_}; }
3375 
3376  private:
3377  const ChainBounds* begin_chain_;
3378  const ChainBounds* end_chain_;
3379  const CommittedNode* const first_node_;
3380 };
3381 
3382 // This checker enforces unary dimension requirements.
3383 // A unary dimension requires that there is some valuation of
3384 // node_capacity and demand such that for all paths,
3385 // if arc A -> B is on a path of path_class p,
3386 // then node_capacity[A] + demand[p][A] = node_capacity[B].
3387 // Moreover, all node_capacities of a path must be inside interval
3388 // path_capacity[path].
3389 // Note that Intervals have two meanings:
3390 // - for demand and node_capacity, those are values allowed for each associated
3391 // decision variable.
3392 // - for path_capacity, those are set of values that node_capacities of the path
3393 // must respect.
3394 // If the path capacity of a path is [kint64min, kint64max],
3395 // then the unary dimension requirements are not enforced on this path.
3397  public:
3398  struct Interval {
3399  int64_t min;
3400  int64_t max;
3401  };
3402 
3403  UnaryDimensionChecker(const PathState* path_state,
3404  std::vector<Interval> path_capacity,
3405  std::vector<int> path_class,
3406  std::vector<std::vector<Interval>> demand,
3407  std::vector<Interval> node_capacity);
3408 
3409  // Given the change made in PathState, checks that the unary dimension
3410  // constraint is still feasible.
3411  bool Check() const;
3412 
3413  // Commits to the changes made in PathState,
3414  // must be called before PathState::Commit().
3415  void Commit();
3416 
3417  private:
3418  // Range min/max query on partial_demand_sums_.
3419  // The first_node and last_node MUST form a subpath in the committed state.
3420  // Nodes first_node and last_node are passed by their index in precomputed
3421  // data, they must be committed in some path, and it has to be the same path.
3422  // See partial_demand_sums_.
3423  Interval GetMinMaxPartialDemandSum(int first_node_index,
3424  int last_node_index) const;
3425 
3426  // Queries whether all nodes in the committed subpath [first_node, last_node]
3427  // have fixed demands and trivial node_capacity [kint64min, kint64max].
3428  // first_node and last_node MUST form a subpath in the committed state.
3429  // Nodes are passed by their index in precomputed data.
3430  bool SubpathOnlyHasTrivialNodes(int first_node_index,
3431  int last_node_index) const;
3432 
3433  // Commits to the current solution and rebuilds structures from scratch.
3434  void FullCommit();
3435  // Commits to the current solution and only build structures for paths that
3436  // changed, using additional space to do so in a time-memory tradeoff.
3437  void IncrementalCommit();
3438  // Adds sums of given path to the bottom layer of the RMQ structure,
3439  // updates index_ and previous_nontrivial_index_.
3440  void AppendPathDemandsToSums(int path);
3441  // Updates the RMQ structure from its bottom layer,
3442  // with [begin_index, end_index) the range of the change,
3443  // which must be at the end of the bottom layer.
3444  // Supposes that requests overlapping the range will be inside the range,
3445  // to avoid updating all layers.
3446  void UpdateRMQStructure(int begin_index, int end_index);
3447 
3448  const PathState* const path_state_;
3449  const std::vector<Interval> path_capacity_;
3450  const std::vector<int> path_class_;
3451  const std::vector<std::vector<Interval>> demand_;
3452  const std::vector<Interval> node_capacity_;
3453 
3454  // Precomputed data.
3455  // Maps nodes to their pre-computed data, except for isolated nodes,
3456  // which do not have precomputed data.
3457  // Only valid for nodes that are in some path in the committed state.
3458  std::vector<int> index_;
3459  // Implementation of a <O(n log n), O(1)> range min/max query, n = #nodes.
3460  // partial_demand_sums_rmq_[0][index_[node]] contains the sum of demands
3461  // from the start of the node's path to the node.
3462  // If node is the start of path, the sum is demand_[path_class_[path]][node],
3463  // moreover partial_demand_sums_rmq_[0][index_[node]-1] is {0, 0}.
3464  // partial_demand_sums_rmq_[layer][index] contains an interval
3465  // [min_value, max_value] such that min_value is
3466  // min(partial_demand_sums_rmq_[0][index+i].min | i in [0, 2^layer)),
3467  // similarly max_value is the maximum of .max on the same range.
3468  std::vector<std::vector<Interval>> partial_demand_sums_rmq_;
3469  // The incremental branch of Commit() may waste space in the layers of the
3470  // RMQ structure. This is the upper limit of a layer's size.
3471  const int maximum_partial_demand_layer_size_;
3472  // previous_nontrivial_index_[index_[node]] has the index of the previous
3473  // node on its committed path that has nonfixed demand or nontrivial node
3474  // capacity. This allows for O(1) queries that all nodes on a subpath
3475  // are nonfixed and nontrivial.
3476  std::vector<int> previous_nontrivial_index_;
3477 };
3478 
3479 // Make a filter that takes ownership of a PathState and synchronizes it with
3480 // solver events. The solver represents a graph with array of variables 'nexts'.
3481 // Solver events are embodied by Assignment* deltas, that are translated to node
3482 // changes during Relax(), committed during Synchronize(), and reverted on
3483 // Revert().
3485  std::unique_ptr<PathState> path_state,
3486  const std::vector<IntVar*>& nexts);
3487 
3488 // Make a filter that translates solver events to the input checker's interface.
3489 // Since UnaryDimensionChecker has a PathState, the filter returned by this
3490 // must be synchronized to the corresponding PathStateFilter:
3491 // - Relax() must be called after the PathStateFilter's.
3492 // - Accept() must be called after.
3493 // - Synchronize() must be called before.
3494 // - Revert() must be called before.
3496  Solver* solver, std::unique_ptr<UnaryDimensionChecker> checker,
3497  const std::string& dimension_name);
3498 
3499 #endif // !defined(SWIG)
3500 
3501 } // namespace operations_research
3502 
3503 #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:491
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:4830
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:702
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:703
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:891
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:1544
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:4838
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:700
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:890
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:4846
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:698
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:885
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:886
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:888
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:699
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:889
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.