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 
78 namespace operations_research {
79 class CPArgumentProto;
80 class CPConstraintProto;
81 class CPIntegerExpressionProto;
82 class CPIntervalVariableProto;
83 
109 class BaseIntExpr : public IntExpr {
110  public:
111  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
112  ~BaseIntExpr() override {}
113 
114  IntVar* Var() override;
115  virtual IntVar* CastToVar();
116 
117  private:
118  IntVar* var_;
119 };
120 
123 enum VarTypes {
133 };
134 
143 #ifndef SWIG
144 template <class T>
145 class SimpleRevFIFO {
146  private:
147  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
148  struct Chunk {
149  T data_[CHUNK_SIZE];
150  const Chunk* const next_;
151  explicit Chunk(const Chunk* next) : next_(next) {}
152  };
153 
154  public:
156  class Iterator {
157  public:
158  explicit Iterator(const SimpleRevFIFO<T>* l)
159  : chunk_(l->chunks_), value_(l->Last()) {}
160  bool ok() const { return (value_ != nullptr); }
161  T operator*() const { return *value_; }
162  void operator++() {
163  ++value_;
164  if (value_ == chunk_->data_ + CHUNK_SIZE) {
165  chunk_ = chunk_->next_;
166  value_ = chunk_ ? chunk_->data_ : nullptr;
167  }
168  }
169 
170  private:
171  const Chunk* chunk_;
172  const T* value_;
173  };
174 
175  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
176 
177  void Push(Solver* const s, T val) {
178  if (pos_.Value() == 0) {
179  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
180  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
181  reinterpret_cast<void*>(chunk));
182  pos_.SetValue(s, CHUNK_SIZE - 1);
183  } else {
184  pos_.Decr(s);
185  }
186  chunks_->data_[pos_.Value()] = val;
187  }
188 
190  void PushIfNotTop(Solver* const s, T val) {
191  if (chunks_ == nullptr || LastValue() != val) {
192  Push(s, val);
193  }
194  }
195 
197  const T* Last() const {
198  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
199  }
200 
201  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
202 
204  const T& LastValue() const {
205  DCHECK(chunks_);
206  return chunks_->data_[pos_.Value()];
207  }
208 
210  void SetLastValue(const T& v) {
211  DCHECK(Last());
212  chunks_->data_[pos_.Value()] = v;
213  }
214 
215  private:
216  Chunk* chunks_;
217  NumericalRev<int> pos_;
218 };
219 
221 // TODO(user): use murmurhash.
222 inline uint64 Hash1(uint64 value) {
223  value = (~value) + (value << 21);
224  value ^= value >> 24;
225  value += (value << 3) + (value << 8);
226  value ^= value >> 14;
227  value += (value << 2) + (value << 4);
228  value ^= value >> 28;
229  value += (value << 31);
230  return value;
231 }
232 
233 inline uint64 Hash1(uint32 value) {
234  uint64 a = value;
235  a = (a + 0x7ed55d16) + (a << 12);
236  a = (a ^ 0xc761c23c) ^ (a >> 19);
237  a = (a + 0x165667b1) + (a << 5);
238  a = (a + 0xd3a2646c) ^ (a << 9);
239  a = (a + 0xfd7046c5) + (a << 3);
240  a = (a ^ 0xb55a4f09) ^ (a >> 16);
241  return a;
242 }
243 
244 inline uint64 Hash1(int64 value) { return Hash1(static_cast<uint64>(value)); }
245 
246 inline uint64 Hash1(int value) { return Hash1(static_cast<uint32>(value)); }
247 
248 inline uint64 Hash1(void* const ptr) {
249 #if defined(ARCH_K8) || defined(__powerpc64__) || defined(__aarch64__)
250  return Hash1(reinterpret_cast<uint64>(ptr));
251 #else
252  return Hash1(reinterpret_cast<uint32>(ptr));
253 #endif
254 }
255 
256 template <class T>
257 uint64 Hash1(const std::vector<T*>& ptrs) {
258  if (ptrs.empty()) {
259  return 0;
260  } else if (ptrs.size() == 1) {
261  return Hash1(ptrs[0]);
262  } else {
263  uint64 hash = Hash1(ptrs[0]);
264  for (int i = 1; i < ptrs.size(); ++i) {
265  hash = hash * i + Hash1(ptrs[i]);
266  }
267  return hash;
268  }
269 }
270 
271 inline uint64 Hash1(const std::vector<int64>& ptrs) {
272  if (ptrs.empty()) {
273  return 0;
274  } else if (ptrs.size() == 1) {
275  return Hash1(ptrs[0]);
276  } else {
277  uint64 hash = Hash1(ptrs[0]);
278  for (int i = 1; i < ptrs.size(); ++i) {
279  hash = hash * i + Hash1(ptrs[i]);
280  }
281  return hash;
282  }
283 }
284 
287 template <class K, class V>
289  public:
290  RevImmutableMultiMap(Solver* const solver, int initial_size)
291  : solver_(solver),
292  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
293  size_(initial_size),
294  num_items_(0) {
295  memset(array_, 0, sizeof(*array_) * size_.Value());
296  }
297 
299 
300  int num_items() const { return num_items_.Value(); }
301 
303  bool ContainsKey(const K& key) const {
304  uint64 code = Hash1(key) % size_.Value();
305  Cell* tmp = array_[code];
306  while (tmp) {
307  if (tmp->key() == key) {
308  return true;
309  }
310  tmp = tmp->next();
311  }
312  return false;
313  }
314 
318  const V& FindWithDefault(const K& key, const V& default_value) const {
319  uint64 code = Hash1(key) % size_.Value();
320  Cell* tmp = array_[code];
321  while (tmp) {
322  if (tmp->key() == key) {
323  return tmp->value();
324  }
325  tmp = tmp->next();
326  }
327  return default_value;
328  }
329 
331  void Insert(const K& key, const V& value) {
332  const int position = Hash1(key) % size_.Value();
333  Cell* const cell =
334  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
335  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
336  reinterpret_cast<void*>(cell));
337  num_items_.Incr(solver_);
338  if (num_items_.Value() > 2 * size_.Value()) {
339  Double();
340  }
341  }
342 
343  private:
344  class Cell {
345  public:
346  Cell(const K& key, const V& value, Cell* const next)
347  : key_(key), value_(value), next_(next) {}
348 
349  void SetRevNext(Solver* const solver, Cell* const next) {
350  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
351  reinterpret_cast<void*>(next));
352  }
353 
354  Cell* next() const { return next_; }
355 
356  const K& key() const { return key_; }
357 
358  const V& value() const { return value_; }
359 
360  private:
361  const K key_;
362  const V value_;
363  Cell* next_;
364  };
365 
366  void Double() {
367  Cell** const old_cell_array = array_;
368  const int old_size = size_.Value();
369  size_.SetValue(solver_, size_.Value() * 2);
370  solver_->SaveAndSetValue(
371  reinterpret_cast<void**>(&array_),
372  reinterpret_cast<void*>(
373  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
374  memset(array_, 0, size_.Value() * sizeof(*array_));
375  for (int i = 0; i < old_size; ++i) {
376  Cell* tmp = old_cell_array[i];
377  while (tmp != nullptr) {
378  Cell* const to_reinsert = tmp;
379  tmp = tmp->next();
380  const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value();
381  to_reinsert->SetRevNext(solver_, array_[new_position]);
382  solver_->SaveAndSetValue(
383  reinterpret_cast<void**>(&array_[new_position]),
384  reinterpret_cast<void*>(to_reinsert));
385  }
386  }
387  }
388 
389  Solver* const solver_;
390  Cell** array_;
391  NumericalRev<int> size_;
392  NumericalRev<int> num_items_;
393 };
394 
396 class RevSwitch {
397  public:
398  RevSwitch() : value_(false) {}
399 
400  bool Switched() const { return value_; }
401 
402  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
403 
404  private:
405  bool value_;
406 };
407 
411  public:
412  explicit SmallRevBitSet(int64 size);
414  void SetToOne(Solver* const solver, int64 pos);
416  void SetToZero(Solver* const solver, int64 pos);
418  int64 Cardinality() const;
420  bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); }
422  bool IsCardinalityOne() const {
423  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
424  }
427  int64 GetFirstOne() const;
428 
429  private:
430  Rev<uint64> bits_;
431 };
432 
435 class RevBitSet {
436  public:
437  explicit RevBitSet(int64 size);
438  ~RevBitSet();
439 
441  void SetToOne(Solver* const solver, int64 index);
443  void SetToZero(Solver* const solver, int64 index);
445  bool IsSet(int64 index) const;
447  int64 Cardinality() const;
449  bool IsCardinalityZero() const;
451  bool IsCardinalityOne() const;
454  int64 GetFirstBit(int start) const;
456  void ClearAll(Solver* const solver);
457 
458  friend class RevBitMatrix;
459 
460  private:
462  void Save(Solver* const solver, int offset);
463  const int64 size_;
464  const int64 length_;
465  uint64* bits_;
466  uint64* stamps_;
467 };
468 
470 class RevBitMatrix : private RevBitSet {
471  public:
472  RevBitMatrix(int64 rows, int64 columns);
473  ~RevBitMatrix();
474 
476  void SetToOne(Solver* const solver, int64 row, int64 column);
478  void SetToZero(Solver* const solver, int64 row, int64 column);
480  bool IsSet(int64 row, int64 column) const {
481  DCHECK_GE(row, 0);
482  DCHECK_LT(row, rows_);
483  DCHECK_GE(column, 0);
484  DCHECK_LT(column, columns_);
485  return RevBitSet::IsSet(row * columns_ + column);
486  }
488  int64 Cardinality(int row) const;
490  bool IsCardinalityZero(int row) const;
492  bool IsCardinalityOne(int row) const;
495  int64 GetFirstBit(int row, int start) const;
497  void ClearAll(Solver* const solver);
498 
499  private:
500  const int64 rows_;
501  const int64 columns_;
502 };
503 
509 
511 template <class T>
512 class CallMethod0 : public Demon {
513  public:
514  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
515  : constraint_(ct), method_(method), name_(name) {}
516 
517  ~CallMethod0() override {}
518 
519  void Run(Solver* const s) override { (constraint_->*method_)(); }
520 
521  std::string DebugString() const override {
522  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
523  }
524 
525  private:
526  T* const constraint_;
527  void (T::*const method_)();
528  const std::string name_;
529 };
530 
531 template <class T>
532 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
533  const std::string& name) {
534  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
535 }
536 
537 template <class P>
538 std::string ParameterDebugString(P param) {
539  return absl::StrCat(param);
540 }
541 
543 template <class P>
544 std::string ParameterDebugString(P* param) {
545  return param->DebugString();
546 }
547 
549 template <class T, class P>
550 class CallMethod1 : public Demon {
551  public:
552  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
553  P param1)
554  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
555 
556  ~CallMethod1() override {}
557 
558  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
559 
560  std::string DebugString() const override {
561  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
562  ", ", ParameterDebugString(param1_), ")");
563  }
564 
565  private:
566  T* const constraint_;
567  void (T::*const method_)(P);
568  const std::string name_;
569  P param1_;
570 };
571 
572 template <class T, class P>
573 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
574  const std::string& name, P param1) {
575  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
576 }
577 
579 template <class T, class P, class Q>
580 class CallMethod2 : public Demon {
581  public:
582  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
583  P param1, Q param2)
584  : constraint_(ct),
585  method_(method),
586  name_(name),
587  param1_(param1),
588  param2_(param2) {}
589 
590  ~CallMethod2() override {}
591 
592  void Run(Solver* const s) override {
593  (constraint_->*method_)(param1_, param2_);
594  }
595 
596  std::string DebugString() const override {
597  return absl::StrCat(absl::StrCat("CallMethod_", name_),
598  absl::StrCat("(", constraint_->DebugString()),
599  absl::StrCat(", ", ParameterDebugString(param1_)),
600  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
601  }
602 
603  private:
604  T* const constraint_;
605  void (T::*const method_)(P, Q);
606  const std::string name_;
607  P param1_;
608  Q param2_;
609 };
610 
611 template <class T, class P, class Q>
612 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
613  void (T::*method)(P, Q), const std::string& name,
614  P param1, Q param2) {
615  return s->RevAlloc(
616  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
617 }
619 template <class T, class P, class Q, class R>
620 class CallMethod3 : public Demon {
621  public:
622  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
623  P param1, Q param2, R param3)
624  : constraint_(ct),
625  method_(method),
626  name_(name),
627  param1_(param1),
628  param2_(param2),
629  param3_(param3) {}
630 
631  ~CallMethod3() override {}
632 
633  void Run(Solver* const s) override {
634  (constraint_->*method_)(param1_, param2_, param3_);
635  }
636 
637  std::string DebugString() const override {
638  return absl::StrCat(absl::StrCat("CallMethod_", name_),
639  absl::StrCat("(", constraint_->DebugString()),
640  absl::StrCat(", ", ParameterDebugString(param1_)),
641  absl::StrCat(", ", ParameterDebugString(param2_)),
642  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
643  }
644 
645  private:
646  T* const constraint_;
647  void (T::*const method_)(P, Q, R);
648  const std::string name_;
649  P param1_;
650  Q param2_;
651  R param3_;
652 };
653 
654 template <class T, class P, class Q, class R>
655 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
656  void (T::*method)(P, Q, R), const std::string& name,
657  P param1, Q param2, R param3) {
658  return s->RevAlloc(
659  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
660 }
662 
667 
669 template <class T>
670 class DelayedCallMethod0 : public Demon {
671  public:
672  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
673  : constraint_(ct), method_(method), name_(name) {}
674 
675  ~DelayedCallMethod0() override {}
676 
677  void Run(Solver* const s) override { (constraint_->*method_)(); }
678 
679  Solver::DemonPriority priority() const override {
681  }
682 
683  std::string DebugString() const override {
684  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
685  ")";
686  }
687 
688  private:
689  T* const constraint_;
690  void (T::*const method_)();
691  const std::string name_;
692 };
693 
694 template <class T>
695 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
696  void (T::*method)(),
697  const std::string& name) {
698  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
699 }
700 
702 template <class T, class P>
703 class DelayedCallMethod1 : public Demon {
704  public:
705  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
706  P param1)
707  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
708 
709  ~DelayedCallMethod1() override {}
710 
711  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
712 
713  Solver::DemonPriority priority() const override {
715  }
716 
717  std::string DebugString() const override {
718  return absl::StrCat("DelayedCallMethod_", name_, "(",
719  constraint_->DebugString(), ", ",
720  ParameterDebugString(param1_), ")");
721  }
722 
723  private:
724  T* const constraint_;
725  void (T::*const method_)(P);
726  const std::string name_;
727  P param1_;
728 };
729 
730 template <class T, class P>
731 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
732  void (T::*method)(P),
733  const std::string& name, P param1) {
734  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
735 }
736 
738 template <class T, class P, class Q>
739 class DelayedCallMethod2 : public Demon {
740  public:
741  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
742  const std::string& name, P param1, Q param2)
743  : constraint_(ct),
744  method_(method),
745  name_(name),
746  param1_(param1),
747  param2_(param2) {}
748 
749  ~DelayedCallMethod2() override {}
750 
751  void Run(Solver* const s) override {
752  (constraint_->*method_)(param1_, param2_);
753  }
754 
755  Solver::DemonPriority priority() const override {
757  }
758 
759  std::string DebugString() const override {
760  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
761  absl::StrCat("(", constraint_->DebugString()),
762  absl::StrCat(", ", ParameterDebugString(param1_)),
763  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
764  }
765 
766  private:
767  T* const constraint_;
768  void (T::*const method_)(P, Q);
769  const std::string name_;
770  P param1_;
771  Q param2_;
772 };
773 
774 template <class T, class P, class Q>
775 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
776  void (T::*method)(P, Q),
777  const std::string& name, P param1,
778  Q param2) {
779  return s->RevAlloc(
780  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
781 }
783 
784 #endif // !defined(SWIG)
785 
803 // TODO(user): rename Start to Synchronize ?
804 // TODO(user): decouple the iterating from the defining of a neighbor.
806  public:
808  ~LocalSearchOperator() override {}
809  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
810  virtual void Start(const Assignment* assignment) = 0;
811  virtual void Reset() {}
812 #ifndef SWIG
813  virtual const LocalSearchOperator* Self() const { return this; }
814 #endif // SWIG
815  virtual bool HasFragments() const { return false; }
816  virtual bool HoldsDelta() const { return false; }
817 };
818 
820 template <class V, class Val, class Handler>
822  public:
824  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>
1618 LocalSearchOperator* MakeLocalSearchOperator(
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 
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);
1798  ~IntVarLocalSearchFilter() override;
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 
1836  public:
1837  explicit PropagationMonitor(Solver* const solver);
1838  ~PropagationMonitor() override;
1839  std::string DebugString() const override { return "PropagationMonitor"; }
1840 
1842  virtual void BeginConstraintInitialPropagation(
1843  Constraint* const constraint) = 0;
1844  virtual void EndConstraintInitialPropagation(
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 
1900  // TODO(user): Add monitoring of local search filters.
1901  public:
1902  explicit LocalSearchMonitor(Solver* const solver);
1903  ~LocalSearchMonitor() override;
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;
1910  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
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 = "")
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 
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;
2021  void OutputDecision();
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 
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 
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 
2205  IntExpr* const expr, int64 value,
2206  ExprConstantExpressionType type) const = 0;
2207 
2208  virtual void InsertExprConstantExpression(
2209  IntExpr* const expression, IntExpr* const var, int64 value,
2210  ExprConstantExpressionType type) = 0;
2211 
2213 
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 
2229  virtual void InsertExprExprConstantExpression(
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 
2249  virtual void InsertVarConstantArrayExpression(
2250  IntExpr* const expression, IntVar* const var,
2251  const std::vector<int64>& values,
2253 
2255 
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 
2280  virtual void InsertVarArrayConstantExpression(
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;
2325  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
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:
2352  ModelParser();
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:
2402  void PushArgumentHolder();
2403  void PopArgumentHolder();
2404  ArgumentHolder* Top() const;
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:
2760  explicit UnsortedNullableRevBitset(int bit_size);
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 } // namespace operations_research
2995 
2996 #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
IsEqual.
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
@ VAR_CONSTANT_LESS_OR_EQUAL
bool Contains(int64 v) const override
This method returns whether the value 'v' is in the domain of the variable.
int next_base_to_increment_
const IntContainer & IntVarContainer() const
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
This method returns the priority of the demon.
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
After the initial propagation.
bool AreAllBooleans(const std::vector< IntVar * > &vars)
This class is a reversible growing array.
~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.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
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)
A BaseObject is the root of all reversibly allocated objects.
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)
The class Iterator has two direct subclasses.
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
This method attaches a demon that will watch any domain modification of the domain of the variable.
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
Returns a base name for automatic naming.
@ 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
This is the main callback of the demon.
@ CST_SUB_VAR
bool IsIncremental() const override
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
int Size() const
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.
~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.
void Incr(Solver *const s)
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 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
This method returns the priority of the demon.
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
void SetValue(int64 v)
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.
const E & Element(const V *const var) const
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.
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
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.
@ 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
This method is called when a valid solution is found.
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
This method returns the value of the variable.
~DelayedCallMethod0() override
void Insert(Solver *const solver, const T &elt)
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
void AppendToFragment(int index)
void BeginFail() override
Just when the failure occurs.
friend class RevBitMatrix
~VarLocalSearchOperator() override
bool ok() const
void Run(Solver *const s) override
This is the main callback of the demon.
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
Before refuting the decision.
Base operator class for operators manipulating variables.
static const int kNoInserted
~LocalSearchOperator() override
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.
~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
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
VarConstantConstantExpressionType
@ VAR_ARRAY_MAX
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
void NoMoreSolutions() override
When the search tree is finished.
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
Creates a domain iterator.
virtual void SetValue(IntVar *const var, int64 value)=0
std::vector< int > assignment_indices_
RevSwitch()
@ BOOLEAN_VAR
The class IntVar is a subset of IntExpr.
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
bool Contains(const V *const var) const
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 std::string name() const
Object naming.
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
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
A Decision represents a choice point in the search tree.
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
int index() const
Returns the index of the variable.
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
This method attaches a demon that will be awakened when the variable is bound.
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
void Run(Solver *const s) override
This is the main callback of the demon.
void BeginInitialPropagation() override
Before the initial propagation.
VarLocalSearchOperator(Handler var_handler)
const T & Value() const
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
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
This method removes the value 'v' from the domain of the variable.
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.
void SetValue(Solver *const s, const T &val)
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
@ 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.
void Activate()
ModelParser()
@ VAR_CONSTANT_CONSTRAINT_MAX
void Run(Solver *const s) override
This is the main callback of the demon.
IntVar * Var() override
Creates a variable from the expression.
@ EXPR_EXPR_GREATER
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.
@ 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
This method returns the number of values in the domain of the variable.
virtual int64 ModifyValue(int64 index, int64 value)=0
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
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 Activated() 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
IntContainer * MutableIntVarContainer()
void Clear()
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()
virtual void RankLast(SequenceVar *const var, int index)=0
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
The class IntExpr is the base of all integer expressions in constraint programming.
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
End of the search.
int Size() const
void RemoveInterval(int64 l, int64 u) override
This method removes the interval 'l' .
std::string DebugString() const override
@ 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 ...
Model visitor.
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
A search monitor is a simple set of callbacks to monitor all search events.
int value_
void SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
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)
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...
LocalSearchMonitor(Solver *const solver)
void Run(Solver *const s) override
This is the main callback of the demon.
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
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
const_iterator begin() const
SimpleRevFIFO< Demon * > bound_demons_
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
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
Attach a demon that will watch the min or the max of the expression.
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
virtual void BeginOperatorStart()=0
Local search operator events.
int64 OldPath(int64 node) const
A constraint is the main modeling object.
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
virtual ~ModelCache()
void EnterSearch() override
Beginning of the search.
int64 Prev(int64 node) const
Returns the node before node in the current delta.
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
bool AreAllBound(const std::vector< IntVar * > &vars)
const typedef T * const_iterator
Iterators on the indices.
int Size() 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.
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)
T * RevAlloc(T *object)
Registers the given object as being reversible.
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.
const SequenceContainer & SequenceVarContainer() const
SequenceVar * Var() const
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.
int64 size() const
Returns the number of interval vars in the sequence.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
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)
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.
@ 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.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
void SetForwardSequence(const std::vector< int > &forward_sequence)
IntVar * IsLessOrEqual(int64 constant) override
bool Switched() const
void SetRange(int64 mi, int64 ma) override
This method sets both the min and the max of the expression.
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
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
This is the main callback of the demon.
@ 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.
This class encapsulates an objective.
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.
Solver Class.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
void Deactivate()
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
Solver * solver() const
@ 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 Commit()
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
void SetMax(int64 m) override
std::string DebugString() const override
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.
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
void Install() override
Install itself on the solver.
Demon proxy to a method on the constraint with three arguments.
int64 Next(int64 node) const
Returns the node after node in the current delta.
E * MutableElement(const V *const var)
@ EXPR_EXPR_LESS_OR_EQUAL
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
const std::vector< int > & ForwardSequence() const
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
--— RevPartialSequence --—
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)
int64 Value() const
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_
A Demon is the base element of a propagation queue.
virtual int64 GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
void Decr(Solver *const s)
Interval variables are often used in scheduling.
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.
~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
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
std::vector< Val > prev_values_
@ EXPR_EXPR_DIFFERENCE
void SetBackwardSequence(const std::vector< int > &backward_sequence)
Demon proxy to a method on the constraint with no arguments.
RevPartialSequence(int size)
@ EXPR_EXPR_IS_LESS
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
This is the main callback of the demon.
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)
A DecisionVisitor is used to inspect a decision.
std::string DebugString() const override
@ VAR_ARRAY_CONSTANT_EXPRESSION_MAX
@ VAR_CONSTANT_EQUALITY
~RevIntSet()
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
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
SequenceContainer * MutableSequenceVarContainer()
std::vector< V * > vars_
bool IsRanked(int elt) const
IntVar * Var() 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