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(ARCH_K8) || defined(__powerpc64__) || defined(__aarch64__)
250  return Hash1(reinterpret_cast<uint64>(ptr));
251 #else
252  return Hash1(reinterpret_cast<uint32>(ptr));
253 #endif
254 }
255 
256 template <class T>
257 uint64 Hash1(const std::vector<T*>& ptrs) {
258  if (ptrs.empty()) {
259  return 0;
260  } else if (ptrs.size() == 1) {
261  return Hash1(ptrs[0]);
262  } else {
263  uint64 hash = Hash1(ptrs[0]);
264  for (int i = 1; i < ptrs.size(); ++i) {
265  hash = hash * i + Hash1(ptrs[i]);
266  }
267  return hash;
268  }
269 }
270 
271 inline uint64 Hash1(const std::vector<int64>& ptrs) {
272  if (ptrs.empty()) {
273  return 0;
274  } else if (ptrs.size() == 1) {
275  return Hash1(ptrs[0]);
276  } else {
277  uint64 hash = Hash1(ptrs[0]);
278  for (int i = 1; i < ptrs.size(); ++i) {
279  hash = hash * i + Hash1(ptrs[i]);
280  }
281  return hash;
282  }
283 }
284 
287 template <class K, class V>
289  public:
290  RevImmutableMultiMap(Solver* const solver, int initial_size)
291  : solver_(solver),
292  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
293  size_(initial_size),
294  num_items_(0) {
295  memset(array_, 0, sizeof(*array_) * size_.Value());
296  }
297 
299 
300  int num_items() const { return num_items_.Value(); }
301 
303  bool ContainsKey(const K& key) const {
304  uint64 code = Hash1(key) % size_.Value();
305  Cell* tmp = array_[code];
306  while (tmp) {
307  if (tmp->key() == key) {
308  return true;
309  }
310  tmp = tmp->next();
311  }
312  return false;
313  }
314 
318  const V& FindWithDefault(const K& key, const V& default_value) const {
319  uint64 code = Hash1(key) % size_.Value();
320  Cell* tmp = array_[code];
321  while (tmp) {
322  if (tmp->key() == key) {
323  return tmp->value();
324  }
325  tmp = tmp->next();
326  }
327  return default_value;
328  }
329 
331  void Insert(const K& key, const V& value) {
332  const int position = Hash1(key) % size_.Value();
333  Cell* const cell =
334  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
335  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
336  reinterpret_cast<void*>(cell));
337  num_items_.Incr(solver_);
338  if (num_items_.Value() > 2 * size_.Value()) {
339  Double();
340  }
341  }
342 
343  private:
344  class Cell {
345  public:
346  Cell(const K& key, const V& value, Cell* const next)
347  : key_(key), value_(value), next_(next) {}
348 
349  void SetRevNext(Solver* const solver, Cell* const next) {
350  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
351  reinterpret_cast<void*>(next));
352  }
353 
354  Cell* next() const { return next_; }
355 
356  const K& key() const { return key_; }
357 
358  const V& value() const { return value_; }
359 
360  private:
361  const K key_;
362  const V value_;
363  Cell* next_;
364  };
365 
366  void Double() {
367  Cell** const old_cell_array = array_;
368  const int old_size = size_.Value();
369  size_.SetValue(solver_, size_.Value() * 2);
370  solver_->SaveAndSetValue(
371  reinterpret_cast<void**>(&array_),
372  reinterpret_cast<void*>(
373  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
374  memset(array_, 0, size_.Value() * sizeof(*array_));
375  for (int i = 0; i < old_size; ++i) {
376  Cell* tmp = old_cell_array[i];
377  while (tmp != nullptr) {
378  Cell* const to_reinsert = tmp;
379  tmp = tmp->next();
380  const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value();
381  to_reinsert->SetRevNext(solver_, array_[new_position]);
382  solver_->SaveAndSetValue(
383  reinterpret_cast<void**>(&array_[new_position]),
384  reinterpret_cast<void*>(to_reinsert));
385  }
386  }
387  }
388 
389  Solver* const solver_;
390  Cell** array_;
391  NumericalRev<int> size_;
392  NumericalRev<int> num_items_;
393 };
394 
396 class RevSwitch {
397  public:
398  RevSwitch() : value_(false) {}
399 
400  bool Switched() const { return value_; }
401 
402  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
403 
404  private:
405  bool value_;
406 };
407 
411  public:
412  explicit SmallRevBitSet(int64 size);
414  void SetToOne(Solver* const solver, int64 pos);
416  void SetToZero(Solver* const solver, int64 pos);
418  int64 Cardinality() const;
420  bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); }
422  bool IsCardinalityOne() const {
423  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
424  }
427  int64 GetFirstOne() const;
428 
429  private:
430  Rev<uint64> bits_;
431 };
432 
435 class RevBitSet {
436  public:
437  explicit RevBitSet(int64 size);
439 
441  void SetToOne(Solver* const solver, int64 index);
443  void SetToZero(Solver* const solver, int64 index);
445  bool IsSet(int64 index) const;
447  int64 Cardinality() const;
449  bool IsCardinalityZero() const;
451  bool IsCardinalityOne() const;
454  int64 GetFirstBit(int start) const;
456  void ClearAll(Solver* const solver);
457 
458  friend class RevBitMatrix;
459 
460  private:
462  void Save(Solver* const solver, int offset);
463  const int64 size_;
464  const int64 length_;
465  uint64* bits_;
466  uint64* stamps_;
467 };
468 
470 class RevBitMatrix : private RevBitSet {
471  public:
472  RevBitMatrix(int64 rows, int64 columns);
474 
476  void SetToOne(Solver* const solver, int64 row, int64 column);
478  void SetToZero(Solver* const solver, int64 row, int64 column);
480  bool IsSet(int64 row, int64 column) const {
481  DCHECK_GE(row, 0);
482  DCHECK_LT(row, rows_);
483  DCHECK_GE(column, 0);
484  DCHECK_LT(column, columns_);
485  return RevBitSet::IsSet(row * columns_ + column);
486  }
488  int64 Cardinality(int row) const;
490  bool IsCardinalityZero(int row) const;
492  bool IsCardinalityOne(int row) const;
495  int64 GetFirstBit(int row, int start) const;
497  void ClearAll(Solver* const solver);
498 
499  private:
500  const int64 rows_;
501  const int64 columns_;
502 };
503 
509 
511 template <class T>
512 class CallMethod0 : public Demon {
513  public:
514  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
515  : constraint_(ct), method_(method), name_(name) {}
516 
517  ~CallMethod0() override {}
518 
519  void Run(Solver* const s) override { (constraint_->*method_)(); }
520 
521  std::string DebugString() const override {
522  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
523  }
524 
525  private:
526  T* const constraint_;
527  void (T::*const method_)();
528  const std::string name_;
529 };
530 
531 template <class T>
532 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
533  const std::string& name) {
534  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
535 }
536 
537 template <class P>
538 std::string ParameterDebugString(P param) {
539  return absl::StrCat(param);
540 }
541 
543 template <class P>
544 std::string ParameterDebugString(P* param) {
545  return param->DebugString();
546 }
547 
549 template <class T, class P>
550 class CallMethod1 : public Demon {
551  public:
552  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
553  P param1)
554  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
555 
556  ~CallMethod1() override {}
557 
558  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
559 
560  std::string DebugString() const override {
561  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
562  ", ", ParameterDebugString(param1_), ")");
563  }
564 
565  private:
566  T* const constraint_;
567  void (T::*const method_)(P);
568  const std::string name_;
569  P param1_;
570 };
571 
572 template <class T, class P>
573 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
574  const std::string& name, P param1) {
575  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
576 }
577 
579 template <class T, class P, class Q>
580 class CallMethod2 : public Demon {
581  public:
582  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
583  P param1, Q param2)
584  : constraint_(ct),
585  method_(method),
586  name_(name),
587  param1_(param1),
588  param2_(param2) {}
589 
590  ~CallMethod2() override {}
591 
592  void Run(Solver* const s) override {
593  (constraint_->*method_)(param1_, param2_);
594  }
595 
596  std::string DebugString() const override {
597  return absl::StrCat(absl::StrCat("CallMethod_", name_),
598  absl::StrCat("(", constraint_->DebugString()),
599  absl::StrCat(", ", ParameterDebugString(param1_)),
600  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
601  }
602 
603  private:
604  T* const constraint_;
605  void (T::*const method_)(P, Q);
606  const std::string name_;
607  P param1_;
608  Q param2_;
609 };
610 
611 template <class T, class P, class Q>
612 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
613  void (T::*method)(P, Q), const std::string& name,
614  P param1, Q param2) {
615  return s->RevAlloc(
616  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
617 }
619 template <class T, class P, class Q, class R>
620 class CallMethod3 : public Demon {
621  public:
622  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
623  P param1, Q param2, R param3)
624  : constraint_(ct),
625  method_(method),
626  name_(name),
627  param1_(param1),
628  param2_(param2),
629  param3_(param3) {}
630 
631  ~CallMethod3() override {}
632 
633  void Run(Solver* const s) override {
634  (constraint_->*method_)(param1_, param2_, param3_);
635  }
636 
637  std::string DebugString() const override {
638  return absl::StrCat(absl::StrCat("CallMethod_", name_),
639  absl::StrCat("(", constraint_->DebugString()),
640  absl::StrCat(", ", ParameterDebugString(param1_)),
641  absl::StrCat(", ", ParameterDebugString(param2_)),
642  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
643  }
644 
645  private:
646  T* const constraint_;
647  void (T::*const method_)(P, Q, R);
648  const std::string name_;
649  P param1_;
650  Q param2_;
651  R param3_;
652 };
653 
654 template <class T, class P, class Q, class R>
655 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
656  void (T::*method)(P, Q, R), const std::string& name,
657  P param1, Q param2, R param3) {
658  return s->RevAlloc(
659  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
660 }
662 
667 
669 template <class T>
670 class DelayedCallMethod0 : public Demon {
671  public:
672  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
673  : constraint_(ct), method_(method), name_(name) {}
674 
675  ~DelayedCallMethod0() override {}
676 
677  void Run(Solver* const s) override { (constraint_->*method_)(); }
678 
679  Solver::DemonPriority priority() const override {
680  return Solver::DELAYED_PRIORITY;
681  }
682 
683  std::string DebugString() const override {
684  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
685  ")";
686  }
687 
688  private:
689  T* const constraint_;
690  void (T::*const method_)();
691  const std::string name_;
692 };
693 
694 template <class T>
695 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
696  void (T::*method)(),
697  const std::string& name) {
698  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
699 }
700 
702 template <class T, class P>
703 class DelayedCallMethod1 : public Demon {
704  public:
705  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
706  P param1)
707  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
708 
709  ~DelayedCallMethod1() override {}
710 
711  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
712 
713  Solver::DemonPriority priority() const override {
714  return Solver::DELAYED_PRIORITY;
715  }
716 
717  std::string DebugString() const override {
718  return absl::StrCat("DelayedCallMethod_", name_, "(",
719  constraint_->DebugString(), ", ",
720  ParameterDebugString(param1_), ")");
721  }
722 
723  private:
724  T* const constraint_;
725  void (T::*const method_)(P);
726  const std::string name_;
727  P param1_;
728 };
729 
730 template <class T, class P>
731 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
732  void (T::*method)(P),
733  const std::string& name, P param1) {
734  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
735 }
736 
738 template <class T, class P, class Q>
739 class DelayedCallMethod2 : public Demon {
740  public:
741  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
742  const std::string& name, P param1, Q param2)
743  : constraint_(ct),
744  method_(method),
745  name_(name),
746  param1_(param1),
747  param2_(param2) {}
748 
749  ~DelayedCallMethod2() override {}
750 
751  void Run(Solver* const s) override {
752  (constraint_->*method_)(param1_, param2_);
753  }
754 
755  Solver::DemonPriority priority() const override {
756  return Solver::DELAYED_PRIORITY;
757  }
758 
759  std::string DebugString() const override {
760  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
761  absl::StrCat("(", constraint_->DebugString()),
762  absl::StrCat(", ", ParameterDebugString(param1_)),
763  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
764  }
765 
766  private:
767  T* const constraint_;
768  void (T::*const method_)(P, Q);
769  const std::string name_;
770  P param1_;
771  Q param2_;
772 };
773 
774 template <class T, class P, class Q>
775 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
776  void (T::*method)(P, Q),
777  const std::string& name, P param1,
778  Q param2) {
779  return s->RevAlloc(
780  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
781 }
783 
784 #endif // !defined(SWIG)
785 
803 // TODO(user): rename Start to Synchronize ?
804 // TODO(user): decouple the iterating from the defining of a neighbor.
805 class LocalSearchOperator : public BaseObject {
806  public:
808  ~LocalSearchOperator() override {}
809  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
810  virtual void Start(const Assignment* assignment) = 0;
811  virtual void Reset() {}
812 #ifndef SWIG
813  virtual const LocalSearchOperator* Self() const { return this; }
814 #endif // SWIG
815  virtual bool HasFragments() const { return false; }
816  virtual bool HoldsDelta() const { return false; }
817 };
818 
820 template <class V, class Val, class Handler>
822  public:
824  explicit VarLocalSearchOperator(Handler var_handler)
825  : activated_(),
826  was_activated_(),
827  cleared_(true),
828  var_handler_(var_handler) {}
830  bool HoldsDelta() const override { return true; }
833  void Start(const Assignment* assignment) override {
834  const int size = Size();
835  CHECK_LE(size, assignment->Size())
836  << "Assignment contains fewer variables than operator";
837  for (int i = 0; i < size; ++i) {
838  activated_.Set(i, var_handler_.ValueFromAssignment(*assignment, vars_[i],
839  i, &values_[i]));
840  }
843  was_activated_.SetContentFromBitsetOfSameSize(activated_);
844  OnStart();
845  }
846  virtual bool IsIncremental() const { return false; }
847  int Size() const { return vars_.size(); }
850  const Val& Value(int64 index) const {
851  DCHECK_LT(index, vars_.size());
852  return values_[index];
853  }
855  V* Var(int64 index) const { return vars_[index]; }
856  virtual bool SkipUnchanged(int index) const { return false; }
857  const Val& OldValue(int64 index) const { return old_values_[index]; }
858  void SetValue(int64 index, const Val& value) {
859  values_[index] = value;
860  MarkChange(index);
861  }
862  bool Activated(int64 index) const { return activated_[index]; }
863  void Activate(int64 index) {
864  activated_.Set(index);
865  MarkChange(index);
866  }
867  void Deactivate(int64 index) {
868  activated_.Clear(index);
869  MarkChange(index);
870  }
871  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
872  if (IsIncremental() && !cleared_) {
873  for (const int64 index : delta_changes_.PositionsSetAtLeastOnce()) {
874  V* var = Var(index);
875  const Val& value = Value(index);
876  const bool activated = activated_[index];
877  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
878  deltadelta);
879  var_handler_.AddToAssignment(var, value, activated,
880  &assignment_indices_, index, delta);
881  }
882  } else {
883  delta->Clear();
884  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
885  const Val& value = Value(index);
886  const bool activated = activated_[index];
887  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
888  var_handler_.AddToAssignment(Var(index), value, activated_[index],
889  &assignment_indices_, index, delta);
890  }
891  }
892  }
893  return true;
894  }
895  void RevertChanges(bool incremental) {
896  cleared_ = false;
897  delta_changes_.SparseClearAll();
898  if (incremental && IsIncremental()) return;
899  cleared_ = true;
900  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
901  values_[index] = old_values_[index];
902  var_handler_.OnRevertChanges(index, values_[index]);
903  activated_.CopyBucket(was_activated_, index);
904  assignment_indices_[index] = -1;
905  }
906  changes_.SparseClearAll();
907  }
908  void AddVars(const std::vector<V*>& vars) {
909  if (!vars.empty()) {
910  vars_.insert(vars_.end(), vars.begin(), vars.end());
911  const int64 size = Size();
912  values_.resize(size);
913  old_values_.resize(size);
914  prev_values_.resize(size);
915  assignment_indices_.resize(size, -1);
916  activated_.Resize(size);
917  was_activated_.Resize(size);
918  changes_.ClearAndResize(size);
919  delta_changes_.ClearAndResize(size);
920  var_handler_.OnAddVars();
921  }
922  }
923 
927  virtual void OnStart() {}
928 
931  protected:
932  void MarkChange(int64 index) {
933  delta_changes_.Set(index);
934  changes_.Set(index);
935  }
936 
937  std::vector<V*> vars_;
938  std::vector<Val> values_;
939  std::vector<Val> old_values_;
940  std::vector<Val> prev_values_;
941  mutable std::vector<int> assignment_indices_;
942  Bitset64<> activated_;
943  Bitset64<> was_activated_;
944  SparseBitset<> changes_;
945  SparseBitset<> delta_changes_;
946  bool cleared_;
947  Handler var_handler_;
948 };
949 
952 
954  public:
955  IntVarLocalSearchHandler() : op_(nullptr) {}
957  : op_(other.op_) {}
959  void AddToAssignment(IntVar* var, int64 value, bool active,
960  std::vector<int>* assignment_indices, int64 index,
961  Assignment* assignment) const {
962  Assignment::IntContainer* const container =
963  assignment->MutableIntVarContainer();
964  IntVarElement* element = nullptr;
965  if (assignment_indices != nullptr) {
966  if ((*assignment_indices)[index] == -1) {
967  (*assignment_indices)[index] = container->Size();
968  element = assignment->FastAdd(var);
969  } else {
970  element = container->MutableElement((*assignment_indices)[index]);
971  }
972  } else {
973  element = assignment->FastAdd(var);
974  }
975  if (active) {
976  element->SetValue(value);
977  element->Activate();
978  } else {
979  element->Deactivate();
980  }
981  }
982  bool ValueFromAssignment(const Assignment& assignment, IntVar* var,
983  int64 index, int64* value);
984  void OnRevertChanges(int64 index, int64 value);
985  void OnAddVars() {}
986 
987  private:
988  IntVarLocalSearchOperator* const op_;
989 };
990 
996 
997 #ifdef SWIG
998 // TODO(user): find a way to move this code back to the .i file, where it
1005 #if defined(SWIGPYTHON)
1006 %unignore VarLocalSearchOperator<IntVar, int64,
1007  IntVarLocalSearchHandler>::Size;
1008 %unignore VarLocalSearchOperator<IntVar, int64,
1009  IntVarLocalSearchHandler>::Value;
1010 %unignore VarLocalSearchOperator<IntVar, int64,
1011  IntVarLocalSearchHandler>::OldValue;
1012 %unignore VarLocalSearchOperator<IntVar, int64,
1013  IntVarLocalSearchHandler>::SetValue;
1014 %feature("director") VarLocalSearchOperator<IntVar, int64,
1015  IntVarLocalSearchHandler>::IsIncremental;
1016 %feature("director") VarLocalSearchOperator<IntVar, int64,
1017  IntVarLocalSearchHandler>::OnStart;
1018 %unignore VarLocalSearchOperator<IntVar, int64,
1019  IntVarLocalSearchHandler>::IsIncremental;
1020 %unignore VarLocalSearchOperator<IntVar, int64,
1021  IntVarLocalSearchHandler>::OnStart;
1022 #endif // SWIGPYTHON
1023 
1024 // clang-format off
1025 %rename(IntVarLocalSearchOperatorTemplate)
1026  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1027 %template(IntVarLocalSearchOperatorTemplate)
1028  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1029 // clang-format on
1030 #endif // SWIG
1031 
1034  public:
1035  IntVarLocalSearchOperator() : max_inverse_value_(-1) {}
1036  // If keep_inverse_values is true, assumes that vars models an injective
1037  // function f with domain [0, vars.size()) in which case the operator will
1038  // maintain the inverse function.
1039  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1040  bool keep_inverse_values = false)
1042  IntVarLocalSearchHandler(this)),
1043  max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) {
1044  AddVars(vars);
1045  if (keep_inverse_values) {
1046  int64 max_value = -1;
1047  for (const IntVar* const var : vars) {
1048  max_value = std::max(max_value, var->Max());
1049  }
1050  inverse_values_.resize(max_value + 1, -1);
1051  old_inverse_values_.resize(max_value + 1, -1);
1052  }
1053  }
1061  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1062 
1063  protected:
1065 
1068  // TODO(user): make it pure virtual, implies porting all apps overriding
1070  virtual bool MakeOneNeighbor();
1071 
1072  bool IsInverseValue(int64 index) const {
1073  DCHECK_GE(index, 0);
1074  return index <= max_inverse_value_;
1075  }
1076 
1077  int64 InverseValue(int64 index) const { return inverse_values_[index]; }
1078 
1079  int64 OldInverseValue(int64 index) const {
1080  return old_inverse_values_[index];
1081  }
1082 
1083  void SetInverseValue(int64 index, int64 value) {
1084  inverse_values_[index] = value;
1085  }
1086 
1087  void SetOldInverseValue(int64 index, int64 value) {
1088  old_inverse_values_[index] = value;
1089  }
1090 
1091  private:
1092  const int64 max_inverse_value_;
1093  std::vector<int64> old_inverse_values_;
1094  std::vector<int64> inverse_values_;
1095 };
1096 
1098  const Assignment& assignment, IntVar* var, int64 index, int64* value) {
1099  const Assignment::IntContainer& container = assignment.IntVarContainer();
1100  const IntVarElement* element = &(container.Element(index));
1101  if (element->Var() != var) {
1102  CHECK(container.Contains(var))
1103  << "Assignment does not contain operator variable " << var;
1104  element = &(container.Element(var));
1105  }
1106  *value = element->Value();
1107  if (op_->IsInverseValue(index)) {
1108  op_->SetInverseValue(*value, index);
1109  op_->SetOldInverseValue(*value, index);
1110  }
1111  return element->Activated();
1112 }
1113 
1115  int64 value) {
1116  if (op_->IsInverseValue(index)) {
1117  op_->SetInverseValue(value, index);
1118  }
1119 }
1120 
1123 
1125  public:
1126  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1128  : op_(other.op_) {}
1130  : op_(op) {}
1131  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1132  bool active, std::vector<int>* assignment_indices,
1133  int64 index, Assignment* assignment) const;
1134  bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var,
1135  int64 index, std::vector<int>* value);
1136  void OnRevertChanges(int64 index, const std::vector<int>& value);
1137  void OnAddVars();
1138 
1139  private:
1140  SequenceVarLocalSearchOperator* const op_;
1141 };
1142 
1143 #ifdef SWIG
1144 // TODO(user): find a way to move this code back to the .i file, where it
1149 // clang-format off
1150 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1151  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1152 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1153  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1154 // clang-format on
1155 #endif
1156 
1157 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1158  SequenceVarLocalSearchHandler>
1160 
1163  public:
1165  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1168  AddVars(vars);
1169  }
1173  const std::vector<int>& Sequence(int64 index) const { return Value(index); }
1174  const std::vector<int>& OldSequence(int64 index) const {
1175  return OldValue(index);
1176  }
1177  void SetForwardSequence(int64 index, const std::vector<int>& value) {
1178  SetValue(index, value);
1179  }
1180  void SetBackwardSequence(int64 index, const std::vector<int>& value) {
1181  backward_values_[index] = value;
1182  MarkChange(index);
1183  }
1184 
1185  protected:
1187 
1188  std::vector<std::vector<int>> backward_values_;
1189 };
1190 
1192  SequenceVar* var, const std::vector<int>& value, bool active,
1193  std::vector<int>* assignment_indices, int64 index,
1194  Assignment* assignment) const {
1195  Assignment::SequenceContainer* const container =
1196  assignment->MutableSequenceVarContainer();
1197  SequenceVarElement* element = nullptr;
1198  if (assignment_indices != nullptr) {
1199  if ((*assignment_indices)[index] == -1) {
1200  (*assignment_indices)[index] = container->Size();
1201  element = assignment->FastAdd(var);
1202  } else {
1203  element = container->MutableElement((*assignment_indices)[index]);
1204  }
1205  } else {
1206  element = assignment->FastAdd(var);
1207  }
1208  if (active) {
1209  element->SetForwardSequence(value);
1210  element->SetBackwardSequence(op_->backward_values_[index]);
1211  element->Activate();
1212  } else {
1213  element->Deactivate();
1214  }
1215 }
1216 
1218  const Assignment& assignment, SequenceVar* var, int64 index,
1219  std::vector<int>* value) {
1220  const Assignment::SequenceContainer& container =
1221  assignment.SequenceVarContainer();
1222  const SequenceVarElement* element = &(container.Element(index));
1223  if (element->Var() != var) {
1224  CHECK(container.Contains(var))
1225  << "Assignment does not contain operator variable " << var;
1226  element = &(container.Element(var));
1227  }
1228  const std::vector<int>& element_value = element->ForwardSequence();
1229  CHECK_GE(var->size(), element_value.size());
1230  op_->backward_values_[index].clear();
1231  *value = element_value;
1232  return element->Activated();
1233 }
1234 
1236  int64 index, const std::vector<int>& value) {
1237  op_->backward_values_[index].clear();
1238 }
1239 
1241  op_->backward_values_.resize(op_->Size());
1242 }
1243 
1272  public:
1273  explicit BaseLns(const std::vector<IntVar*>& vars);
1274  ~BaseLns() override;
1275  virtual void InitFragments();
1276  virtual bool NextFragment() = 0;
1277  void AppendToFragment(int index);
1278  int FragmentSize() const;
1279  bool HasFragments() const override { return true; }
1280 
1281  protected:
1283  bool MakeOneNeighbor() override;
1284 
1285  private:
1287  void OnStart() override;
1288  std::vector<int> fragment_;
1289 };
1290 
1296  public:
1297  explicit ChangeValue(const std::vector<IntVar*>& vars);
1298  ~ChangeValue() override;
1299  virtual int64 ModifyValue(int64 index, int64 value) = 0;
1300 
1301  protected:
1303  bool MakeOneNeighbor() override;
1304 
1305  private:
1306  void OnStart() override;
1307 
1308  int index_;
1309 };
1310 
1325  public:
1339  PathOperator(const std::vector<IntVar*>& next_vars,
1340  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1341  bool skip_locally_optimal_paths, bool accept_path_end_base,
1342  std::function<int(int64)> start_empty_path_class);
1343  ~PathOperator() override {}
1344  virtual bool MakeNeighbor() = 0;
1345  void Reset() override;
1346 
1347  // TODO(user): Make the following methods protected.
1348  bool SkipUnchanged(int index) const override;
1349 
1351  int64 Next(int64 node) const {
1352  DCHECK(!IsPathEnd(node));
1353  return Value(node);
1354  }
1355 
1357  int64 Prev(int64 node) const {
1358  DCHECK(!IsPathStart(node));
1359  DCHECK_EQ(Next(InverseValue(node)), node);
1360  return InverseValue(node);
1361  }
1362 
1365  int64 Path(int64 node) const {
1366  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1367  }
1368 
1370  int number_of_nexts() const { return number_of_nexts_; }
1371 
1372  protected:
1374  bool MakeOneNeighbor() override;
1378  virtual void OnNodeInitialization() {}
1379 
1381  int64 BaseNode(int i) const { return base_nodes_[i]; }
1383  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1385  int64 BaseAlternativeNode(int i) const {
1386  if (!ConsiderAlternatives(i)) return BaseNode(i);
1387  const int alternative_index = alternative_index_[BaseNode(i)];
1388  return alternative_index >= 0
1389  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1390  : BaseNode(i);
1391  }
1393  int BaseSiblingAlternative(int i) const {
1394  return base_sibling_alternatives_[i];
1395  }
1397  int64 BaseSiblingAlternativeNode(int i) const {
1398  if (!ConsiderAlternatives(i)) return BaseNode(i);
1399  const int sibling_alternative_index =
1401  return sibling_alternative_index >= 0
1402  ? alternative_sets_[sibling_alternative_index]
1403  [base_sibling_alternatives_[i]]
1404  : BaseNode(i);
1405  }
1407  int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1409  const std::vector<int64>& path_starts() const { return path_starts_; }
1411  int PathClass(int i) const {
1412  return start_empty_path_class_ != nullptr
1413  ? start_empty_path_class_(StartNode(i))
1414  : StartNode(i);
1415  }
1416 
1423  // TODO(user): remove this when automatic detection of such cases in done.
1424  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1428  // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2);
1430  virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; }
1436  virtual int64 GetBaseNodeRestartPosition(int base_index) {
1437  return StartNode(base_index);
1438  }
1441  virtual void SetNextBaseToIncrement(int64 base_index) {
1442  next_base_to_increment_ = base_index;
1443  }
1446  virtual bool ConsiderAlternatives(int64 base_index) const { return false; }
1447 
1448  int64 OldNext(int64 node) const {
1449  DCHECK(!IsPathEnd(node));
1450  return OldValue(node);
1451  }
1452 
1453  int64 OldPrev(int64 node) const {
1454  DCHECK(!IsPathStart(node));
1455  return OldInverseValue(node);
1456  }
1457 
1458  int64 OldPath(int64 node) const {
1459  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1460  }
1461 
1464  bool MoveChain(int64 before_chain, int64 chain_end, int64 destination);
1465 
1468  bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last);
1469 
1471  bool MakeActive(int64 node, int64 destination);
1474  bool MakeChainInactive(int64 before_chain, int64 chain_end);
1476  bool SwapActiveAndInactive(int64 active, int64 inactive);
1477 
1479  void SetNext(int64 from, int64 to, int64 path) {
1480  DCHECK_LT(from, number_of_nexts_);
1481  SetValue(from, to);
1482  SetInverseValue(to, from);
1483  if (!ignore_path_vars_) {
1484  DCHECK_LT(from + number_of_nexts_, Size());
1485  SetValue(from + number_of_nexts_, path);
1486  }
1487  }
1488 
1491  bool IsPathEnd(int64 node) const { return node >= number_of_nexts_; }
1492 
1494  bool IsPathStart(int64 node) const { return OldInverseValue(node) == -1; }
1495 
1497  bool IsInactive(int64 node) const {
1498  return !IsPathEnd(node) && inactives_[node];
1499  }
1500 
1503  virtual bool InitPosition() const { return false; }
1507  void ResetPosition() { just_started_ = true; }
1508 
1512  int AddAlternativeSet(const std::vector<int64>& alternative_set) {
1513  const int alternative = alternative_sets_.size();
1514  for (int64 node : alternative_set) {
1515  DCHECK_EQ(-1, alternative_index_[node]);
1516  alternative_index_[node] = alternative;
1517  }
1518  alternative_sets_.push_back(alternative_set);
1519  sibling_alternative_.push_back(-1);
1520  return alternative;
1521  }
1522 #ifndef SWIG
1526  const std::vector<std::pair<std::vector<int64>, std::vector<int64>>>&
1527  pair_alternative_sets) {
1528  for (const auto& pair_alternative_set : pair_alternative_sets) {
1529  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1530  sibling_alternative_.back() = alternative + 1;
1531  AddAlternativeSet(pair_alternative_set.second);
1532  }
1533  }
1534 #endif // SWIG
1535  int64 GetActiveInAlternativeSet(int alternative_index) const {
1537  return alternative_index >= 0
1538  ? active_in_alternative_set_[alternative_index]
1539  : -1;
1540  }
1542  int64 GetActiveAlternativeNode(int node) const {
1543  return GetActiveInAlternativeSet(alternative_index_[node]);
1544  }
1546  int GetSiblingAlternativeIndex(int node) const {
1547  if (node >= alternative_index_.size()) return -1;
1548  const int alternative = alternative_index_[node];
1549  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1550  }
1553  int64 GetActiveAlternativeSibling(int node) const {
1554  if (node >= alternative_index_.size()) return -1;
1555  const int alternative = alternative_index_[node];
1556  const int sibling_alternative =
1557  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1558  return GetActiveInAlternativeSet(sibling_alternative);
1559  }
1562  bool CheckChainValidity(int64 before_chain, int64 chain_end,
1563  int64 exclude) const;
1564 
1565  const int number_of_nexts_;
1566  const bool ignore_path_vars_;
1568  int num_paths_ = 0;
1569  std::vector<int64> start_to_path_;
1570 
1571  private:
1572  void OnStart() override;
1574  bool OnSamePath(int64 node1, int64 node2) const;
1575 
1576  bool CheckEnds() const {
1577  const int base_node_size = base_nodes_.size();
1578  for (int i = base_node_size - 1; i >= 0; --i) {
1579  if (base_nodes_[i] != end_nodes_[i]) {
1580  return true;
1581  }
1582  }
1583  return false;
1584  }
1585  bool IncrementPosition();
1586  void InitializePathStarts();
1587  void InitializeInactives();
1588  void InitializeBaseNodes();
1589  void InitializeAlternatives();
1590  void Synchronize();
1591 
1592  std::vector<int> base_nodes_;
1593  std::vector<int> base_alternatives_;
1594  std::vector<int> base_sibling_alternatives_;
1595  std::vector<int> end_nodes_;
1596  std::vector<int> base_paths_;
1597  std::vector<int64> path_starts_;
1598  std::vector<bool> inactives_;
1599  bool just_started_;
1600  bool first_start_;
1601  const bool accept_path_end_base_;
1602  std::function<int(int64)> start_empty_path_class_;
1603  bool skip_locally_optimal_paths_;
1604  bool optimal_paths_enabled_;
1605  std::vector<int> path_basis_;
1606  std::vector<bool> optimal_paths_;
1608 #ifndef SWIG
1609  std::vector<std::vector<int64>> alternative_sets_;
1610 #endif // SWIG
1611  std::vector<int> alternative_index_;
1612  std::vector<int64> active_in_alternative_set_;
1613  std::vector<int> sibling_alternative_;
1614 };
1615 
1617 template <class T>
1619  Solver* solver, const std::vector<IntVar*>& vars,
1620  const std::vector<IntVar*>& secondary_vars,
1621  std::function<int(int64)> start_empty_path_class);
1622 
1625 class TwoOpt;
1626 class Relocate;
1627 class Exchange;
1628 class Cross;
1629 class MakeActiveOperator;
1630 class MakeInactiveOperator;
1631 class MakeChainInactiveOperator;
1632 class SwapActiveOperator;
1633 class ExtendedSwapActiveOperator;
1634 class MakeActiveAndRelocate;
1635 class RelocateAndMakeActiveOperator;
1636 class RelocateAndMakeInactiveOperator;
1637 
1638 #if !defined(SWIG)
1639 // A LocalSearchState is a container for variables with bounds that can be
1640 // relaxed and tightened, saved and restored. It represents the solution state
1641 // of a local search engine, and allows it to go from solution to solution by
1642 // relaxing some variables to form a new subproblem, then tightening those
1643 // variables to move to a new solution representation. That state may be saved
1644 // to an internal copy, or reverted to the last saved internal copy.
1645 // Relaxing a variable returns its bounds to their initial state.
1646 // Tightening a variable's bounds may make its min larger than its max,
1647 // in that case, the tightening function will return false, and the state will
1648 // be marked as invalid. No other operations than Revert() can be called on an
1649 // invalid state: in particular, an invalid state cannot be saved.
1650 class LocalSearchVariable;
1652  public:
1653  LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max);
1654  void Commit();
1655  void Revert();
1656  bool StateIsValid() const { return state_is_valid_; }
1657 
1658  private:
1659  friend class LocalSearchVariable;
1660 
1661  struct Bounds {
1662  int64 min;
1663  int64 max;
1664  };
1665 
1666  void RelaxVariableBounds(int variable_index);
1667  bool TightenVariableMin(int variable_index, int64 value);
1668  bool TightenVariableMax(int variable_index, int64 value);
1669  int64 VariableMin(int variable_index) const;
1670  int64 VariableMax(int variable_index) const;
1671 
1672  std::vector<Bounds> initial_variable_bounds_;
1673  std::vector<Bounds> variable_bounds_;
1674  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1675  std::vector<bool> variable_is_relaxed_;
1676  bool state_is_valid_ = true;
1677 };
1678 
1679 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1680 // meant to be passed by copy. If at some point the duplication of
1681 // LocalSearchState pointers is too expensive, we could switch to index only,
1682 // and the user would have to know the relevant state. The present setup allows
1683 // to ensure that variable users will not misuse the state.
1685  public:
1686  int64 Min() const { return state_->VariableMin(variable_index_); }
1687  int64 Max() const { return state_->VariableMax(variable_index_); }
1688  bool SetMin(int64 new_min) {
1689  return state_->TightenVariableMin(variable_index_, new_min);
1690  }
1691  bool SetMax(int64 new_max) {
1692  return state_->TightenVariableMax(variable_index_, new_max);
1693  }
1694  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1695 
1696  private:
1697  // Only LocalSearchState can construct LocalSearchVariables.
1698  friend class LocalSearchState;
1699 
1700  LocalSearchVariable(LocalSearchState* state, int variable_index)
1701  : state_(state), variable_index_(variable_index) {}
1702 
1703  LocalSearchState* const state_;
1704  const int variable_index_;
1705 };
1706 #endif // !defined(SWIG)
1707 
1724 class LocalSearchFilter : public BaseObject {
1725  public:
1728  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1729 
1739  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1740  int64 objective_min, int64 objective_max) = 0;
1741  virtual bool IsIncremental() const { return false; }
1742 
1748  virtual void Synchronize(const Assignment* assignment,
1749  const Assignment* delta) = 0;
1751  virtual void Revert() {}
1752 
1754  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1756  // If the last Accept() call returned false, returns an undefined value.
1757  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1758 };
1759 
1760 #if !defined(SWIG)
1761 class LocalSearchFilterManager : public LocalSearchFilter {
1765  public:
1766  LocalSearchFilterManager(Solver* const solver,
1767  const std::vector<LocalSearchFilter*>& filters);
1768  std::string DebugString() const override {
1769  return "LocalSearchFilterManager";
1770  }
1771  void Relax(const Assignment* delta, const Assignment* deltadelta) override;
1772  void Revert() override;
1775  bool Accept(const Assignment* delta, const Assignment* deltadelta,
1776  int64 objective_min, int64 objective_max) override;
1778  void Synchronize(const Assignment* assignment,
1779  const Assignment* delta) override;
1780  bool IsIncremental() const override { return is_incremental_; }
1781  int64 GetSynchronizedObjectiveValue() const override {
1782  return synchronized_value_;
1783  }
1784  int64 GetAcceptedObjectiveValue() const override { return accepted_value_; }
1785 
1786  private:
1787  Solver* const solver_;
1788  std::vector<LocalSearchFilter*> filters_;
1789  bool is_incremental_;
1790  int64 synchronized_value_;
1791  int64 accepted_value_;
1792 };
1793 #endif
1794 
1796  public:
1797  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1801  void Synchronize(const Assignment* assignment,
1802  const Assignment* delta) override;
1803 
1804  bool FindIndex(IntVar* const var, int64* index) const {
1805  DCHECK(index != nullptr);
1806  const int var_index = var->index();
1807  *index = (var_index < var_index_to_index_.size())
1808  ? var_index_to_index_[var_index]
1809  : kUnassigned;
1810  return *index != kUnassigned;
1811  }
1812 
1814  void AddVars(const std::vector<IntVar*>& vars);
1815  int Size() const { return vars_.size(); }
1816  IntVar* Var(int index) const { return vars_[index]; }
1817  int64 Value(int index) const {
1818  DCHECK(IsVarSynced(index));
1819  return values_[index];
1820  }
1821  bool IsVarSynced(int index) const { return var_synced_[index]; }
1822 
1823  protected:
1824  virtual void OnSynchronize(const Assignment* delta) {}
1825  void SynchronizeOnAssignment(const Assignment* assignment);
1826 
1827  private:
1828  std::vector<IntVar*> vars_;
1829  std::vector<int64> values_;
1830  std::vector<bool> var_synced_;
1831  std::vector<int> var_index_to_index_;
1832  static const int kUnassigned;
1833 };
1834 
1835 class PropagationMonitor : public SearchMonitor {
1836  public:
1837  explicit PropagationMonitor(Solver* const solver);
1839  std::string DebugString() const override { return "PropagationMonitor"; }
1840 
1843  Constraint* const constraint) = 0;
1845  Constraint* const constraint) = 0;
1847  Constraint* const parent, Constraint* const nested) = 0;
1849  Constraint* const parent, Constraint* const nested) = 0;
1850  virtual void RegisterDemon(Demon* const demon) = 0;
1851  virtual void BeginDemonRun(Demon* const demon) = 0;
1852  virtual void EndDemonRun(Demon* const demon) = 0;
1853  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1854  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1855  virtual void PushContext(const std::string& context) = 0;
1856  virtual void PopContext() = 0;
1858  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1859  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1860  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1862  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1863  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1864  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1865  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1866  virtual void SetValue(IntVar* const var, int64 value) = 0;
1867  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1868  virtual void SetValues(IntVar* const var,
1869  const std::vector<int64>& values) = 0;
1870  virtual void RemoveValues(IntVar* const var,
1871  const std::vector<int64>& values) = 0;
1873  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1874  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1875  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1876  int64 new_max) = 0;
1877  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1878  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1879  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1880  int64 new_max) = 0;
1881  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1882  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1883  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1884  int64 new_max) = 0;
1885  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1887  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1888  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1889  virtual void RankLast(SequenceVar* const var, int index) = 0;
1890  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1891  virtual void RankSequence(SequenceVar* const var,
1892  const std::vector<int>& rank_first,
1893  const std::vector<int>& rank_last,
1894  const std::vector<int>& unperformed) = 0;
1896  void Install() override;
1897 };
1898 
1899 class LocalSearchMonitor : public SearchMonitor {
1900  // TODO(user): Add monitoring of local search filters.
1901  public:
1902  explicit LocalSearchMonitor(Solver* const solver);
1904  std::string DebugString() const override { return "LocalSearchMonitor"; }
1905 
1907  virtual void BeginOperatorStart() = 0;
1908  virtual void EndOperatorStart() = 0;
1909  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1911  bool neighbor_found, const Assignment* delta,
1912  const Assignment* deltadelta) = 0;
1913  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1914  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1915  bool neighbor_found) = 0;
1916  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1917  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1918  bool neighbor_found) = 0;
1919  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1920  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1921 
1923  void Install() override;
1924 };
1925 
1926 class BooleanVar : public IntVar {
1927  public:
1928  static const int kUnboundBooleanVarValue;
1929 
1930  explicit BooleanVar(Solver* const s, const std::string& name = "")
1931  : IntVar(s, name), value_(kUnboundBooleanVarValue) {}
1932 
1933  ~BooleanVar() override {}
1934 
1935  int64 Min() const override { return (value_ == 1); }
1936  void SetMin(int64 m) override;
1937  int64 Max() const override { return (value_ != 0); }
1938  void SetMax(int64 m) override;
1939  void SetRange(int64 mi, int64 ma) override;
1940  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1941  int64 Value() const override {
1942  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1943  return value_;
1944  }
1945  void RemoveValue(int64 v) override;
1946  void RemoveInterval(int64 l, int64 u) override;
1947  void WhenBound(Demon* d) override;
1948  void WhenRange(Demon* d) override { WhenBound(d); }
1949  void WhenDomain(Demon* d) override { WhenBound(d); }
1950  uint64 Size() const override;
1951  bool Contains(int64 v) const override;
1952  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1953  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1954  std::string DebugString() const override;
1955  int VarType() const override { return BOOLEAN_VAR; }
1956 
1957  IntVar* IsEqual(int64 constant) override;
1958  IntVar* IsDifferent(int64 constant) override;
1959  IntVar* IsGreaterOrEqual(int64 constant) override;
1960  IntVar* IsLessOrEqual(int64 constant) override;
1961 
1962  virtual void RestoreValue() = 0;
1963  std::string BaseName() const override { return "BooleanVar"; }
1964 
1965  int RawValue() const { return value_; }
1966 
1967  protected:
1968  int value_;
1971 };
1972 
1973 class SymmetryManager;
1974 
1978 class SymmetryBreaker : public DecisionVisitor {
1979  public:
1981  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1982  ~SymmetryBreaker() override {}
1983 
1984  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
1986  int64 value);
1987  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
1988 
1989  private:
1990  friend class SymmetryManager;
1991  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
1992  CHECK(symmetry_manager_ == nullptr);
1993  CHECK_EQ(-1, index_in_symmetry_manager_);
1994  symmetry_manager_ = manager;
1995  index_in_symmetry_manager_ = index;
1996  }
1997  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
1998  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
1999 
2000  SymmetryManager* symmetry_manager_;
2002  int index_in_symmetry_manager_;
2003 };
2004 
2007 class SearchLog : public SearchMonitor {
2008  public:
2009  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2010  double scaling_factor, double offset,
2011  std::function<std::string()> display_callback, int period);
2012  ~SearchLog() override;
2013  void EnterSearch() override;
2014  void ExitSearch() override;
2015  bool AtSolution() override;
2016  void BeginFail() override;
2017  void NoMoreSolutions() override;
2018  void AcceptUncheckedNeighbor() override;
2019  void ApplyDecision(Decision* const decision) override;
2020  void RefuteDecision(Decision* const decision) override;
2022  void Maintain();
2023  void BeginInitialPropagation() override;
2024  void EndInitialPropagation() override;
2025  std::string DebugString() const override;
2026 
2027  protected:
2028  /* Bottleneck function used for all UI related output. */
2029  virtual void OutputLine(const std::string& line);
2030 
2031  private:
2032  static std::string MemoryUsage();
2033 
2034  const int period_;
2035  std::unique_ptr<WallTimer> timer_;
2036  IntVar* const var_;
2037  OptimizeVar* const obj_;
2038  const double scaling_factor_;
2039  const double offset_;
2040  std::function<std::string()> display_callback_;
2041  int nsol_;
2042  int64 tick_;
2043  int64 objective_min_;
2044  int64 objective_max_;
2045  int min_right_depth_;
2046  int max_depth_;
2047  int sliding_min_depth_;
2048  int sliding_max_depth_;
2049 };
2050 
2055 class ModelCache {
2056  public:
2061  };
2062 
2069  };
2070 
2074  };
2075 
2084  };
2085 
2091  };
2092 
2105  };
2106 
2110  };
2111 
2124  };
2128  };
2129 
2133  };
2134 
2138  };
2139 
2145  };
2146 
2150  };
2151 
2152  explicit ModelCache(Solver* const solver);
2153  virtual ~ModelCache();
2154 
2155  virtual void Clear() = 0;
2156 
2158 
2159  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
2160 
2161  virtual void InsertVoidConstraint(Constraint* const ct,
2162  VoidConstraintType type) = 0;
2163 
2165  virtual Constraint* FindVarConstantConstraint(
2166  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
2167 
2168  virtual void InsertVarConstantConstraint(Constraint* const ct,
2169  IntVar* const var, int64 value,
2170  VarConstantConstraintType type) = 0;
2171 
2173 
2175  IntVar* const var, int64 value1, int64 value2,
2176  VarConstantConstantConstraintType type) const = 0;
2177 
2179  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
2181 
2183 
2184  virtual Constraint* FindExprExprConstraint(
2185  IntExpr* const expr1, IntExpr* const expr2,
2186  ExprExprConstraintType type) const = 0;
2187 
2188  virtual void InsertExprExprConstraint(Constraint* const ct,
2189  IntExpr* const expr1,
2190  IntExpr* const expr2,
2191  ExprExprConstraintType type) = 0;
2192 
2194 
2195  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2196  ExprExpressionType type) const = 0;
2197 
2198  virtual void InsertExprExpression(IntExpr* const expression,
2199  IntExpr* const expr,
2200  ExprExpressionType type) = 0;
2201 
2203 
2204  virtual IntExpr* FindExprConstantExpression(
2205  IntExpr* const expr, int64 value,
2206  ExprConstantExpressionType type) const = 0;
2207 
2209  IntExpr* const expression, IntExpr* const var, int64 value,
2210  ExprConstantExpressionType type) = 0;
2211 
2213 
2214  virtual IntExpr* FindExprExprExpression(
2215  IntExpr* const var1, IntExpr* const var2,
2216  ExprExprExpressionType type) const = 0;
2217 
2218  virtual void InsertExprExprExpression(IntExpr* const expression,
2219  IntExpr* const var1,
2220  IntExpr* const var2,
2221  ExprExprExpressionType type) = 0;
2222 
2224 
2226  IntExpr* const var1, IntExpr* const var2, int64 constant,
2227  ExprExprConstantExpressionType type) const = 0;
2228 
2230  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2231  int64 constant, ExprExprConstantExpressionType type) = 0;
2232 
2234 
2236  IntVar* const var, int64 value1, int64 value2,
2237  VarConstantConstantExpressionType type) const = 0;
2238 
2240  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2242 
2244 
2246  IntVar* const var, const std::vector<int64>& values,
2247  VarConstantArrayExpressionType type) const = 0;
2248 
2250  IntExpr* const expression, IntVar* const var,
2251  const std::vector<int64>& values,
2253 
2255 
2256  virtual IntExpr* FindVarArrayExpression(
2257  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2258 
2259  virtual void InsertVarArrayExpression(IntExpr* const expression,
2260  const std::vector<IntVar*>& vars,
2261  VarArrayExpressionType type) = 0;
2262 
2264 
2266  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2267  VarArrayConstantArrayExpressionType type) const = 0;
2268 
2270  IntExpr* const expression, const std::vector<IntVar*>& var,
2271  const std::vector<int64>& values,
2273 
2275 
2277  const std::vector<IntVar*>& vars, int64 value,
2278  VarArrayConstantExpressionType type) const = 0;
2279 
2281  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2283 
2284  Solver* solver() const;
2285 
2286  private:
2287  Solver* const solver_;
2288 };
2289 
2291 #if !defined(SWIG)
2293  public:
2295  const std::string& TypeName() const;
2296  void SetTypeName(const std::string& type_name);
2297 
2299  void SetIntegerArgument(const std::string& arg_name, int64 value);
2300  void SetIntegerArrayArgument(const std::string& arg_name,
2301  const std::vector<int64>& values);
2302  void SetIntegerMatrixArgument(const std::string& arg_name,
2303  const IntTupleSet& values);
2304  void SetIntegerExpressionArgument(const std::string& arg_name,
2305  IntExpr* const expr);
2306  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2307  const std::vector<IntVar*>& vars);
2308  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2309  void SetIntervalArrayArgument(const std::string& arg_name,
2310  const std::vector<IntervalVar*>& vars);
2311  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2312  void SetSequenceArrayArgument(const std::string& arg_name,
2313  const std::vector<SequenceVar*>& vars);
2314 
2316  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2317  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2318 
2320  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2321  int64 def) const;
2322  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2323  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2324  const std::string& arg_name) const;
2326  const std::string& arg_name) const;
2327 
2329  const std::string& arg_name) const;
2330  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2331  const std::string& arg_name) const;
2332 
2333  private:
2334  std::string type_name_;
2335  absl::flat_hash_map<std::string, int64> integer_argument_;
2336  absl::flat_hash_map<std::string, std::vector<int64>> integer_array_argument_;
2337  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2338  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2339  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2340  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2341  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2342  integer_variable_array_argument_;
2343  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2344  interval_array_argument_;
2345  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2346  sequence_array_argument_;
2347 };
2348 
2350 class ModelParser : public ModelVisitor {
2351  public:
2353 
2354  ~ModelParser() override;
2355 
2357  void BeginVisitModel(const std::string& solver_name) override;
2358  void EndVisitModel(const std::string& solver_name) override;
2359  void BeginVisitConstraint(const std::string& type_name,
2360  const Constraint* const constraint) override;
2361  void EndVisitConstraint(const std::string& type_name,
2362  const Constraint* const constraint) override;
2363  void BeginVisitIntegerExpression(const std::string& type_name,
2364  const IntExpr* const expr) override;
2365  void EndVisitIntegerExpression(const std::string& type_name,
2366  const IntExpr* const expr) override;
2367  void VisitIntegerVariable(const IntVar* const variable,
2368  IntExpr* const delegate) override;
2369  void VisitIntegerVariable(const IntVar* const variable,
2370  const std::string& operation, int64 value,
2371  IntVar* const delegate) override;
2372  void VisitIntervalVariable(const IntervalVar* const variable,
2373  const std::string& operation, int64 value,
2374  IntervalVar* const delegate) override;
2375  void VisitSequenceVariable(const SequenceVar* const variable) override;
2377  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2378  void VisitIntegerArrayArgument(const std::string& arg_name,
2379  const std::vector<int64>& values) override;
2380  void VisitIntegerMatrixArgument(const std::string& arg_name,
2381  const IntTupleSet& values) override;
2383  void VisitIntegerExpressionArgument(const std::string& arg_name,
2384  IntExpr* const argument) override;
2386  const std::string& arg_name,
2387  const std::vector<IntVar*>& arguments) override;
2389  void VisitIntervalArgument(const std::string& arg_name,
2390  IntervalVar* const argument) override;
2392  const std::string& arg_name,
2393  const std::vector<IntervalVar*>& arguments) override;
2395  void VisitSequenceArgument(const std::string& arg_name,
2396  SequenceVar* const argument) override;
2398  const std::string& arg_name,
2399  const std::vector<SequenceVar*>& arguments) override;
2400 
2401  protected:
2405 
2406  private:
2407  std::vector<ArgumentHolder*> holders_;
2408 };
2409 
2410 template <class T>
2411 class ArrayWithOffset : public BaseObject {
2412  public:
2413  ArrayWithOffset(int64 index_min, int64 index_max)
2414  : index_min_(index_min),
2415  index_max_(index_max),
2416  values_(new T[index_max - index_min + 1]) {
2417  DCHECK_LE(index_min, index_max);
2418  }
2419 
2420  ~ArrayWithOffset() override {}
2421 
2422  virtual T Evaluate(int64 index) const {
2423  DCHECK_GE(index, index_min_);
2424  DCHECK_LE(index, index_max_);
2425  return values_[index - index_min_];
2426  }
2427 
2428  void SetValue(int64 index, T value) {
2429  DCHECK_GE(index, index_min_);
2430  DCHECK_LE(index, index_max_);
2431  values_[index - index_min_] = value;
2432  }
2433 
2434  std::string DebugString() const override { return "ArrayWithOffset"; }
2435 
2436  private:
2437  const int64 index_min_;
2438  const int64 index_max_;
2439  std::unique_ptr<T[]> values_;
2440 };
2441 #endif // SWIG
2442 
2447 template <class T, class C>
2449  public:
2450  explicit RevGrowingArray(int64 block_size)
2451  : block_size_(block_size), block_offset_(0) {
2452  CHECK_GT(block_size, 0);
2453  }
2454 
2456  for (int i = 0; i < elements_.size(); ++i) {
2457  delete[] elements_[i];
2458  }
2459  }
2460 
2461  T At(int64 index) const {
2462  const int64 block_index = ComputeBlockIndex(index);
2463  const int64 relative_index = block_index - block_offset_;
2464  if (relative_index < 0 || relative_index >= elements_.size()) {
2465  return T();
2466  }
2467  const T* block = elements_[relative_index];
2468  return block != nullptr ? block[index - block_index * block_size_] : T();
2469  }
2470 
2471  void RevInsert(Solver* const solver, int64 index, T value) {
2472  const int64 block_index = ComputeBlockIndex(index);
2473  T* const block = GetOrCreateBlock(block_index);
2474  const int64 residual = index - block_index * block_size_;
2475  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2476  reinterpret_cast<C>(value));
2477  }
2478 
2479  private:
2480  T* NewBlock() const {
2481  T* const result = new T[block_size_];
2482  for (int i = 0; i < block_size_; ++i) {
2483  result[i] = T();
2484  }
2485  return result;
2486  }
2487 
2488  T* GetOrCreateBlock(int block_index) {
2489  if (elements_.size() == 0) {
2490  block_offset_ = block_index;
2491  GrowUp(block_index);
2492  } else if (block_index < block_offset_) {
2493  GrowDown(block_index);
2494  } else if (block_index - block_offset_ >= elements_.size()) {
2495  GrowUp(block_index);
2496  }
2497  T* block = elements_[block_index - block_offset_];
2498  if (block == nullptr) {
2499  block = NewBlock();
2500  elements_[block_index - block_offset_] = block;
2501  }
2502  return block;
2503  }
2504 
2505  int64 ComputeBlockIndex(int64 value) const {
2506  return value >= 0 ? value / block_size_
2507  : (value - block_size_ + 1) / block_size_;
2508  }
2509 
2510  void GrowUp(int64 block_index) {
2511  elements_.resize(block_index - block_offset_ + 1);
2512  }
2513 
2514  void GrowDown(int64 block_index) {
2515  const int64 delta = block_offset_ - block_index;
2516  block_offset_ = block_index;
2517  DCHECK_GT(delta, 0);
2518  elements_.insert(elements_.begin(), delta, nullptr);
2519  }
2520 
2521  const int64 block_size_;
2522  std::vector<T*> elements_;
2523  int block_offset_;
2524 };
2525 
2530 template <class T>
2531 class RevIntSet {
2532  public:
2533  static const int kNoInserted = -1;
2534 
2536  explicit RevIntSet(int capacity)
2537  : elements_(new T[capacity]),
2538  num_elements_(0),
2539  capacity_(capacity),
2540  position_(new int[capacity]),
2541  delete_position_(true) {
2542  for (int i = 0; i < capacity; ++i) {
2543  position_[i] = kNoInserted;
2544  }
2545  }
2546 
2548  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2549  : elements_(new T[capacity]),
2550  num_elements_(0),
2551  capacity_(capacity),
2552  position_(shared_positions),
2553  delete_position_(false) {
2554  for (int i = 0; i < shared_positions_size; ++i) {
2555  position_[i] = kNoInserted;
2556  }
2557  }
2558 
2560  if (delete_position_) {
2561  delete[] position_;
2562  }
2563  }
2564 
2565  int Size() const { return num_elements_.Value(); }
2566 
2567  int Capacity() const { return capacity_; }
2568 
2569  T Element(int i) const {
2570  DCHECK_GE(i, 0);
2571  DCHECK_LT(i, num_elements_.Value());
2572  return elements_[i];
2573  }
2574 
2575  T RemovedElement(int i) const {
2576  DCHECK_GE(i, 0);
2577  DCHECK_LT(i + num_elements_.Value(), capacity_);
2578  return elements_[i + num_elements_.Value()];
2579  }
2580 
2581  void Insert(Solver* const solver, const T& elt) {
2582  const int position = num_elements_.Value();
2583  DCHECK_LT(position, capacity_);
2584  DCHECK(NotAlreadyInserted(elt));
2585  elements_[position] = elt;
2586  position_[elt] = position;
2587  num_elements_.Incr(solver);
2588  }
2589 
2590  void Remove(Solver* const solver, const T& value_index) {
2591  num_elements_.Decr(solver);
2592  SwapTo(value_index, num_elements_.Value());
2593  }
2594 
2595  void Restore(Solver* const solver, const T& value_index) {
2596  SwapTo(value_index, num_elements_.Value());
2597  num_elements_.Incr(solver);
2598  }
2599 
2600  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2601 
2603  typedef const T* const_iterator;
2604  const_iterator begin() const { return elements_.get(); }
2605  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2606 
2607  private:
2609  bool NotAlreadyInserted(const T& elt) {
2610  for (int i = 0; i < num_elements_.Value(); ++i) {
2611  if (elt == elements_[i]) {
2612  return false;
2613  }
2614  }
2615  return true;
2616  }
2617 
2618  void SwapTo(T value_index, int next_position) {
2619  const int current_position = position_[value_index];
2620  if (current_position != next_position) {
2621  const T next_value_index = elements_[next_position];
2622  elements_[current_position] = next_value_index;
2623  elements_[next_position] = value_index;
2624  position_[value_index] = next_position;
2625  position_[next_value_index] = current_position;
2626  }
2627  }
2628 
2630  std::unique_ptr<T[]> elements_;
2632  NumericalRev<int> num_elements_;
2634  const int capacity_;
2636  int* position_;
2638  const bool delete_position_;
2639 };
2640 
2642 
2644  public:
2645  explicit RevPartialSequence(const std::vector<int>& items)
2646  : elements_(items),
2647  first_ranked_(0),
2648  last_ranked_(items.size() - 1),
2649  size_(items.size()),
2650  position_(new int[size_]) {
2651  for (int i = 0; i < size_; ++i) {
2652  elements_[i] = items[i];
2653  position_[i] = i;
2654  }
2655  }
2656 
2657  explicit RevPartialSequence(int size)
2658  : elements_(size),
2659  first_ranked_(0),
2660  last_ranked_(size - 1),
2661  size_(size),
2662  position_(new int[size_]) {
2663  for (int i = 0; i < size_; ++i) {
2664  elements_[i] = i;
2665  position_[i] = i;
2666  }
2667  }
2668 
2670 
2671  int NumFirstRanked() const { return first_ranked_.Value(); }
2672 
2673  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2674 
2675  int Size() const { return size_; }
2676 
2677 #if !defined(SWIG)
2678  const int& operator[](int index) const {
2679  DCHECK_GE(index, 0);
2680  DCHECK_LT(index, size_);
2681  return elements_[index];
2682  }
2683 #endif
2684 
2685  void RankFirst(Solver* const solver, int elt) {
2686  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2687  SwapTo(elt, first_ranked_.Value());
2688  first_ranked_.Incr(solver);
2689  }
2690 
2691  void RankLast(Solver* const solver, int elt) {
2692  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2693  SwapTo(elt, last_ranked_.Value());
2694  last_ranked_.Decr(solver);
2695  }
2696 
2697  bool IsRanked(int elt) const {
2698  const int position = position_[elt];
2699  return (position < first_ranked_.Value() ||
2700  position > last_ranked_.Value());
2701  }
2702 
2703  std::string DebugString() const {
2704  std::string result = "[";
2705  for (int i = 0; i < first_ranked_.Value(); ++i) {
2706  absl::StrAppend(&result, elements_[i]);
2707  if (i != first_ranked_.Value() - 1) {
2708  result.append("-");
2709  }
2710  }
2711  result.append("|");
2712  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2713  absl::StrAppend(&result, elements_[i]);
2714  if (i != last_ranked_.Value()) {
2715  result.append("-");
2716  }
2717  }
2718  result.append("|");
2719  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2720  absl::StrAppend(&result, elements_[i]);
2721  if (i != size_ - 1) {
2722  result.append("-");
2723  }
2724  }
2725  result.append("]");
2726  return result;
2727  }
2728 
2729  private:
2730  void SwapTo(int elt, int next_position) {
2731  const int current_position = position_[elt];
2732  if (current_position != next_position) {
2733  const int next_elt = elements_[next_position];
2734  elements_[current_position] = next_elt;
2735  elements_[next_position] = elt;
2736  position_[elt] = next_position;
2737  position_[next_elt] = current_position;
2738  }
2739  }
2740 
2742  std::vector<int> elements_;
2744  NumericalRev<int> first_ranked_;
2746  NumericalRev<int> last_ranked_;
2748  const int size_;
2750  std::unique_ptr<int[]> position_;
2751 };
2752 
2758  public:
2761 
2763 
2766  void Init(Solver* const solver, const std::vector<uint64>& mask);
2767 
2770  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2771 
2774  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2775 
2778  int ActiveWordSize() const { return active_words_.Size(); }
2779 
2781  bool Empty() const { return active_words_.Size() == 0; }
2782 
2790  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2791 
2793  int64 bit_size() const { return bit_size_; }
2795  int64 word_size() const { return word_size_; }
2797  const RevIntSet<int>& active_words() const { return active_words_; }
2798 
2799  private:
2800  void CleanUpActives(Solver* const solver);
2801 
2802  const int64 bit_size_;
2803  const int64 word_size_;
2804  RevArray<uint64> bits_;
2805  RevIntSet<int> active_words_;
2806  std::vector<int> to_remove_;
2807 };
2808 
2809 template <class T>
2810 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2811  for (int i = 0; i < values.size(); ++i) {
2812  if (values[i] != value) {
2813  return false;
2814  }
2815  }
2816  return true;
2817 }
2818 
2819 template <class T>
2820 bool IsArrayBoolean(const std::vector<T>& values) {
2821  for (int i = 0; i < values.size(); ++i) {
2822  if (values[i] != 0 && values[i] != 1) {
2823  return false;
2824  }
2825  }
2826  return true;
2827 }
2828 
2829 template <class T>
2830 bool AreAllOnes(const std::vector<T>& values) {
2831  return IsArrayConstant(values, T(1));
2832 }
2833 
2834 template <class T>
2835 bool AreAllNull(const std::vector<T>& values) {
2836  return IsArrayConstant(values, T(0));
2837 }
2838 
2839 template <class T>
2840 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2841  for (const T& current_value : values) {
2842  if (current_value < value) {
2843  return false;
2844  }
2845  }
2846  return true;
2847 }
2848 
2849 template <class T>
2850 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2851  for (const T& current_value : values) {
2852  if (current_value > value) {
2853  return false;
2854  }
2855  }
2856  return true;
2857 }
2858 
2859 template <class T>
2860 bool AreAllPositive(const std::vector<T>& values) {
2861  return AreAllGreaterOrEqual(values, T(0));
2862 }
2863 
2864 template <class T>
2865 bool AreAllNegative(const std::vector<T>& values) {
2866  return AreAllLessOrEqual(values, T(0));
2867 }
2868 
2869 template <class T>
2870 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2871  return AreAllGreaterOrEqual(values, T(1));
2872 }
2873 
2874 template <class T>
2875 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2876  return AreAllLessOrEqual(values, T(-1));
2877 }
2878 
2879 template <class T>
2880 bool IsIncreasingContiguous(const std::vector<T>& values) {
2881  for (int i = 0; i < values.size() - 1; ++i) {
2882  if (values[i + 1] != values[i] + 1) {
2883  return false;
2884  }
2885  }
2886  return true;
2887 }
2888 
2889 template <class T>
2890 bool IsIncreasing(const std::vector<T>& values) {
2891  for (int i = 0; i < values.size() - 1; ++i) {
2892  if (values[i + 1] < values[i]) {
2893  return false;
2894  }
2895  }
2896  return true;
2897 }
2898 
2899 template <class T>
2900 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2901  T range_max) {
2902  for (int i = 0; i < vars.size(); ++i) {
2903  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2904  return false;
2905  }
2906  }
2907  return true;
2908 }
2909 
2910 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2911  for (int i = 0; i < vars.size(); ++i) {
2912  if (!vars[i]->Bound()) {
2913  return false;
2914  }
2915  }
2916  return true;
2917 }
2918 
2919 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2920  return IsArrayInRange(vars, 0, 1);
2921 }
2922 
2925 template <class T>
2926 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2927  const std::vector<T>& values) {
2928  for (int i = 0; i < vars.size(); ++i) {
2929  if (values[i] != 0 && !vars[i]->Bound()) {
2930  return false;
2931  }
2932  }
2933  return true;
2934 }
2935 
2937 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2938  for (int i = 0; i < vars.size(); ++i) {
2939  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2940  return false;
2941  }
2942  }
2943  return true;
2944 }
2945 
2946 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2947  DCHECK(!vars.empty());
2948  int64 result = kint64min;
2949  for (int i = 0; i < vars.size(); ++i) {
2951  result = std::max<int64>(result, vars[i]->Max());
2952  }
2953  return result;
2954 }
2955 
2956 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2957  DCHECK(!vars.empty());
2958  int64 result = kint64max;
2959  for (int i = 0; i < vars.size(); ++i) {
2961  result = std::min<int64>(result, vars[i]->Min());
2962  }
2963  return result;
2964 }
2965 
2966 inline void FillValues(const std::vector<IntVar*>& vars,
2967  std::vector<int64>* const values) {
2968  values->clear();
2969  values->resize(vars.size());
2970  for (int i = 0; i < vars.size(); ++i) {
2971  (*values)[i] = vars[i]->Value();
2972  }
2973 }
2974 
2975 inline int64 PosIntDivUp(int64 e, int64 v) {
2976  DCHECK_GT(v, 0);
2977  if (e >= 0) {
2978  return e % v == 0 ? e / v : e / v + 1;
2979  } else {
2980  return e / v;
2981  }
2982 }
2983 
2984 inline int64 PosIntDivDown(int64 e, int64 v) {
2985  DCHECK_GT(v, 0);
2986  if (e >= 0) {
2987  return e / v;
2988  } else {
2989  return e % v == 0 ? e / v : e / v - 1;
2990  }
2991 }
2992 
2993 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
2994 
2995 #if !defined(SWIG)
2996 // A PathState represents a set of paths and changed made on it.
2997 //
2998 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
2999 // directed graphs with nodes [0, num_nodes) whose connected components are
3000 // paths from starts[i] to ends[i] (for the same i) and loops.
3001 // Let us fix num_nodes, starts and ends so we call these P-graphs.
3002 //
3003 // Let us define some notions on graphs with the same set of nodes:
3004 // tails(D) is the set of nodes that are the tail of some arc of D.
3005 // P0 inter P1 is the graph of all arcs both in P0 and P1.
3006 // P0 union P1 is the graph of all arcs either in P0 or P1.
3007 // P1 - P0 is the graph with arcs in P1 and not in P0.
3008 // P0 |> D is the graph with arcs of P0 whose tail is not in tails(D).
3009 // P0 + D is (P0 |> D) union D.
3010 //
3011 // Now suppose P0 and P1 are P-graphs.
3012 // P0 + (P1 - P0) is exactly P1.
3013 // Moreover, note that P0 |> D is not a union of paths from some starts[i] to
3014 // ends[i] and loops like P0, because the operation removes arcs from P0.
3015 // P0 |> D is a union of generic paths, loops, and isolated nodes.
3016 // Let us call the generic paths and isolated nodes "chains".
3017 // Then the paths of P0 + D are chains linked by arcs of D.
3018 // Those chains are particularly interesting when examining a P-graph change.
3019 //
3020 // A PathState represents a P-graph for a fixed {num_nodes, starts, ends}.
3021 // The value of a PathState can be changed incrementally from P0 to P1
3022 // by passing the arcs of P1 - P0 to ChangeNext() and marking the end of the
3023 // change with a call to CutChains().
3024 // If P0 + D is not a P-graph, the behaviour is undefined.
3025 // TODO(user): check whether we want to have a DCHECK that P0 + D
3026 // is a P-graph or if CutChains() should return false.
3027 //
3028 // After CutChains(), tails(D) can be traversed using an iterator,
3029 // and the chains of P0 |> D can be browsed by chain-based iterators.
3030 // An iterator allows to browse the set of paths that have changed.
3031 // Then Commit() or Revert() can be called: Commit() changes the PathState to
3032 // represent P1 = P0 + D, all further changes are made from P1; Revert() changes
3033 // the PathState to forget D completely and return the state to P0.
3034 //
3035 // After a Commit(), Revert() or at initial state, the same iterators are
3036 // available and represent the change by an empty D: the set of changed paths
3037 // and the set of changed nodes is empty. Still, the chain-based iterator allows
3038 // to browse paths: each path has exactly one chain.
3039 class PathState {
3040  public:
3041  // A ChainRange allows to iterate on all chains of a path.
3042  // ChainRange is a range, its iterator Chain*, its value type Chain.
3043  class ChainRange;
3044  // A Chain allows to iterate on all nodes of a chain, and access some data:
3045  // first node, last node, number of nodes in the chain.
3046  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3047  // Chains are returned by PathChainIterator's operator*().
3048  class Chain;
3049  // A NodeRange allows to iterate on all nodes of a path.
3050  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3051  class NodeRange;
3052 
3053  // Path constructor: path_start and path_end must be disjoint,
3054  // their values in [0, num_nodes).
3055  PathState(int num_nodes, std::vector<int> path_start,
3056  std::vector<int> path_end);
3057 
3058  // Instance-constant accessors.
3059 
3060  // Returns the number of nodes in the underlying graph.
3061  int NumNodes() const { return num_nodes_; }
3062  // Returns the number of paths (empty paths included).
3063  int NumPaths() const { return num_paths_; }
3064  // Returns the start of a path.
3065  int Start(int path) const { return path_start_end_[path].start; }
3066  // Returns the end of a path.
3067  int End(int path) const { return path_start_end_[path].end; }
3068 
3069  // State-dependent accessors.
3070 
3071  // Returns the committed path of a given node, -1 if it is a loop.
3072  int Path(int node) const {
3073  return committed_nodes_[committed_index_[node]].path;
3074  }
3075  // Returns the set of arcs that have been added,
3076  // i.e. that were changed and were not in the committed state.
3077  const std::vector<std::pair<int, int>>& ChangedArcs() const {
3078  return changed_arcs_;
3079  }
3080  // Returns the set of paths that actually changed,
3081  // i.e. that have an arc in ChangedArcs().
3082  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3083  // Returns the current range of chains of path.
3084  ChainRange Chains(int path) const;
3085  // Returns the current range of nodes of path.
3086  NodeRange Nodes(int path) const;
3087 
3088  // State modifiers.
3089 
3090  // Adds arc (node, new_next) to the changed state, more formally,
3091  // changes the state from (P0, D) to (P0, D + (node, new_next)).
3092  void ChangeNext(int node, int new_next) {
3093  changed_arcs_.emplace_back(node, new_next);
3094  }
3095  // Marks the end of ChangeNext() sequence, more formally,
3096  // changes the state from (P0, D) to (P0 |> D, D).
3097  void CutChains();
3098  // Makes the current temporary state permanent, more formally,
3099  // changes the state from (P0 |> D, D) to (P0 + D, \emptyset),
3100  void Commit();
3101  // Erase incremental changes made by ChangeNext() and CutChains(),
3102  // more formally, changes the state from (P0 |> D, D) to (P0, \emptyset).
3103  void Revert();
3104 
3105  private:
3106  // Most structs below are named pairs of ints, for typing purposes.
3107 
3108  // Start and end are stored together to optimize (likely) simultaneous access.
3109  struct PathStartEnd {
3110  PathStartEnd(int start, int end) : start(start), end(end) {}
3111  int start;
3112  int end;
3113  };
3114  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3115  struct PathBounds {
3116  int begin_index;
3117  int end_index;
3118  };
3119  struct ChainBounds {
3120  ChainBounds() = default;
3121  ChainBounds(int begin_index, int end_index)
3122  : begin_index(begin_index), end_index(end_index) {}
3123  int begin_index;
3124  int end_index;
3125  };
3126  struct CommittedNode {
3127  CommittedNode(int node, int path) : node(node), path(path) {}
3128  int node;
3129  // Path of node in the committed state, -1 for loop nodes.
3130  // TODO(user): check if path would be better stored
3131  // with committed_index_, or in its own vector, or just recomputed.
3132  int path;
3133  };
3134  // Used in temporary structures, see below.
3135  struct TailHeadIndices {
3136  int tail_index;
3137  int head_index;
3138  };
3139  struct IndexArc {
3140  int index;
3141  int arc;
3142  bool operator<(const IndexArc& other) const { return index < other.index; }
3143  };
3144 
3145  // Copies nodes in chains of path at the end of nodes,
3146  // and sets those nodes' path member to value path.
3147  void CopyNewPathAtEndOfNodes(int path);
3148  // Commits paths in O(#{changed paths' nodes}) time,
3149  // increasing this object's space usage by O(|changed path nodes|).
3150  void IncrementalCommit();
3151  // Commits paths in O(num_nodes + num_paths) time,
3152  // reducing this object's space usage to O(num_nodes + num_paths).
3153  void FullCommit();
3154 
3155  // Instance-constant data.
3156  const int num_nodes_;
3157  const int num_paths_;
3158  std::vector<PathStartEnd> path_start_end_;
3159 
3160  // Representation of the committed and changed paths.
3161  // A path is a range of chains, which is a range of nodes.
3162  // Ranges are represented internally by indices in vectors:
3163  // ChainBounds are indices in committed_nodes_. PathBounds are indices in
3164  // chains_. When committed (after construction, Revert() or Commit()):
3165  // - path ranges are [path, path+1): they have one chain.
3166  // - chain ranges don't overlap, chains_ has an empty sentinel at the end.
3167  // - committed_nodes_ contains all nodes and old duplicates may appear,
3168  // the current version of a node is at the index given by
3169  // committed_index_[node]. A Commit() can add nodes at the end of
3170  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3171  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3172  // space by rewriting the path/chain/nodes structure.
3173  // When changed (after CutChains()), new chains are computed,
3174  // and the structure is updated accordingly:
3175  // - path ranges that were changed have nonoverlapping values [begin, end)
3176  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3177  // committed state.
3178  // - additional chain ranges are stored after the committed chains
3179  // to represent the new chains resulting from the changes.
3180  // Those chains do not overlap with each other or with unchanged chains.
3181  // An empty sentinel chain is added at the end of additional chains.
3182  // - committed_nodes_ are not modified, and still represent the committed
3183  // paths.
3184  // committed_index_ is not modified either.
3185  std::vector<CommittedNode> committed_nodes_;
3186  std::vector<int> committed_index_;
3187  const int num_nodes_threshold_;
3188  std::vector<ChainBounds> chains_;
3189  std::vector<PathBounds> paths_;
3190 
3191  // Incremental information: indices of nodes whose successor have changed,
3192  // path that have changed nodes.
3193  std::vector<std::pair<int, int>> changed_arcs_;
3194  std::vector<int> changed_paths_;
3195  std::vector<bool> path_has_changed_;
3196 
3197  // Temporary structures, since they will be reused heavily,
3198  // those are members in order to be allocated once and for all.
3199  std::vector<TailHeadIndices> tail_head_indices_;
3200  std::vector<IndexArc> arcs_by_tail_index_;
3201  std::vector<IndexArc> arcs_by_head_index_;
3202  std::vector<int> next_arc_;
3203 };
3204 
3205 // A Chain is a range of committed nodes.
3207  public:
3208  class Iterator {
3209  public:
3211  ++current_node_;
3212  return *this;
3213  }
3214  int operator*() const { return current_node_->node; }
3215  bool operator!=(Iterator other) const {
3216  return current_node_ != other.current_node_;
3217  }
3218 
3219  private:
3220  // Only a Chain can construct its iterator.
3221  friend class PathState::Chain;
3222  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3223  const CommittedNode* current_node_;
3224  };
3225 
3226  // Chains hold CommittedNode* values, a Chain may be invalidated
3227  // if the underlying vector is modified.
3228  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3229  : begin_(begin_node), end_(end_node) {}
3230 
3231  int NumNodes() const { return end_ - begin_; }
3232  int First() const { return begin_->node; }
3233  int Last() const { return (end_ - 1)->node; }
3234  Iterator begin() const { return Iterator(begin_); }
3235  Iterator end() const { return Iterator(end_); }
3236 
3237  private:
3238  const CommittedNode* const begin_;
3239  const CommittedNode* const end_;
3240 };
3241 
3242 // A ChainRange is a range of Chains, committed or not.
3244  public:
3245  class Iterator {
3246  public:
3248  ++current_chain_;
3249  return *this;
3250  }
3251  Chain operator*() const {
3252  return {first_node_ + current_chain_->begin_index,
3253  first_node_ + current_chain_->end_index};
3254  }
3255  bool operator!=(Iterator other) const {
3256  return current_chain_ != other.current_chain_;
3257  }
3258 
3259  private:
3260  // Only a ChainRange can construct its Iterator.
3261  friend class ChainRange;
3262  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3263  : current_chain_(chain), first_node_(first_node) {}
3264  const ChainBounds* current_chain_;
3265  const CommittedNode* const first_node_;
3266  };
3267 
3268  // ChainRanges hold ChainBounds* and CommittedNode*,
3269  // a ChainRange may be invalidated if on of the underlying vector is modified.
3270  ChainRange(const ChainBounds* const begin_chain,
3271  const ChainBounds* const end_chain,
3272  const CommittedNode* const first_node)
3273  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3274 
3275  Iterator begin() const { return {begin_, first_node_}; }
3276  Iterator end() const { return {end_, first_node_}; }
3277 
3278  private:
3279  const ChainBounds* const begin_;
3280  const ChainBounds* const end_;
3281  const CommittedNode* const first_node_;
3282 };
3283 
3284 // A NodeRange allows to iterate on all nodes of a path,
3285 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3287  public:
3288  class Iterator {
3289  public:
3291  ++current_node_;
3292  if (current_node_ == end_node_) {
3293  ++current_chain_;
3294  // Note: dereferencing bounds is valid because there is a sentinel
3295  // value at the end of PathState::chains_ to that intent.
3296  const ChainBounds bounds = *current_chain_;
3297  current_node_ = first_node_ + bounds.begin_index;
3298  end_node_ = first_node_ + bounds.end_index;
3299  }
3300  return *this;
3301  }
3302  int operator*() const { return current_node_->node; }
3303  bool operator!=(Iterator other) const {
3304  return current_chain_ != other.current_chain_;
3305  }
3306 
3307  private:
3308  // Only a NodeRange can construct its Iterator.
3309  friend class NodeRange;
3310  Iterator(const ChainBounds* current_chain,
3311  const CommittedNode* const first_node)
3312  : current_node_(first_node + current_chain->begin_index),
3313  end_node_(first_node + current_chain->end_index),
3314  current_chain_(current_chain),
3315  first_node_(first_node) {}
3316  const CommittedNode* current_node_;
3317  const CommittedNode* end_node_;
3318  const ChainBounds* current_chain_;
3319  const CommittedNode* const first_node_;
3320  };
3321 
3322  // NodeRanges hold ChainBounds* and CommittedNode*,
3323  // a NodeRange may be invalidated if on of the underlying vector is modified.
3324  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3325  const CommittedNode* first_node)
3326  : begin_chain_(begin_chain),
3327  end_chain_(end_chain),
3328  first_node_(first_node) {}
3329  Iterator begin() const { return {begin_chain_, first_node_}; }
3330  // Note: there is a sentinel value at the end of PathState::chains_,
3331  // so dereferencing chain_range_.end()->begin_ is always valid.
3332  Iterator end() const { return {end_chain_, first_node_}; }
3333 
3334  private:
3335  const ChainBounds* begin_chain_;
3336  const ChainBounds* end_chain_;
3337  const CommittedNode* const first_node_;
3338 };
3339 
3340 // This checker enforces unary dimension requirements.
3341 // A unary dimension requires that there is some valuation of
3342 // node_capacity and demand such that for all paths,
3343 // if arc A -> B is on a path of path_class p,
3344 // then node_capacity[A] + demand[p][A] = node_capacity[B].
3345 // Moreover, all node_capacities of a path must be inside interval
3346 // path_capacity[path].
3347 // Note that Intervals have two meanings:
3348 // - for demand and node_capacity, those are values allowed for each associated
3349 // decision variable.
3350 // - for path_capacity, those are set of values that node_capacities of the path
3351 // must respect.
3352 // If the path capacity of a path is [kint64min, kint64max],
3353 // then the unary dimension requirements are not enforced on this path.
3355  public:
3356  struct Interval {
3357  int64 min;
3358  int64 max;
3359  };
3360 
3362  std::vector<Interval> path_capacity,
3363  std::vector<int> path_class,
3364  std::vector<std::vector<Interval>> demand,
3365  std::vector<Interval> node_capacity);
3366 
3367  // Given the change made in PathState, checks that the unary dimension
3368  // constraint is still feasible.
3369  bool Check() const;
3370 
3371  // Commits to the changes made in PathState,
3372  // must be called before PathState::Commit().
3373  void Commit();
3374 
3375  private:
3376  // Range min/max query on partial_demand_sums_.
3377  // The first_node and last_node MUST form a subpath in the committed state.
3378  // Nodes first_node and last_node are passed by their index in precomputed
3379  // data, they must be committed in some path, and it has to be the same path.
3380  // See partial_demand_sums_.
3381  Interval GetMinMaxPartialDemandSum(int first_node_index,
3382  int last_node_index) const;
3383 
3384  // Queries whether all nodes in the committed subpath [first_node, last_node]
3385  // have fixed demands and trivial node_capacity [kint64min, kint64max].
3386  // first_node and last_node MUST form a subpath in the committed state.
3387  // Nodes are passed by their index in precomputed data.
3388  bool SubpathOnlyHasTrivialNodes(int first_node_index,
3389  int last_node_index) const;
3390 
3391  const PathState* const path_state_;
3392  const std::vector<Interval> path_capacity_;
3393  const std::vector<int> path_class_;
3394  const std::vector<std::vector<Interval>> demand_;
3395  const std::vector<Interval> node_capacity_;
3396 
3397  // Precomputed data.
3398  // Maps nodes to their pre-computed data, except for isolated nodes,
3399  // which do not have precomputed data.
3400  // Only valid for nodes that are in some path in the committed state.
3401  std::vector<int> index_;
3402  // Implementation of a <O(n log n), O(1)> range min/max query, n = #nodes.
3403  // partial_demand_sums_rmq_[0][index_[node]] contains the sum of demands
3404  // from the start of the node's path to the node.
3405  // If node is the start of path, the sum is demand_[path_class_[path]][node],
3406  // moreover partial_demand_sums_rmq_[0][index_[node]-1] is {0, 0}.
3407  // partial_demand_sums_rmq_[layer][index] contains an interval
3408  // [min_value, max_value] such that min_value is
3409  // min(partial_demand_sums_rmq_[0][index+i].min | i in [0, 2^layer)),
3410  // similarly max_value is the maximum of .max on the same range.
3411  std::vector<std::vector<Interval>> partial_demand_sums_rmq_;
3412  const int maximum_rmq_exponent_; // floor(log_2(#nodes)).
3413  // previous_nontrivial_index_[index_[node]] has the index of the previous
3414  // node on its committed path that has nonfixed demand or nontrivial node
3415  // capacity. This allows for O(1) queries that all nodes on a subpath
3416  // are nonfixed and nontrivial.
3417  std::vector<int> previous_nontrivial_index_;
3418 };
3419 
3420 // Make a filter that takes ownership of a PathState and synchronizes it with
3421 // solver events. The solver represents a graph with array of variables 'nexts'.
3422 // Solver events are embodied by Assignment* deltas, that are translated to node
3423 // changes during Relax(), committed during Synchronize(), and reverted on
3424 // Revert().
3426  std::unique_ptr<PathState> path_state,
3427  const std::vector<IntVar*>& nexts);
3428 
3429 // Make a filter that translates solver events to the input checker's interface.
3430 // Since UnaryDimensionChecker has a PathState, the filter returned by this
3431 // must be synchronized to the corresponding PathStateFilter:
3432 // - Relax() must be called after the PathStateFilter's.
3433 // - Accept() must be called after.
3434 // - Synchronize() must be called before.
3435 // - Revert() must be called before.
3437  Solver* solver, std::unique_ptr<UnaryDimensionChecker> checker);
3438 
3439 #endif // !defined(SWIG)
3440 
3441 } // namespace operations_research
3442 
3443 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
void Switch(Solver *const solver)
SparseBitset changes_
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64 value, VarConstantConstraintType type) const =0
Var Constant Constraints.
bool AreAllPositive(const std::vector< T > &values)
VarArrayConstantExpressionType
int64 MinVarArray(const std::vector< IntVar * > &vars)
IntVar * IsEqual(int64 constant) override
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
IntVarIterator * MakeHoleIterator(bool reversible) const override
@ VAR_CONSTANT_LESS_OR_EQUAL
bool Contains(int64 v) const override
int next_base_to_increment_
LocalSearchFilterManager(Solver *const solver, const std::vector< LocalSearchFilter * > &filters)
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64 value, VarConstantConstraintType type)=0
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
int64 Min() const override
IntVarLocalSearchHandler()
int64 StartNode(int i) const
Returns the start node of the ith base node.
Solver * solver() const
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
int BaseSiblingAlternative(int i) const
Returns the alternative for the sibling of the ith base node.
std::string DebugString() const override
Solver::DemonPriority priority() const override
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
~SymmetryBreaker() override
bool MakeActive(int64 node, int64 destination)
Insert the inactive node after destination.
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
int64 GetFirstOne() const
Gets the index of the first bit set starting from 0.
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
void EndInitialPropagation() override
bool AreAllBooleans(const std::vector< IntVar * > &vars)
This class is a reversible growing array.
int64 max
~ModelParser() override
const int number_of_nexts_
~UnsortedNullableRevBitset()
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.
virtual IntVar * CastToVar()
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64 value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
@ OPP_VAR
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
T * MutableLast()
SimpleRevFIFO< Demon * > delayed_bound_demons_
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
int64 Value(int index) const
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
int64 GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
void RevertChanges(bool incremental)
void Restore(Solver *const solver, const T &value_index)
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
void RankFirst(Solver *const solver, int elt)
@ VOID_TRUE_CONSTRAINT
@ VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD
bool IsIncreasingContiguous(const std::vector< T > &values)
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.
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
Model Parser.
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
This iterator is not stable with respect to deletion.
void SetInverseValue(int64 index, int64 value)
@ EXPR_CONSTANT_SUM
@ EXPR_EXPR_MAX
SimpleRevFIFO()
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void EndDemonRun(Demon *const demon)=0
void WhenDomain(Demon *d) override
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
@ EXPR_CONSTANT_DIVIDE
int64 InverseValue(int64 index) const
std::string DebugString() const override
@ EXPR_CONSTANT_IS_LESS_OR_EQUAL
T operator*() const
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
@ VAR_CONSTANT_ARRAY_EXPRESSION_MAX
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
Low-priority demon proxy to a method on the constraint with two arguments.
const bool ignore_path_vars_
int NumFirstRanked() const
@ EXPR_EXPR_EXPRESSION_MAX
IntVarLocalSearchHandler(const IntVarLocalSearchHandler &other)
@ EXPR_EXPR_DIV
std::string DebugString() const override
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type)=0
std::string BaseName() const override
@ VAR_CONSTANT_CONSTANT_BETWEEN
@ EXPR_EXPR_PROD
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
@ EXPR_OPPOSITE
virtual void OutputLine(const std::string &line)
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
void Run(Solver *const s) override
@ CST_SUB_VAR
bool IsIncremental() const override
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
std::string DebugString() const override
This class represents a reversible bitset.
bool AreAllOnes(const std::vector< T > &values)
Bitset64 activated_
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
int FragmentSize() const
void AddVars(const std::vector< V * > &vars)
friend class IntVarLocalSearchHandler
void OnAddVars()
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values) override
virtual bool OnSamePathAsPreviousBase(int64 base_index)
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
Iterator begin() const
~SearchLog() override
void operator++()
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
int64 BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
This is the base class for building an Lns operator.
@ EXPR_EXPR_EQUALITY
~ChangeValue() override
@ EXPR_EXPR_CONSTANT_CONDITIONAL
~RevBitSet()
BaseLns(const std::vector< IntVar * > &vars)
virtual bool InitPosition() const
Returns true if the operator needs to restart its initial position at each call to Start()
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
bool Check() const
bool IsVarSynced(int index) const
bool SwapActiveAndInactive(int64 active, int64 inactive)
Replaces active by inactive in the current path, making active inactive.
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void BeginDemonRun(Demon *const demon)=0
SymmetryBreaker()
void OutputDecision()
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
virtual void EndOperatorStart()=0
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
@ VAR_ARRAY_EXPRESSION_MAX
IntVar * IsGreaterOrEqual(int64 constant) override
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
@ EXPR_CONSTANT_EXPRESSION_MAX
Solver::DemonPriority priority() const override
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
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...
~LocalSearchMonitor() override
The base class of all search logs that periodically outputs information when the search is running.
void VisitSequenceVariable(const SequenceVar *const variable) override
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64 value)
Returns true if all variables are assigned to 'value'.
int64 GetActiveAlternativeSibling(int node) const
Returns the active node in the alternative set of the sibling of the given node.
@ VAR_CONSTANT_ARRAY_ELEMENT
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
Reversible Immutable MultiMap class.
PropagationMonitor(Solver *const solver)
~PropagationMonitor() 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)
virtual void SetMin(IntExpr *const expr, int64 new_min)=0
IntExpr modifiers.
int Start(int path) const
bool IsInverseValue(int64 index) const
void VisitIntegerArgument(const std::string &arg_name, int64 value) override
Integer arguments.
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...
SmallRevBitSet(int64 size)
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
T Element(int i) const
int64 OldNext(int64 node) const
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
int64 Min() const
~BaseLns() override
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
void PushArgumentHolder()
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
VarConstantArrayExpressionType
virtual bool IsIncremental() const
Iterator end() const
void Clear(Solver *const solver)
ExprExprExpressionType
int num_paths_
bool IsInactive(int64 node) const
Returns true if node is inactive.
int64 PosIntDivUp(int64 e, int64 v)
const T & LastValue() const
Returns the last value in the FIFO.
Chain operator*() const
@ EXPR_EXPR_CONSTANT_EXPRESSION_MAX
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
bool AreAllNull(const std::vector< T > &values)
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type)=0
~BaseIntExpr() override
bool AtSolution() override
std::string DebugString() const
~SequenceVarLocalSearchOperator() override
virtual void RegisterDemon(Demon *const demon)=0
T At(int64 index) const
@ VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX
bool SetMin(int64 new_min)
@ VAR_ADD_CST
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
void Revert()
Demon proxy to a method on the constraint with one argument.
std::vector< int64 > start_to_path_
int64 Value() const override
~DelayedCallMethod0() override
void Insert(Solver *const solver, const T &elt)
bool Bound() const override
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
void AppendToFragment(int index)
void BeginFail() override
~VarLocalSearchOperator() override
bool ok() const
void Run(Solver *const s) override
T RemovedElement(int i) const
void SetToOne(Solver *const solver, int64 index)
Sets the 'index' bit.
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
void RefuteDecision(Decision *const decision) override
Base operator class for operators manipulating variables.
static const int kNoInserted
~LocalSearchOperator() override
virtual bool MakeOneNeighbor()
Creates a new neighbor.
int64 Path(int64 node) const
Returns the index of the path to which node belongs in the current delta.
const Val & Value(int64 index) const
Returns the value in the current assignment of the variable of given index.
void CutChains()
RevBitMatrix(int64 rows, int64 columns)
~IntVarLocalSearchOperator() override
~ArrayWithOffset() override
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
~RevBitMatrix()
ExprExprConstraintType
void PopArgumentHolder()
RevBitSet(int64 size)
bool SkipUnchanged(int index) const override
const_iterator end() const
@ VAR_ARRAY_MIN
@ EXPR_CONSTANT_IS_GREATER_OR_EQUAL
int RawValue() const
friend class SymmetryManager
virtual bool HoldsDelta() const
VarConstantConstantExpressionType
@ VAR_ARRAY_MAX
Iterator & operator++()
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
void NoMoreSolutions() override
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
bool ValueFromAssignment(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
void RankLast(Solver *const solver, int elt)
~CallMethod3() override
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
void SetToZero(Solver *const solver, int64 pos)
Erases the 'pos' bit.
void SetToZero(Solver *const solver, int64 index)
Erases the 'index' bit.
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
IntVarIterator * MakeDomainIterator(bool reversible) const override
virtual void SetValue(IntVar *const var, int64 value)=0
std::vector< int > assignment_indices_
RevSwitch()
@ BOOLEAN_VAR
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
void MarkChange(int64 index)
OnStart() should really be protected, but then SWIG doesn't see it.
Bitset64 was_activated_
virtual void Relax(const Assignment *delta, const Assignment *deltadelta)
Lets the filter know what delta and deltadelta will be passed in the next Accept().
virtual void OnSynchronize(const Assignment *delta)
int64 bit_size() const
Returns the number of bits given in the constructor of the bitset.
IntVar * IsDifferent(int64 constant) override
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
The base class for all local search operators.
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
@ EXPR_CONSTANT_PROD
bool IsArrayConstant(const std::vector< T > &values, const T &value)
SparseBitset delta_changes_
VarConstantConstantConstraintType
bool IsIncreasing(const std::vector< T > &values)
void WhenBound(Demon *d) override
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
void Run(Solver *const s) override
void BeginInitialPropagation() override
VarLocalSearchOperator(Handler var_handler)
Solver::DemonPriority priority() const override
int64 GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
@ CONST_VAR
virtual const LocalSearchOperator * Self() 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.
ExprConstantExpressionType
void SetLastValue(const T &v)
Sets the last value in the FIFO.
virtual void RestoreValue()=0
int64 GetActiveInAlternativeSet(int alternative_index) const
Returns the active node in the given alternative set.
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, double offset, std::function< std::string()> display_callback, int period)
void SetBackwardSequence(int64 index, const std::vector< int > &value)
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
int64 BaseNode(int i) const
Returns the ith base node of the operator.
~DelayedCallMethod2() override
void RemoveValue(int64 v) override
std::string DebugString() const override
const std::vector< int64 > & path_starts() const
Returns the vector of path start nodes.
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 ...
int64 Max() const
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
@ EXPR_ABS
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
int64 FindIntegerArgumentWithDefault(const std::string &arg_name, int64 def) const
Getters.
void Init(Solver *const solver, const std::vector< uint64 > &mask)
This methods overwrites the active bitset with the mask.
SequenceVarLocalSearchOperator()
ExprExprConstantExpressionType
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...
@ TRACE_VAR
void Commit()
@ EXPR_EXPR_IS_LESS_OR_EQUAL
~PathOperator() override
Implements a complete cache for model elements: expressions and constraints.
bool RevSubtract(Solver *const solver, const std::vector< uint64 > &mask)
This method subtracts the mask from the active bitset.
Chain(const CommittedNode *begin_node, const CommittedNode *end_node)
ModelParser()
ChainRange Chains(int path) const
@ VAR_CONSTANT_CONSTRAINT_MAX
void ChangeNext(int node, int new_next)
void Run(Solver *const s) override
IntVar * Var() override
@ EXPR_EXPR_GREATER
NodeRange Nodes(int path) const
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
@ EXPR_EXPR_IS_NOT_EQUAL
void SetMin(int64 m) override
int PathClass(int i) const
Returns the class of the path of the ith base node.
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
@ EXPR_SQUARE
@ VOID_CONSTRAINT_MAX
VarArrayExpressionType
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
std::string DebugString() const override
VarLocalSearchOperator()
virtual bool MakeNeighbor()=0
@ VAR_CONSTANT_GREATER_OR_EQUAL
bool AreAllBoundOrNull(const std::vector< IntVar * > &vars, const std::vector< T > &values)
Returns true if all the variables are assigned to a single value, or if their corresponding value is ...
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64 value, VarArrayConstantExpressionType type)=0
Demon proxy to a method on the constraint with two arguments.
virtual void SetMin(IntVar *const var, int64 new_min)=0
IntVar modifiers.
@ EXPR_CONSTANT_IS_NOT_EQUAL
std::vector< int64 > ToInt64Vector(const std::vector< int > &input)
RevPartialSequence(const std::vector< int > &items)
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
int64 Max() const override
uint64 Size() const override
virtual int64 ModifyValue(int64 index, int64 value)=0
int NumNodes() const
bool IsCardinalityOne() const
Does it contains only one bit set?
@ EXPR_EXPR_GREATER_OR_EQUAL
int64 word_size() const
Returns the number of 64 bit words used to store the bitset.
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64 value, IntervalVar *const delegate) override
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
~RevImmutableMultiMap()
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
Iterator & operator++()
virtual bool NextFragment()=0
void OnAddVars()
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
LocalSearchOperator()
virtual bool SkipUnchanged(int index) const
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
virtual void Start(const Assignment *assignment)=0
virtual T Evaluate(int64 index) const
int AddAlternativeSet(const std::vector< int64 > &alternative_set)
Handling node alternatives.
@ EXPR_EXPR_SUM
ChangeValue(const std::vector< IntVar * > &vars)
Low-priority demon proxy to a method on the constraint with no arguments.
std::vector< std::vector< int > > backward_values_
void SetNext(int64 from, int64 to, int64 path)
Sets 'to' to be the node after 'from' on the given path.
@ EXPR_EXPR_NON_EQUALITY
virtual void SetPerformed(IntervalVar *const var, bool value)=0
virtual bool HasFragments() const
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
virtual void Reset()
bool IsCardinalityOne(int row) const
Does the 'row' bitset contains only one bit set?
int operator*() const
virtual void RankLast(SequenceVar *const var, int index)=0
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 InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type)=0
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
@ EXPR_CONSTANT_DIFFERENCE
virtual void PushContext(const std::string &context)=0
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
IntVarLocalSearchOperator()
void Reset() override
void ExitSearch() override
int Size() const
void Commit()
void RemoveInterval(int64 l, int64 u) override
std::string DebugString() const override
bool operator!=(Iterator other) const
@ EXPR_CONSTANT_MIN
void Relax()
BaseIntExpr(Solver *const s)
@ EXPR_EXPRESSION_MAX
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
SequenceVarLocalSearchHandler()
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 ...
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
int value_
void SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
bool IsCardinalityZero(int row) const
Is bitset of row 'row' null?
void Remove(Solver *const solver, const T &value_index)
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Returns true iff all filters return true, and the sum of their accepted objectives is between objecti...
const int & operator[](int index) const
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
@ EXPR_EXPR_CONSTRAINT_MAX
~IntVarLocalSearchFilter() override
uint64 Hash1(uint64 value)
Hash functions.
ArgumentHolder * Top() const
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64 value)
void Push(Solver *const s, T val)
const T * const_iterator
Iterators on the indices.
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...
int64 Cardinality(int row) const
Returns the number of bits set to one in the 'row' row.
LocalSearchMonitor(Solver *const solver)
void Run(Solver *const s) override
std::string DebugString() const override
bool Activated(int64 index) const
A reversible switch that can switch once from false to true.
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
bool HoldsDelta() const override
ChainRange(const ChainBounds *const begin_chain, const ChainBounds *const end_chain, const CommittedNode *const first_node)
bool AreAllStrictlyNegative(const std::vector< T > &values)
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
bool MakeChainInactive(int64 before_chain, int64 chain_end)
Makes the nodes on the chain starting after before_chain and ending at chain_end inactive.
int64 GetSynchronizedObjectiveValue() const override
Objective value from last time Synchronize() was called.
bool cleared_
IntVar * Var(int index) const
int operator*() const
const_iterator begin() const
SimpleRevFIFO< Demon * > bound_demons_
int First() const
VarConstantConstraintType
int64 Cardinality() const
Returns the number of bits set to one.
bool SetMax(int64 new_max)
void RevInsert(Solver *const solver, int64 index, T value)
void Synchronize(const Assignment *assignment, const Assignment *delta) override
Synchronizes all filters to assignment.
@ EXPR_EXPR_LESS
int Path(int node) const
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64 value, ExprConstantExpressionType type)=0
This class represents a small reversible bitset (size <= 64).
V * Var(int64 index) const
Returns the variable of given index.
void WhenRange(Demon *d) override
virtual void SetMax(IntExpr *const expr, int64 new_max)=0
void SetToZero(Solver *const solver, int64 row, int64 column)
Erases the 'column' bit in the 'row' row.
bool AreAllStrictlyPositive(const std::vector< T > &values)
void Revert() override
Cancels the changes made by the last Relax()/Accept() calls.
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
void Activate(int64 index)
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
~CallMethod2() override
const std::vector< std::pair< int, int > > & ChangedArcs() const
virtual void BeginOperatorStart()=0
Local search operator events.
int64 OldPath(int64 node) const
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
virtual ~ModelCache()
void EnterSearch() override
int64 Prev(int64 node) const
Returns the node before node in the current delta.
void AcceptUncheckedNeighbor() override
bool AreAllBound(const std::vector< IntVar * > &vars)
int Last() const
void Maintain()
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
int NumLastRanked() const
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
ExprExpressionType
int VarType() const override
@ VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX
int Size() const
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64)> start_empty_path_class)
Operator Factories.
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
Argument Holder: useful when visiting a model.
Iterator end() const
Handler var_handler_
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
Local Search Filters are used for fast neighbor pruning.
int Size() const
@ 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)
std::string DebugString() const override
@ VAR_ARRAY_CONSTANT_INDEX
virtual void SetNextBaseToIncrement(int64 base_index)
Set the next base to increment on next iteration.
~CallMethod1() override
This is a special class to represent a 'residual' set of T.
void OnRevertChanges(int64 index, int64 value)
void SetToOne(Solver *const solver, int64 row, int64 column)
Sets the 'column' bit in the 'row' row.
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
virtual bool ConsiderAlternatives(int64 base_index) const
Indicates if alternatives should be considered when iterating over base nodes.
bool ValueFromAssignment(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
This class represent a reversible FIFO structure.
void ClearAll(Solver *const solver)
Cleans all bits.
void ApplyDecision(Decision *const decision) override
virtual void Clear()=0
bool HasFragments() const override
Matrix version of the RevBitSet class.
@ EXPR_EXPR_MIN
bool IsCardinalityZero() const
Is bitset null?
@ EXPR_CONSTANT_IS_EQUAL
@ UNSPECIFIED
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max)
Iterator & operator++()
virtual void SetValues(IntVar *const var, const std::vector< int64 > &values)=0
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
~RevPartialSequence()
This class represents a reversible bitset.
PathState(int num_nodes, std::vector< int > path_start, std::vector< int > path_end)
@ VAR_CONSTANT_NON_EQUALITY
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type)=0
void Install() override
Install itself on the solver.
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
IntVar * IsLessOrEqual(int64 constant) override
bool Switched() const
void SetRange(int64 mi, int64 ma) override
int64 FindIntegerArgumentOrDie(const std::string &arg_name) const
int Capacity() const
void Relax(const Assignment *delta, const Assignment *deltadelta) override
Lets the filter know what delta and deltadelta will be passed in the next Accept().
bool IsPathStart(int64 node) const
Returns true if node is the first node on the path.
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
int NumPaths() const
const std::vector< int > & ChangedPaths() const
ModelCache(Solver *const solver)
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
bool Empty() const
This method returns true if the active bitset is null.
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
void Run(Solver *const s) override
@ VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS
static const int kUnboundBooleanVarValue
int64 GetActiveAlternativeNode(int node) const
Returns the active node in the alternative set of the given node.
RevImmutableMultiMap(Solver *const solver, int initial_size)
int64 Cardinality() const
Returns the number of bits set to one.
ArrayWithOffset(int64 index_min, int64 index_max)
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
virtual void PopContext()=0
const std::vector< int > & Sequence(int64 index) const
Returns the value in the current assignment of the variable of given index.
bool RevAnd(Solver *const solver, const std::vector< uint64 > &mask)
This method ANDs the mask with the active bitset.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
@ DOMAIN_INT_VAR
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 OnRevertChanges(int64 index, const std::vector< int > &value)
std::vector< Val > values_
void VisitIntegerVariable(const IntVar *const variable, const std::string &operation, int64 value, IntVar *const delegate) override
void Commit()
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
void SetMax(int64 m) override
std::string DebugString() const override
virtual void SetRange(IntVar *const var, int64 new_min, int64 new_max)=0
int64 PosIntDivDown(int64 e, int64 v)
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
void ClearAll(Solver *const solver)
Cleans all bits.
int NumNodes() const
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
Iterator begin() const
void Install() override
Install itself on the solver.
Demon proxy to a method on the constraint with three arguments.
void Revert()
int64 Next(int64 node) const
Returns the node after node in the current delta.
@ EXPR_EXPR_LESS_OR_EQUAL
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
LocalSearchFilter * MakeUnaryDimensionFilter(Solver *solver, std::unique_ptr< UnaryDimensionChecker > checker)
--— RevPartialSequence --—
bool operator!=(Iterator other) const
void Start(const Assignment *assignment) override
This method should not be overridden.
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64 value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
@ EXPR_EXPR_IS_EQUAL
void SetOldInverseValue(int64 index, int64 value)
void SetForwardSequence(int64 index, const std::vector< int > &value)
VoidConstraintType
RevGrowingArray(int64 block_size)
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
const std::vector< int > & OldSequence(int64 index) const
int64 OldInverseValue(int64 index) const
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
@ EXPR_CONSTANT_MAX
bool IsCardinalityOne() const
Does it contains only one bit set?
const T * Last() const
Returns the last item of the FIFO.
void SetValue(int64 index, const Val &value)
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
virtual int64 GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
Low-priority demon proxy to a method on the constraint with one argument.
virtual void RemoveValue(IntVar *const var, int64 value)=0
void SynchronizeOnAssignment(const Assignment *assignment)
@ VOID_FALSE_CONSTRAINT
void Deactivate(int64 index)
int64 MaxVarArray(const std::vector< IntVar * > &vars)
std::vector< Val > old_values_
virtual int64 GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64 > *const values)
bool ReverseChain(int64 before_chain, int64 after_chain, int64 *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
Iterator(const SimpleRevFIFO< T > *l)
bool IsCardinalityZero() const
Is bitset null?
bool StateIsValid() const
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
This is the base class for all expressions that are not variables.
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
std::string DebugString() const override
void EndVisitModel(const std::string &solver_name) override
virtual void OnNodeInitialization()
Called by OnStart() after initializing node information.
Iterator end() const
~CallMethod0() override
void SetValue(int64 index, T value)
std::string DebugString() const override
~DelayedCallMethod1() override
~RevGrowingArray()
const Val & OldValue(int64 index) const
int64 BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual bool IsIncremental() const
~BooleanVar() override
std::vector< Val > prev_values_
@ EXPR_EXPR_DIFFERENCE
Demon proxy to a method on the constraint with no arguments.
RevPartialSequence(int size)
@ EXPR_EXPR_IS_LESS
Iterator begin() const
BooleanVar(Solver *const s, const std::string &name="")
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
const std::string & TypeName() const
Type of the argument.
int Size() const
bool IsArrayBoolean(const std::vector< T > &values)
int num_items() const
void Run(Solver *const s) override
bool FindIndex(IntVar *const var, int64 *index) const
virtual void InitFragments()
int number_of_nexts() const
Number of next variables.
void SetTypeName(const std::string &type_name)
std::string DebugString() const override
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
@ VAR_ARRAY_CONSTANT_EXPRESSION_MAX
@ VAR_CONSTANT_EQUALITY
~RevIntSet()
int End(int path) const
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64 value)
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
int64 GetAcceptedObjectiveValue() const override
Objective value from the last time Accept() was called and returned true.
int64 OldPrev(int64 node) const
int64 min
bool operator!=(Iterator other) const
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
std::vector< V * > vars_
virtual void SetMax(IntVar *const var, int64 new_max)=0
NodeRange(const ChainBounds *begin_chain, const ChainBounds *end_chain, const CommittedNode *first_node)
bool IsRanked(int elt) const
IntVarLocalSearchHandler(IntVarLocalSearchOperator *op)
@ VAR_CONSTANT_CONSTANT_EXPRESSION_MAX
bool AreAllNegative(const std::vector< T > &values)
std::string ParameterDebugString(P param)
virtual void RankNotLast(SequenceVar *const var, int index)=0
VarArrayConstantArrayExpressionType
@ VAR_ARRAY_SUM
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0