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  VarLocalSearchOperator(std::vector<V*> vars, 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_.ValueFromAssignent(*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);
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  public:
953  void AddToAssignment(IntVar* var, int64 value, bool active,
954  std::vector<int>* assignment_indices, int64 index,
955  Assignment* assignment) const {
956  Assignment::IntContainer* const container =
957  assignment->MutableIntVarContainer();
958  IntVarElement* element = nullptr;
959  if (assignment_indices != nullptr) {
960  if ((*assignment_indices)[index] == -1) {
961  (*assignment_indices)[index] = container->Size();
962  element = assignment->FastAdd(var);
963  } else {
964  element = container->MutableElement((*assignment_indices)[index]);
965  }
966  } else {
967  element = assignment->FastAdd(var);
968  }
969  if (active) {
970  element->SetValue(value);
971  element->Activate();
972  } else {
973  element->Deactivate();
974  }
975  }
976  bool ValueFromAssignent(const Assignment& assignment, IntVar* var,
977  int64 index, int64* value) {
978  const Assignment::IntContainer& container = assignment.IntVarContainer();
979  const IntVarElement* element = &(container.Element(index));
980  if (element->Var() != var) {
981  CHECK(container.Contains(var))
982  << "Assignment does not contain operator variable " << var;
983  element = &(container.Element(var));
984  }
985  *value = element->Value();
986  return element->Activated();
987  }
988  void OnRevertChanges(int64 index) {}
989  void OnAddVars() {}
990 };
991 
997 
998 #ifdef SWIG
999 // TODO(user): find a way to move this code back to the .i file, where it
1006 #if defined(SWIGPYTHON)
1007 %unignore VarLocalSearchOperator<IntVar, int64,
1008  IntVarLocalSearchHandler>::Size;
1009 %unignore VarLocalSearchOperator<IntVar, int64,
1010  IntVarLocalSearchHandler>::Value;
1011 %unignore VarLocalSearchOperator<IntVar, int64,
1012  IntVarLocalSearchHandler>::OldValue;
1013 %unignore VarLocalSearchOperator<IntVar, int64,
1014  IntVarLocalSearchHandler>::SetValue;
1015 %feature("director") VarLocalSearchOperator<IntVar, int64,
1016  IntVarLocalSearchHandler>::IsIncremental;
1017 %feature("director") VarLocalSearchOperator<IntVar, int64,
1018  IntVarLocalSearchHandler>::OnStart;
1019 %unignore VarLocalSearchOperator<IntVar, int64,
1020  IntVarLocalSearchHandler>::IsIncremental;
1021 %unignore VarLocalSearchOperator<IntVar, int64,
1022  IntVarLocalSearchHandler>::OnStart;
1023 #endif // SWIGPYTHON
1024 
1025 // clang-format off
1026 %rename(IntVarLocalSearchOperatorTemplate)
1027  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1028 %template(IntVarLocalSearchOperatorTemplate)
1029  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1030 // clang-format on
1031 #endif // SWIG
1032 
1035  public:
1037  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars)
1039  vars, IntVarLocalSearchHandler()) {
1040  AddVars(vars);
1041  }
1049  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1050 
1051  protected:
1054  // TODO(user): make it pure virtual, implies porting all apps overriding
1056  virtual bool MakeOneNeighbor();
1057 };
1058 
1060 class SequenceVarLocalSearchOperator;
1061 
1063  public:
1064  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1066  : op_(other.op_) {}
1068  : op_(op) {}
1069  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1070  bool active, std::vector<int>* assignment_indices,
1071  int64 index, Assignment* assignment) const;
1072  bool ValueFromAssignent(const Assignment& assignment, SequenceVar* var,
1073  int64 index, std::vector<int>* value);
1074  void OnRevertChanges(int64 index);
1075  void OnAddVars();
1076 
1077  private:
1078  SequenceVarLocalSearchOperator* const op_;
1079 };
1080 
1081 #ifdef SWIG
1082 // TODO(user): find a way to move this code back to the .i file, where it
1087 // clang-format off
1088 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1089  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1090 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1091  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1092 // clang-format on
1093 #endif
1094 
1095 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1096  SequenceVarLocalSearchHandler>
1098 
1101  public:
1103  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1105  vars, SequenceVarLocalSearchHandler(this)) {
1106  AddVars(vars);
1107  }
1111  const std::vector<int>& Sequence(int64 index) const { return Value(index); }
1112  const std::vector<int>& OldSequence(int64 index) const {
1113  return OldValue(index);
1114  }
1115  void SetForwardSequence(int64 index, const std::vector<int>& value) {
1116  SetValue(index, value);
1117  }
1118  void SetBackwardSequence(int64 index, const std::vector<int>& value) {
1119  backward_values_[index] = value;
1120  MarkChange(index);
1121  }
1122 
1123  protected:
1125 
1126  std::vector<std::vector<int>> backward_values_;
1127 };
1128 
1130  SequenceVar* var, const std::vector<int>& value, bool active,
1131  std::vector<int>* assignment_indices, int64 index,
1132  Assignment* assignment) const {
1133  Assignment::SequenceContainer* const container =
1134  assignment->MutableSequenceVarContainer();
1135  SequenceVarElement* element = nullptr;
1136  if (assignment_indices != nullptr) {
1137  if ((*assignment_indices)[index] == -1) {
1138  (*assignment_indices)[index] = container->Size();
1139  element = assignment->FastAdd(var);
1140  } else {
1141  element = container->MutableElement((*assignment_indices)[index]);
1142  }
1143  } else {
1144  element = assignment->FastAdd(var);
1145  }
1146  if (active) {
1147  element->SetForwardSequence(value);
1148  element->SetBackwardSequence(op_->backward_values_[index]);
1149  element->Activate();
1150  } else {
1151  element->Deactivate();
1152  }
1153 }
1154 
1156  const Assignment& assignment, SequenceVar* var, int64 index,
1157  std::vector<int>* value) {
1158  const Assignment::SequenceContainer& container =
1159  assignment.SequenceVarContainer();
1160  const SequenceVarElement* element = &(container.Element(index));
1161  if (element->Var() != var) {
1162  CHECK(container.Contains(var))
1163  << "Assignment does not contain operator variable " << var;
1164  element = &(container.Element(var));
1165  }
1166  const std::vector<int>& element_value = element->ForwardSequence();
1167  CHECK_GE(var->size(), element_value.size());
1168  op_->backward_values_[index].clear();
1169  *value = element_value;
1170  return element->Activated();
1171 }
1172 
1174  op_->backward_values_[index].clear();
1175 }
1176 
1178  op_->backward_values_.resize(op_->Size());
1179 }
1180 
1209  public:
1210  explicit BaseLns(const std::vector<IntVar*>& vars);
1211  ~BaseLns() override;
1212  virtual void InitFragments();
1213  virtual bool NextFragment() = 0;
1214  void AppendToFragment(int index);
1215  int FragmentSize() const;
1216  bool HasFragments() const override { return true; }
1217 
1218  protected:
1220  bool MakeOneNeighbor() override;
1221 
1222  private:
1224  void OnStart() override;
1225  std::vector<int> fragment_;
1226 };
1227 
1233  public:
1234  explicit ChangeValue(const std::vector<IntVar*>& vars);
1235  ~ChangeValue() override;
1236  virtual int64 ModifyValue(int64 index, int64 value) = 0;
1237 
1238  protected:
1240  bool MakeOneNeighbor() override;
1241 
1242  private:
1243  void OnStart() override;
1244 
1245  int index_;
1246 };
1247 
1262  public:
1276  PathOperator(const std::vector<IntVar*>& next_vars,
1277  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1278  bool skip_locally_optimal_paths,
1279  std::function<int(int64)> start_empty_path_class);
1280  ~PathOperator() override {}
1281  virtual bool MakeNeighbor() = 0;
1282  void Reset() override;
1283 
1284  // TODO(user): Make the following methods protected.
1285  bool SkipUnchanged(int index) const override;
1286 
1288  int64 Next(int64 node) const {
1289  DCHECK(!IsPathEnd(node));
1290  return Value(node);
1291  }
1292 
1295  int64 Path(int64 node) const {
1296  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1297  }
1298 
1300  int number_of_nexts() const { return number_of_nexts_; }
1301 
1302  protected:
1304  bool MakeOneNeighbor() override;
1305 
1307  int64 BaseNode(int i) const { return base_nodes_[i]; }
1309  int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1311  const std::vector<int64>& path_starts() const { return path_starts_; }
1313  int PathClass(int i) const {
1314  return start_empty_path_class_ != nullptr
1315  ? start_empty_path_class_(StartNode(i))
1316  : StartNode(i);
1317  }
1318 
1325  // TODO(user): remove this when automatic detection of such cases in done.
1326  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1330  // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2);
1332  virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; }
1338  virtual int64 GetBaseNodeRestartPosition(int base_index) {
1339  return StartNode(base_index);
1340  }
1343  virtual void SetNextBaseToIncrement(int64 base_index) {
1344  next_base_to_increment_ = base_index;
1345  }
1346 
1347  int64 OldNext(int64 node) const {
1348  DCHECK(!IsPathEnd(node));
1349  return OldValue(node);
1350  }
1351 
1352  int64 OldPath(int64 node) const {
1353  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1354  }
1355 
1358  bool MoveChain(int64 before_chain, int64 chain_end, int64 destination);
1359 
1362  bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last);
1363 
1365  bool MakeActive(int64 node, int64 destination);
1368  bool MakeChainInactive(int64 before_chain, int64 chain_end);
1369 
1371  void SetNext(int64 from, int64 to, int64 path) {
1372  DCHECK_LT(from, number_of_nexts_);
1373  SetValue(from, to);
1374  if (!ignore_path_vars_) {
1375  DCHECK_LT(from + number_of_nexts_, Size());
1376  SetValue(from + number_of_nexts_, path);
1377  }
1378  }
1379 
1382  bool IsPathEnd(int64 node) const { return node >= number_of_nexts_; }
1383 
1385  bool IsInactive(int64 node) const {
1386  return !IsPathEnd(node) && inactives_[node];
1387  }
1388 
1391  virtual bool InitPosition() const { return false; }
1395  void ResetPosition() { just_started_ = true; }
1396 
1400  int AddAlternativeSet(const std::vector<int64>& alternative_set) {
1401  const int alternative = alternative_sets_.size();
1402  for (int64 node : alternative_set) {
1403  DCHECK_EQ(-1, alternative_index_[node]);
1404  alternative_index_[node] = alternative;
1405  }
1406  alternative_sets_.push_back(alternative_set);
1407  sibling_alternative_.push_back(-1);
1408  return alternative;
1409  }
1410 #ifndef SWIG
1414  const std::vector<std::pair<std::vector<int64>, std::vector<int64>>>&
1415  pair_alternative_sets) {
1416  for (const auto& pair_alternative_set : pair_alternative_sets) {
1417  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1418  sibling_alternative_.back() = alternative + 1;
1419  AddAlternativeSet(pair_alternative_set.second);
1420  }
1421  }
1422 #endif // SWIG
1423  int64 GetActiveInAlternativeSet(int alternative_index) const {
1425  return alternative_index >= 0
1426  ? active_in_alternative_set_[alternative_index]
1427  : -1;
1428  }
1430  int64 GetActiveAlternativeNode(int node) const {
1431  return GetActiveInAlternativeSet(alternative_index_[node]);
1432  }
1435  int64 GetActiveAlternativeSibling(int node) const {
1436  if (node >= alternative_index_.size()) return -1;
1437  const int alternative = alternative_index_[node];
1438  const int sibling_alternative =
1439  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1440  return GetActiveInAlternativeSet(sibling_alternative);
1441  }
1442 
1443  const int number_of_nexts_;
1444  const bool ignore_path_vars_;
1446  int num_paths_ = 0;
1447  std::vector<int64> start_to_path_;
1448 
1449  private:
1450  void OnStart() override;
1454  virtual void OnNodeInitialization() {}
1456  bool OnSamePath(int64 node1, int64 node2) const;
1457 
1458  bool CheckEnds() const {
1459  const int base_node_size = base_nodes_.size();
1460  for (int i = base_node_size - 1; i >= 0; --i) {
1461  if (base_nodes_[i] != end_nodes_[i]) {
1462  return true;
1463  }
1464  }
1465  return false;
1466  }
1467  bool IncrementPosition();
1468  void InitializePathStarts();
1469  void InitializeInactives();
1470  void InitializeBaseNodes();
1471  void InitializeAlternatives();
1472  bool CheckChainValidity(int64 before_chain, int64 chain_end,
1473  int64 exclude) const;
1474  void Synchronize();
1475 
1476  std::vector<int> base_nodes_;
1477  std::vector<int> end_nodes_;
1478  std::vector<int> base_paths_;
1479  std::vector<int64> path_starts_;
1480  std::vector<bool> inactives_;
1481  bool just_started_;
1482  bool first_start_;
1483  std::function<int(int64)> start_empty_path_class_;
1484  bool skip_locally_optimal_paths_;
1485  bool optimal_paths_enabled_;
1486  std::vector<int> path_basis_;
1487  std::vector<bool> optimal_paths_;
1489 #ifndef SWIG
1490  std::vector<std::vector<int64>> alternative_sets_;
1491 #endif // SWIG
1492  std::vector<int> alternative_index_;
1493  std::vector<int64> active_in_alternative_set_;
1494  std::vector<int> sibling_alternative_;
1495 };
1496 
1500  public:
1502  const std::vector<IntVar*>& vars,
1503  const std::vector<IntVar*>& secondary_vars, int number_of_base_nodes,
1504  std::function<int(int64)> start_empty_path_class);
1506 
1507  bool IsPathStart(int64 node) const { return prevs_[node] == -1; }
1508 
1509  int64 Prev(int64 node) const {
1510  DCHECK(!IsPathStart(node));
1511  return prevs_[node];
1512  }
1513 
1514  std::string DebugString() const override {
1515  return "PathWithPreviousNodesOperator";
1516  }
1517 
1518  protected:
1519  void OnNodeInitialization() override;
1520 
1521  private:
1522  std::vector<int64> prevs_;
1523 };
1524 
1526 template <class T>
1527 LocalSearchOperator* MakeLocalSearchOperator(
1528  Solver* solver, const std::vector<IntVar*>& vars,
1529  const std::vector<IntVar*>& secondary_vars,
1530  std::function<int(int64)> start_empty_path_class);
1531 
1534 class TwoOpt;
1535 class Relocate;
1536 class Exchange;
1537 class Cross;
1538 class MakeActiveOperator;
1539 class MakeInactiveOperator;
1540 class MakeChainInactiveOperator;
1541 class SwapActiveOperator;
1542 class ExtendedSwapActiveOperator;
1543 class MakeActiveAndRelocate;
1544 class RelocateAndMakeActiveOperator;
1545 class RelocateAndMakeInactiveOperator;
1546 
1547 #if !defined(SWIG)
1548 // A LocalSearchState is a container for variables with bounds that can be
1549 // relaxed and tightened, saved and restored. It represents the solution state
1550 // of a local search engine, and allows it to go from solution to solution by
1551 // relaxing some variables to form a new subproblem, then tightening those
1552 // variables to move to a new solution representation. That state may be saved
1553 // to an internal copy, or reverted to the last saved internal copy.
1554 // Relaxing a variable returns its bounds to their initial state.
1555 // Tightening a variable's bounds may make its min larger than its max,
1556 // in that case, the tightening function will return false, and the state will
1557 // be marked as invalid. No other operations than Revert() can be called on an
1558 // invalid state: in particular, an invalid state cannot be saved.
1559 class LocalSearchVariable;
1561  public:
1562  LocalSearchVariable AddVariable(int64 initial_min, int64 initial_max);
1563  void Commit();
1564  void Revert();
1565  bool StateIsValid() const { return state_is_valid_; }
1566 
1567  private:
1568  friend class LocalSearchVariable;
1569 
1570  struct Bounds {
1571  int64 min;
1572  int64 max;
1573  };
1574 
1575  void RelaxVariableBounds(int variable_index);
1576  bool TightenVariableMin(int variable_index, int64 value);
1577  bool TightenVariableMax(int variable_index, int64 value);
1578  int64 VariableMin(int variable_index) const;
1579  int64 VariableMax(int variable_index) const;
1580 
1581  std::vector<Bounds> initial_variable_bounds_;
1582  std::vector<Bounds> variable_bounds_;
1583  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1584  std::vector<bool> variable_is_relaxed_;
1585  bool state_is_valid_ = true;
1586 };
1587 
1588 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1589 // meant to be passed by copy. If at some point the duplication of
1590 // LocalSearchState pointers is too expensive, we could switch to index only,
1591 // and the user would have to know the relevant state. The present setup allows
1592 // to ensure that variable users will not misuse the state.
1594  public:
1595  int64 Min() const { return state_->VariableMin(variable_index_); }
1596  int64 Max() const { return state_->VariableMax(variable_index_); }
1597  bool SetMin(int64 new_min) {
1598  return state_->TightenVariableMin(variable_index_, new_min);
1599  }
1600  bool SetMax(int64 new_max) {
1601  return state_->TightenVariableMax(variable_index_, new_max);
1602  }
1603  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1604 
1605  private:
1606  // Only LocalSearchState can construct LocalSearchVariables.
1607  friend class LocalSearchState;
1608 
1609  LocalSearchVariable(LocalSearchState* state, int variable_index)
1610  : state_(state), variable_index_(variable_index) {}
1611 
1612  LocalSearchState* const state_;
1613  const int variable_index_;
1614 };
1615 #endif // !defined(SWIG)
1616 
1634  public:
1637  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1638 
1648  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1649  int64 objective_min, int64 objective_max) = 0;
1650  virtual bool IsIncremental() const { return false; }
1651 
1657  virtual void Synchronize(const Assignment* assignment,
1658  const Assignment* delta) = 0;
1660  virtual void Revert() {}
1661 
1663  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1665  // If the last Accept() call returned false, returns an undefined value.
1666  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1667 };
1668 
1669 #if !defined(SWIG)
1670 class LocalSearchFilterManager : public LocalSearchFilter {
1674  public:
1675  LocalSearchFilterManager(Solver* const solver,
1676  const std::vector<LocalSearchFilter*>& filters);
1677  std::string DebugString() const override {
1678  return "LocalSearchFilterManager";
1679  }
1680  void Relax(const Assignment* delta, const Assignment* deltadelta) override;
1681  void Revert() override;
1684  bool Accept(const Assignment* delta, const Assignment* deltadelta,
1685  int64 objective_min, int64 objective_max) override;
1687  void Synchronize(const Assignment* assignment,
1688  const Assignment* delta) override;
1689  bool IsIncremental() const override { return is_incremental_; }
1690  int64 GetSynchronizedObjectiveValue() const override {
1691  return synchronized_value_;
1692  }
1693  int64 GetAcceptedObjectiveValue() const override { return accepted_value_; }
1694 
1695  private:
1696  Solver* const solver_;
1697  std::vector<LocalSearchFilter*> filters_;
1698  bool is_incremental_;
1699  int64 synchronized_value_;
1700  int64 accepted_value_;
1701 };
1702 #endif
1703 
1705  public:
1706  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1707  ~IntVarLocalSearchFilter() override;
1710  void Synchronize(const Assignment* assignment,
1711  const Assignment* delta) override;
1712 
1713  bool FindIndex(IntVar* const var, int64* index) const {
1714  DCHECK(index != nullptr);
1715  const int var_index = var->index();
1716  *index = (var_index < var_index_to_index_.size())
1717  ? var_index_to_index_[var_index]
1718  : kUnassigned;
1719  return *index != kUnassigned;
1720  }
1721 
1723  void AddVars(const std::vector<IntVar*>& vars);
1724  int Size() const { return vars_.size(); }
1725  IntVar* Var(int index) const { return vars_[index]; }
1726  int64 Value(int index) const {
1727  DCHECK(IsVarSynced(index));
1728  return values_[index];
1729  }
1730  bool IsVarSynced(int index) const { return var_synced_[index]; }
1731 
1732  protected:
1733  virtual void OnSynchronize(const Assignment* delta) {}
1734  void SynchronizeOnAssignment(const Assignment* assignment);
1735 
1736  private:
1737  std::vector<IntVar*> vars_;
1738  std::vector<int64> values_;
1739  std::vector<bool> var_synced_;
1740  std::vector<int> var_index_to_index_;
1741  static const int kUnassigned;
1742 };
1743 
1745  public:
1746  explicit PropagationMonitor(Solver* const solver);
1747  ~PropagationMonitor() override;
1748  std::string DebugString() const override { return "PropagationMonitor"; }
1749 
1751  virtual void BeginConstraintInitialPropagation(
1752  Constraint* const constraint) = 0;
1753  virtual void EndConstraintInitialPropagation(
1754  Constraint* const constraint) = 0;
1756  Constraint* const parent, Constraint* const nested) = 0;
1758  Constraint* const parent, Constraint* const nested) = 0;
1759  virtual void RegisterDemon(Demon* const demon) = 0;
1760  virtual void BeginDemonRun(Demon* const demon) = 0;
1761  virtual void EndDemonRun(Demon* const demon) = 0;
1762  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1763  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1764  virtual void PushContext(const std::string& context) = 0;
1765  virtual void PopContext() = 0;
1767  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1768  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1769  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1771  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1772  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1773  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1774  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1775  virtual void SetValue(IntVar* const var, int64 value) = 0;
1776  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1777  virtual void SetValues(IntVar* const var,
1778  const std::vector<int64>& values) = 0;
1779  virtual void RemoveValues(IntVar* const var,
1780  const std::vector<int64>& values) = 0;
1782  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1783  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1784  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1785  int64 new_max) = 0;
1786  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1787  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1788  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1789  int64 new_max) = 0;
1790  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1791  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1792  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1793  int64 new_max) = 0;
1794  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1796  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1797  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1798  virtual void RankLast(SequenceVar* const var, int index) = 0;
1799  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1800  virtual void RankSequence(SequenceVar* const var,
1801  const std::vector<int>& rank_first,
1802  const std::vector<int>& rank_last,
1803  const std::vector<int>& unperformed) = 0;
1805  void Install() override;
1806 };
1807 
1809  // TODO(user): Add monitoring of local search filters.
1810  public:
1811  explicit LocalSearchMonitor(Solver* const solver);
1812  ~LocalSearchMonitor() override;
1813  std::string DebugString() const override { return "LocalSearchMonitor"; }
1814 
1816  virtual void BeginOperatorStart() = 0;
1817  virtual void EndOperatorStart() = 0;
1818  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1819  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1820  bool neighbor_found, const Assignment* delta,
1821  const Assignment* deltadelta) = 0;
1822  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1823  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1824  bool neighbor_found) = 0;
1825  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1826  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1827  bool neighbor_found) = 0;
1828  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1829  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1830 
1832  void Install() override;
1833 };
1834 
1835 class BooleanVar : public IntVar {
1836  public:
1837  static const int kUnboundBooleanVarValue;
1838 
1839  explicit BooleanVar(Solver* const s, const std::string& name = "")
1841 
1842  ~BooleanVar() override {}
1843 
1844  int64 Min() const override { return (value_ == 1); }
1845  void SetMin(int64 m) override;
1846  int64 Max() const override { return (value_ != 0); }
1847  void SetMax(int64 m) override;
1848  void SetRange(int64 mi, int64 ma) override;
1849  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1850  int64 Value() const override {
1851  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1852  return value_;
1853  }
1854  void RemoveValue(int64 v) override;
1855  void RemoveInterval(int64 l, int64 u) override;
1856  void WhenBound(Demon* d) override;
1857  void WhenRange(Demon* d) override { WhenBound(d); }
1858  void WhenDomain(Demon* d) override { WhenBound(d); }
1859  uint64 Size() const override;
1860  bool Contains(int64 v) const override;
1861  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1862  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1863  std::string DebugString() const override;
1864  int VarType() const override { return BOOLEAN_VAR; }
1865 
1866  IntVar* IsEqual(int64 constant) override;
1867  IntVar* IsDifferent(int64 constant) override;
1868  IntVar* IsGreaterOrEqual(int64 constant) override;
1869  IntVar* IsLessOrEqual(int64 constant) override;
1870 
1871  virtual void RestoreValue() = 0;
1872  std::string BaseName() const override { return "BooleanVar"; }
1873 
1874  int RawValue() const { return value_; }
1875 
1876  protected:
1877  int value_;
1880 };
1881 
1882 class SymmetryManager;
1883 
1888  public:
1890  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1891  ~SymmetryBreaker() override {}
1892 
1893  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
1895  int64 value);
1896  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
1897 
1898  private:
1899  friend class SymmetryManager;
1900  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
1901  CHECK(symmetry_manager_ == nullptr);
1902  CHECK_EQ(-1, index_in_symmetry_manager_);
1903  symmetry_manager_ = manager;
1904  index_in_symmetry_manager_ = index;
1905  }
1906  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
1907  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
1908 
1909  SymmetryManager* symmetry_manager_;
1911  int index_in_symmetry_manager_;
1912 };
1913 
1916 class SearchLog : public SearchMonitor {
1917  public:
1918  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
1919  double scaling_factor, double offset,
1920  std::function<std::string()> display_callback, int period);
1921  ~SearchLog() override;
1922  void EnterSearch() override;
1923  void ExitSearch() override;
1924  bool AtSolution() override;
1925  void BeginFail() override;
1926  void NoMoreSolutions() override;
1927  void AcceptUncheckedNeighbor() override;
1928  void ApplyDecision(Decision* const decision) override;
1929  void RefuteDecision(Decision* const decision) override;
1930  void OutputDecision();
1931  void Maintain();
1932  void BeginInitialPropagation() override;
1933  void EndInitialPropagation() override;
1934  std::string DebugString() const override;
1935 
1936  protected:
1937  /* Bottleneck function used for all UI related output. */
1938  virtual void OutputLine(const std::string& line);
1939 
1940  private:
1941  static std::string MemoryUsage();
1942 
1943  const int period_;
1944  std::unique_ptr<WallTimer> timer_;
1945  IntVar* const var_;
1946  OptimizeVar* const obj_;
1947  const double scaling_factor_;
1948  const double offset_;
1949  std::function<std::string()> display_callback_;
1950  int nsol_;
1951  int64 tick_;
1952  int64 objective_min_;
1953  int64 objective_max_;
1954  int min_right_depth_;
1955  int max_depth_;
1956  int sliding_min_depth_;
1957  int sliding_max_depth_;
1958 };
1959 
1964 class ModelCache {
1965  public:
1970  };
1971 
1978  };
1979 
1983  };
1984 
1993  };
1994 
2000  };
2001 
2014  };
2015 
2019  };
2020 
2033  };
2037  };
2038 
2042  };
2043 
2047  };
2048 
2054  };
2055 
2059  };
2060 
2061  explicit ModelCache(Solver* const solver);
2062  virtual ~ModelCache();
2063 
2064  virtual void Clear() = 0;
2065 
2067 
2068  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
2069 
2070  virtual void InsertVoidConstraint(Constraint* const ct,
2071  VoidConstraintType type) = 0;
2072 
2075  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
2076 
2077  virtual void InsertVarConstantConstraint(Constraint* const ct,
2078  IntVar* const var, int64 value,
2079  VarConstantConstraintType type) = 0;
2080 
2082 
2084  IntVar* const var, int64 value1, int64 value2,
2085  VarConstantConstantConstraintType type) const = 0;
2086 
2088  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
2090 
2092 
2094  IntExpr* const expr1, IntExpr* const expr2,
2095  ExprExprConstraintType type) const = 0;
2096 
2097  virtual void InsertExprExprConstraint(Constraint* const ct,
2098  IntExpr* const expr1,
2099  IntExpr* const expr2,
2100  ExprExprConstraintType type) = 0;
2101 
2103 
2104  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2105  ExprExpressionType type) const = 0;
2106 
2107  virtual void InsertExprExpression(IntExpr* const expression,
2108  IntExpr* const expr,
2109  ExprExpressionType type) = 0;
2110 
2112 
2114  IntExpr* const expr, int64 value,
2115  ExprConstantExpressionType type) const = 0;
2116 
2117  virtual void InsertExprConstantExpression(
2118  IntExpr* const expression, IntExpr* const var, int64 value,
2119  ExprConstantExpressionType type) = 0;
2120 
2122 
2124  IntExpr* const var1, IntExpr* const var2,
2125  ExprExprExpressionType type) const = 0;
2126 
2127  virtual void InsertExprExprExpression(IntExpr* const expression,
2128  IntExpr* const var1,
2129  IntExpr* const var2,
2130  ExprExprExpressionType type) = 0;
2131 
2133 
2135  IntExpr* const var1, IntExpr* const var2, int64 constant,
2136  ExprExprConstantExpressionType type) const = 0;
2137 
2138  virtual void InsertExprExprConstantExpression(
2139  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2140  int64 constant, ExprExprConstantExpressionType type) = 0;
2141 
2143 
2145  IntVar* const var, int64 value1, int64 value2,
2146  VarConstantConstantExpressionType type) const = 0;
2147 
2149  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2151 
2153 
2155  IntVar* const var, const std::vector<int64>& values,
2156  VarConstantArrayExpressionType type) const = 0;
2157 
2158  virtual void InsertVarConstantArrayExpression(
2159  IntExpr* const expression, IntVar* const var,
2160  const std::vector<int64>& values,
2162 
2164 
2166  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2167 
2168  virtual void InsertVarArrayExpression(IntExpr* const expression,
2169  const std::vector<IntVar*>& vars,
2170  VarArrayExpressionType type) = 0;
2171 
2173 
2175  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2176  VarArrayConstantArrayExpressionType type) const = 0;
2177 
2179  IntExpr* const expression, const std::vector<IntVar*>& var,
2180  const std::vector<int64>& values,
2182 
2184 
2186  const std::vector<IntVar*>& vars, int64 value,
2187  VarArrayConstantExpressionType type) const = 0;
2188 
2189  virtual void InsertVarArrayConstantExpression(
2190  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2192 
2193  Solver* solver() const;
2194 
2195  private:
2196  Solver* const solver_;
2197 };
2198 
2200 #if !defined(SWIG)
2202  public:
2204  const std::string& TypeName() const;
2205  void SetTypeName(const std::string& type_name);
2206 
2208  void SetIntegerArgument(const std::string& arg_name, int64 value);
2209  void SetIntegerArrayArgument(const std::string& arg_name,
2210  const std::vector<int64>& values);
2211  void SetIntegerMatrixArgument(const std::string& arg_name,
2212  const IntTupleSet& values);
2213  void SetIntegerExpressionArgument(const std::string& arg_name,
2214  IntExpr* const expr);
2215  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2216  const std::vector<IntVar*>& vars);
2217  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2218  void SetIntervalArrayArgument(const std::string& arg_name,
2219  const std::vector<IntervalVar*>& vars);
2220  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2221  void SetSequenceArrayArgument(const std::string& arg_name,
2222  const std::vector<SequenceVar*>& vars);
2223 
2225  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2226  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2227 
2229  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2230  int64 def) const;
2231  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2232  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2233  const std::string& arg_name) const;
2234  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2235  const std::string& arg_name) const;
2236 
2238  const std::string& arg_name) const;
2239  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2240  const std::string& arg_name) const;
2241 
2242  private:
2243  std::string type_name_;
2244  absl::flat_hash_map<std::string, int64> integer_argument_;
2245  absl::flat_hash_map<std::string, std::vector<int64>> integer_array_argument_;
2246  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2247  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2248  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2249  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2250  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2251  integer_variable_array_argument_;
2252  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2253  interval_array_argument_;
2254  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2255  sequence_array_argument_;
2256 };
2257 
2259 class ModelParser : public ModelVisitor {
2260  public:
2261  ModelParser();
2262 
2263  ~ModelParser() override;
2264 
2266  void BeginVisitModel(const std::string& solver_name) override;
2267  void EndVisitModel(const std::string& solver_name) override;
2268  void BeginVisitConstraint(const std::string& type_name,
2269  const Constraint* const constraint) override;
2270  void EndVisitConstraint(const std::string& type_name,
2271  const Constraint* const constraint) override;
2272  void BeginVisitIntegerExpression(const std::string& type_name,
2273  const IntExpr* const expr) override;
2274  void EndVisitIntegerExpression(const std::string& type_name,
2275  const IntExpr* const expr) override;
2276  void VisitIntegerVariable(const IntVar* const variable,
2277  IntExpr* const delegate) override;
2278  void VisitIntegerVariable(const IntVar* const variable,
2279  const std::string& operation, int64 value,
2280  IntVar* const delegate) override;
2281  void VisitIntervalVariable(const IntervalVar* const variable,
2282  const std::string& operation, int64 value,
2283  IntervalVar* const delegate) override;
2284  void VisitSequenceVariable(const SequenceVar* const variable) override;
2286  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2287  void VisitIntegerArrayArgument(const std::string& arg_name,
2288  const std::vector<int64>& values) override;
2289  void VisitIntegerMatrixArgument(const std::string& arg_name,
2290  const IntTupleSet& values) override;
2292  void VisitIntegerExpressionArgument(const std::string& arg_name,
2293  IntExpr* const argument) override;
2295  const std::string& arg_name,
2296  const std::vector<IntVar*>& arguments) override;
2298  void VisitIntervalArgument(const std::string& arg_name,
2299  IntervalVar* const argument) override;
2301  const std::string& arg_name,
2302  const std::vector<IntervalVar*>& arguments) override;
2304  void VisitSequenceArgument(const std::string& arg_name,
2305  SequenceVar* const argument) override;
2307  const std::string& arg_name,
2308  const std::vector<SequenceVar*>& arguments) override;
2309 
2310  protected:
2311  void PushArgumentHolder();
2312  void PopArgumentHolder();
2313  ArgumentHolder* Top() const;
2314 
2315  private:
2316  std::vector<ArgumentHolder*> holders_;
2317 };
2318 
2319 template <class T>
2320 class ArrayWithOffset : public BaseObject {
2321  public:
2322  ArrayWithOffset(int64 index_min, int64 index_max)
2323  : index_min_(index_min),
2324  index_max_(index_max),
2325  values_(new T[index_max - index_min + 1]) {
2326  DCHECK_LE(index_min, index_max);
2327  }
2328 
2329  ~ArrayWithOffset() override {}
2330 
2331  virtual T Evaluate(int64 index) const {
2332  DCHECK_GE(index, index_min_);
2333  DCHECK_LE(index, index_max_);
2334  return values_[index - index_min_];
2335  }
2336 
2337  void SetValue(int64 index, T value) {
2338  DCHECK_GE(index, index_min_);
2339  DCHECK_LE(index, index_max_);
2340  values_[index - index_min_] = value;
2341  }
2342 
2343  std::string DebugString() const override { return "ArrayWithOffset"; }
2344 
2345  private:
2346  const int64 index_min_;
2347  const int64 index_max_;
2348  std::unique_ptr<T[]> values_;
2349 };
2350 #endif // SWIG
2351 
2356 template <class T, class C>
2358  public:
2359  explicit RevGrowingArray(int64 block_size)
2360  : block_size_(block_size), block_offset_(0) {
2361  CHECK_GT(block_size, 0);
2362  }
2363 
2365  for (int i = 0; i < elements_.size(); ++i) {
2366  delete[] elements_[i];
2367  }
2368  }
2369 
2370  T At(int64 index) const {
2371  const int64 block_index = ComputeBlockIndex(index);
2372  const int64 relative_index = block_index - block_offset_;
2373  if (relative_index < 0 || relative_index >= elements_.size()) {
2374  return T();
2375  }
2376  const T* block = elements_[relative_index];
2377  return block != nullptr ? block[index - block_index * block_size_] : T();
2378  }
2379 
2380  void RevInsert(Solver* const solver, int64 index, T value) {
2381  const int64 block_index = ComputeBlockIndex(index);
2382  T* const block = GetOrCreateBlock(block_index);
2383  const int64 residual = index - block_index * block_size_;
2384  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2385  reinterpret_cast<C>(value));
2386  }
2387 
2388  private:
2389  T* NewBlock() const {
2390  T* const result = new T[block_size_];
2391  for (int i = 0; i < block_size_; ++i) {
2392  result[i] = T();
2393  }
2394  return result;
2395  }
2396 
2397  T* GetOrCreateBlock(int block_index) {
2398  if (elements_.size() == 0) {
2399  block_offset_ = block_index;
2400  GrowUp(block_index);
2401  } else if (block_index < block_offset_) {
2402  GrowDown(block_index);
2403  } else if (block_index - block_offset_ >= elements_.size()) {
2404  GrowUp(block_index);
2405  }
2406  T* block = elements_[block_index - block_offset_];
2407  if (block == nullptr) {
2408  block = NewBlock();
2409  elements_[block_index - block_offset_] = block;
2410  }
2411  return block;
2412  }
2413 
2414  int64 ComputeBlockIndex(int64 value) const {
2415  return value >= 0 ? value / block_size_
2416  : (value - block_size_ + 1) / block_size_;
2417  }
2418 
2419  void GrowUp(int64 block_index) {
2420  elements_.resize(block_index - block_offset_ + 1);
2421  }
2422 
2423  void GrowDown(int64 block_index) {
2424  const int64 delta = block_offset_ - block_index;
2425  block_offset_ = block_index;
2426  DCHECK_GT(delta, 0);
2427  elements_.insert(elements_.begin(), delta, nullptr);
2428  }
2429 
2430  const int64 block_size_;
2431  std::vector<T*> elements_;
2432  int block_offset_;
2433 };
2434 
2439 template <class T>
2440 class RevIntSet {
2441  public:
2442  static const int kNoInserted = -1;
2443 
2445  explicit RevIntSet(int capacity)
2446  : elements_(new T[capacity]),
2447  num_elements_(0),
2448  capacity_(capacity),
2449  position_(new int[capacity]),
2450  delete_position_(true) {
2451  for (int i = 0; i < capacity; ++i) {
2452  position_[i] = kNoInserted;
2453  }
2454  }
2455 
2457  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2458  : elements_(new T[capacity]),
2459  num_elements_(0),
2460  capacity_(capacity),
2461  position_(shared_positions),
2462  delete_position_(false) {
2463  for (int i = 0; i < shared_positions_size; ++i) {
2464  position_[i] = kNoInserted;
2465  }
2466  }
2467 
2469  if (delete_position_) {
2470  delete[] position_;
2471  }
2472  }
2473 
2474  int Size() const { return num_elements_.Value(); }
2475 
2476  int Capacity() const { return capacity_; }
2477 
2478  T Element(int i) const {
2479  DCHECK_GE(i, 0);
2480  DCHECK_LT(i, num_elements_.Value());
2481  return elements_[i];
2482  }
2483 
2484  T RemovedElement(int i) const {
2485  DCHECK_GE(i, 0);
2486  DCHECK_LT(i + num_elements_.Value(), capacity_);
2487  return elements_[i + num_elements_.Value()];
2488  }
2489 
2490  void Insert(Solver* const solver, const T& elt) {
2491  const int position = num_elements_.Value();
2492  DCHECK_LT(position, capacity_);
2493  DCHECK(NotAlreadyInserted(elt));
2494  elements_[position] = elt;
2495  position_[elt] = position;
2496  num_elements_.Incr(solver);
2497  }
2498 
2499  void Remove(Solver* const solver, const T& value_index) {
2500  num_elements_.Decr(solver);
2501  SwapTo(value_index, num_elements_.Value());
2502  }
2503 
2504  void Restore(Solver* const solver, const T& value_index) {
2505  SwapTo(value_index, num_elements_.Value());
2506  num_elements_.Incr(solver);
2507  }
2508 
2509  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2510 
2512  typedef const T* const_iterator;
2513  const_iterator begin() const { return elements_.get(); }
2514  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2515 
2516  private:
2518  bool NotAlreadyInserted(const T& elt) {
2519  for (int i = 0; i < num_elements_.Value(); ++i) {
2520  if (elt == elements_[i]) {
2521  return false;
2522  }
2523  }
2524  return true;
2525  }
2526 
2527  void SwapTo(T value_index, int next_position) {
2528  const int current_position = position_[value_index];
2529  if (current_position != next_position) {
2530  const T next_value_index = elements_[next_position];
2531  elements_[current_position] = next_value_index;
2532  elements_[next_position] = value_index;
2533  position_[value_index] = next_position;
2534  position_[next_value_index] = current_position;
2535  }
2536  }
2537 
2539  std::unique_ptr<T[]> elements_;
2541  NumericalRev<int> num_elements_;
2543  const int capacity_;
2545  int* position_;
2547  const bool delete_position_;
2548 };
2549 
2551 
2553  public:
2554  explicit RevPartialSequence(const std::vector<int>& items)
2555  : elements_(items),
2556  first_ranked_(0),
2557  last_ranked_(items.size() - 1),
2558  size_(items.size()),
2559  position_(new int[size_]) {
2560  for (int i = 0; i < size_; ++i) {
2561  elements_[i] = items[i];
2562  position_[i] = i;
2563  }
2564  }
2565 
2566  explicit RevPartialSequence(int size)
2567  : elements_(size),
2568  first_ranked_(0),
2569  last_ranked_(size - 1),
2570  size_(size),
2571  position_(new int[size_]) {
2572  for (int i = 0; i < size_; ++i) {
2573  elements_[i] = i;
2574  position_[i] = i;
2575  }
2576  }
2577 
2579 
2580  int NumFirstRanked() const { return first_ranked_.Value(); }
2581 
2582  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2583 
2584  int Size() const { return size_; }
2585 
2586 #if !defined(SWIG)
2587  const int& operator[](int index) const {
2588  DCHECK_GE(index, 0);
2589  DCHECK_LT(index, size_);
2590  return elements_[index];
2591  }
2592 #endif
2593 
2594  void RankFirst(Solver* const solver, int elt) {
2595  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2596  SwapTo(elt, first_ranked_.Value());
2597  first_ranked_.Incr(solver);
2598  }
2599 
2600  void RankLast(Solver* const solver, int elt) {
2601  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2602  SwapTo(elt, last_ranked_.Value());
2603  last_ranked_.Decr(solver);
2604  }
2605 
2606  bool IsRanked(int elt) const {
2607  const int position = position_[elt];
2608  return (position < first_ranked_.Value() ||
2609  position > last_ranked_.Value());
2610  }
2611 
2612  std::string DebugString() const {
2613  std::string result = "[";
2614  for (int i = 0; i < first_ranked_.Value(); ++i) {
2615  absl::StrAppend(&result, elements_[i]);
2616  if (i != first_ranked_.Value() - 1) {
2617  result.append("-");
2618  }
2619  }
2620  result.append("|");
2621  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2622  absl::StrAppend(&result, elements_[i]);
2623  if (i != last_ranked_.Value()) {
2624  result.append("-");
2625  }
2626  }
2627  result.append("|");
2628  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2629  absl::StrAppend(&result, elements_[i]);
2630  if (i != size_ - 1) {
2631  result.append("-");
2632  }
2633  }
2634  result.append("]");
2635  return result;
2636  }
2637 
2638  private:
2639  void SwapTo(int elt, int next_position) {
2640  const int current_position = position_[elt];
2641  if (current_position != next_position) {
2642  const int next_elt = elements_[next_position];
2643  elements_[current_position] = next_elt;
2644  elements_[next_position] = elt;
2645  position_[elt] = next_position;
2646  position_[next_elt] = current_position;
2647  }
2648  }
2649 
2651  std::vector<int> elements_;
2653  NumericalRev<int> first_ranked_;
2655  NumericalRev<int> last_ranked_;
2657  const int size_;
2659  std::unique_ptr<int[]> position_;
2660 };
2661 
2667  public:
2669  explicit UnsortedNullableRevBitset(int bit_size);
2670 
2672 
2675  void Init(Solver* const solver, const std::vector<uint64>& mask);
2676 
2679  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2680 
2683  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2684 
2687  int ActiveWordSize() const { return active_words_.Size(); }
2688 
2690  bool Empty() const { return active_words_.Size() == 0; }
2691 
2699  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2700 
2702  int64 bit_size() const { return bit_size_; }
2704  int64 word_size() const { return word_size_; }
2706  const RevIntSet<int>& active_words() const { return active_words_; }
2707 
2708  private:
2709  void CleanUpActives(Solver* const solver);
2710 
2711  const int64 bit_size_;
2712  const int64 word_size_;
2713  RevArray<uint64> bits_;
2714  RevIntSet<int> active_words_;
2715  std::vector<int> to_remove_;
2716 };
2717 
2718 template <class T>
2719 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2720  for (int i = 0; i < values.size(); ++i) {
2721  if (values[i] != value) {
2722  return false;
2723  }
2724  }
2725  return true;
2726 }
2727 
2728 template <class T>
2729 bool IsArrayBoolean(const std::vector<T>& values) {
2730  for (int i = 0; i < values.size(); ++i) {
2731  if (values[i] != 0 && values[i] != 1) {
2732  return false;
2733  }
2734  }
2735  return true;
2736 }
2737 
2738 template <class T>
2739 bool AreAllOnes(const std::vector<T>& values) {
2740  return IsArrayConstant(values, T(1));
2741 }
2742 
2743 template <class T>
2744 bool AreAllNull(const std::vector<T>& values) {
2745  return IsArrayConstant(values, T(0));
2746 }
2747 
2748 template <class T>
2749 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2750  for (const T& current_value : values) {
2751  if (current_value < value) {
2752  return false;
2753  }
2754  }
2755  return true;
2756 }
2757 
2758 template <class T>
2759 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2760  for (const T& current_value : values) {
2761  if (current_value > value) {
2762  return false;
2763  }
2764  }
2765  return true;
2766 }
2767 
2768 template <class T>
2769 bool AreAllPositive(const std::vector<T>& values) {
2770  return AreAllGreaterOrEqual(values, T(0));
2771 }
2772 
2773 template <class T>
2774 bool AreAllNegative(const std::vector<T>& values) {
2775  return AreAllLessOrEqual(values, T(0));
2776 }
2777 
2778 template <class T>
2779 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2780  return AreAllGreaterOrEqual(values, T(1));
2781 }
2782 
2783 template <class T>
2784 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2785  return AreAllLessOrEqual(values, T(-1));
2786 }
2787 
2788 template <class T>
2789 bool IsIncreasingContiguous(const std::vector<T>& values) {
2790  for (int i = 0; i < values.size() - 1; ++i) {
2791  if (values[i + 1] != values[i] + 1) {
2792  return false;
2793  }
2794  }
2795  return true;
2796 }
2797 
2798 template <class T>
2799 bool IsIncreasing(const std::vector<T>& values) {
2800  for (int i = 0; i < values.size() - 1; ++i) {
2801  if (values[i + 1] < values[i]) {
2802  return false;
2803  }
2804  }
2805  return true;
2806 }
2807 
2808 template <class T>
2809 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2810  T range_max) {
2811  for (int i = 0; i < vars.size(); ++i) {
2812  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2813  return false;
2814  }
2815  }
2816  return true;
2817 }
2818 
2819 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2820  for (int i = 0; i < vars.size(); ++i) {
2821  if (!vars[i]->Bound()) {
2822  return false;
2823  }
2824  }
2825  return true;
2826 }
2827 
2828 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2829  return IsArrayInRange(vars, 0, 1);
2830 }
2831 
2834 template <class T>
2835 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2836  const std::vector<T>& values) {
2837  for (int i = 0; i < vars.size(); ++i) {
2838  if (values[i] != 0 && !vars[i]->Bound()) {
2839  return false;
2840  }
2841  }
2842  return true;
2843 }
2844 
2846 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2847  for (int i = 0; i < vars.size(); ++i) {
2848  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2849  return false;
2850  }
2851  }
2852  return true;
2853 }
2854 
2855 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2856  DCHECK(!vars.empty());
2857  int64 result = kint64min;
2858  for (int i = 0; i < vars.size(); ++i) {
2860  result = std::max<int64>(result, vars[i]->Max());
2861  }
2862  return result;
2863 }
2864 
2865 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2866  DCHECK(!vars.empty());
2867  int64 result = kint64max;
2868  for (int i = 0; i < vars.size(); ++i) {
2870  result = std::min<int64>(result, vars[i]->Min());
2871  }
2872  return result;
2873 }
2874 
2875 inline void FillValues(const std::vector<IntVar*>& vars,
2876  std::vector<int64>* const values) {
2877  values->clear();
2878  values->resize(vars.size());
2879  for (int i = 0; i < vars.size(); ++i) {
2880  (*values)[i] = vars[i]->Value();
2881  }
2882 }
2883 
2884 inline int64 PosIntDivUp(int64 e, int64 v) {
2885  DCHECK_GT(v, 0);
2886  if (e >= 0) {
2887  return e % v == 0 ? e / v : e / v + 1;
2888  } else {
2889  return e / v;
2890  }
2891 }
2892 
2893 inline int64 PosIntDivDown(int64 e, int64 v) {
2894  DCHECK_GT(v, 0);
2895  if (e >= 0) {
2896  return e / v;
2897  } else {
2898  return e % v == 0 ? e / v : e / v - 1;
2899  }
2900 }
2901 
2902 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
2903 } // namespace operations_research
2904 
2905 #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.
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
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
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.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
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)
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.
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
std::string DebugString() const override
T operator*() const
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
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
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.
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
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.
void OnRevertChanges(int64 index)
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)
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
void Incr(Solver *const s)
This is the base class for building an Lns operator.
~ChangeValue() override
~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
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.
IntVar * IsGreaterOrEqual(int64 constant) override
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
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.
bool IsPathStart(int64 node) const
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.
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.
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.
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
bool SetMin(int64 new_min)
Simple PathOperator wrapper that also stores the current previous nodes, and is thus able to provide ...
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.
~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.
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, std::function< int(int64)> start_empty_path_class)
Builds an instance of PathOperator from next and path variables.
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.
RevBitMatrix(int64 rows, int64 columns)
~IntVarLocalSearchOperator() override
~ArrayWithOffset() override
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
~RevBitMatrix()
ExprExprConstraintType
void PopArgumentHolder()
RevBitSet(int64 size)
bool SkipUnchanged(int index) const override
const_iterator end() const
int RawValue() const
PathWithPreviousNodesOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, int number_of_base_nodes, std::function< int(int64)> start_empty_path_class)
friend class SymmetryManager
virtual bool HoldsDelta() const
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
VarConstantConstantExpressionType
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...
void RankLast(Solver *const solver, int elt)
~CallMethod3() override
bool ValueFromAssignent(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
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()
The class IntVar is a subset of IntExpr.
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)
void OnRevertChanges(int64 index)
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.
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.
VarLocalSearchOperator(std::vector< V * > vars, Handler var_handler)
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.
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'.
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.
int64 Max() const
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
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...
~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()
void Run(Solver *const s) override
This is the main callback of the demon.
IntVar * Var() override
Creates a variable from the expression.
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
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.
VarArrayExpressionType
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
std::string DebugString() const override
VarLocalSearchOperator()
virtual bool MakeNeighbor()=0
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.
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
std::string DebugString() const 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?
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),...
Base operator class for operators manipulating IntVars.
~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'.
int64 Prev(int64 node) const
virtual void Start(const Assignment *assignment)=0
virtual T Evaluate(int64 index) const
int AddAlternativeSet(const std::vector< int64 > &alternative_set)
Handling node alternatives.
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.
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).
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars)
The class IntExpr is the base of all integer expressions in constraint programming.
virtual void PushContext(const std::string &context)=0
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
void Relax()
BaseIntExpr(Solver *const s)
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)
void OnNodeInitialization() override
Called by OnStart() after initializing node information.
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
~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.
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.
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
~PathWithPreviousNodesOperator() override
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
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
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
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 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
const SequenceContainer & SequenceVarContainer() const
SequenceVar * Var() const
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.
bool IsCardinalityZero() const
Is bitset null?
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.
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().
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.
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
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
bool ValueFromAssignent(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
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)
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.
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
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
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 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
~CallMethod0() override
void SetValue(int64 index, T value)
std::string DebugString() const override
~DelayedCallMethod1() override
~RevGrowingArray()
const Val & OldValue(int64 index) const
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_
void SetBackwardSequence(const std::vector< int > &backward_sequence)
Demon proxy to a method on the constraint with no arguments.
RevPartialSequence(int size)
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
~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.
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
bool AreAllNegative(const std::vector< T > &values)
std::string ParameterDebugString(P param)
virtual void RankNotLast(SequenceVar *const var, int index)=0
VarArrayConstantArrayExpressionType
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0