C++ Reference

C++ Reference: Routing

constraint_solveri.h
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
48 
49 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
51 
52 #include <algorithm>
53 #include <cmath>
54 #include <cstddef>
55 #include <functional>
56 #include <memory>
57 #include <string>
58 #include <vector>
59 
60 #include "absl/container/flat_hash_map.h"
61 #include "absl/strings/str_cat.h"
62 #include "absl/strings/str_format.h"
63 #include "absl/strings/str_join.h"
64 #include "ortools/base/commandlineflags.h"
65 #include "ortools/base/hash.h"
66 #include "ortools/base/integral_types.h"
67 #include "ortools/base/logging.h"
68 #include "ortools/base/map_util.h"
69 #include "ortools/base/sysinfo.h"
70 #include "ortools/base/timer.h"
72 #include "ortools/util/bitset.h"
73 #include "ortools/util/tuple_set.h"
74 #include "ortools/util/vector_map.h"
75 
76 class WallTimer;
77 
79 class CPArgumentProto;
80 class CPConstraintProto;
81 class CPIntegerExpressionProto;
82 class CPIntervalVariableProto;
83 
109 class BaseIntExpr : public IntExpr {
110  public:
111  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
112  ~BaseIntExpr() override {}
113 
114  IntVar* Var() override;
115  virtual IntVar* CastToVar();
116 
117  private:
118  IntVar* var_;
119 };
120 
123 enum VarTypes {
132  TRACE_VAR
133 };
134 
143 #ifndef SWIG
144 template <class T>
146  private:
147  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
148  struct Chunk {
149  T data_[CHUNK_SIZE];
150  const Chunk* const next_;
151  explicit Chunk(const Chunk* next) : next_(next) {}
152  };
153 
154  public:
156  class Iterator {
157  public:
158  explicit Iterator(const SimpleRevFIFO<T>* l)
159  : chunk_(l->chunks_), value_(l->Last()) {}
160  bool ok() const { return (value_ != nullptr); }
161  T operator*() const { return *value_; }
162  void operator++() {
163  ++value_;
164  if (value_ == chunk_->data_ + CHUNK_SIZE) {
165  chunk_ = chunk_->next_;
166  value_ = chunk_ ? chunk_->data_ : nullptr;
167  }
168  }
169 
170  private:
171  const Chunk* chunk_;
172  const T* value_;
173  };
174 
175  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
176 
177  void Push(Solver* const s, T val) {
178  if (pos_.Value() == 0) {
179  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
180  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
181  reinterpret_cast<void*>(chunk));
182  pos_.SetValue(s, CHUNK_SIZE - 1);
183  } else {
184  pos_.Decr(s);
185  }
186  chunks_->data_[pos_.Value()] = val;
187  }
188 
190  void PushIfNotTop(Solver* const s, T val) {
191  if (chunks_ == nullptr || LastValue() != val) {
192  Push(s, val);
193  }
194  }
195 
197  const T* Last() const {
198  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
199  }
200 
201  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
202 
204  const T& LastValue() const {
205  DCHECK(chunks_);
206  return chunks_->data_[pos_.Value()];
207  }
208 
210  void SetLastValue(const T& v) {
211  DCHECK(Last());
212  chunks_->data_[pos_.Value()] = v;
213  }
214 
215  private:
216  Chunk* chunks_;
217  NumericalRev<int> pos_;
218 };
219 
221 // TODO(user): use murmurhash.
222 inline uint64 Hash1(uint64 value) {
223  value = (~value) + (value << 21);
224  value ^= value >> 24;
225  value += (value << 3) + (value << 8);
226  value ^= value >> 14;
227  value += (value << 2) + (value << 4);
228  value ^= value >> 28;
229  value += (value << 31);
230  return value;
231 }
232 
233 inline uint64 Hash1(uint32 value) {
234  uint64 a = value;
235  a = (a + 0x7ed55d16) + (a << 12);
236  a = (a ^ 0xc761c23c) ^ (a >> 19);
237  a = (a + 0x165667b1) + (a << 5);
238  a = (a + 0xd3a2646c) ^ (a << 9);
239  a = (a + 0xfd7046c5) + (a << 3);
240  a = (a ^ 0xb55a4f09) ^ (a >> 16);
241  return a;
242 }
243 
244 inline uint64 Hash1(int64 value) { return Hash1(static_cast<uint64>(value)); }
245 
246 inline uint64 Hash1(int value) { return Hash1(static_cast<uint32>(value)); }
247 
248 inline uint64 Hash1(void* const ptr) {
249 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
250  defined(__aarch64__)
251  return Hash1(reinterpret_cast<uint64>(ptr));
252 #else
253  return Hash1(reinterpret_cast<uint32>(ptr));
254 #endif
255 }
256 
257 template <class T>
258 uint64 Hash1(const std::vector<T*>& ptrs) {
259  if (ptrs.empty()) {
260  return 0;
261  } else if (ptrs.size() == 1) {
262  return Hash1(ptrs[0]);
263  } else {
264  uint64 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 }
271 
272 inline uint64 Hash1(const std::vector<int64>& ptrs) {
273  if (ptrs.empty()) {
274  return 0;
275  } else if (ptrs.size() == 1) {
276  return Hash1(ptrs[0]);
277  } else {
278  uint64 hash = Hash1(ptrs[0]);
279  for (int i = 1; i < ptrs.size(); ++i) {
280  hash = hash * i + Hash1(ptrs[i]);
281  }
282  return hash;
283  }
284 }
285 
288 template <class K, class V>
290  public:
291  RevImmutableMultiMap(Solver* const solver, int initial_size)
292  : solver_(solver),
293  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
294  size_(initial_size),
295  num_items_(0) {
296  memset(array_, 0, sizeof(*array_) * size_.Value());
297  }
298 
300 
301  int num_items() const { return num_items_.Value(); }
302 
304  bool ContainsKey(const K& key) const {
305  uint64 code = Hash1(key) % size_.Value();
306  Cell* tmp = array_[code];
307  while (tmp) {
308  if (tmp->key() == key) {
309  return true;
310  }
311  tmp = tmp->next();
312  }
313  return false;
314  }
315 
319  const V& FindWithDefault(const K& key, const V& default_value) const {
320  uint64 code = Hash1(key) % size_.Value();
321  Cell* tmp = array_[code];
322  while (tmp) {
323  if (tmp->key() == key) {
324  return tmp->value();
325  }
326  tmp = tmp->next();
327  }
328  return default_value;
329  }
330 
332  void Insert(const K& key, const V& value) {
333  const int position = Hash1(key) % size_.Value();
334  Cell* const cell =
335  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
336  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
337  reinterpret_cast<void*>(cell));
338  num_items_.Incr(solver_);
339  if (num_items_.Value() > 2 * size_.Value()) {
340  Double();
341  }
342  }
343 
344  private:
345  class Cell {
346  public:
347  Cell(const K& key, const V& value, Cell* const next)
348  : key_(key), value_(value), next_(next) {}
349 
350  void SetRevNext(Solver* const solver, Cell* const next) {
351  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
352  reinterpret_cast<void*>(next));
353  }
354 
355  Cell* next() const { return next_; }
356 
357  const K& key() const { return key_; }
358 
359  const V& value() const { return value_; }
360 
361  private:
362  const K key_;
363  const V value_;
364  Cell* next_;
365  };
366 
367  void Double() {
368  Cell** const old_cell_array = array_;
369  const int old_size = size_.Value();
370  size_.SetValue(solver_, size_.Value() * 2);
371  solver_->SaveAndSetValue(
372  reinterpret_cast<void**>(&array_),
373  reinterpret_cast<void*>(
374  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
375  memset(array_, 0, size_.Value() * sizeof(*array_));
376  for (int i = 0; i < old_size; ++i) {
377  Cell* tmp = old_cell_array[i];
378  while (tmp != nullptr) {
379  Cell* const to_reinsert = tmp;
380  tmp = tmp->next();
381  const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value();
382  to_reinsert->SetRevNext(solver_, array_[new_position]);
383  solver_->SaveAndSetValue(
384  reinterpret_cast<void**>(&array_[new_position]),
385  reinterpret_cast<void*>(to_reinsert));
386  }
387  }
388  }
389 
390  Solver* const solver_;
391  Cell** array_;
392  NumericalRev<int> size_;
393  NumericalRev<int> num_items_;
394 };
395 
397 class RevSwitch {
398  public:
399  RevSwitch() : value_(false) {}
400 
401  bool Switched() const { return value_; }
402 
403  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
404 
405  private:
406  bool value_;
407 };
408 
412  public:
413  explicit SmallRevBitSet(int64 size);
415  void SetToOne(Solver* const solver, int64 pos);
417  void SetToZero(Solver* const solver, int64 pos);
419  int64 Cardinality() const;
421  bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); }
423  bool IsCardinalityOne() const {
424  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
425  }
428  int64 GetFirstOne() const;
429 
430  private:
431  Rev<uint64> bits_;
432 };
433 
436 class RevBitSet {
437  public:
438  explicit RevBitSet(int64 size);
440 
442  void SetToOne(Solver* const solver, int64 index);
444  void SetToZero(Solver* const solver, int64 index);
446  bool IsSet(int64 index) const;
448  int64 Cardinality() const;
450  bool IsCardinalityZero() const;
452  bool IsCardinalityOne() const;
455  int64 GetFirstBit(int start) const;
457  void ClearAll(Solver* const solver);
458 
459  friend class RevBitMatrix;
460 
461  private:
463  void Save(Solver* const solver, int offset);
464  const int64 size_;
465  const int64 length_;
466  uint64* bits_;
467  uint64* stamps_;
468 };
469 
471 class RevBitMatrix : private RevBitSet {
472  public:
473  RevBitMatrix(int64 rows, int64 columns);
475 
477  void SetToOne(Solver* const solver, int64 row, int64 column);
479  void SetToZero(Solver* const solver, int64 row, int64 column);
481  bool IsSet(int64 row, int64 column) const {
482  DCHECK_GE(row, 0);
483  DCHECK_LT(row, rows_);
484  DCHECK_GE(column, 0);
485  DCHECK_LT(column, columns_);
486  return RevBitSet::IsSet(row * columns_ + column);
487  }
489  int64 Cardinality(int row) const;
491  bool IsCardinalityZero(int row) const;
493  bool IsCardinalityOne(int row) const;
496  int64 GetFirstBit(int row, int start) const;
498  void ClearAll(Solver* const solver);
499 
500  private:
501  const int64 rows_;
502  const int64 columns_;
503 };
504 
510 
512 template <class T>
513 class CallMethod0 : public Demon {
514  public:
515  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
516  : constraint_(ct), method_(method), name_(name) {}
517 
518  ~CallMethod0() override {}
519 
520  void Run(Solver* const s) override { (constraint_->*method_)(); }
521 
522  std::string DebugString() const override {
523  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
524  }
525 
526  private:
527  T* const constraint_;
528  void (T::*const method_)();
529  const std::string name_;
530 };
531 
532 template <class T>
533 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
534  const std::string& name) {
535  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
536 }
537 
538 template <class P>
539 std::string ParameterDebugString(P param) {
540  return absl::StrCat(param);
541 }
542 
544 template <class P>
545 std::string ParameterDebugString(P* param) {
546  return param->DebugString();
547 }
548 
550 template <class T, class P>
551 class CallMethod1 : public Demon {
552  public:
553  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
554  P param1)
555  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
556 
557  ~CallMethod1() override {}
558 
559  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
560 
561  std::string DebugString() const override {
562  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
563  ", ", ParameterDebugString(param1_), ")");
564  }
565 
566  private:
567  T* const constraint_;
568  void (T::*const method_)(P);
569  const std::string name_;
570  P param1_;
571 };
572 
573 template <class T, class P>
574 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
575  const std::string& name, P param1) {
576  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
577 }
578 
580 template <class T, class P, class Q>
581 class CallMethod2 : public Demon {
582  public:
583  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
584  P param1, Q param2)
585  : constraint_(ct),
586  method_(method),
587  name_(name),
588  param1_(param1),
589  param2_(param2) {}
590 
591  ~CallMethod2() override {}
592 
593  void Run(Solver* const s) override {
594  (constraint_->*method_)(param1_, param2_);
595  }
596 
597  std::string DebugString() const override {
598  return absl::StrCat(absl::StrCat("CallMethod_", name_),
599  absl::StrCat("(", constraint_->DebugString()),
600  absl::StrCat(", ", ParameterDebugString(param1_)),
601  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
602  }
603 
604  private:
605  T* const constraint_;
606  void (T::*const method_)(P, Q);
607  const std::string name_;
608  P param1_;
609  Q param2_;
610 };
611 
612 template <class T, class P, class Q>
613 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
614  void (T::*method)(P, Q), const std::string& name,
615  P param1, Q param2) {
616  return s->RevAlloc(
617  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
618 }
620 template <class T, class P, class Q, class R>
621 class CallMethod3 : public Demon {
622  public:
623  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
624  P param1, Q param2, R param3)
625  : constraint_(ct),
626  method_(method),
627  name_(name),
628  param1_(param1),
629  param2_(param2),
630  param3_(param3) {}
631 
632  ~CallMethod3() override {}
633 
634  void Run(Solver* const s) override {
635  (constraint_->*method_)(param1_, param2_, param3_);
636  }
637 
638  std::string DebugString() const override {
639  return absl::StrCat(absl::StrCat("CallMethod_", name_),
640  absl::StrCat("(", constraint_->DebugString()),
641  absl::StrCat(", ", ParameterDebugString(param1_)),
642  absl::StrCat(", ", ParameterDebugString(param2_)),
643  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
644  }
645 
646  private:
647  T* const constraint_;
648  void (T::*const method_)(P, Q, R);
649  const std::string name_;
650  P param1_;
651  Q param2_;
652  R param3_;
653 };
654 
655 template <class T, class P, class Q, class R>
656 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
657  void (T::*method)(P, Q, R), const std::string& name,
658  P param1, Q param2, R param3) {
659  return s->RevAlloc(
660  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
661 }
663 
668 
670 template <class T>
671 class DelayedCallMethod0 : public Demon {
672  public:
673  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
674  : constraint_(ct), method_(method), name_(name) {}
675 
676  ~DelayedCallMethod0() override {}
677 
678  void Run(Solver* const s) override { (constraint_->*method_)(); }
679 
680  Solver::DemonPriority priority() const override {
681  return Solver::DELAYED_PRIORITY;
682  }
683 
684  std::string DebugString() const override {
685  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
686  ")";
687  }
688 
689  private:
690  T* const constraint_;
691  void (T::*const method_)();
692  const std::string name_;
693 };
694 
695 template <class T>
696 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
697  void (T::*method)(),
698  const std::string& name) {
699  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
700 }
701 
703 template <class T, class P>
704 class DelayedCallMethod1 : public Demon {
705  public:
706  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
707  P param1)
708  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
709 
710  ~DelayedCallMethod1() override {}
711 
712  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
713 
714  Solver::DemonPriority priority() const override {
715  return Solver::DELAYED_PRIORITY;
716  }
717 
718  std::string DebugString() const override {
719  return absl::StrCat("DelayedCallMethod_", name_, "(",
720  constraint_->DebugString(), ", ",
721  ParameterDebugString(param1_), ")");
722  }
723 
724  private:
725  T* const constraint_;
726  void (T::*const method_)(P);
727  const std::string name_;
728  P param1_;
729 };
730 
731 template <class T, class P>
732 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
733  void (T::*method)(P),
734  const std::string& name, P param1) {
735  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
736 }
737 
739 template <class T, class P, class Q>
740 class DelayedCallMethod2 : public Demon {
741  public:
742  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
743  const std::string& name, P param1, Q param2)
744  : constraint_(ct),
745  method_(method),
746  name_(name),
747  param1_(param1),
748  param2_(param2) {}
749 
750  ~DelayedCallMethod2() override {}
751 
752  void Run(Solver* const s) override {
753  (constraint_->*method_)(param1_, param2_);
754  }
755 
756  Solver::DemonPriority priority() const override {
757  return Solver::DELAYED_PRIORITY;
758  }
759 
760  std::string DebugString() const override {
761  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
762  absl::StrCat("(", constraint_->DebugString()),
763  absl::StrCat(", ", ParameterDebugString(param1_)),
764  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
765  }
766 
767  private:
768  T* const constraint_;
769  void (T::*const method_)(P, Q);
770  const std::string name_;
771  P param1_;
772  Q param2_;
773 };
774 
775 template <class T, class P, class Q>
776 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
777  void (T::*method)(P, Q),
778  const std::string& name, P param1,
779  Q param2) {
780  return s->RevAlloc(
781  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
782 }
784 
785 #endif // !defined(SWIG)
786 
804 // TODO(user): rename Start to Synchronize ?
805 // TODO(user): decouple the iterating from the defining of a neighbor.
806 class LocalSearchOperator : public BaseObject {
807  public:
809  ~LocalSearchOperator() override {}
810  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
811  virtual void Start(const Assignment* assignment) = 0;
812  virtual void Reset() {}
813 #ifndef SWIG
814  virtual const LocalSearchOperator* Self() const { return this; }
815 #endif // SWIG
816  virtual bool HasFragments() const { return false; }
817  virtual bool HoldsDelta() const { return false; }
818 };
819 
821 template <class V, class Val, class Handler>
823  public:
825  explicit VarLocalSearchOperator(Handler var_handler)
826  : activated_(),
827  was_activated_(),
828  cleared_(true),
829  var_handler_(var_handler) {}
831  bool HoldsDelta() const override { return true; }
834  void Start(const Assignment* assignment) override {
835  const int size = Size();
836  CHECK_LE(size, assignment->Size())
837  << "Assignment contains fewer variables than operator";
838  for (int i = 0; i < size; ++i) {
839  activated_.Set(i, var_handler_.ValueFromAssignment(*assignment, vars_[i],
840  i, &values_[i]));
841  }
844  was_activated_.SetContentFromBitsetOfSameSize(activated_);
845  OnStart();
846  }
847  virtual bool IsIncremental() const { return false; }
848  int Size() const { return vars_.size(); }
851  const Val& Value(int64 index) const {
852  DCHECK_LT(index, vars_.size());
853  return values_[index];
854  }
856  V* Var(int64 index) const { return vars_[index]; }
857  virtual bool SkipUnchanged(int index) const { return false; }
858  const Val& OldValue(int64 index) const { return old_values_[index]; }
859  void SetValue(int64 index, const Val& value) {
860  values_[index] = value;
861  MarkChange(index);
862  }
863  bool Activated(int64 index) const { return activated_[index]; }
864  void Activate(int64 index) {
865  activated_.Set(index);
866  MarkChange(index);
867  }
868  void Deactivate(int64 index) {
869  activated_.Clear(index);
870  MarkChange(index);
871  }
872  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
873  if (IsIncremental() && !cleared_) {
874  for (const int64 index : delta_changes_.PositionsSetAtLeastOnce()) {
875  V* var = Var(index);
876  const Val& value = Value(index);
877  const bool activated = activated_[index];
878  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
879  deltadelta);
880  var_handler_.AddToAssignment(var, value, activated,
881  &assignment_indices_, index, delta);
882  }
883  } else {
884  delta->Clear();
885  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
886  const Val& value = Value(index);
887  const bool activated = activated_[index];
888  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
889  var_handler_.AddToAssignment(Var(index), value, activated_[index],
890  &assignment_indices_, index, delta);
891  }
892  }
893  }
894  return true;
895  }
896  void RevertChanges(bool incremental) {
897  cleared_ = false;
898  delta_changes_.SparseClearAll();
899  if (incremental && IsIncremental()) return;
900  cleared_ = true;
901  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
902  values_[index] = old_values_[index];
903  var_handler_.OnRevertChanges(index, values_[index]);
904  activated_.CopyBucket(was_activated_, index);
905  assignment_indices_[index] = -1;
906  }
907  changes_.SparseClearAll();
908  }
909  void AddVars(const std::vector<V*>& vars) {
910  if (!vars.empty()) {
911  vars_.insert(vars_.end(), vars.begin(), vars.end());
912  const int64 size = Size();
913  values_.resize(size);
914  old_values_.resize(size);
915  prev_values_.resize(size);
916  assignment_indices_.resize(size, -1);
917  activated_.Resize(size);
918  was_activated_.Resize(size);
919  changes_.ClearAndResize(size);
920  delta_changes_.ClearAndResize(size);
921  var_handler_.OnAddVars();
922  }
923  }
924 
928  virtual void OnStart() {}
929 
932  protected:
933  void MarkChange(int64 index) {
934  delta_changes_.Set(index);
935  changes_.Set(index);
936  }
937 
938  std::vector<V*> vars_;
939  std::vector<Val> values_;
940  std::vector<Val> old_values_;
941  std::vector<Val> prev_values_;
942  mutable std::vector<int> assignment_indices_;
943  Bitset64<> activated_;
944  Bitset64<> was_activated_;
945  SparseBitset<> changes_;
946  SparseBitset<> delta_changes_;
947  bool cleared_;
948  Handler var_handler_;
949 };
950 
953 
955  public:
956  IntVarLocalSearchHandler() : op_(nullptr) {}
958  : op_(other.op_) {}
960  void AddToAssignment(IntVar* var, int64 value, bool active,
961  std::vector<int>* assignment_indices, int64 index,
962  Assignment* assignment) const {
963  Assignment::IntContainer* const container =
964  assignment->MutableIntVarContainer();
965  IntVarElement* element = nullptr;
966  if (assignment_indices != nullptr) {
967  if ((*assignment_indices)[index] == -1) {
968  (*assignment_indices)[index] = container->Size();
969  element = assignment->FastAdd(var);
970  } else {
971  element = container->MutableElement((*assignment_indices)[index]);
972  }
973  } else {
974  element = assignment->FastAdd(var);
975  }
976  if (active) {
977  element->SetValue(value);
978  element->Activate();
979  } else {
980  element->Deactivate();
981  }
982  }
983  bool ValueFromAssignment(const Assignment& assignment, IntVar* var,
984  int64 index, int64* value);
985  void OnRevertChanges(int64 index, int64 value);
986  void OnAddVars() {}
987 
988  private:
989  IntVarLocalSearchOperator* const op_;
990 };
991 
997 
998 #ifdef SWIG
999 // TODO(user): find a way to move this code back to the .i file, where it
1006 #if defined(SWIGPYTHON)
1007 %unignore VarLocalSearchOperator<IntVar, int64,
1008  IntVarLocalSearchHandler>::Size;
1009 %unignore VarLocalSearchOperator<IntVar, int64,
1010  IntVarLocalSearchHandler>::Value;
1011 %unignore VarLocalSearchOperator<IntVar, int64,
1012  IntVarLocalSearchHandler>::OldValue;
1013 %unignore VarLocalSearchOperator<IntVar, int64,
1014  IntVarLocalSearchHandler>::SetValue;
1015 %feature("director") VarLocalSearchOperator<IntVar, int64,
1016  IntVarLocalSearchHandler>::IsIncremental;
1017 %feature("director") VarLocalSearchOperator<IntVar, int64,
1018  IntVarLocalSearchHandler>::OnStart;
1019 %unignore VarLocalSearchOperator<IntVar, int64,
1020  IntVarLocalSearchHandler>::IsIncremental;
1021 %unignore VarLocalSearchOperator<IntVar, int64,
1022  IntVarLocalSearchHandler>::OnStart;
1023 #endif // SWIGPYTHON
1024 
1025 // clang-format off
1026 %rename(IntVarLocalSearchOperatorTemplate)
1027  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1028 %template(IntVarLocalSearchOperatorTemplate)
1029  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1030 // clang-format on
1031 #endif // SWIG
1032 
1035  public:
1036  IntVarLocalSearchOperator() : max_inverse_value_(-1) {}
1037  // If keep_inverse_values is true, assumes that vars models an injective
1038  // function f with domain [0, vars.size()) in which case the operator will
1039  // maintain the inverse function.
1040  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1041  bool keep_inverse_values = false)
1043  IntVarLocalSearchHandler(this)),
1044  max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) {
1045  AddVars(vars);
1046  if (keep_inverse_values) {
1047  int64 max_value = -1;
1048  for (const IntVar* const var : vars) {
1049  max_value = std::max(max_value, var->Max());
1050  }
1051  inverse_values_.resize(max_value + 1, -1);
1052  old_inverse_values_.resize(max_value + 1, -1);
1053  }
1054  }
1062  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1063 
1064  protected:
1066 
1069  // TODO(user): make it pure virtual, implies porting all apps overriding
1071  virtual bool MakeOneNeighbor();
1072 
1073  bool IsInverseValue(int64 index) const {
1074  DCHECK_GE(index, 0);
1075  return index <= max_inverse_value_;
1076  }
1077 
1078  int64 InverseValue(int64 index) const { return inverse_values_[index]; }
1079 
1080  int64 OldInverseValue(int64 index) const {
1081  return old_inverse_values_[index];
1082  }
1083 
1084  void SetInverseValue(int64 index, int64 value) {
1085  inverse_values_[index] = value;
1086  }
1087 
1088  void SetOldInverseValue(int64 index, int64 value) {
1089  old_inverse_values_[index] = value;
1090  }
1091 
1092  private:
1093  const int64 max_inverse_value_;
1094  std::vector<int64> old_inverse_values_;
1095  std::vector<int64> inverse_values_;
1096 };
1097 
1099  const Assignment& assignment, IntVar* var, int64 index, int64* value) {
1100  const Assignment::IntContainer& container = assignment.IntVarContainer();
1101  const IntVarElement* element = &(container.Element(index));
1102  if (element->Var() != var) {
1103  CHECK(container.Contains(var))
1104  << "Assignment does not contain operator variable " << var;
1105  element = &(container.Element(var));
1106  }
1107  *value = element->Value();
1108  if (op_->IsInverseValue(index)) {
1109  op_->SetInverseValue(*value, index);
1110  op_->SetOldInverseValue(*value, index);
1111  }
1112  return element->Activated();
1113 }
1114 
1116  int64 value) {
1117  if (op_->IsInverseValue(index)) {
1118  op_->SetInverseValue(value, index);
1119  }
1120 }
1121 
1124 
1126  public:
1127  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1129  : op_(other.op_) {}
1131  : op_(op) {}
1132  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1133  bool active, std::vector<int>* assignment_indices,
1134  int64 index, Assignment* assignment) const;
1135  bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var,
1136  int64 index, std::vector<int>* value);
1137  void OnRevertChanges(int64 index, const std::vector<int>& value);
1138  void OnAddVars();
1139 
1140  private:
1141  SequenceVarLocalSearchOperator* const op_;
1142 };
1143 
1144 #ifdef SWIG
1145 // TODO(user): find a way to move this code back to the .i file, where it
1150 // clang-format off
1151 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1152  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1153 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1154  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1155 // clang-format on
1156 #endif
1157 
1158 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1159  SequenceVarLocalSearchHandler>
1161 
1164  public:
1166  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1169  AddVars(vars);
1170  }
1174  const std::vector<int>& Sequence(int64 index) const { return Value(index); }
1175  const std::vector<int>& OldSequence(int64 index) const {
1176  return OldValue(index);
1177  }
1178  void SetForwardSequence(int64 index, const std::vector<int>& value) {
1179  SetValue(index, value);
1180  }
1181  void SetBackwardSequence(int64 index, const std::vector<int>& value) {
1182  backward_values_[index] = value;
1183  MarkChange(index);
1184  }
1185 
1186  protected:
1188 
1189  std::vector<std::vector<int>> backward_values_;
1190 };
1191 
1193  SequenceVar* var, const std::vector<int>& value, bool active,
1194  std::vector<int>* assignment_indices, int64 index,
1195  Assignment* assignment) const {
1196  Assignment::SequenceContainer* const container =
1197  assignment->MutableSequenceVarContainer();
1198  SequenceVarElement* element = nullptr;
1199  if (assignment_indices != nullptr) {
1200  if ((*assignment_indices)[index] == -1) {
1201  (*assignment_indices)[index] = container->Size();
1202  element = assignment->FastAdd(var);
1203  } else {
1204  element = container->MutableElement((*assignment_indices)[index]);
1205  }
1206  } else {
1207  element = assignment->FastAdd(var);
1208  }
1209  if (active) {
1210  element->SetForwardSequence(value);
1211  element->SetBackwardSequence(op_->backward_values_[index]);
1212  element->Activate();
1213  } else {
1214  element->Deactivate();
1215  }
1216 }
1217 
1219  const Assignment& assignment, SequenceVar* var, int64 index,
1220  std::vector<int>* value) {
1221  const Assignment::SequenceContainer& container =
1222  assignment.SequenceVarContainer();
1223  const SequenceVarElement* element = &(container.Element(index));
1224  if (element->Var() != var) {
1225  CHECK(container.Contains(var))
1226  << "Assignment does not contain operator variable " << var;
1227  element = &(container.Element(var));
1228  }
1229  const std::vector<int>& element_value = element->ForwardSequence();
1230  CHECK_GE(var->size(), element_value.size());
1231  op_->backward_values_[index].clear();
1232  *value = element_value;
1233  return element->Activated();
1234 }
1235 
1237  int64 index, const std::vector<int>& value) {
1238  op_->backward_values_[index].clear();
1239 }
1240 
1242  op_->backward_values_.resize(op_->Size());
1243 }
1244 
1273  public:
1274  explicit BaseLns(const std::vector<IntVar*>& vars);
1275  ~BaseLns() override;
1276  virtual void InitFragments();
1277  virtual bool NextFragment() = 0;
1278  void AppendToFragment(int index);
1279  int FragmentSize() const;
1280  bool HasFragments() const override { return true; }
1281 
1282  protected:
1284  bool MakeOneNeighbor() override;
1285 
1286  private:
1288  void OnStart() override;
1289  std::vector<int> fragment_;
1290 };
1291 
1297  public:
1298  explicit ChangeValue(const std::vector<IntVar*>& vars);
1299  ~ChangeValue() override;
1300  virtual int64 ModifyValue(int64 index, int64 value) = 0;
1301 
1302  protected:
1304  bool MakeOneNeighbor() override;
1305 
1306  private:
1307  void OnStart() override;
1308 
1309  int index_;
1310 };
1311 
1326  public:
1340  PathOperator(const std::vector<IntVar*>& next_vars,
1341  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1342  bool skip_locally_optimal_paths, bool accept_path_end_base,
1343  std::function<int(int64)> start_empty_path_class);
1344  ~PathOperator() override {}
1345  virtual bool MakeNeighbor() = 0;
1346  void Reset() override;
1347 
1348  // TODO(user): Make the following methods protected.
1349  bool SkipUnchanged(int index) const override;
1350 
1352  int64 Next(int64 node) const {
1353  DCHECK(!IsPathEnd(node));
1354  return Value(node);
1355  }
1356 
1358  int64 Prev(int64 node) const {
1359  DCHECK(!IsPathStart(node));
1360  DCHECK_EQ(Next(InverseValue(node)), node);
1361  return InverseValue(node);
1362  }
1363 
1366  int64 Path(int64 node) const {
1367  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1368  }
1369 
1371  int number_of_nexts() const { return number_of_nexts_; }
1372 
1373  protected:
1375  bool MakeOneNeighbor() override;
1379  virtual void OnNodeInitialization() {}
1380 
1382  int64 BaseNode(int i) const { return base_nodes_[i]; }
1384  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1386  int64 BaseAlternativeNode(int i) const {
1387  if (!ConsiderAlternatives(i)) return BaseNode(i);
1388  const int alternative_index = alternative_index_[BaseNode(i)];
1389  return alternative_index >= 0
1390  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1391  : BaseNode(i);
1392  }
1394  int BaseSiblingAlternative(int i) const {
1395  return base_sibling_alternatives_[i];
1396  }
1398  int64 BaseSiblingAlternativeNode(int i) const {
1399  if (!ConsiderAlternatives(i)) return BaseNode(i);
1400  const int sibling_alternative_index =
1402  return sibling_alternative_index >= 0
1403  ? alternative_sets_[sibling_alternative_index]
1404  [base_sibling_alternatives_[i]]
1405  : BaseNode(i);
1406  }
1408  int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1410  const std::vector<int64>& path_starts() const { return path_starts_; }
1412  int PathClass(int i) const {
1413  return start_empty_path_class_ != nullptr
1414  ? start_empty_path_class_(StartNode(i))
1415  : StartNode(i);
1416  }
1417 
1424  // TODO(user): remove this when automatic detection of such cases in done.
1425  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1429  // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2);
1431  virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; }
1437  virtual int64 GetBaseNodeRestartPosition(int base_index) {
1438  return StartNode(base_index);
1439  }
1442  virtual void SetNextBaseToIncrement(int64 base_index) {
1443  next_base_to_increment_ = base_index;
1444  }
1447  virtual bool ConsiderAlternatives(int64 base_index) const { return false; }
1448 
1449  int64 OldNext(int64 node) const {
1450  DCHECK(!IsPathEnd(node));
1451  return OldValue(node);
1452  }
1453 
1454  int64 OldPrev(int64 node) const {
1455  DCHECK(!IsPathStart(node));
1456  return OldInverseValue(node);
1457  }
1458 
1459  int64 OldPath(int64 node) const {
1460  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1461  }
1462 
1465  bool MoveChain(int64 before_chain, int64 chain_end, int64 destination);
1466 
1469  bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last);
1470 
1472  bool MakeActive(int64 node, int64 destination);
1475  bool MakeChainInactive(int64 before_chain, int64 chain_end);
1477  bool SwapActiveAndInactive(int64 active, int64 inactive);
1478 
1480  void SetNext(int64 from, int64 to, int64 path) {
1481  DCHECK_LT(from, number_of_nexts_);
1482  SetValue(from, to);
1483  SetInverseValue(to, from);
1484  if (!ignore_path_vars_) {
1485  DCHECK_LT(from + number_of_nexts_, Size());
1486  SetValue(from + number_of_nexts_, path);
1487  }
1488  }
1489 
1492  bool IsPathEnd(int64 node) const { return node >= number_of_nexts_; }
1493 
1495  bool IsPathStart(int64 node) const { return OldInverseValue(node) == -1; }
1496 
1498  bool IsInactive(int64 node) const {
1499  return !IsPathEnd(node) && inactives_[node];
1500  }
1501 
1504  virtual bool InitPosition() const { return false; }
1508  void ResetPosition() { just_started_ = true; }
1509 
1513  int AddAlternativeSet(const std::vector<int64>& alternative_set) {
1514  const int alternative = alternative_sets_.size();
1515  for (int64 node : alternative_set) {
1516  DCHECK_EQ(-1, alternative_index_[node]);
1517  alternative_index_[node] = alternative;
1518  }
1519  alternative_sets_.push_back(alternative_set);
1520  sibling_alternative_.push_back(-1);
1521  return alternative;
1522  }
1523 #ifndef SWIG
1527  const std::vector<std::pair<std::vector<int64>, std::vector<int64>>>&
1528  pair_alternative_sets) {
1529  for (const auto& pair_alternative_set : pair_alternative_sets) {
1530  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1531  sibling_alternative_.back() = alternative + 1;
1532  AddAlternativeSet(pair_alternative_set.second);
1533  }
1534  }
1535 #endif // SWIG
1536  int64 GetActiveInAlternativeSet(int alternative_index) const {
1538  return alternative_index >= 0
1539  ? active_in_alternative_set_[alternative_index]
1540  : -1;
1541  }
1543  int64 GetActiveAlternativeNode(int node) const {
1544  return GetActiveInAlternativeSet(alternative_index_[node]);
1545  }
1547  int GetSiblingAlternativeIndex(int node) const {
1548  if (node >= alternative_index_.size()) return -1;
1549  const int alternative = alternative_index_[node];
1550  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1551  }
1554  int64 GetActiveAlternativeSibling(int node) const {
1555  if (node >= alternative_index_.size()) return -1;
1556  const int alternative = alternative_index_[node];
1557  const int sibling_alternative =
1558  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1559  return GetActiveInAlternativeSet(sibling_alternative);
1560  }
1563  bool CheckChainValidity(int64 before_chain, int64 chain_end,
1564  int64 exclude) const;
1565 
1566  const int number_of_nexts_;
1567  const bool ignore_path_vars_;
1569  int num_paths_ = 0;
1570  std::vector<int64> start_to_path_;
1571 
1572  private:
1573  void OnStart() override;
1575  bool OnSamePath(int64 node1, int64 node2) const;
1576 
1577  bool CheckEnds() const {
1578  const int base_node_size = base_nodes_.size();
1579  for (int i = base_node_size - 1; i >= 0; --i) {
1580  if (base_nodes_[i] != end_nodes_[i]) {
1581  return true;
1582  }
1583  }
1584  return false;
1585  }
1586  bool IncrementPosition();
1587  void InitializePathStarts();
1588  void InitializeInactives();
1589  void InitializeBaseNodes();
1590  void InitializeAlternatives();
1591  void Synchronize();
1592 
1593  std::vector<int> base_nodes_;
1594  std::vector<int> base_alternatives_;
1595  std::vector<int> base_sibling_alternatives_;
1596  std::vector<int> end_nodes_;
1597  std::vector<int> base_paths_;
1598  std::vector<int64> path_starts_;
1599  std::vector<bool> inactives_;
1600  bool just_started_;
1601  bool first_start_;
1602  const bool accept_path_end_base_;
1603  std::function<int(int64)> start_empty_path_class_;
1604  bool skip_locally_optimal_paths_;
1605  bool optimal_paths_enabled_;
1606  std::vector<int> path_basis_;
1607  std::vector<bool> optimal_paths_;
1609 #ifndef SWIG
1610  std::vector<std::vector<int64>> alternative_sets_;
1611 #endif // SWIG
1612  std::vector<int> alternative_index_;
1613  std::vector<int64> active_in_alternative_set_;
1614  std::vector<int> sibling_alternative_;
1615 };
1616 
1618 template <class T>
1620  Solver* solver, const std::vector<IntVar*>& vars,
1621  const std::vector<IntVar*>& secondary_vars,
1622  std::function<int(int64)> start_empty_path_class);
1623 
1626 class TwoOpt;
1627 class Relocate;
1628 class Exchange;
1629 class Cross;
1630 class MakeActiveOperator;
1631 class MakeInactiveOperator;
1632 class MakeChainInactiveOperator;
1633 class SwapActiveOperator;
1634 class ExtendedSwapActiveOperator;
1635 class MakeActiveAndRelocate;
1636 class RelocateAndMakeActiveOperator;
1637 class RelocateAndMakeInactiveOperator;
1638 
1639 #if !defined(SWIG)
1640 // A LocalSearchState is a container for variables with bounds that can be
1641 // relaxed and tightened, saved and restored. It represents the solution state
1642 // of a local search engine, and allows it to go from solution to solution by
1643 // relaxing some variables to form a new subproblem, then tightening those
1644 // variables to move to a new solution representation. That state may be saved
1645 // to an internal copy, or reverted to the last saved internal copy.
1646 // Relaxing a variable returns its bounds to their initial state.
1647 // Tightening a variable's bounds may make its min larger than its max,
1648 // in that case, the tightening function will return false, and the state will
1649 // be marked as invalid. No other operations than Revert() can be called on an
1650 // invalid state: in particular, an invalid state cannot be saved.
1651 class LocalSearchVariable;
1653  public:
1654  LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max);
1655  void Commit();
1656  void Revert();
1657  bool StateIsValid() const { return state_is_valid_; }
1658 
1659  private:
1660  friend class LocalSearchVariable;
1661 
1662  struct Bounds {
1663  int64 min;
1664  int64 max;
1665  };
1666 
1667  void RelaxVariableBounds(int variable_index);
1668  bool TightenVariableMin(int variable_index, int64 value);
1669  bool TightenVariableMax(int variable_index, int64 value);
1670  int64 VariableMin(int variable_index) const;
1671  int64 VariableMax(int variable_index) const;
1672 
1673  std::vector<Bounds> initial_variable_bounds_;
1674  std::vector<Bounds> variable_bounds_;
1675  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1676  std::vector<bool> variable_is_relaxed_;
1677  bool state_is_valid_ = true;
1678 };
1679 
1680 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1681 // meant to be passed by copy. If at some point the duplication of
1682 // LocalSearchState pointers is too expensive, we could switch to index only,
1683 // and the user would have to know the relevant state. The present setup allows
1684 // to ensure that variable users will not misuse the state.
1686  public:
1687  int64 Min() const { return state_->VariableMin(variable_index_); }
1688  int64 Max() const { return state_->VariableMax(variable_index_); }
1689  bool SetMin(int64 new_min) {
1690  return state_->TightenVariableMin(variable_index_, new_min);
1691  }
1692  bool SetMax(int64 new_max) {
1693  return state_->TightenVariableMax(variable_index_, new_max);
1694  }
1695  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1696 
1697  private:
1698  // Only LocalSearchState can construct LocalSearchVariables.
1699  friend class LocalSearchState;
1700 
1701  LocalSearchVariable(LocalSearchState* state, int variable_index)
1702  : state_(state), variable_index_(variable_index) {}
1703 
1704  LocalSearchState* const state_;
1705  const int variable_index_;
1706 };
1707 #endif // !defined(SWIG)
1708 
1725 class LocalSearchFilter : public BaseObject {
1726  public:
1729  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1731  virtual void Commit(const Assignment* delta, const Assignment* deltadelta) {}
1732 
1742  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1743  int64 objective_min, int64 objective_max) = 0;
1744  virtual bool IsIncremental() const { return false; }
1745 
1751  virtual void Synchronize(const Assignment* assignment,
1752  const Assignment* delta) = 0;
1754  virtual void Revert() {}
1755 
1757  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1759  // If the last Accept() call returned false, returns an undefined value.
1760  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1761 };
1762 
1766 class LocalSearchFilterManager : public BaseObject {
1767  public:
1768  // This class is responsible for calling filters methods in a correct order.
1769  // For now, an order is specified explicitly by the user.
1771  struct FilterEvent {
1774  };
1775 
1776  std::string DebugString() const override {
1777  return "LocalSearchFilterManager";
1778  }
1779  // Builds a manager that calls filter methods using an explicit ordering.
1780  explicit LocalSearchFilterManager(std::vector<FilterEvent> filter_events);
1781  // Builds a manager that calls filter methods using the following ordering:
1782  // first Relax() in vector order, then Accept() in vector order.
1783  // Note that some filters might appear only once, if their Relax() or Accept()
1784  // are trivial.
1785  explicit LocalSearchFilterManager(std::vector<LocalSearchFilter*> filters);
1786 
1787  // Calls Revert() of filters, in reverse order of Relax events.
1788  void Revert();
1792  bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta,
1793  const Assignment* deltadelta, int64 objective_min,
1794  int64 objective_max);
1796  void Synchronize(const Assignment* assignment, const Assignment* delta);
1797  int64 GetSynchronizedObjectiveValue() const { return synchronized_value_; }
1798  int64 GetAcceptedObjectiveValue() const { return accepted_value_; }
1799 
1800  private:
1801  void InitializeForcedEvents();
1802 
1803  std::vector<FilterEvent> filter_events_;
1804  int last_event_called_ = -1;
1805  // If a filter is incremental, its Relax() and Accept() must be called for
1806  // every candidate, even if a previous Accept() rejected it.
1807  // To ensure that those filters have consistent inputs, all intermediate
1808  // Relax events are also triggered. All those events are called 'forced'.
1809  std::vector<int> next_forced_events_;
1810  int64 synchronized_value_;
1811  int64 accepted_value_;
1812 };
1813 
1815  public:
1816  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1820  void Synchronize(const Assignment* assignment,
1821  const Assignment* delta) override;
1822 
1823  bool FindIndex(IntVar* const var, int64* index) const {
1824  DCHECK(index != nullptr);
1825  const int var_index = var->index();
1826  *index = (var_index < var_index_to_index_.size())
1827  ? var_index_to_index_[var_index]
1828  : kUnassigned;
1829  return *index != kUnassigned;
1830  }
1831 
1833  void AddVars(const std::vector<IntVar*>& vars);
1834  int Size() const { return vars_.size(); }
1835  IntVar* Var(int index) const { return vars_[index]; }
1836  int64 Value(int index) const {
1837  DCHECK(IsVarSynced(index));
1838  return values_[index];
1839  }
1840  bool IsVarSynced(int index) const { return var_synced_[index]; }
1841 
1842  protected:
1843  virtual void OnSynchronize(const Assignment* delta) {}
1844  void SynchronizeOnAssignment(const Assignment* assignment);
1845 
1846  private:
1847  std::vector<IntVar*> vars_;
1848  std::vector<int64> values_;
1849  std::vector<bool> var_synced_;
1850  std::vector<int> var_index_to_index_;
1851  static const int kUnassigned;
1852 };
1853 
1854 class PropagationMonitor : public SearchMonitor {
1855  public:
1856  explicit PropagationMonitor(Solver* const solver);
1858  std::string DebugString() const override { return "PropagationMonitor"; }
1859 
1862  Constraint* const constraint) = 0;
1864  Constraint* const constraint) = 0;
1866  Constraint* const parent, Constraint* const nested) = 0;
1868  Constraint* const parent, Constraint* const nested) = 0;
1869  virtual void RegisterDemon(Demon* const demon) = 0;
1870  virtual void BeginDemonRun(Demon* const demon) = 0;
1871  virtual void EndDemonRun(Demon* const demon) = 0;
1872  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1873  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1874  virtual void PushContext(const std::string& context) = 0;
1875  virtual void PopContext() = 0;
1877  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1878  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1879  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1881  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1882  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1883  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1884  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1885  virtual void SetValue(IntVar* const var, int64 value) = 0;
1886  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1887  virtual void SetValues(IntVar* const var,
1888  const std::vector<int64>& values) = 0;
1889  virtual void RemoveValues(IntVar* const var,
1890  const std::vector<int64>& values) = 0;
1892  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1893  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1894  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1895  int64 new_max) = 0;
1896  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1897  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1898  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1899  int64 new_max) = 0;
1900  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1901  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1902  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1903  int64 new_max) = 0;
1904  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1906  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1907  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1908  virtual void RankLast(SequenceVar* const var, int index) = 0;
1909  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1910  virtual void RankSequence(SequenceVar* const var,
1911  const std::vector<int>& rank_first,
1912  const std::vector<int>& rank_last,
1913  const std::vector<int>& unperformed) = 0;
1915  void Install() override;
1916 };
1917 
1918 class LocalSearchMonitor : public SearchMonitor {
1919  // TODO(user): Add monitoring of local search filters.
1920  public:
1921  explicit LocalSearchMonitor(Solver* const solver);
1923  std::string DebugString() const override { return "LocalSearchMonitor"; }
1924 
1926  virtual void BeginOperatorStart() = 0;
1927  virtual void EndOperatorStart() = 0;
1928  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1930  bool neighbor_found, const Assignment* delta,
1931  const Assignment* deltadelta) = 0;
1932  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1933  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1934  bool neighbor_found) = 0;
1935  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1936  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1937  bool neighbor_found) = 0;
1938  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1939  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1940 
1942  void Install() override;
1943 };
1944 
1945 class BooleanVar : public IntVar {
1946  public:
1947  static const int kUnboundBooleanVarValue;
1948 
1949  explicit BooleanVar(Solver* const s, const std::string& name = "")
1950  : IntVar(s, name), value_(kUnboundBooleanVarValue) {}
1951 
1952  ~BooleanVar() override {}
1953 
1954  int64 Min() const override { return (value_ == 1); }
1955  void SetMin(int64 m) override;
1956  int64 Max() const override { return (value_ != 0); }
1957  void SetMax(int64 m) override;
1958  void SetRange(int64 mi, int64 ma) override;
1959  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1960  int64 Value() const override {
1961  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1962  return value_;
1963  }
1964  void RemoveValue(int64 v) override;
1965  void RemoveInterval(int64 l, int64 u) override;
1966  void WhenBound(Demon* d) override;
1967  void WhenRange(Demon* d) override { WhenBound(d); }
1968  void WhenDomain(Demon* d) override { WhenBound(d); }
1969  uint64 Size() const override;
1970  bool Contains(int64 v) const override;
1971  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1972  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1973  std::string DebugString() const override;
1974  int VarType() const override { return BOOLEAN_VAR; }
1975 
1976  IntVar* IsEqual(int64 constant) override;
1977  IntVar* IsDifferent(int64 constant) override;
1978  IntVar* IsGreaterOrEqual(int64 constant) override;
1979  IntVar* IsLessOrEqual(int64 constant) override;
1980 
1981  virtual void RestoreValue() = 0;
1982  std::string BaseName() const override { return "BooleanVar"; }
1983 
1984  int RawValue() const { return value_; }
1985 
1986  protected:
1987  int value_;
1990 };
1991 
1992 class SymmetryManager;
1993 
1997 class SymmetryBreaker : public DecisionVisitor {
1998  public:
2000  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
2001  ~SymmetryBreaker() override {}
2002 
2003  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
2005  int64 value);
2006  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
2007 
2008  private:
2009  friend class SymmetryManager;
2010  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
2011  CHECK(symmetry_manager_ == nullptr);
2012  CHECK_EQ(-1, index_in_symmetry_manager_);
2013  symmetry_manager_ = manager;
2014  index_in_symmetry_manager_ = index;
2015  }
2016  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
2017  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
2018 
2019  SymmetryManager* symmetry_manager_;
2021  int index_in_symmetry_manager_;
2022 };
2023 
2026 class SearchLog : public SearchMonitor {
2027  public:
2028  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2029  double scaling_factor, double offset,
2030  std::function<std::string()> display_callback, int period);
2031  ~SearchLog() override;
2032  void EnterSearch() override;
2033  void ExitSearch() override;
2034  bool AtSolution() override;
2035  void BeginFail() override;
2036  void NoMoreSolutions() override;
2037  void AcceptUncheckedNeighbor() override;
2038  void ApplyDecision(Decision* const decision) override;
2039  void RefuteDecision(Decision* const decision) override;
2041  void Maintain();
2042  void BeginInitialPropagation() override;
2043  void EndInitialPropagation() override;
2044  std::string DebugString() const override;
2045 
2046  protected:
2047  /* Bottleneck function used for all UI related output. */
2048  virtual void OutputLine(const std::string& line);
2049 
2050  private:
2051  static std::string MemoryUsage();
2052 
2053  const int period_;
2054  std::unique_ptr<WallTimer> timer_;
2055  IntVar* const var_;
2056  OptimizeVar* const obj_;
2057  const double scaling_factor_;
2058  const double offset_;
2059  std::function<std::string()> display_callback_;
2060  int nsol_;
2061  int64 tick_;
2062  int64 objective_min_;
2063  int64 objective_max_;
2064  int min_right_depth_;
2065  int max_depth_;
2066  int sliding_min_depth_;
2067  int sliding_max_depth_;
2068 };
2069 
2074 class ModelCache {
2075  public:
2080  };
2081 
2088  };
2089 
2093  };
2094 
2103  };
2104 
2110  };
2111 
2124  };
2125 
2129  };
2130 
2143  };
2147  };
2148 
2152  };
2153 
2157  };
2158 
2164  };
2165 
2169  };
2170 
2171  explicit ModelCache(Solver* const solver);
2172  virtual ~ModelCache();
2173 
2174  virtual void Clear() = 0;
2175 
2177 
2178  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
2179 
2180  virtual void InsertVoidConstraint(Constraint* const ct,
2181  VoidConstraintType type) = 0;
2182 
2184  virtual Constraint* FindVarConstantConstraint(
2185  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
2186 
2187  virtual void InsertVarConstantConstraint(Constraint* const ct,
2188  IntVar* const var, int64 value,
2189  VarConstantConstraintType type) = 0;
2190 
2192 
2194  IntVar* const var, int64 value1, int64 value2,
2195  VarConstantConstantConstraintType type) const = 0;
2196 
2198  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
2200 
2202 
2203  virtual Constraint* FindExprExprConstraint(
2204  IntExpr* const expr1, IntExpr* const expr2,
2205  ExprExprConstraintType type) const = 0;
2206 
2207  virtual void InsertExprExprConstraint(Constraint* const ct,
2208  IntExpr* const expr1,
2209  IntExpr* const expr2,
2210  ExprExprConstraintType type) = 0;
2211 
2213 
2214  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2215  ExprExpressionType type) const = 0;
2216 
2217  virtual void InsertExprExpression(IntExpr* const expression,
2218  IntExpr* const expr,
2219  ExprExpressionType type) = 0;
2220 
2222 
2223  virtual IntExpr* FindExprConstantExpression(
2224  IntExpr* const expr, int64 value,
2225  ExprConstantExpressionType type) const = 0;
2226 
2228  IntExpr* const expression, IntExpr* const var, int64 value,
2229  ExprConstantExpressionType type) = 0;
2230 
2232 
2233  virtual IntExpr* FindExprExprExpression(
2234  IntExpr* const var1, IntExpr* const var2,
2235  ExprExprExpressionType type) const = 0;
2236 
2237  virtual void InsertExprExprExpression(IntExpr* const expression,
2238  IntExpr* const var1,
2239  IntExpr* const var2,
2240  ExprExprExpressionType type) = 0;
2241 
2243 
2245  IntExpr* const var1, IntExpr* const var2, int64 constant,
2246  ExprExprConstantExpressionType type) const = 0;
2247 
2249  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2250  int64 constant, ExprExprConstantExpressionType type) = 0;
2251 
2253 
2255  IntVar* const var, int64 value1, int64 value2,
2256  VarConstantConstantExpressionType type) const = 0;
2257 
2259  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2261 
2263 
2265  IntVar* const var, const std::vector<int64>& values,
2266  VarConstantArrayExpressionType type) const = 0;
2267 
2269  IntExpr* const expression, IntVar* const var,
2270  const std::vector<int64>& values,
2272 
2274 
2275  virtual IntExpr* FindVarArrayExpression(
2276  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2277 
2278  virtual void InsertVarArrayExpression(IntExpr* const expression,
2279  const std::vector<IntVar*>& vars,
2280  VarArrayExpressionType type) = 0;
2281 
2283 
2285  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2286  VarArrayConstantArrayExpressionType type) const = 0;
2287 
2289  IntExpr* const expression, const std::vector<IntVar*>& var,
2290  const std::vector<int64>& values,
2292 
2294 
2296  const std::vector<IntVar*>& vars, int64 value,
2297  VarArrayConstantExpressionType type) const = 0;
2298 
2300  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2302 
2303  Solver* solver() const;
2304 
2305  private:
2306  Solver* const solver_;
2307 };
2308 
2310 #if !defined(SWIG)
2312  public:
2314  const std::string& TypeName() const;
2315  void SetTypeName(const std::string& type_name);
2316 
2318  void SetIntegerArgument(const std::string& arg_name, int64 value);
2319  void SetIntegerArrayArgument(const std::string& arg_name,
2320  const std::vector<int64>& values);
2321  void SetIntegerMatrixArgument(const std::string& arg_name,
2322  const IntTupleSet& values);
2323  void SetIntegerExpressionArgument(const std::string& arg_name,
2324  IntExpr* const expr);
2325  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2326  const std::vector<IntVar*>& vars);
2327  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2328  void SetIntervalArrayArgument(const std::string& arg_name,
2329  const std::vector<IntervalVar*>& vars);
2330  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2331  void SetSequenceArrayArgument(const std::string& arg_name,
2332  const std::vector<SequenceVar*>& vars);
2333 
2335  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2336  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2337 
2339  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2340  int64 def) const;
2341  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2342  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2343  const std::string& arg_name) const;
2345  const std::string& arg_name) const;
2346 
2348  const std::string& arg_name) const;
2349  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2350  const std::string& arg_name) const;
2351 
2352  private:
2353  std::string type_name_;
2354  absl::flat_hash_map<std::string, int64> integer_argument_;
2355  absl::flat_hash_map<std::string, std::vector<int64>> integer_array_argument_;
2356  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2357  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2358  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2359  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2360  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2361  integer_variable_array_argument_;
2362  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2363  interval_array_argument_;
2364  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2365  sequence_array_argument_;
2366 };
2367 
2369 class ModelParser : public ModelVisitor {
2370  public:
2372 
2373  ~ModelParser() override;
2374 
2376  void BeginVisitModel(const std::string& solver_name) override;
2377  void EndVisitModel(const std::string& solver_name) override;
2378  void BeginVisitConstraint(const std::string& type_name,
2379  const Constraint* const constraint) override;
2380  void EndVisitConstraint(const std::string& type_name,
2381  const Constraint* const constraint) override;
2382  void BeginVisitIntegerExpression(const std::string& type_name,
2383  const IntExpr* const expr) override;
2384  void EndVisitIntegerExpression(const std::string& type_name,
2385  const IntExpr* const expr) override;
2386  void VisitIntegerVariable(const IntVar* const variable,
2387  IntExpr* const delegate) override;
2388  void VisitIntegerVariable(const IntVar* const variable,
2389  const std::string& operation, int64 value,
2390  IntVar* const delegate) override;
2391  void VisitIntervalVariable(const IntervalVar* const variable,
2392  const std::string& operation, int64 value,
2393  IntervalVar* const delegate) override;
2394  void VisitSequenceVariable(const SequenceVar* const variable) override;
2396  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2397  void VisitIntegerArrayArgument(const std::string& arg_name,
2398  const std::vector<int64>& values) override;
2399  void VisitIntegerMatrixArgument(const std::string& arg_name,
2400  const IntTupleSet& values) override;
2402  void VisitIntegerExpressionArgument(const std::string& arg_name,
2403  IntExpr* const argument) override;
2405  const std::string& arg_name,
2406  const std::vector<IntVar*>& arguments) override;
2408  void VisitIntervalArgument(const std::string& arg_name,
2409  IntervalVar* const argument) override;
2411  const std::string& arg_name,
2412  const std::vector<IntervalVar*>& arguments) override;
2414  void VisitSequenceArgument(const std::string& arg_name,
2415  SequenceVar* const argument) override;
2417  const std::string& arg_name,
2418  const std::vector<SequenceVar*>& arguments) override;
2419 
2420  protected:
2424 
2425  private:
2426  std::vector<ArgumentHolder*> holders_;
2427 };
2428 
2429 template <class T>
2430 class ArrayWithOffset : public BaseObject {
2431  public:
2432  ArrayWithOffset(int64 index_min, int64 index_max)
2433  : index_min_(index_min),
2434  index_max_(index_max),
2435  values_(new T[index_max - index_min + 1]) {
2436  DCHECK_LE(index_min, index_max);
2437  }
2438 
2439  ~ArrayWithOffset() override {}
2440 
2441  virtual T Evaluate(int64 index) const {
2442  DCHECK_GE(index, index_min_);
2443  DCHECK_LE(index, index_max_);
2444  return values_[index - index_min_];
2445  }
2446 
2447  void SetValue(int64 index, T value) {
2448  DCHECK_GE(index, index_min_);
2449  DCHECK_LE(index, index_max_);
2450  values_[index - index_min_] = value;
2451  }
2452 
2453  std::string DebugString() const override { return "ArrayWithOffset"; }
2454 
2455  private:
2456  const int64 index_min_;
2457  const int64 index_max_;
2458  std::unique_ptr<T[]> values_;
2459 };
2460 #endif // SWIG
2461 
2466 template <class T, class C>
2468  public:
2469  explicit RevGrowingArray(int64 block_size)
2470  : block_size_(block_size), block_offset_(0) {
2471  CHECK_GT(block_size, 0);
2472  }
2473 
2475  for (int i = 0; i < elements_.size(); ++i) {
2476  delete[] elements_[i];
2477  }
2478  }
2479 
2480  T At(int64 index) const {
2481  const int64 block_index = ComputeBlockIndex(index);
2482  const int64 relative_index = block_index - block_offset_;
2483  if (relative_index < 0 || relative_index >= elements_.size()) {
2484  return T();
2485  }
2486  const T* block = elements_[relative_index];
2487  return block != nullptr ? block[index - block_index * block_size_] : T();
2488  }
2489 
2490  void RevInsert(Solver* const solver, int64 index, T value) {
2491  const int64 block_index = ComputeBlockIndex(index);
2492  T* const block = GetOrCreateBlock(block_index);
2493  const int64 residual = index - block_index * block_size_;
2494  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2495  reinterpret_cast<C>(value));
2496  }
2497 
2498  private:
2499  T* NewBlock() const {
2500  T* const result = new T[block_size_];
2501  for (int i = 0; i < block_size_; ++i) {
2502  result[i] = T();
2503  }
2504  return result;
2505  }
2506 
2507  T* GetOrCreateBlock(int block_index) {
2508  if (elements_.size() == 0) {
2509  block_offset_ = block_index;
2510  GrowUp(block_index);
2511  } else if (block_index < block_offset_) {
2512  GrowDown(block_index);
2513  } else if (block_index - block_offset_ >= elements_.size()) {
2514  GrowUp(block_index);
2515  }
2516  T* block = elements_[block_index - block_offset_];
2517  if (block == nullptr) {
2518  block = NewBlock();
2519  elements_[block_index - block_offset_] = block;
2520  }
2521  return block;
2522  }
2523 
2524  int64 ComputeBlockIndex(int64 value) const {
2525  return value >= 0 ? value / block_size_
2526  : (value - block_size_ + 1) / block_size_;
2527  }
2528 
2529  void GrowUp(int64 block_index) {
2530  elements_.resize(block_index - block_offset_ + 1);
2531  }
2532 
2533  void GrowDown(int64 block_index) {
2534  const int64 delta = block_offset_ - block_index;
2535  block_offset_ = block_index;
2536  DCHECK_GT(delta, 0);
2537  elements_.insert(elements_.begin(), delta, nullptr);
2538  }
2539 
2540  const int64 block_size_;
2541  std::vector<T*> elements_;
2542  int block_offset_;
2543 };
2544 
2549 template <class T>
2550 class RevIntSet {
2551  public:
2552  static constexpr int kNoInserted = -1;
2553 
2555  explicit RevIntSet(int capacity)
2556  : elements_(new T[capacity]),
2557  num_elements_(0),
2558  capacity_(capacity),
2559  position_(new int[capacity]),
2560  delete_position_(true) {
2561  for (int i = 0; i < capacity; ++i) {
2562  position_[i] = kNoInserted;
2563  }
2564  }
2565 
2567  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2568  : elements_(new T[capacity]),
2569  num_elements_(0),
2570  capacity_(capacity),
2571  position_(shared_positions),
2572  delete_position_(false) {
2573  for (int i = 0; i < shared_positions_size; ++i) {
2574  position_[i] = kNoInserted;
2575  }
2576  }
2577 
2579  if (delete_position_) {
2580  delete[] position_;
2581  }
2582  }
2583 
2584  int Size() const { return num_elements_.Value(); }
2585 
2586  int Capacity() const { return capacity_; }
2587 
2588  T Element(int i) const {
2589  DCHECK_GE(i, 0);
2590  DCHECK_LT(i, num_elements_.Value());
2591  return elements_[i];
2592  }
2593 
2594  T RemovedElement(int i) const {
2595  DCHECK_GE(i, 0);
2596  DCHECK_LT(i + num_elements_.Value(), capacity_);
2597  return elements_[i + num_elements_.Value()];
2598  }
2599 
2600  void Insert(Solver* const solver, const T& elt) {
2601  const int position = num_elements_.Value();
2602  DCHECK_LT(position, capacity_);
2603  DCHECK(NotAlreadyInserted(elt));
2604  elements_[position] = elt;
2605  position_[elt] = position;
2606  num_elements_.Incr(solver);
2607  }
2608 
2609  void Remove(Solver* const solver, const T& value_index) {
2610  num_elements_.Decr(solver);
2611  SwapTo(value_index, num_elements_.Value());
2612  }
2613 
2614  void Restore(Solver* const solver, const T& value_index) {
2615  SwapTo(value_index, num_elements_.Value());
2616  num_elements_.Incr(solver);
2617  }
2618 
2619  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2620 
2622  typedef const T* const_iterator;
2623  const_iterator begin() const { return elements_.get(); }
2624  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2625 
2626  private:
2628  bool NotAlreadyInserted(const T& elt) {
2629  for (int i = 0; i < num_elements_.Value(); ++i) {
2630  if (elt == elements_[i]) {
2631  return false;
2632  }
2633  }
2634  return true;
2635  }
2636 
2637  void SwapTo(T value_index, int next_position) {
2638  const int current_position = position_[value_index];
2639  if (current_position != next_position) {
2640  const T next_value_index = elements_[next_position];
2641  elements_[current_position] = next_value_index;
2642  elements_[next_position] = value_index;
2643  position_[value_index] = next_position;
2644  position_[next_value_index] = current_position;
2645  }
2646  }
2647 
2649  std::unique_ptr<T[]> elements_;
2651  NumericalRev<int> num_elements_;
2653  const int capacity_;
2655  int* position_;
2657  const bool delete_position_;
2658 };
2659 
2661 
2663  public:
2664  explicit RevPartialSequence(const std::vector<int>& items)
2665  : elements_(items),
2666  first_ranked_(0),
2667  last_ranked_(items.size() - 1),
2668  size_(items.size()),
2669  position_(new int[size_]) {
2670  for (int i = 0; i < size_; ++i) {
2671  elements_[i] = items[i];
2672  position_[i] = i;
2673  }
2674  }
2675 
2676  explicit RevPartialSequence(int size)
2677  : elements_(size),
2678  first_ranked_(0),
2679  last_ranked_(size - 1),
2680  size_(size),
2681  position_(new int[size_]) {
2682  for (int i = 0; i < size_; ++i) {
2683  elements_[i] = i;
2684  position_[i] = i;
2685  }
2686  }
2687 
2689 
2690  int NumFirstRanked() const { return first_ranked_.Value(); }
2691 
2692  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2693 
2694  int Size() const { return size_; }
2695 
2696 #if !defined(SWIG)
2697  const int& operator[](int index) const {
2698  DCHECK_GE(index, 0);
2699  DCHECK_LT(index, size_);
2700  return elements_[index];
2701  }
2702 #endif
2703 
2704  void RankFirst(Solver* const solver, int elt) {
2705  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2706  SwapTo(elt, first_ranked_.Value());
2707  first_ranked_.Incr(solver);
2708  }
2709 
2710  void RankLast(Solver* const solver, int elt) {
2711  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2712  SwapTo(elt, last_ranked_.Value());
2713  last_ranked_.Decr(solver);
2714  }
2715 
2716  bool IsRanked(int elt) const {
2717  const int position = position_[elt];
2718  return (position < first_ranked_.Value() ||
2719  position > last_ranked_.Value());
2720  }
2721 
2722  std::string DebugString() const {
2723  std::string result = "[";
2724  for (int i = 0; i < first_ranked_.Value(); ++i) {
2725  absl::StrAppend(&result, elements_[i]);
2726  if (i != first_ranked_.Value() - 1) {
2727  result.append("-");
2728  }
2729  }
2730  result.append("|");
2731  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2732  absl::StrAppend(&result, elements_[i]);
2733  if (i != last_ranked_.Value()) {
2734  result.append("-");
2735  }
2736  }
2737  result.append("|");
2738  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2739  absl::StrAppend(&result, elements_[i]);
2740  if (i != size_ - 1) {
2741  result.append("-");
2742  }
2743  }
2744  result.append("]");
2745  return result;
2746  }
2747 
2748  private:
2749  void SwapTo(int elt, int next_position) {
2750  const int current_position = position_[elt];
2751  if (current_position != next_position) {
2752  const int next_elt = elements_[next_position];
2753  elements_[current_position] = next_elt;
2754  elements_[next_position] = elt;
2755  position_[elt] = next_position;
2756  position_[next_elt] = current_position;
2757  }
2758  }
2759 
2761  std::vector<int> elements_;
2763  NumericalRev<int> first_ranked_;
2765  NumericalRev<int> last_ranked_;
2767  const int size_;
2769  std::unique_ptr<int[]> position_;
2770 };
2771 
2777  public:
2780 
2782 
2785  void Init(Solver* const solver, const std::vector<uint64>& mask);
2786 
2789  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2790 
2793  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2794 
2797  int ActiveWordSize() const { return active_words_.Size(); }
2798 
2800  bool Empty() const { return active_words_.Size() == 0; }
2801 
2809  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2810 
2812  int64 bit_size() const { return bit_size_; }
2814  int64 word_size() const { return word_size_; }
2816  const RevIntSet<int>& active_words() const { return active_words_; }
2817 
2818  private:
2819  void CleanUpActives(Solver* const solver);
2820 
2821  const int64 bit_size_;
2822  const int64 word_size_;
2823  RevArray<uint64> bits_;
2824  RevIntSet<int> active_words_;
2825  std::vector<int> to_remove_;
2826 };
2827 
2828 template <class T>
2829 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2830  for (int i = 0; i < values.size(); ++i) {
2831  if (values[i] != value) {
2832  return false;
2833  }
2834  }
2835  return true;
2836 }
2837 
2838 template <class T>
2839 bool IsArrayBoolean(const std::vector<T>& values) {
2840  for (int i = 0; i < values.size(); ++i) {
2841  if (values[i] != 0 && values[i] != 1) {
2842  return false;
2843  }
2844  }
2845  return true;
2846 }
2847 
2848 template <class T>
2849 bool AreAllOnes(const std::vector<T>& values) {
2850  return IsArrayConstant(values, T(1));
2851 }
2852 
2853 template <class T>
2854 bool AreAllNull(const std::vector<T>& values) {
2855  return IsArrayConstant(values, T(0));
2856 }
2857 
2858 template <class T>
2859 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2860  for (const T& current_value : values) {
2861  if (current_value < value) {
2862  return false;
2863  }
2864  }
2865  return true;
2866 }
2867 
2868 template <class T>
2869 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2870  for (const T& current_value : values) {
2871  if (current_value > value) {
2872  return false;
2873  }
2874  }
2875  return true;
2876 }
2877 
2878 template <class T>
2879 bool AreAllPositive(const std::vector<T>& values) {
2880  return AreAllGreaterOrEqual(values, T(0));
2881 }
2882 
2883 template <class T>
2884 bool AreAllNegative(const std::vector<T>& values) {
2885  return AreAllLessOrEqual(values, T(0));
2886 }
2887 
2888 template <class T>
2889 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2890  return AreAllGreaterOrEqual(values, T(1));
2891 }
2892 
2893 template <class T>
2894 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2895  return AreAllLessOrEqual(values, T(-1));
2896 }
2897 
2898 template <class T>
2899 bool IsIncreasingContiguous(const std::vector<T>& values) {
2900  for (int i = 0; i < values.size() - 1; ++i) {
2901  if (values[i + 1] != values[i] + 1) {
2902  return false;
2903  }
2904  }
2905  return true;
2906 }
2907 
2908 template <class T>
2909 bool IsIncreasing(const std::vector<T>& values) {
2910  for (int i = 0; i < values.size() - 1; ++i) {
2911  if (values[i + 1] < values[i]) {
2912  return false;
2913  }
2914  }
2915  return true;
2916 }
2917 
2918 template <class T>
2919 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2920  T range_max) {
2921  for (int i = 0; i < vars.size(); ++i) {
2922  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2923  return false;
2924  }
2925  }
2926  return true;
2927 }
2928 
2929 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2930  for (int i = 0; i < vars.size(); ++i) {
2931  if (!vars[i]->Bound()) {
2932  return false;
2933  }
2934  }
2935  return true;
2936 }
2937 
2938 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2939  return IsArrayInRange(vars, 0, 1);
2940 }
2941 
2944 template <class T>
2945 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2946  const std::vector<T>& values) {
2947  for (int i = 0; i < vars.size(); ++i) {
2948  if (values[i] != 0 && !vars[i]->Bound()) {
2949  return false;
2950  }
2951  }
2952  return true;
2953 }
2954 
2956 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2957  for (int i = 0; i < vars.size(); ++i) {
2958  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2959  return false;
2960  }
2961  }
2962  return true;
2963 }
2964 
2965 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2966  DCHECK(!vars.empty());
2967  int64 result = kint64min;
2968  for (int i = 0; i < vars.size(); ++i) {
2970  result = std::max<int64>(result, vars[i]->Max());
2971  }
2972  return result;
2973 }
2974 
2975 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2976  DCHECK(!vars.empty());
2977  int64 result = kint64max;
2978  for (int i = 0; i < vars.size(); ++i) {
2980  result = std::min<int64>(result, vars[i]->Min());
2981  }
2982  return result;
2983 }
2984 
2985 inline void FillValues(const std::vector<IntVar*>& vars,
2986  std::vector<int64>* const values) {
2987  values->clear();
2988  values->resize(vars.size());
2989  for (int i = 0; i < vars.size(); ++i) {
2990  (*values)[i] = vars[i]->Value();
2991  }
2992 }
2993 
2994 inline int64 PosIntDivUp(int64 e, int64 v) {
2995  DCHECK_GT(v, 0);
2996  if (e >= 0) {
2997  return e % v == 0 ? e / v : e / v + 1;
2998  } else {
2999  return e / v;
3000  }
3001 }
3002 
3003 inline int64 PosIntDivDown(int64 e, int64 v) {
3004  DCHECK_GT(v, 0);
3005  if (e >= 0) {
3006  return e / v;
3007  } else {
3008  return e % v == 0 ? e / v : e / v - 1;
3009  }
3010 }
3011 
3012 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
3013 
3014 #if !defined(SWIG)
3015 // A PathState represents a set of paths and changed made on it.
3016 //
3017 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
3018 // directed graphs with nodes [0, num_nodes) whose connected components are
3019 // paths from starts[i] to ends[i] (for the same i) and loops.
3020 // Let us fix num_nodes, starts and ends so we call these P-graphs.
3021 //
3022 // Let us define some notions on graphs with the same set of nodes:
3023 // tails(D) is the set of nodes that are the tail of some arc of D.
3024 // P0 inter P1 is the graph of all arcs both in P0 and P1.
3025 // P0 union P1 is the graph of all arcs either in P0 or P1.
3026 // P1 - P0 is the graph with arcs in P1 and not in P0.
3027 // P0 |> D is the graph with arcs of P0 whose tail is not in tails(D).
3028 // P0 + D is (P0 |> D) union D.
3029 //
3030 // Now suppose P0 and P1 are P-graphs.
3031 // P0 + (P1 - P0) is exactly P1.
3032 // Moreover, note that P0 |> D is not a union of paths from some starts[i] to
3033 // ends[i] and loops like P0, because the operation removes arcs from P0.
3034 // P0 |> D is a union of generic paths, loops, and isolated nodes.
3035 // Let us call the generic paths and isolated nodes "chains".
3036 // Then the paths of P0 + D are chains linked by arcs of D.
3037 // Those chains are particularly interesting when examining a P-graph change.
3038 //
3039 // A PathState represents a P-graph for a fixed {num_nodes, starts, ends}.
3040 // The value of a PathState can be changed incrementally from P0 to P1
3041 // by passing the arcs of P1 - P0 to ChangeNext() and marking the end of the
3042 // change with a call to CutChains().
3043 // If P0 + D is not a P-graph, the behaviour is undefined.
3044 // TODO(user): check whether we want to have a DCHECK that P0 + D
3045 // is a P-graph or if CutChains() should return false.
3046 //
3047 // After CutChains(), tails(D) can be traversed using an iterator,
3048 // and the chains of P0 |> D can be browsed by chain-based iterators.
3049 // An iterator allows to browse the set of paths that have changed.
3050 // Then Commit() or Revert() can be called: Commit() changes the PathState to
3051 // represent P1 = P0 + D, all further changes are made from P1; Revert() changes
3052 // the PathState to forget D completely and return the state to P0.
3053 //
3054 // After a Commit(), Revert() or at initial state, the same iterators are
3055 // available and represent the change by an empty D: the set of changed paths
3056 // and the set of changed nodes is empty. Still, the chain-based iterator allows
3057 // to browse paths: each path has exactly one chain.
3058 class PathState {
3059  public:
3060  // A ChainRange allows to iterate on all chains of a path.
3061  // ChainRange is a range, its iterator Chain*, its value type Chain.
3062  class ChainRange;
3063  // A Chain allows to iterate on all nodes of a chain, and access some data:
3064  // first node, last node, number of nodes in the chain.
3065  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3066  // Chains are returned by PathChainIterator's operator*().
3067  class Chain;
3068  // A NodeRange allows to iterate on all nodes of a path.
3069  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3070  class NodeRange;
3071 
3072  // Path constructor: path_start and path_end must be disjoint,
3073  // their values in [0, num_nodes).
3074  PathState(int num_nodes, std::vector<int> path_start,
3075  std::vector<int> path_end);
3076 
3077  // Instance-constant accessors.
3078 
3079  // Returns the number of nodes in the underlying graph.
3080  int NumNodes() const { return num_nodes_; }
3081  // Returns the number of paths (empty paths included).
3082  int NumPaths() const { return num_paths_; }
3083  // Returns the start of a path.
3084  int Start(int path) const { return path_start_end_[path].start; }
3085  // Returns the end of a path.
3086  int End(int path) const { return path_start_end_[path].end; }
3087 
3088  // State-dependent accessors.
3089 
3090  // Returns the committed path of a given node, -1 if it is a loop.
3091  int Path(int node) const {
3092  return committed_nodes_[committed_index_[node]].path;
3093  }
3094  // Returns the set of arcs that have been added,
3095  // i.e. that were changed and were not in the committed state.
3096  const std::vector<std::pair<int, int>>& ChangedArcs() const {
3097  return changed_arcs_;
3098  }
3099  // Returns the set of paths that actually changed,
3100  // i.e. that have an arc in ChangedArcs().
3101  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3102  // Returns the current range of chains of path.
3103  ChainRange Chains(int path) const;
3104  // Returns the current range of nodes of path.
3105  NodeRange Nodes(int path) const;
3106 
3107  // State modifiers.
3108 
3109  // Adds arc (node, new_next) to the changed state, more formally,
3110  // changes the state from (P0, D) to (P0, D + (node, new_next)).
3111  void ChangeNext(int node, int new_next) {
3112  changed_arcs_.emplace_back(node, new_next);
3113  }
3114  // Marks the end of ChangeNext() sequence, more formally,
3115  // changes the state from (P0, D) to (P0 |> D, D).
3116  void CutChains();
3117  // Makes the current temporary state permanent, more formally,
3118  // changes the state from (P0 |> D, D) to (P0 + D, \emptyset),
3119  void Commit();
3120  // Erase incremental changes made by ChangeNext() and CutChains(),
3121  // more formally, changes the state from (P0 |> D, D) to (P0, \emptyset).
3122  void Revert();
3123 
3124  private:
3125  // Most structs below are named pairs of ints, for typing purposes.
3126 
3127  // Start and end are stored together to optimize (likely) simultaneous access.
3128  struct PathStartEnd {
3129  PathStartEnd(int start, int end) : start(start), end(end) {}
3130  int start;
3131  int end;
3132  };
3133  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3134  struct PathBounds {
3135  int begin_index;
3136  int end_index;
3137  };
3138  struct ChainBounds {
3139  ChainBounds() = default;
3140  ChainBounds(int begin_index, int end_index)
3141  : begin_index(begin_index), end_index(end_index) {}
3142  int begin_index;
3143  int end_index;
3144  };
3145  struct CommittedNode {
3146  CommittedNode(int node, int path) : node(node), path(path) {}
3147  int node;
3148  // Path of node in the committed state, -1 for loop nodes.
3149  // TODO(user): check if path would be better stored
3150  // with committed_index_, or in its own vector, or just recomputed.
3151  int path;
3152  };
3153  // Used in temporary structures, see below.
3154  struct TailHeadIndices {
3155  int tail_index;
3156  int head_index;
3157  };
3158  struct IndexArc {
3159  int index;
3160  int arc;
3161  bool operator<(const IndexArc& other) const { return index < other.index; }
3162  };
3163 
3164  // Copies nodes in chains of path at the end of nodes,
3165  // and sets those nodes' path member to value path.
3166  void CopyNewPathAtEndOfNodes(int path);
3167  // Commits paths in O(#{changed paths' nodes}) time,
3168  // increasing this object's space usage by O(|changed path nodes|).
3169  void IncrementalCommit();
3170  // Commits paths in O(num_nodes + num_paths) time,
3171  // reducing this object's space usage to O(num_nodes + num_paths).
3172  void FullCommit();
3173 
3174  // Instance-constant data.
3175  const int num_nodes_;
3176  const int num_paths_;
3177  std::vector<PathStartEnd> path_start_end_;
3178 
3179  // Representation of the committed and changed paths.
3180  // A path is a range of chains, which is a range of nodes.
3181  // Ranges are represented internally by indices in vectors:
3182  // ChainBounds are indices in committed_nodes_. PathBounds are indices in
3183  // chains_. When committed (after construction, Revert() or Commit()):
3184  // - path ranges are [path, path+1): they have one chain.
3185  // - chain ranges don't overlap, chains_ has an empty sentinel at the end.
3186  // - committed_nodes_ contains all nodes and old duplicates may appear,
3187  // the current version of a node is at the index given by
3188  // committed_index_[node]. A Commit() can add nodes at the end of
3189  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3190  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3191  // space by rewriting the path/chain/nodes structure.
3192  // When changed (after CutChains()), new chains are computed,
3193  // and the structure is updated accordingly:
3194  // - path ranges that were changed have nonoverlapping values [begin, end)
3195  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3196  // committed state.
3197  // - additional chain ranges are stored after the committed chains
3198  // to represent the new chains resulting from the changes.
3199  // Those chains do not overlap with each other or with unchanged chains.
3200  // An empty sentinel chain is added at the end of additional chains.
3201  // - committed_nodes_ are not modified, and still represent the committed
3202  // paths.
3203  // committed_index_ is not modified either.
3204  std::vector<CommittedNode> committed_nodes_;
3205  std::vector<int> committed_index_;
3206  const int num_nodes_threshold_;
3207  std::vector<ChainBounds> chains_;
3208  std::vector<PathBounds> paths_;
3209 
3210  // Incremental information: indices of nodes whose successor have changed,
3211  // path that have changed nodes.
3212  std::vector<std::pair<int, int>> changed_arcs_;
3213  std::vector<int> changed_paths_;
3214  std::vector<bool> path_has_changed_;
3215 
3216  // Temporary structures, since they will be reused heavily,
3217  // those are members in order to be allocated once and for all.
3218  std::vector<TailHeadIndices> tail_head_indices_;
3219  std::vector<IndexArc> arcs_by_tail_index_;
3220  std::vector<IndexArc> arcs_by_head_index_;
3221  std::vector<int> next_arc_;
3222 };
3223 
3224 // A Chain is a range of committed nodes.
3226  public:
3227  class Iterator {
3228  public:
3230  ++current_node_;
3231  return *this;
3232  }
3233  int operator*() const { return current_node_->node; }
3234  bool operator!=(Iterator other) const {
3235  return current_node_ != other.current_node_;
3236  }
3237 
3238  private:
3239  // Only a Chain can construct its iterator.
3240  friend class PathState::Chain;
3241  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3242  const CommittedNode* current_node_;
3243  };
3244 
3245  // Chains hold CommittedNode* values, a Chain may be invalidated
3246  // if the underlying vector is modified.
3247  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3248  : begin_(begin_node), end_(end_node) {}
3249 
3250  int NumNodes() const { return end_ - begin_; }
3251  int First() const { return begin_->node; }
3252  int Last() const { return (end_ - 1)->node; }
3253  Iterator begin() const { return Iterator(begin_); }
3254  Iterator end() const { return Iterator(end_); }
3255 
3256  private:
3257  const CommittedNode* const begin_;
3258  const CommittedNode* const end_;
3259 };
3260 
3261 // A ChainRange is a range of Chains, committed or not.
3263  public:
3264  class Iterator {
3265  public:
3267  ++current_chain_;
3268  return *this;
3269  }
3270  Chain operator*() const {
3271  return {first_node_ + current_chain_->begin_index,
3272  first_node_ + current_chain_->end_index};
3273  }
3274  bool operator!=(Iterator other) const {
3275  return current_chain_ != other.current_chain_;
3276  }
3277 
3278  private:
3279  // Only a ChainRange can construct its Iterator.
3280  friend class ChainRange;
3281  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3282  : current_chain_(chain), first_node_(first_node) {}
3283  const ChainBounds* current_chain_;
3284  const CommittedNode* const first_node_;
3285  };
3286 
3287  // ChainRanges hold ChainBounds* and CommittedNode*,
3288  // a ChainRange may be invalidated if on of the underlying vector is modified.
3289  ChainRange(const ChainBounds* const begin_chain,
3290  const ChainBounds* const end_chain,
3291  const CommittedNode* const first_node)
3292  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3293 
3294  Iterator begin() const { return {begin_, first_node_}; }
3295  Iterator end() const { return {end_, first_node_}; }
3296 
3297  private:
3298  const ChainBounds* const begin_;
3299  const ChainBounds* const end_;
3300  const CommittedNode* const first_node_;
3301 };
3302 
3303 // A NodeRange allows to iterate on all nodes of a path,
3304 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3306  public:
3307  class Iterator {
3308  public:
3310  ++current_node_;
3311  if (current_node_ == end_node_) {
3312  ++current_chain_;
3313  // Note: dereferencing bounds is valid because there is a sentinel
3314  // value at the end of PathState::chains_ to that intent.
3315  const ChainBounds bounds = *current_chain_;
3316  current_node_ = first_node_ + bounds.begin_index;
3317  end_node_ = first_node_ + bounds.end_index;
3318  }
3319  return *this;
3320  }
3321  int operator*() const { return current_node_->node; }
3322  bool operator!=(Iterator other) const {
3323  return current_chain_ != other.current_chain_;
3324  }
3325 
3326  private:
3327  // Only a NodeRange can construct its Iterator.
3328  friend class NodeRange;
3329  Iterator(const ChainBounds* current_chain,
3330  const CommittedNode* const first_node)
3331  : current_node_(first_node + current_chain->begin_index),
3332  end_node_(first_node + current_chain->end_index),
3333  current_chain_(current_chain),
3334  first_node_(first_node) {}
3335  const CommittedNode* current_node_;
3336  const CommittedNode* end_node_;
3337  const ChainBounds* current_chain_;
3338  const CommittedNode* const first_node_;
3339  };
3340 
3341  // NodeRanges hold ChainBounds* and CommittedNode*,
3342  // a NodeRange may be invalidated if on of the underlying vector is modified.
3343  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3344  const CommittedNode* first_node)
3345  : begin_chain_(begin_chain),
3346  end_chain_(end_chain),
3347  first_node_(first_node) {}
3348  Iterator begin() const { return {begin_chain_, first_node_}; }
3349  // Note: there is a sentinel value at the end of PathState::chains_,
3350  // so dereferencing chain_range_.end()->begin_ is always valid.
3351  Iterator end() const { return {end_chain_, first_node_}; }
3352 
3353  private:
3354  const ChainBounds* begin_chain_;
3355  const ChainBounds* end_chain_;
3356  const CommittedNode* const first_node_;
3357 };
3358 
3359 // This checker enforces unary dimension requirements.
3360 // A unary dimension requires that there is some valuation of
3361 // node_capacity and demand such that for all paths,
3362 // if arc A -> B is on a path of path_class p,
3363 // then node_capacity[A] + demand[p][A] = node_capacity[B].
3364 // Moreover, all node_capacities of a path must be inside interval
3365 // path_capacity[path].
3366 // Note that Intervals have two meanings:
3367 // - for demand and node_capacity, those are values allowed for each associated
3368 // decision variable.
3369 // - for path_capacity, those are set of values that node_capacities of the path
3370 // must respect.
3371 // If the path capacity of a path is [kint64min, kint64max],
3372 // then the unary dimension requirements are not enforced on this path.
3374  public:
3375  struct Interval {
3376  int64 min;
3377  int64 max;
3378  };
3379 
3381  std::vector<Interval> path_capacity,
3382  std::vector<int> path_class,
3383  std::vector<std::vector<Interval>> demand,
3384  std::vector<Interval> node_capacity);
3385 
3386  // Given the change made in PathState, checks that the unary dimension
3387  // constraint is still feasible.
3388  bool Check() const;
3389 
3390  // Commits to the changes made in PathState,
3391  // must be called before PathState::Commit().
3392  void Commit();
3393 
3394  private:
3395  // Range min/max query on partial_demand_sums_.
3396  // The first_node and last_node MUST form a subpath in the committed state.
3397  // Nodes first_node and last_node are passed by their index in precomputed
3398  // data, they must be committed in some path, and it has to be the same path.
3399  // See partial_demand_sums_.
3400  Interval GetMinMaxPartialDemandSum(int first_node_index,
3401  int last_node_index) const;
3402 
3403  // Queries whether all nodes in the committed subpath [first_node, last_node]
3404  // have fixed demands and trivial node_capacity [kint64min, kint64max].
3405  // first_node and last_node MUST form a subpath in the committed state.
3406  // Nodes are passed by their index in precomputed data.
3407  bool SubpathOnlyHasTrivialNodes(int first_node_index,
3408  int last_node_index) const;
3409 
3410  // Commits to the current solution and rebuilds structures from scratch.
3411  void FullCommit();
3412  // Commits to the current solution and only build structures for paths that
3413  // changed, using additional space to do so in a time-memory tradeoff.
3414  void IncrementalCommit();
3415  // Adds sums of given path to the bottom layer of the RMQ structure,
3416  // updates index_ and previous_nontrivial_index_.
3417  void AppendPathDemandsToSums(int path);
3418  // Updates the RMQ structure from its bottom layer,
3419  // with [begin_index, end_index) the range of the change,
3420  // which must be at the end of the bottom layer.
3421  // Supposes that requests overlapping the range will be inside the range,
3422  // to avoid updating all layers.
3423  void UpdateRMQStructure(int begin_index, int end_index);
3424 
3425  const PathState* const path_state_;
3426  const std::vector<Interval> path_capacity_;
3427  const std::vector<int> path_class_;
3428  const std::vector<std::vector<Interval>> demand_;
3429  const std::vector<Interval> node_capacity_;
3430 
3431  // Precomputed data.
3432  // Maps nodes to their pre-computed data, except for isolated nodes,
3433  // which do not have precomputed data.
3434  // Only valid for nodes that are in some path in the committed state.
3435  std::vector<int> index_;
3436  // Implementation of a <O(n log n), O(1)> range min/max query, n = #nodes.
3437  // partial_demand_sums_rmq_[0][index_[node]] contains the sum of demands
3438  // from the start of the node's path to the node.
3439  // If node is the start of path, the sum is demand_[path_class_[path]][node],
3440  // moreover partial_demand_sums_rmq_[0][index_[node]-1] is {0, 0}.
3441  // partial_demand_sums_rmq_[layer][index] contains an interval
3442  // [min_value, max_value] such that min_value is
3443  // min(partial_demand_sums_rmq_[0][index+i].min | i in [0, 2^layer)),
3444  // similarly max_value is the maximum of .max on the same range.
3445  std::vector<std::vector<Interval>> partial_demand_sums_rmq_;
3446  // The incremental branch of Commit() may waste space in the layers of the
3447  // RMQ structure. This is the upper limit of a layer's size.
3448  const int maximum_partial_demand_layer_size_;
3449  // previous_nontrivial_index_[index_[node]] has the index of the previous
3450  // node on its committed path that has nonfixed demand or nontrivial node
3451  // capacity. This allows for O(1) queries that all nodes on a subpath
3452  // are nonfixed and nontrivial.
3453  std::vector<int> previous_nontrivial_index_;
3454 };
3455 
3456 // Make a filter that takes ownership of a PathState and synchronizes it with
3457 // solver events. The solver represents a graph with array of variables 'nexts'.
3458 // Solver events are embodied by Assignment* deltas, that are translated to node
3459 // changes during Relax(), committed during Synchronize(), and reverted on
3460 // Revert().
3462  std::unique_ptr<PathState> path_state,
3463  const std::vector<IntVar*>& nexts);
3464 
3465 // Make a filter that translates solver events to the input checker's interface.
3466 // Since UnaryDimensionChecker has a PathState, the filter returned by this
3467 // must be synchronized to the corresponding PathStateFilter:
3468 // - Relax() must be called after the PathStateFilter's.
3469 // - Accept() must be called after.
3470 // - Synchronize() must be called before.
3471 // - Revert() must be called before.
3473  Solver* solver, std::unique_ptr<UnaryDimensionChecker> checker);
3474 
3475 #endif // !defined(SWIG)
3476 
3477 } // namespace operations_research
3478 
3479 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
bool AreAllPositive(const std::vector< T > &values)
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
@ EXPR_EXPR_EXPRESSION_MAX
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
int64 MinVarArray(const std::vector< IntVar * > &vars)
void Run(Solver *const s) override
void SetInverseValue(int64 index, int64 value)
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
bool IsVarSynced(int index) const
const std::vector< std::pair< int, int > > & ChangedArcs() const
void AppendToFragment(int index)
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
IntVarIterator * MakeHoleIterator(bool reversible) const override
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
friend class IntVarLocalSearchHandler
int NumFirstRanked() const
IntVarLocalSearchHandler(IntVarLocalSearchOperator *op)
BooleanVar(Solver *const s, const std::string &name="")
std::string DebugString() const override
virtual void OutputLine(const std::string &line)
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
Bitset64 activated_
virtual void RankNotFirst(SequenceVar *const var, int index)=0
int End(int path) const
Demon proxy to a method on the constraint with one argument.
int64 Next(int64 node) const
Returns the node after node in the current delta.
int64 bit_size() const
Returns the number of bits given in the constructor of the bitset.
bool AreAllBooleans(const std::vector< IntVar * > &vars)
@ VOID_CONSTRAINT_MAX
int64 Cardinality(int row) const
Returns the number of bits set to one in the 'row' row.
@ OPP_VAR
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
int NumLastRanked() const
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
int64 FindIntegerArgumentWithDefault(const std::string &arg_name, int64 def) const
Getters.
void Run(Solver *const s) override
std::string DebugString() const override
Demon proxy to a method on the constraint with three arguments.
int64 GetSynchronizedObjectiveValue() const
IntVar * IsDifferent(int64 constant) override
Iterator end() const
const bool ignore_path_vars_
ChainRange Chains(int path) const
void EndInitialPropagation() override
void SetValue(int64 index, T value)
IntVarLocalSearchOperator()
bool IsIncreasingContiguous(const std::vector< T > &values)
std::string DebugString() const override
VarConstantConstraintType
const T * const_iterator
Iterators on the indices.
bool ValueFromAssignment(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
FilterEventType event_type
int64 StartNode(int i) const
Returns the start node of the ith base node.
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
std::vector< int64 > start_to_path_
int VarType() const override
int FragmentSize() const
ExprExpressionType
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 AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64 value)
ArgumentHolder * Top() const
virtual void RankLast(SequenceVar *const var, int index)=0
This class represents a small reversible bitset (size <= 64).
bool IsCardinalityZero() const
Is bitset null?
This is the base class for building an Lns operator.
void Commit()
virtual int64 GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
const std::vector< int > & ChangedPaths() const
The base class of all search logs that periodically outputs information when the search is running.
Low-priority demon proxy to a method on the constraint with two arguments.
~BooleanVar() override
@ kRelax
@ VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
int64 GetFirstOne() const
Gets the index of the first bit set starting from 0.
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
@ EXPR_EXPR_SUM
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
@ VOID_TRUE_CONSTRAINT
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
std::string DebugString() const
IntVar * Var() override
RevPartialSequence(const std::vector< int > &items)
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
virtual void SetValue(IntVar *const var, int64 value)=0
@ CST_SUB_VAR
@ EXPR_EXPR_IS_EQUAL
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
int64 GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
const std::vector< int64 > & path_starts() const
Returns the vector of path start nodes.
bool AreAllOnes(const std::vector< T > &values)
bool MoveChain(int64 before_chain, int64 chain_end, int64 destination)
Moves the chain starting after the node before_chain and ending at the node chain_end after the node ...
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void Run(Solver *const s) override
VarConstantConstantExpressionType
const std::string & TypeName() const
Type of the argument.
Solver::DemonPriority priority() const override
~CallMethod0() override
bool SetMax(int64 new_max)
~ModelParser() override
void Install() override
Install itself on the solver.
void WhenRange(Demon *d) override
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
std::string DebugString() const override
void Activate(int64 index)
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
const Val & Value(int64 index) const
Returns the value in the current assignment of the variable of given index.
virtual bool ConsiderAlternatives(int64 base_index) const
Indicates if alternatives should be considered when iterating over base nodes.
virtual void SetMin(IntExpr *const expr, int64 new_min)=0
IntExpr modifiers.
int64 OldPrev(int64 node) const
~CallMethod3() override
int64 BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
~PathOperator() override
void OnAddVars()
const Val & OldValue(int64 index) const
LocalSearchFilterManager(std::vector< LocalSearchFilter * > filters)
@ EXPR_EXPR_MIN
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type)=0
~RevImmutableMultiMap()
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
bool StateIsValid() const
virtual bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
int AddAlternativeSet(const std::vector< int64 > &alternative_set)
Handling node alternatives.
--— RevPartialSequence --—
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
This class represents a reversible bitset.
@ VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX
virtual void Clear()=0
~VarLocalSearchOperator() override
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64 value)
Returns true if all variables are assigned to 'value'.
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64 value, VarConstantConstraintType type) const =0
Var Constant Constraints.
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type)=0
Model Parser.
int64 Cardinality() const
Returns the number of bits set to one.
~ArrayWithOffset() override
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void Run(Solver *const s) override
VarTypes
This enum is used internally to do dynamic typing on subclasses of integer variables.
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
T RemovedElement(int i) const
bool cleared_
@ VAR_ARRAY_SUM
~SymmetryBreaker() override
~RevGrowingArray()
@ EXPR_SQUARE
int next_base_to_increment_
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
virtual void RemoveValue(IntVar *const var, int64 value)=0
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64 value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
@ VAR_CONSTANT_EQUALITY
~DelayedCallMethod0() override
virtual void InitFragments()
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
Solver * solver() const
@ EXPR_CONSTANT_MAX
Matrix version of the RevBitSet class.
const std::vector< int > & Sequence(int64 index) const
Returns the value in the current assignment of the variable of given index.
Demon proxy to a method on the constraint with no arguments.
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
int64 InverseValue(int64 index) const
bool SwapActiveAndInactive(int64 active, int64 inactive)
Replaces active by inactive in the current path, making active inactive.
void SetToOne(Solver *const solver, int64 row, int64 column)
Sets the 'column' bit in the 'row' row.
Bitset64 was_activated_
int NumPaths() const
int64 PosIntDivUp(int64 e, int64 v)
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
@ EXPR_EXPR_IS_LESS
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
void Commit()
@ VAR_CONSTANT_CONSTANT_EXPRESSION_MAX
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
@ EXPR_EXPR_CONSTRAINT_MAX
bool AreAllNull(const std::vector< T > &values)
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
@ kAccept
virtual int64 GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
int Start(int path) const
bool Contains(int64 v) const override
SymmetryBreaker()
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
@ VAR_ADD_CST
void ChangeNext(int node, int new_next)
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
bool Intersects(const std::vector< uint64 > &mask, int *support_index)
This method returns true iff the mask and the active bitset have a non null intersection.
virtual void SetMax(IntVar *const var, int64 new_max)=0
virtual int64 GetBaseNodeRestartPosition(int base_index)
Returns the index of the node to which the base node of index base_index must be set to when it reach...
IntVar * IsGreaterOrEqual(int64 constant) override
SequenceVarLocalSearchHandler()
virtual void RegisterDemon(Demon *const demon)=0
@ EXPR_CONSTANT_EXPRESSION_MAX
static const int kUnboundBooleanVarValue
This is the base class for all expressions that are not variables.
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
void AcceptUncheckedNeighbor() override
This class represents a reversible bitset.
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
void VisitSequenceVariable(const SequenceVar *const variable) override
~PropagationMonitor() override
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
Solver::DemonPriority priority() const override
bool Accept(LocalSearchMonitor *const monitor, const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max)
Returns true iff all filters return true, and the sum of their accepted objectives is between objecti...
void BeginFail() override
~RevIntSet()
Low-priority demon proxy to a method on the constraint with one argument.
void WhenBound(Demon *d) override
@ EXPR_EXPR_MAX
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type)=0
ExprExprExpressionType
std::string DebugString() const override
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...
void RemoveInterval(int64 l, int64 u) override
bool IsCardinalityOne() const
Does it contains only one bit set?
SparseBitset delta_changes_
void Switch(Solver *const solver)
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void RankNotLast(SequenceVar *const var, int index)=0
VarLocalSearchOperator()
virtual void SetMax(IntExpr *const expr, int64 new_max)=0
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
~DelayedCallMethod2() override
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
~UnsortedNullableRevBitset()
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
bool HasFragments() const override
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
RevSwitch()
void Maintain()
@ BOOLEAN_VAR
RevPartialSequence(int size)
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
@ VAR_ARRAY_CONSTANT_EXPRESSION_MAX
ExprConstantExpressionType
Local Search Filters are used for fast neighbor pruning.
virtual void SetRange(IntVar *const var, int64 new_min, int64 new_max)=0
bool IsCardinalityZero() const
Is bitset null?
int Size() const
void Synchronize(const Assignment *assignment, const Assignment *delta)
Synchronizes all filters to assignment.
std::string BaseName() const override
VarArrayConstantArrayExpressionType
void VisitIntegerVariable(const IntVar *const variable, const std::string &operation, int64 value, IntVar *const delegate) override
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
void SynchronizeOnAssignment(const Assignment *assignment)
void CutChains()
void ExitSearch() override
bool Activated(int64 index) const
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
void AddVars(const std::vector< V * > &vars)
virtual bool SkipUnchanged(int index) const
bool SetMin(int64 new_min)
std::vector< Val > values_
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
@ EXPR_EXPR_LESS
bool IsArrayConstant(const std::vector< T > &values, const T &value)
bool Check() const
LocalSearchOperator()
int PathClass(int i) const
Returns the class of the path of the ith base node.
Iterator & operator++()
bool IsIncreasing(const std::vector< T > &values)
This class represent a reversible FIFO structure.
int operator*() const
virtual void Commit(const Assignment *delta, const Assignment *deltadelta)
Dual of Relax(), lets the filter know that the delta was accepted.
@ EXPR_CONSTANT_IS_NOT_EQUAL
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
void SetToZero(Solver *const solver, int64 pos)
Erases the 'pos' bit.
Iterator end() const
~LocalSearchOperator() override
int Size() const
bool Empty() const
This method returns true if the active bitset is null.
IntVarIterator * MakeDomainIterator(bool reversible) const override
int RawValue() const
~SequenceVarLocalSearchOperator() override
@ CONST_VAR
void EndVisitModel(const std::string &solver_name) override
void SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
ExprExprConstantExpressionType
int num_paths_
int64 Min() const override
void Insert(Solver *const solver, const T &elt)
@ VOID_FALSE_CONSTRAINT
int NumNodes() const
@ EXPR_CONSTANT_DIFFERENCE
~RevBitSet()
void ClearAll(Solver *const solver)
Cleans all bits.
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
void RemoveValue(int64 v) override
virtual void EndOperatorStart()=0
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
Argument Holder: useful when visiting a model.
@ EXPR_CONSTANT_SUM
void PopArgumentHolder()
int operator*() const
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.
@ TRACE_VAR
@ EXPR_EXPR_DIFFERENCE
VarLocalSearchOperator(Handler var_handler)
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
Base operator class for operators manipulating variables.
T At(int64 index) const
@ EXPR_EXPR_IS_LESS_OR_EQUAL
T Element(int i) const
int64 GetActiveInAlternativeSet(int alternative_index) const
Returns the active node in the given alternative set.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
void RevInsert(Solver *const solver, int64 index, T value)
virtual void BeginOperatorStart()=0
Local search operator events.
int64 Value(int index) const
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
Iterator begin() const
PathState(int num_nodes, std::vector< int > path_start, std::vector< int > path_end)
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
ModelCache(Solver *const solver)
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
std::string DebugString() const override
SequenceVarLocalSearchOperator()
~DelayedCallMethod1() override
bool Bound() const override
void RevertChanges(bool incremental)
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64 value, VarConstantConstraintType type)=0
RevBitSet(int64 size)
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 ...
void Remove(Solver *const solver, const T &value_index)
void SetRange(int64 mi, int64 ma) override
virtual IntVar * CastToVar()
LocalSearchMonitor(Solver *const solver)
std::vector< int64 > ToInt64Vector(const std::vector< int > &input)
Iterator end() const
SimpleRevFIFO()
virtual int64 ModifyValue(int64 index, int64 value)=0
bool RevSubtract(Solver *const solver, const std::vector< uint64 > &mask)
This method subtracts the mask from the active bitset.
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
~BaseIntExpr() override
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
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)> start_empty_path_class)
Builds an instance of PathOperator from next and path variables.
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64 value, IntervalVar *const delegate) override
V * Var(int64 index) const
Returns the variable of given index.
VarConstantConstantConstraintType
virtual void Reset()
This iterator is not stable with respect to deletion.
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
BaseIntExpr(Solver *const s)
void Run(Solver *const s) override
SimpleRevFIFO< Demon * > bound_demons_
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
void Init(Solver *const solver, const std::vector< uint64 > &mask)
This methods overwrites the active bitset with the mask.
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
int64 GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
bool CheckChainValidity(int64 before_chain, int64 chain_end, int64 exclude) const
Returns true if the chain is a valid path without cycles from before_chain to chain_end and does not ...
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
friend class SymmetryManager
int64 FindIntegerArgumentOrDie(const std::string &arg_name) const
Iterator & operator++()
ModelParser()
NodeRange Nodes(int path) const
std::string DebugString() const override
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
void RankFirst(Solver *const solver, int elt)
int64 OldPath(int64 node) const
int64 Value() const override
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
int BaseSiblingAlternative(int i) const
Returns the alternative for the sibling of the ith base node.
virtual void PushContext(const std::string &context)=0
static constexpr int kNoInserted
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
@ EXPR_CONSTANT_PROD
void Revert()
Reversible Immutable MultiMap class.
@ VAR_CONSTANT_GREATER_OR_EQUAL
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
SmallRevBitSet(int64 size)
int64 Cardinality() const
Returns the number of bits set to one.
Handler var_handler_
LocalSearchFilterManager(std::vector< FilterEvent > filter_events)
const T * Last() const
Returns the last item of the FIFO.
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64 value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
virtual bool MakeNeighbor()=0
virtual void EndDemonRun(Demon *const demon)=0
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values) override
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
int Last() const
void MarkChange(int64 index)
OnStart() should really be protected, but then SWIG doesn't see it.
uint64 Hash1(uint64 value)
Hash functions.
@ VAR_ARRAY_MIN
@ EXPR_CONSTANT_IS_EQUAL
IntVar * IsLessOrEqual(int64 constant) override
@ VAR_CONSTANT_CONSTANT_BETWEEN
bool operator!=(Iterator other) const
void OutputDecision()
bool operator!=(Iterator other) const
uint64 Size() const override
void SetToZero(Solver *const solver, int64 index)
Erases the 'index' bit.
virtual T Evaluate(int64 index) const
VarConstantArrayExpressionType
@ VAR_CONSTANT_CONSTRAINT_MAX
int64 Prev(int64 node) const
Returns the node before node in the current delta.
@ EXPR_EXPRESSION_MAX
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
void SetNext(int64 from, int64 to, int64 path)
Sets 'to' to be the node after 'from' on the given path.
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 SetValues(IntVar *const var, const std::vector< int64 > &values)=0
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
RevImmutableMultiMap(Solver *const solver, int initial_size)
~ChangeValue() override
bool AreAllStrictlyNegative(const std::vector< T > &values)
int num_items() const
std::string DebugString() const override
Iterator & operator++()
void AddPairAlternativeSets(const std::vector< std::pair< std::vector< int64 >, std::vector< int64 >>> &pair_alternative_sets)
Adds all sets of node alternatives of a vector of alternative pairs.
int number_of_nexts() const
Number of next variables.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
bool IsCardinalityOne() const
Does it contains only one bit set?
FilterEventType
virtual void SetMin(IntVar *const var, int64 new_min)=0
IntVar modifiers.
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
~IntVarLocalSearchFilter() override
void OnRevertChanges(int64 index, const std::vector< int > &value)
int64 min
@ EXPR_EXPR_EQUALITY
virtual bool OnSamePathAsPreviousBase(int64 base_index)
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
bool MakeActive(int64 node, int64 destination)
Insert the inactive node after destination.
bool AreAllStrictlyPositive(const std::vector< T > &values)
bool operator!=(Iterator other) const
T operator*() const
void SetMax(int64 m) override
NodeRange(const ChainBounds *begin_chain, const ChainBounds *end_chain, const CommittedNode *first_node)
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64 value)
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64 value, VarArrayConstantExpressionType type)=0
Low-priority demon proxy to a method on the constraint with no arguments.
LocalSearchFilter * filter
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
int64 max
IntVarLocalSearchHandler()
void Reset() override
Iterator begin() const
SparseBitset changes_
void Run(Solver *const s) override
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
@ VAR_ARRAY_MAX
int64 BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
bool AreAllBound(const std::vector< IntVar * > &vars)
BaseLns(const std::vector< IntVar * > &vars)
bool IsInverseValue(int64 index) const
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type)=0
void SetBackwardSequence(int64 index, const std::vector< int > &value)
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
~BaseLns() override
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
VarArrayExpressionType
int64 GetActiveAlternativeSibling(int node) const
Returns the active node in the alternative set of the sibling of the given node.
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
ArrayWithOffset(int64 index_min, int64 index_max)
void ClearAll(Solver *const solver)
Cleans all bits.
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
void RankLast(Solver *const solver, int elt)
bool ValueFromAssignment(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64)> start_empty_path_class)
Operator Factories.
std::vector< V * > vars_
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
Solver::DemonPriority priority() const override
@ EXPR_EXPR_DIV
bool IsCardinalityZero(int row) const
Is bitset of row 'row' null?
std::vector< int > assignment_indices_
@ VAR_TIMES_CST
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 Revert()
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
void Restore(Solver *const solver, const T &value_index)
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
void SetForwardSequence(int64 index, const std::vector< int > &value)
~CallMethod2() override
void SetValue(int64 index, const Val &value)
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
std::string DebugString() const override
void Deactivate(int64 index)
const std::vector< int > & OldSequence(int64 index) const
~SearchLog() override
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
void OnAddVars()
int Size() const
ChainRange(const ChainBounds *const begin_chain, const ChainBounds *const end_chain, const CommittedNode *const first_node)
void SetToOne(Solver *const solver, int64 index)
Sets the 'index' bit.
void VisitIntegerArgument(const std::string &arg_name, int64 value) override
Integer arguments.
virtual bool HoldsDelta() const
void SetTypeName(const std::string &type_name)
@ EXPR_EXPR_PROD
@ VAR_CONSTANT_NON_EQUALITY
bool IsInactive(int64 node) const
Returns true if node is inactive.
virtual void SetNextBaseToIncrement(int64 base_index)
Set the next base to increment on next iteration.
@ UNSPECIFIED
void operator++()
virtual bool MakeOneNeighbor()
Creates a new neighbor.
@ EXPR_EXPR_IS_NOT_EQUAL
void RefuteDecision(Decision *const decision) override
Iterator begin() const
IntVar * IsEqual(int64 constant) override
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
This is a special class to represent a 'residual' set of T.
@ VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS
int64 Max() const
const int number_of_nexts_
Iterator(const SimpleRevFIFO< T > *l)
int Size() const
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
@ EXPR_OPPOSITE
A reversible switch that can switch once from false to true.
virtual ~ModelCache()
~RevBitMatrix()
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
bool IsRanked(int elt) const
SimpleRevFIFO< Demon * > delayed_bound_demons_
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
@ EXPR_ABS
int value_
virtual void Relax(const Assignment *delta, const Assignment *deltadelta)
Lets the filter know what delta and deltadelta will be passed in the next Accept().
@ EXPR_EXPR_LESS_OR_EQUAL
virtual void SetPerformed(IntervalVar *const var, bool value)=0
VoidConstraintType
std::string DebugString() const override
int First() const
Demon proxy to a method on the constraint with two arguments.
int64 OldInverseValue(int64 index) const
std::string DebugString() const override
ExprExprConstraintType
bool AtSolution() override
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
bool Switched() const
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
bool IsPathEnd(int64 node) const
Returns true if node is the last node on the path; defined by the fact that node is outside the range...
@ DOMAIN_INT_VAR
virtual void RestoreValue()=0
VarArrayConstantExpressionType
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
The base class for all local search operators.
const_iterator end() const
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
virtual void OnNodeInitialization()
Called by OnStart() after initializing node information.
@ EXPR_EXPR_CONSTANT_EXPRESSION_MAX
void Relax()
int64 PosIntDivDown(int64 e, int64 v)
@ VAR_ARRAY_EXPRESSION_MAX
std::vector< Val > old_values_
const_iterator begin() const
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
bool RevAnd(Solver *const solver, const std::vector< uint64 > &mask)
This method ANDs the mask with the active bitset.
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
@ EXPR_CONSTANT_DIVIDE
Implements a complete cache for model elements: expressions and constraints.
@ EXPR_CONSTANT_IS_GREATER_OR_EQUAL
virtual bool IsIncremental() const
int Path(int node) const
void BeginInitialPropagation() override
void SetMin(int64 m) override
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64 value, ExprConstantExpressionType type)=0
int NumNodes() const
const int & operator[](int index) const
LocalSearchFilter * MakeUnaryDimensionFilter(Solver *solver, std::unique_ptr< UnaryDimensionChecker > checker)
virtual void Start(const Assignment *assignment)=0
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, double offset, std::function< std::string()> display_callback, int period)
~LocalSearchMonitor() override
void SetToZero(Solver *const solver, int64 row, int64 column)
Erases the 'column' bit in the 'row' row.
virtual void PopContext()=0
bool IsPathStart(int64 node) const
Returns true if node is the first node on the path.
~CallMethod1() override
virtual bool NextFragment()=0
void OnRevertChanges(int64 index, int64 value)
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
@ VAR_CONSTANT_ARRAY_EXPRESSION_MAX
~IntVarLocalSearchOperator() override
int64 MaxVarArray(const std::vector< IntVar * > &vars)
int64 BaseNode(int i) const
Returns the ith base node of the operator.
std::vector< Val > prev_values_
void Push(Solver *const s, T val)
@ EXPR_EXPR_GREATER_OR_EQUAL
std::string DebugString() const override
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64 > *const values)
void Revert()
RevBitMatrix(int64 rows, int64 columns)
@ EXPR_EXPR_GREATER
void Commit()
This class is a reversible growing array.
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
int64 Min() const
void EnterSearch() override
virtual bool IsIncremental() const
bool SkipUnchanged(int index) const override
virtual const LocalSearchOperator * Self() const
Chain(const CommittedNode *begin_node, const CommittedNode *end_node)
IntVar * Var(int index) const
IntVarLocalSearchHandler(const IntVarLocalSearchHandler &other)
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
int Capacity() const
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
@ EXPR_CONSTANT_MIN
int64 GetAcceptedObjectiveValue() const
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
void SetLastValue(const T &v)
Sets the last value in the FIFO.
@ EXPR_CONSTANT_IS_LESS_OR_EQUAL
std::string DebugString() const override
void Install() override
Install itself on the solver.
@ EXPR_EXPR_NON_EQUALITY
RevGrowingArray(int64 block_size)
ChangeValue(const std::vector< IntVar * > &vars)
Chain operator*() const
@ VAR_CONSTANT_ARRAY_ELEMENT
void SetOldInverseValue(int64 index, int64 value)
bool IsArrayBoolean(const std::vector< T > &values)
int64 OldNext(int64 node) const
int64 word_size() const
Returns the number of 64 bit words used to store the bitset.
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
~RevPartialSequence()
virtual bool InitPosition() const
Returns true if the operator needs to restart its initial position at each call to Start()
const T & LastValue() const
Returns the last value in the FIFO.
int64 Path(int64 node) const
Returns the index of the path to which node belongs in the current delta.
void PushArgumentHolder()
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
@ VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD
PropagationMonitor(Solver *const solver)
int64 Max() const override
std::vector< std::vector< int > > backward_values_
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
@ VAR_CONSTANT_LESS_OR_EQUAL
T * MutableLast()
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
bool MakeChainInactive(int64 before_chain, int64 chain_end)
Makes the nodes on the chain starting after before_chain and ending at chain_end inactive.
bool IsCardinalityOne(int row) const
Does the 'row' bitset contains only one bit set?
void Clear(Solver *const solver)
int64 GetActiveAlternativeNode(int node) const
Returns the active node in the alternative set of the given node.
@ VAR_ARRAY_CONSTANT_INDEX
void ApplyDecision(Decision *const decision) override
LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max)
void WhenDomain(Demon *d) override
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
void Run(Solver *const s) override
bool AreAllNegative(const std::vector< T > &values)
@ EXPR_EXPR_CONSTANT_CONDITIONAL
bool ReverseChain(int64 before_chain, int64 after_chain, int64 *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
std::string ParameterDebugString(P param)
bool HoldsDelta() const override
bool ok() const
virtual void OnSynchronize(const Assignment *delta)
void Start(const Assignment *assignment) override
This method should not be overridden.
virtual bool HasFragments() const
virtual void BeginDemonRun(Demon *const demon)=0
void NoMoreSolutions() override
bool FindIndex(IntVar *const var, int64 *index) const