C++ Reference

C++ Reference: Routing

constraint_solveri.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
48 
49 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
51 
52 #include <stdint.h>
53 #include <string.h>
54 
55 #include <algorithm>
56 #include <functional>
57 #include <initializer_list>
58 #include <memory>
59 #include <string>
60 #include <utility>
61 #include <vector>
62 
63 #include "absl/container/flat_hash_map.h"
64 #include "absl/strings/str_cat.h"
65 #include "ortools/base/integral_types.h"
66 #include "ortools/base/logging.h"
67 #include "ortools/base/timer.h"
69 #include "ortools/util/bitset.h"
70 #include "ortools/util/tuple_set.h"
71 
72 namespace operations_research {
73 
99 class LocalSearchMonitor;
100 
101 class BaseIntExpr : public IntExpr {
102  public:
103  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
104  ~BaseIntExpr() override {}
105 
106  IntVar* Var() override;
107  virtual IntVar* CastToVar();
108 
109  private:
110  IntVar* var_;
111 };
112 
115 enum VarTypes {
124  TRACE_VAR
125 };
126 
135 #ifndef SWIG
136 template <class T>
138  private:
139  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
140  struct Chunk {
141  T data_[CHUNK_SIZE];
142  const Chunk* const next_;
143  explicit Chunk(const Chunk* next) : next_(next) {}
144  };
145 
146  public:
148  class Iterator {
149  public:
150  explicit Iterator(const SimpleRevFIFO<T>* l)
151  : chunk_(l->chunks_), value_(l->Last()) {}
152  bool ok() const { return (value_ != nullptr); }
153  T operator*() const { return *value_; }
154  void operator++() {
155  ++value_;
156  if (value_ == chunk_->data_ + CHUNK_SIZE) {
157  chunk_ = chunk_->next_;
158  value_ = chunk_ ? chunk_->data_ : nullptr;
159  }
160  }
161 
162  private:
163  const Chunk* chunk_;
164  const T* value_;
165  };
166 
167  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
168 
169  void Push(Solver* const s, T val) {
170  if (pos_.Value() == 0) {
171  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
172  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
173  reinterpret_cast<void*>(chunk));
174  pos_.SetValue(s, CHUNK_SIZE - 1);
175  } else {
176  pos_.Decr(s);
177  }
178  chunks_->data_[pos_.Value()] = val;
179  }
180 
182  void PushIfNotTop(Solver* const s, T val) {
183  if (chunks_ == nullptr || LastValue() != val) {
184  Push(s, val);
185  }
186  }
187 
189  const T* Last() const {
190  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
191  }
192 
193  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
194 
196  const T& LastValue() const {
197  DCHECK(chunks_);
198  return chunks_->data_[pos_.Value()];
199  }
200 
202  void SetLastValue(const T& v) {
203  DCHECK(Last());
204  chunks_->data_[pos_.Value()] = v;
205  }
206 
207  private:
208  Chunk* chunks_;
209  NumericalRev<int> pos_;
210 };
211 
213 // TODO(user): use murmurhash.
214 inline uint64_t Hash1(uint64_t value) {
215  value = (~value) + (value << 21);
216  value ^= value >> 24;
217  value += (value << 3) + (value << 8);
218  value ^= value >> 14;
219  value += (value << 2) + (value << 4);
220  value ^= value >> 28;
221  value += (value << 31);
222  return value;
223 }
224 
225 inline uint64_t Hash1(uint32_t value) {
226  uint64_t a = value;
227  a = (a + 0x7ed55d16) + (a << 12);
228  a = (a ^ 0xc761c23c) ^ (a >> 19);
229  a = (a + 0x165667b1) + (a << 5);
230  a = (a + 0xd3a2646c) ^ (a << 9);
231  a = (a + 0xfd7046c5) + (a << 3);
232  a = (a ^ 0xb55a4f09) ^ (a >> 16);
233  return a;
234 }
235 
236 inline uint64_t Hash1(int64_t value) {
237  return Hash1(static_cast<uint64_t>(value));
238 }
239 
240 inline uint64_t Hash1(int value) { return Hash1(static_cast<uint32_t>(value)); }
241 
242 inline uint64_t Hash1(void* const ptr) {
243 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
244  defined(__aarch64__) || (defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64))
245  return Hash1(reinterpret_cast<uint64_t>(ptr));
246 #else
247  return Hash1(reinterpret_cast<uint32_t>(ptr));
248 #endif
249 }
250 
251 template <class T>
252 uint64_t Hash1(const std::vector<T*>& ptrs) {
253  if (ptrs.empty()) return 0;
254  if (ptrs.size() == 1) return Hash1(ptrs[0]);
255  uint64_t hash = Hash1(ptrs[0]);
256  for (int i = 1; i < ptrs.size(); ++i) {
257  hash = hash * i + Hash1(ptrs[i]);
258  }
259  return hash;
260 }
261 
262 inline uint64_t Hash1(const std::vector<int64_t>& ptrs) {
263  if (ptrs.empty()) return 0;
264  if (ptrs.size() == 1) return Hash1(ptrs[0]);
265  uint64_t hash = Hash1(ptrs[0]);
266  for (int i = 1; i < ptrs.size(); ++i) {
267  hash = hash * i + Hash1(ptrs[i]);
268  }
269  return hash;
270 }
271 
274 template <class K, class V>
276  public:
277  RevImmutableMultiMap(Solver* const solver, int initial_size)
278  : solver_(solver),
279  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
280  size_(initial_size),
281  num_items_(0) {
282  memset(array_, 0, sizeof(*array_) * size_.Value());
283  }
284 
286 
287  int num_items() const { return num_items_.Value(); }
288 
290  bool ContainsKey(const K& key) const {
291  uint64_t code = Hash1(key) % size_.Value();
292  Cell* tmp = array_[code];
293  while (tmp) {
294  if (tmp->key() == key) {
295  return true;
296  }
297  tmp = tmp->next();
298  }
299  return false;
300  }
301 
305  const V& FindWithDefault(const K& key, const V& default_value) const {
306  uint64_t code = Hash1(key) % size_.Value();
307  Cell* tmp = array_[code];
308  while (tmp) {
309  if (tmp->key() == key) {
310  return tmp->value();
311  }
312  tmp = tmp->next();
313  }
314  return default_value;
315  }
316 
318  void Insert(const K& key, const V& value) {
319  const int position = Hash1(key) % size_.Value();
320  Cell* const cell =
321  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
322  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
323  reinterpret_cast<void*>(cell));
324  num_items_.Incr(solver_);
325  if (num_items_.Value() > 2 * size_.Value()) {
326  Double();
327  }
328  }
329 
330  private:
331  class Cell {
332  public:
333  Cell(const K& key, const V& value, Cell* const next)
334  : key_(key), value_(value), next_(next) {}
335 
336  void SetRevNext(Solver* const solver, Cell* const next) {
337  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
338  reinterpret_cast<void*>(next));
339  }
340 
341  Cell* next() const { return next_; }
342 
343  const K& key() const { return key_; }
344 
345  const V& value() const { return value_; }
346 
347  private:
348  const K key_;
349  const V value_;
350  Cell* next_;
351  };
352 
353  void Double() {
354  Cell** const old_cell_array = array_;
355  const int old_size = size_.Value();
356  size_.SetValue(solver_, size_.Value() * 2);
357  solver_->SaveAndSetValue(
358  reinterpret_cast<void**>(&array_),
359  reinterpret_cast<void*>(
360  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
361  memset(array_, 0, size_.Value() * sizeof(*array_));
362  for (int i = 0; i < old_size; ++i) {
363  Cell* tmp = old_cell_array[i];
364  while (tmp != nullptr) {
365  Cell* const to_reinsert = tmp;
366  tmp = tmp->next();
367  const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value();
368  to_reinsert->SetRevNext(solver_, array_[new_position]);
369  solver_->SaveAndSetValue(
370  reinterpret_cast<void**>(&array_[new_position]),
371  reinterpret_cast<void*>(to_reinsert));
372  }
373  }
374  }
375 
376  Solver* const solver_;
377  Cell** array_;
378  NumericalRev<int> size_;
379  NumericalRev<int> num_items_;
380 };
381 
383 class RevSwitch {
384  public:
385  RevSwitch() : value_(false) {}
386 
387  bool Switched() const { return value_; }
388 
389  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
390 
391  private:
392  bool value_;
393 };
394 
398  public:
399  explicit SmallRevBitSet(int64_t size);
401  void SetToOne(Solver* const solver, int64_t pos);
403  void SetToZero(Solver* const solver, int64_t pos);
405  int64_t Cardinality() const;
407  bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; }
409  bool IsCardinalityOne() const {
410  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
411  }
414  int64_t GetFirstOne() const;
415 
416  private:
417  Rev<uint64_t> bits_;
418 };
419 
422 class RevBitSet {
423  public:
424  explicit RevBitSet(int64_t size);
426 
428  void SetToOne(Solver* const solver, int64_t index);
430  void SetToZero(Solver* const solver, int64_t index);
432  bool IsSet(int64_t index) const;
434  int64_t Cardinality() const;
436  bool IsCardinalityZero() const;
438  bool IsCardinalityOne() const;
441  int64_t GetFirstBit(int start) const;
443  void ClearAll(Solver* const solver);
444 
445  friend class RevBitMatrix;
446 
447  private:
449  void Save(Solver* const solver, int offset);
450  const int64_t size_;
451  const int64_t length_;
452  uint64_t* bits_;
453  uint64_t* stamps_;
454 };
455 
457 class RevBitMatrix : private RevBitSet {
458  public:
459  RevBitMatrix(int64_t rows, int64_t columns);
461 
463  void SetToOne(Solver* const solver, int64_t row, int64_t column);
465  void SetToZero(Solver* const solver, int64_t row, int64_t column);
467  bool IsSet(int64_t row, int64_t column) const {
468  DCHECK_GE(row, 0);
469  DCHECK_LT(row, rows_);
470  DCHECK_GE(column, 0);
471  DCHECK_LT(column, columns_);
472  return RevBitSet::IsSet(row * columns_ + column);
473  }
475  int64_t Cardinality(int row) const;
477  bool IsCardinalityZero(int row) const;
479  bool IsCardinalityOne(int row) const;
482  int64_t GetFirstBit(int row, int start) const;
484  void ClearAll(Solver* const solver);
485 
486  private:
487  const int64_t rows_;
488  const int64_t columns_;
489 };
490 
496 
498 template <class T>
499 class CallMethod0 : public Demon {
500  public:
501  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
502  : constraint_(ct), method_(method), name_(name) {}
503 
504  ~CallMethod0() override {}
505 
506  void Run(Solver* const s) override { (constraint_->*method_)(); }
507 
508  std::string DebugString() const override {
509  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
510  }
511 
512  private:
513  T* const constraint_;
514  void (T::*const method_)();
515  const std::string name_;
516 };
517 
518 template <class T>
519 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
520  const std::string& name) {
521  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
522 }
523 
524 template <class P>
525 std::string ParameterDebugString(P param) {
526  return absl::StrCat(param);
527 }
528 
530 template <class P>
531 std::string ParameterDebugString(P* param) {
532  return param->DebugString();
533 }
534 
536 template <class T, class P>
537 class CallMethod1 : public Demon {
538  public:
539  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
540  P param1)
541  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
542 
543  ~CallMethod1() override {}
544 
545  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
546 
547  std::string DebugString() const override {
548  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
549  ", ", ParameterDebugString(param1_), ")");
550  }
551 
552  private:
553  T* const constraint_;
554  void (T::*const method_)(P);
555  const std::string name_;
556  P param1_;
557 };
558 
559 template <class T, class P>
560 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
561  const std::string& name, P param1) {
562  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
563 }
564 
566 template <class T, class P, class Q>
567 class CallMethod2 : public Demon {
568  public:
569  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
570  P param1, Q param2)
571  : constraint_(ct),
572  method_(method),
573  name_(name),
574  param1_(param1),
575  param2_(param2) {}
576 
577  ~CallMethod2() override {}
578 
579  void Run(Solver* const s) override {
580  (constraint_->*method_)(param1_, param2_);
581  }
582 
583  std::string DebugString() const override {
584  return absl::StrCat(absl::StrCat("CallMethod_", name_),
585  absl::StrCat("(", constraint_->DebugString()),
586  absl::StrCat(", ", ParameterDebugString(param1_)),
587  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
588  }
589 
590  private:
591  T* const constraint_;
592  void (T::*const method_)(P, Q);
593  const std::string name_;
594  P param1_;
595  Q param2_;
596 };
597 
598 template <class T, class P, class Q>
599 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
600  void (T::*method)(P, Q), const std::string& name,
601  P param1, Q param2) {
602  return s->RevAlloc(
603  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
604 }
606 template <class T, class P, class Q, class R>
607 class CallMethod3 : public Demon {
608  public:
609  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
610  P param1, Q param2, R param3)
611  : constraint_(ct),
612  method_(method),
613  name_(name),
614  param1_(param1),
615  param2_(param2),
616  param3_(param3) {}
617 
618  ~CallMethod3() override {}
619 
620  void Run(Solver* const s) override {
621  (constraint_->*method_)(param1_, param2_, param3_);
622  }
623 
624  std::string DebugString() const override {
625  return absl::StrCat(absl::StrCat("CallMethod_", name_),
626  absl::StrCat("(", constraint_->DebugString()),
627  absl::StrCat(", ", ParameterDebugString(param1_)),
628  absl::StrCat(", ", ParameterDebugString(param2_)),
629  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
630  }
631 
632  private:
633  T* const constraint_;
634  void (T::*const method_)(P, Q, R);
635  const std::string name_;
636  P param1_;
637  Q param2_;
638  R param3_;
639 };
640 
641 template <class T, class P, class Q, class R>
642 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
643  void (T::*method)(P, Q, R), const std::string& name,
644  P param1, Q param2, R param3) {
645  return s->RevAlloc(
646  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
647 }
649 
654 
656 template <class T>
657 class DelayedCallMethod0 : public Demon {
658  public:
659  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
660  : constraint_(ct), method_(method), name_(name) {}
661 
662  ~DelayedCallMethod0() override {}
663 
664  void Run(Solver* const s) override { (constraint_->*method_)(); }
665 
666  Solver::DemonPriority priority() const override {
668  }
669 
670  std::string DebugString() const override {
671  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
672  ")";
673  }
674 
675  private:
676  T* const constraint_;
677  void (T::*const method_)();
678  const std::string name_;
679 };
680 
681 template <class T>
682 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
683  void (T::*method)(),
684  const std::string& name) {
685  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
686 }
687 
689 template <class T, class P>
690 class DelayedCallMethod1 : public Demon {
691  public:
692  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
693  P param1)
694  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
695 
696  ~DelayedCallMethod1() override {}
697 
698  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
699 
700  Solver::DemonPriority priority() const override {
702  }
703 
704  std::string DebugString() const override {
705  return absl::StrCat("DelayedCallMethod_", name_, "(",
706  constraint_->DebugString(), ", ",
707  ParameterDebugString(param1_), ")");
708  }
709 
710  private:
711  T* const constraint_;
712  void (T::*const method_)(P);
713  const std::string name_;
714  P param1_;
715 };
716 
717 template <class T, class P>
718 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
719  void (T::*method)(P),
720  const std::string& name, P param1) {
721  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
722 }
723 
725 template <class T, class P, class Q>
726 class DelayedCallMethod2 : public Demon {
727  public:
728  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
729  const std::string& name, P param1, Q param2)
730  : constraint_(ct),
731  method_(method),
732  name_(name),
733  param1_(param1),
734  param2_(param2) {}
735 
736  ~DelayedCallMethod2() override {}
737 
738  void Run(Solver* const s) override {
739  (constraint_->*method_)(param1_, param2_);
740  }
741 
742  Solver::DemonPriority priority() const override {
744  }
745 
746  std::string DebugString() const override {
747  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
748  absl::StrCat("(", constraint_->DebugString()),
749  absl::StrCat(", ", ParameterDebugString(param1_)),
750  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
751  }
752 
753  private:
754  T* const constraint_;
755  void (T::*const method_)(P, Q);
756  const std::string name_;
757  P param1_;
758  Q param2_;
759 };
760 
761 template <class T, class P, class Q>
762 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
763  void (T::*method)(P, Q),
764  const std::string& name, P param1,
765  Q param2) {
766  return s->RevAlloc(
767  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
768 }
770 
771 #endif // !defined(SWIG)
772 
773 // ----- LightIntFunctionElementCt -----
774 
775 template <typename F>
777  public:
779  IntVar* const index, F values,
780  std::function<bool()> deep_serialize)
781  : Constraint(solver),
782  var_(var),
783  index_(index),
784  values_(std::move(values)),
785  deep_serialize_(std::move(deep_serialize)) {}
787 
788  void Post() override {
789  Demon* demon = MakeConstraintDemon0(
790  solver(), this, &LightIntFunctionElementCt::IndexBound, "IndexBound");
791  index_->WhenBound(demon);
792  }
793 
794  void InitialPropagate() override {
795  if (index_->Bound()) {
796  IndexBound();
797  }
798  }
799 
800  std::string DebugString() const override {
801  return absl::StrFormat("LightIntFunctionElementCt(%s, %s)",
802  var_->DebugString(), index_->DebugString());
803  }
804 
805  void Accept(ModelVisitor* const visitor) const override {
808  var_);
810  index_);
811  // Warning: This will expand all values into a vector.
812  if (deep_serialize_ == nullptr || deep_serialize_()) {
813  visitor->VisitInt64ToInt64Extension(values_, index_->Min(),
814  index_->Max());
815  }
817  }
818 
819  private:
820  void IndexBound() { var_->SetValue(values_(index_->Min())); }
821 
822  IntVar* const var_;
823  IntVar* const index_;
824  F values_;
825  std::function<bool()> deep_serialize_;
826 };
827 
828 // ----- LightIntIntFunctionElementCt -----
829 
830 template <typename F>
832  public:
834  IntVar* const index1, IntVar* const index2,
835  F values, std::function<bool()> deep_serialize)
836  : Constraint(solver),
837  var_(var),
838  index1_(index1),
839  index2_(index2),
840  values_(std::move(values)),
841  deep_serialize_(std::move(deep_serialize)) {}
843  void Post() override {
844  Demon* demon = MakeConstraintDemon0(
845  solver(), this, &LightIntIntFunctionElementCt::IndexBound,
846  "IndexBound");
847  index1_->WhenBound(demon);
848  index2_->WhenBound(demon);
849  }
850  void InitialPropagate() override { IndexBound(); }
851 
852  std::string DebugString() const override {
853  return "LightIntIntFunctionElementCt";
854  }
855 
856  void Accept(ModelVisitor* const visitor) const override {
859  var_);
861  index1_);
863  index2_);
864  // Warning: This will expand all values into a vector.
865  const int64_t index1_min = index1_->Min();
866  const int64_t index1_max = index1_->Max();
867  visitor->VisitIntegerArgument(ModelVisitor::kMinArgument, index1_min);
868  visitor->VisitIntegerArgument(ModelVisitor::kMaxArgument, index1_max);
869  if (deep_serialize_ == nullptr || deep_serialize_()) {
870  for (int i = index1_min; i <= index1_max; ++i) {
872  [this, i](int64_t j) { return values_(i, j); }, index2_->Min(),
873  index2_->Max());
874  }
875  }
877  }
878 
879  private:
880  void IndexBound() {
881  if (index1_->Bound() && index2_->Bound()) {
882  var_->SetValue(values_(index1_->Min(), index2_->Min()));
883  }
884  }
885 
886  IntVar* const var_;
887  IntVar* const index1_;
888  IntVar* const index2_;
889  Solver::IndexEvaluator2 values_;
890  std::function<bool()> deep_serialize_;
891 };
892 
910 // TODO(user): rename Start to Synchronize ?
911 // TODO(user): decouple the iterating from the defining of a neighbor.
913  public:
915  ~LocalSearchOperator() override {}
916  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
917  virtual void Start(const Assignment* assignment) = 0;
918  virtual void Reset() {}
919 #ifndef SWIG
920  virtual const LocalSearchOperator* Self() const { return this; }
921 #endif // SWIG
922  virtual bool HasFragments() const { return false; }
923  virtual bool HoldsDelta() const { return false; }
924 };
925 
927  public:
929 
931  max_inversible_index_ = candidate_values_.size();
932  candidate_value_to_index_.resize(max_value + 1, -1);
933  committed_value_to_index_.resize(max_value + 1, -1);
934  }
935 
938  int64_t CandidateValue(int64_t index) const {
939  DCHECK_LT(index, candidate_values_.size());
940  return candidate_values_[index];
941  }
942  int64_t CommittedValue(int64_t index) const {
943  return committed_values_[index];
944  }
945  int64_t CheckPointValue(int64_t index) const {
946  return checkpoint_values_[index];
947  }
948  void SetCandidateValue(int64_t index, int64_t value) {
949  candidate_values_[index] = value;
950  if (index < max_inversible_index_) {
951  candidate_value_to_index_[value] = index;
952  }
953  MarkChange(index);
954  }
955 
956  bool CandidateIsActive(int64_t index) const {
957  return candidate_is_active_[index];
958  }
959  void SetCandidateActive(int64_t index, bool active) {
960  if (active) {
961  candidate_is_active_.Set(index);
962  } else {
963  candidate_is_active_.Clear(index);
964  }
965  MarkChange(index);
966  }
967 
968  void Commit() {
969  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
970  const int64_t value = candidate_values_[index];
971  committed_values_[index] = value;
972  if (index < max_inversible_index_) {
973  committed_value_to_index_[value] = index;
974  }
975  committed_is_active_.CopyBucket(candidate_is_active_, index);
976  }
977  changes_.SparseClearAll();
978  incremental_changes_.SparseClearAll();
979  }
980 
981  void CheckPoint() { checkpoint_values_ = committed_values_; }
982 
983  void Revert(bool only_incremental) {
984  incremental_changes_.SparseClearAll();
985  if (only_incremental) return;
986 
987  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
988  const int64_t committed_value = committed_values_[index];
989  candidate_values_[index] = committed_value;
990  if (index < max_inversible_index_) {
991  candidate_value_to_index_[committed_value] = index;
992  }
993  candidate_is_active_.CopyBucket(committed_is_active_, index);
994  }
995  changes_.SparseClearAll();
996  }
997 
998  const std::vector<int64_t>& CandidateIndicesChanged() const {
999  return changes_.PositionsSetAtLeastOnce();
1000  }
1001  const std::vector<int64_t>& IncrementalIndicesChanged() const {
1002  return incremental_changes_.PositionsSetAtLeastOnce();
1003  }
1004 
1005  void Resize(int size) {
1006  candidate_values_.resize(size);
1007  committed_values_.resize(size);
1008  checkpoint_values_.resize(size);
1009  candidate_is_active_.Resize(size);
1010  committed_is_active_.Resize(size);
1011  changes_.ClearAndResize(size);
1012  incremental_changes_.ClearAndResize(size);
1013  }
1014 
1015  int64_t CandidateInverseValue(int64_t value) const {
1016  return candidate_value_to_index_[value];
1017  }
1018  int64_t CommittedInverseValue(int64_t value) const {
1019  return committed_value_to_index_[value];
1020  }
1021 
1022  private:
1023  void MarkChange(int64_t index) {
1024  incremental_changes_.Set(index);
1025  changes_.Set(index);
1026  }
1027 
1028  std::vector<int64_t> candidate_values_;
1029  std::vector<int64_t> committed_values_;
1030  std::vector<int64_t> checkpoint_values_;
1031 
1032  Bitset64<> candidate_is_active_;
1033  Bitset64<> committed_is_active_;
1034 
1035  SparseBitset<> changes_;
1036  SparseBitset<> incremental_changes_;
1037 
1038  int64_t max_inversible_index_ = -1;
1039  std::vector<int64_t> candidate_value_to_index_;
1040  std::vector<int64_t> committed_value_to_index_;
1041 };
1042 
1049  public:
1050  // If keep_inverse_values is true, assumes that vars models an injective
1051  // function f with domain [0, vars.size()) in which case the operator will
1052  // maintain the inverse function.
1053  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1054  bool keep_inverse_values = false) {
1055  AddVars(vars);
1056  if (keep_inverse_values) {
1057  int64_t max_value = -1;
1058  for (const IntVar* const var : vars) {
1059  max_value = std::max(max_value, var->Max());
1060  }
1062  }
1063  }
1065 
1066  bool HoldsDelta() const override { return true; }
1069  void Start(const Assignment* assignment) override {
1070  state_.CheckPoint();
1071  RevertChanges(false);
1072  const int size = Size();
1073  CHECK_LE(size, assignment->Size())
1074  << "Assignment contains fewer variables than operator";
1075  const Assignment::IntContainer& container = assignment->IntVarContainer();
1076  for (int i = 0; i < size; ++i) {
1077  const IntVarElement* element = &(container.Element(i));
1078  if (element->Var() != vars_[i]) {
1079  CHECK(container.Contains(vars_[i]))
1080  << "Assignment does not contain operator variable " << vars_[i];
1081  element = &(container.Element(vars_[i]));
1082  }
1083  state_.SetCandidateValue(i, element->Value());
1084  state_.SetCandidateActive(i, element->Activated());
1085  }
1086  state_.Commit();
1087  OnStart();
1088  }
1089  virtual bool IsIncremental() const { return false; }
1090 
1091  int Size() const { return vars_.size(); }
1094  int64_t Value(int64_t index) const {
1095  DCHECK_LT(index, vars_.size());
1096  return state_.CandidateValue(index);
1097  }
1099  IntVar* Var(int64_t index) const { return vars_[index]; }
1100  virtual bool SkipUnchanged(int index) const { return false; }
1101  int64_t OldValue(int64_t index) const { return state_.CommittedValue(index); }
1102  int64_t PrevValue(int64_t index) const {
1103  return state_.CheckPointValue(index);
1104  }
1105  void SetValue(int64_t index, int64_t value) {
1106  state_.SetCandidateValue(index, value);
1107  }
1108  bool Activated(int64_t index) const {
1109  return state_.CandidateIsActive(index);
1110  }
1111  void Activate(int64_t index) { state_.SetCandidateActive(index, true); }
1112  void Deactivate(int64_t index) { state_.SetCandidateActive(index, false); }
1113 
1114  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
1115  if (IsIncremental() && candidate_has_changes_) {
1116  for (const int64_t index : state_.IncrementalIndicesChanged()) {
1117  IntVar* var = Var(index);
1118  const int64_t value = Value(index);
1119  const bool activated = Activated(index);
1120  AddToAssignment(var, value, activated, nullptr, index, deltadelta);
1121  AddToAssignment(var, value, activated, &assignment_indices_, index,
1122  delta);
1123  }
1124  } else {
1125  delta->Clear();
1126  for (const int64_t index : state_.CandidateIndicesChanged()) {
1127  const int64_t value = Value(index);
1128  const bool activated = Activated(index);
1129  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
1130  AddToAssignment(Var(index), value, activated, &assignment_indices_,
1131  index, delta);
1132  }
1133  }
1134  }
1135  return true;
1136  }
1137 
1138  void RevertChanges(bool change_was_incremental) {
1139  candidate_has_changes_ = change_was_incremental && IsIncremental();
1140 
1141  if (!candidate_has_changes_) {
1142  for (const int64_t index : state_.CandidateIndicesChanged()) {
1143  assignment_indices_[index] = -1;
1144  }
1145  }
1146  state_.Revert(candidate_has_changes_);
1147  }
1148 
1149  void AddVars(const std::vector<IntVar*>& vars) {
1150  if (!vars.empty()) {
1151  vars_.insert(vars_.end(), vars.begin(), vars.end());
1152  const int64_t size = Size();
1153  assignment_indices_.resize(size, -1);
1154  state_.Resize(size);
1155  }
1156  }
1157 
1161  virtual void OnStart() {}
1162 
1165 
1172  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1173 
1174  protected:
1177  // TODO(user): make it pure virtual, implies porting all apps overriding
1179  virtual bool MakeOneNeighbor();
1180 
1181  int64_t InverseValue(int64_t index) const {
1182  return state_.CandidateInverseValue(index);
1183  }
1184  int64_t OldInverseValue(int64_t index) const {
1185  return state_.CommittedInverseValue(index);
1186  }
1187 
1188  void AddToAssignment(IntVar* var, int64_t value, bool active,
1189  std::vector<int>* assignment_indices, int64_t index,
1190  Assignment* assignment) const {
1191  Assignment::IntContainer* const container =
1192  assignment->MutableIntVarContainer();
1193  IntVarElement* element = nullptr;
1194  if (assignment_indices != nullptr) {
1195  if ((*assignment_indices)[index] == -1) {
1196  (*assignment_indices)[index] = container->Size();
1197  element = assignment->FastAdd(var);
1198  } else {
1199  element = container->MutableElement((*assignment_indices)[index]);
1200  }
1201  } else {
1202  element = assignment->FastAdd(var);
1203  }
1204  if (active) {
1205  element->SetValue(value);
1206  element->Activate();
1207  } else {
1208  element->Deactivate();
1209  }
1210  }
1211 
1212  private:
1213  std::vector<IntVar*> vars_;
1214  mutable std::vector<int> assignment_indices_;
1215  bool candidate_has_changes_ = false;
1216 
1217  LocalSearchOperatorState state_;
1218 };
1219 
1248  public:
1249  explicit BaseLns(const std::vector<IntVar*>& vars);
1250  ~BaseLns() override;
1251  virtual void InitFragments();
1252  virtual bool NextFragment() = 0;
1253  void AppendToFragment(int index);
1254  int FragmentSize() const;
1255  bool HasFragments() const override { return true; }
1256 
1257  protected:
1259  bool MakeOneNeighbor() override;
1260 
1261  private:
1263  void OnStart() override;
1264  std::vector<int> fragment_;
1265 };
1266 
1272  public:
1273  explicit ChangeValue(const std::vector<IntVar*>& vars);
1274  ~ChangeValue() override;
1275  virtual int64_t ModifyValue(int64_t index, int64_t value) = 0;
1276 
1277  protected:
1279  bool MakeOneNeighbor() override;
1280 
1281  private:
1282  void OnStart() override;
1283 
1284  int index_;
1285 };
1286 
1301  public:
1321  std::function<int(int64_t)> start_empty_path_class;
1322  };
1324  PathOperator(const std::vector<IntVar*>& next_vars,
1325  const std::vector<IntVar*>& path_vars,
1326  IterationParameters iteration_parameters);
1327  PathOperator(const std::vector<IntVar*>& next_vars,
1328  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1329  bool skip_locally_optimal_paths, bool accept_path_end_base,
1330  std::function<int(int64_t)> start_empty_path_class)
1331  : PathOperator(
1332  next_vars, path_vars,
1333  {number_of_base_nodes, skip_locally_optimal_paths,
1334  accept_path_end_base, std::move(start_empty_path_class)}) {}
1335  ~PathOperator() override {}
1336  virtual bool MakeNeighbor() = 0;
1337  void Reset() override;
1338 
1339  // TODO(user): Make the following methods protected.
1340  bool SkipUnchanged(int index) const override;
1341 
1343  int64_t Next(int64_t node) const {
1344  DCHECK(!IsPathEnd(node));
1345  return Value(node);
1346  }
1347 
1349  int64_t Prev(int64_t node) const {
1350  DCHECK(!IsPathStart(node));
1351  DCHECK_EQ(Next(InverseValue(node)), node);
1352  return InverseValue(node);
1353  }
1354 
1357  int64_t Path(int64_t node) const {
1358  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1359  }
1360 
1362  int number_of_nexts() const { return number_of_nexts_; }
1363 
1364  protected:
1366  bool MakeOneNeighbor() override;
1370  virtual void OnNodeInitialization() {}
1371 
1373  int64_t BaseNode(int i) const { return base_nodes_[i]; }
1375  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1377  int64_t BaseAlternativeNode(int i) const {
1378  if (!ConsiderAlternatives(i)) return BaseNode(i);
1379  const int alternative_index = alternative_index_[BaseNode(i)];
1380  return alternative_index >= 0
1381  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1382  : BaseNode(i);
1383  }
1385  int BaseSiblingAlternative(int i) const {
1386  return base_sibling_alternatives_[i];
1387  }
1389  int64_t BaseSiblingAlternativeNode(int i) const {
1390  if (!ConsiderAlternatives(i)) return BaseNode(i);
1391  const int sibling_alternative_index =
1393  return sibling_alternative_index >= 0
1394  ? alternative_sets_[sibling_alternative_index]
1395  [base_sibling_alternatives_[i]]
1396  : BaseNode(i);
1397  }
1399  int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1401  int64_t EndNode(int i) const { return path_ends_[base_paths_[i]]; }
1403  const std::vector<int64_t>& path_starts() const { return path_starts_; }
1405  int PathClass(int i) const {
1406  return iteration_parameters_.start_empty_path_class != nullptr
1407  ? iteration_parameters_.start_empty_path_class(StartNode(i))
1408  : StartNode(i);
1409  }
1410 
1417  // TODO(user): remove this when automatic detection of such cases in done.
1418  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1422  // TODO(user): ideally this should be OnSamePath(int64_t node1, int64_t
1423  // node2);
1425  virtual bool OnSamePathAsPreviousBase(int64_t base_index) { return false; }
1431  virtual int64_t GetBaseNodeRestartPosition(int base_index) {
1432  return StartNode(base_index);
1433  }
1436  virtual void SetNextBaseToIncrement(int64_t base_index) {
1437  next_base_to_increment_ = base_index;
1438  }
1441  virtual bool ConsiderAlternatives(int64_t base_index) const { return false; }
1442 
1443  int64_t OldNext(int64_t node) const {
1444  DCHECK(!IsPathEnd(node));
1445  return OldValue(node);
1446  }
1447 
1448  int64_t PrevNext(int64_t node) const {
1449  DCHECK(!IsPathEnd(node));
1450  return PrevValue(node);
1451  }
1452 
1453  int64_t OldPrev(int64_t node) const {
1454  DCHECK(!IsPathStart(node));
1455  return OldInverseValue(node);
1456  }
1457 
1458  int64_t OldPath(int64_t node) const {
1459  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1460  }
1461 
1464  bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination);
1465 
1468  bool ReverseChain(int64_t before_chain, int64_t after_chain,
1469  int64_t* chain_last);
1470 
1472  bool MakeActive(int64_t node, int64_t destination);
1475  bool MakeChainInactive(int64_t before_chain, int64_t chain_end);
1477  bool SwapActiveAndInactive(int64_t active, int64_t inactive);
1478 
1480  void SetNext(int64_t from, int64_t to, int64_t path) {
1481  DCHECK_LT(from, number_of_nexts_);
1482  SetValue(from, to);
1483  if (!ignore_path_vars_) {
1484  DCHECK_LT(from + number_of_nexts_, Size());
1485  SetValue(from + number_of_nexts_, path);
1486  }
1487  }
1488 
1491  bool IsPathEnd(int64_t node) const { return node >= number_of_nexts_; }
1492 
1494  bool IsPathStart(int64_t node) const { return OldInverseValue(node) == -1; }
1495 
1497  bool IsInactive(int64_t node) const {
1498  return !IsPathEnd(node) && inactives_[node];
1499  }
1500 
1503  virtual bool InitPosition() const { return false; }
1507  void ResetPosition() { just_started_ = true; }
1508 
1512  int AddAlternativeSet(const std::vector<int64_t>& alternative_set) {
1513  const int alternative = alternative_sets_.size();
1514  for (int64_t node : alternative_set) {
1515  DCHECK_EQ(-1, alternative_index_[node]);
1516  alternative_index_[node] = alternative;
1517  }
1518  alternative_sets_.push_back(alternative_set);
1519  sibling_alternative_.push_back(-1);
1520  return alternative;
1521  }
1522 #ifndef SWIG
1526  const std::vector<std::pair<std::vector<int64_t>, std::vector<int64_t>>>&
1527  pair_alternative_sets) {
1528  for (const auto& pair_alternative_set : pair_alternative_sets) {
1529  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1530  sibling_alternative_.back() = alternative + 1;
1531  AddAlternativeSet(pair_alternative_set.second);
1532  }
1533  }
1534 #endif // SWIG
1536  int64_t GetActiveInAlternativeSet(int alternative_index) const {
1537  return alternative_index >= 0
1538  ? active_in_alternative_set_[alternative_index]
1539  : -1;
1540  }
1542  int64_t GetActiveAlternativeNode(int node) const {
1543  return GetActiveInAlternativeSet(alternative_index_[node]);
1544  }
1546  int GetSiblingAlternativeIndex(int node) const {
1547  if (node >= alternative_index_.size()) return -1;
1548  const int alternative = alternative_index_[node];
1549  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1550  }
1553  int64_t GetActiveAlternativeSibling(int node) const {
1554  if (node >= alternative_index_.size()) return -1;
1555  const int alternative = alternative_index_[node];
1556  const int sibling_alternative =
1557  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1558  return GetActiveInAlternativeSet(sibling_alternative);
1559  }
1562  bool CheckChainValidity(int64_t before_chain, int64_t chain_end,
1563  int64_t exclude) const;
1564 
1565  const int number_of_nexts_;
1566  const bool ignore_path_vars_;
1568  int num_paths_ = 0;
1569  std::vector<int64_t> start_to_path_;
1570 
1571  private:
1572  void OnStart() override;
1574  bool OnSamePath(int64_t node1, int64_t node2) const;
1575 
1576  bool CheckEnds() const {
1577  const int base_node_size = base_nodes_.size();
1578  for (int i = base_node_size - 1; i >= 0; --i) {
1579  if (base_nodes_[i] != end_nodes_[i]) {
1580  return true;
1581  }
1582  }
1583  return false;
1584  }
1585  bool IncrementPosition();
1586  void InitializePathStarts();
1587  void InitializeInactives();
1588  void InitializeBaseNodes();
1589  void InitializeAlternatives();
1590  void Synchronize();
1591 
1592  std::vector<int> base_nodes_;
1593  std::vector<int> base_alternatives_;
1594  std::vector<int> base_sibling_alternatives_;
1595  std::vector<int> end_nodes_;
1596  std::vector<int> base_paths_;
1597  std::vector<int64_t> path_starts_;
1598  std::vector<int64_t> path_ends_;
1599  std::vector<bool> inactives_;
1600  bool just_started_;
1601  bool first_start_;
1602  IterationParameters iteration_parameters_;
1603  bool optimal_paths_enabled_;
1604  std::vector<int> path_basis_;
1605  std::vector<bool> optimal_paths_;
1607 #ifndef SWIG
1608  std::vector<std::vector<int64_t>> alternative_sets_;
1609 #endif // SWIG
1610  std::vector<int> alternative_index_;
1611  std::vector<int64_t> active_in_alternative_set_;
1612  std::vector<int> sibling_alternative_;
1613 };
1614 
1616 template <class T>
1618  Solver* solver, const std::vector<IntVar*>& vars,
1619  const std::vector<IntVar*>& secondary_vars,
1620  std::function<int(int64_t)> start_empty_path_class);
1621 
1636 
1637 #if !defined(SWIG)
1638 // A LocalSearchState is a container for variables with bounds that can be
1639 // relaxed and tightened, saved and restored. It represents the solution state
1640 // of a local search engine, and allows it to go from solution to solution by
1641 // relaxing some variables to form a new subproblem, then tightening those
1642 // variables to move to a new solution representation. That state may be saved
1643 // to an internal copy, or reverted to the last saved internal copy.
1644 // Relaxing a variable returns its bounds to their initial state.
1645 // Tightening a variable's bounds may make its min larger than its max,
1646 // in that case, the tightening function will return false, and the state will
1647 // be marked as invalid. No other operations than Revert() can be called on an
1648 // invalid state: in particular, an invalid state cannot be saved.
1649 class LocalSearchVariable;
1650 
1652  public:
1653  LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max);
1654  void Commit();
1655  void Revert();
1656  bool StateIsValid() const { return state_is_valid_; }
1657 
1658  private:
1659  friend class LocalSearchVariable;
1660 
1661  struct Bounds {
1662  int64_t min;
1663  int64_t max;
1664  };
1665 
1666  void RelaxVariableBounds(int variable_index);
1667  bool TightenVariableMin(int variable_index, int64_t value);
1668  bool TightenVariableMax(int variable_index, int64_t value);
1669  int64_t VariableMin(int variable_index) const;
1670  int64_t VariableMax(int variable_index) const;
1671 
1672  std::vector<Bounds> initial_variable_bounds_;
1673  std::vector<Bounds> variable_bounds_;
1674  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1675  std::vector<bool> variable_is_relaxed_;
1676  bool state_is_valid_ = true;
1677 };
1678 
1679 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1680 // meant to be passed by copy. If at some point the duplication of
1681 // LocalSearchState pointers is too expensive, we could switch to index only,
1682 // and the user would have to know the relevant state. The present setup allows
1683 // to ensure that variable users will not misuse the state.
1685  public:
1686  int64_t Min() const { return state_->VariableMin(variable_index_); }
1687  int64_t Max() const { return state_->VariableMax(variable_index_); }
1688  bool SetMin(int64_t new_min) {
1689  return state_->TightenVariableMin(variable_index_, new_min);
1690  }
1691  bool SetMax(int64_t new_max) {
1692  return state_->TightenVariableMax(variable_index_, new_max);
1693  }
1694  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1695 
1696  private:
1697  // Only LocalSearchState can construct LocalSearchVariables.
1698  friend class LocalSearchState;
1699 
1700  LocalSearchVariable(LocalSearchState* state, int variable_index)
1701  : state_(state), variable_index_(variable_index) {}
1702 
1703  LocalSearchState* const state_;
1704  const int variable_index_;
1705 };
1706 #endif // !defined(SWIG)
1707 
1725  public:
1728  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1730  virtual void Commit(const Assignment* delta, const Assignment* deltadelta) {}
1731 
1741  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1742  int64_t objective_min, int64_t objective_max) = 0;
1743  virtual bool IsIncremental() const { return false; }
1744 
1750  virtual void Synchronize(const Assignment* assignment,
1751  const Assignment* delta) = 0;
1753  virtual void Revert() {}
1754 
1756  virtual void Reset() {}
1757 
1759  virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; }
1761  // If the last Accept() call returned false, returns an undefined value.
1762  virtual int64_t GetAcceptedObjectiveValue() const { return 0LL; }
1763 };
1764 
1769  public:
1770  // This class is responsible for calling filters methods in a correct order.
1771  // For now, an order is specified explicitly by the user.
1772  enum FilterEventType { kAccept, kRelax };
1773  struct FilterEvent {
1777  };
1778 
1779  std::string DebugString() const override {
1780  return "LocalSearchFilterManager";
1781  }
1782  // Builds a manager that calls filter methods ordered by increasing priority.
1783  // Note that some filters might appear only once, if their Relax() or Accept()
1784  // are trivial.
1785  explicit LocalSearchFilterManager(std::vector<FilterEvent> filter_events);
1786  // Builds a manager that calls filter methods using the following ordering:
1787  // first Relax() in vector order, then Accept() in vector order.
1788  explicit LocalSearchFilterManager(std::vector<LocalSearchFilter*> filters);
1789 
1790  // Calls Revert() of filters, in reverse order of Relax events.
1791  void Revert();
1795  bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta,
1796  const Assignment* deltadelta, int64_t objective_min,
1797  int64_t objective_max);
1799  void Synchronize(const Assignment* assignment, const Assignment* delta);
1800  int64_t GetSynchronizedObjectiveValue() const { return synchronized_value_; }
1801  int64_t GetAcceptedObjectiveValue() const { return accepted_value_; }
1802 
1803  private:
1804  // Finds the last event (incremental -itself- or not) with the same priority
1805  // as the last incremental event.
1806  void FindIncrementalEventEnd();
1807 
1808  std::vector<FilterEvent> events_;
1809  int last_event_called_ = -1;
1810  // If a filter is incremental, its Relax() and Accept() must be called for
1811  // every candidate, even if the Accept() of a prior filter rejected it.
1812  // To ensure that those incremental filters have consistent inputs, all
1813  // intermediate events with Relax() must also be called.
1814  int incremental_events_end_ = 0;
1815  int64_t synchronized_value_;
1816  int64_t accepted_value_;
1817 };
1818 
1820  public:
1821  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1825  void Synchronize(const Assignment* assignment,
1826  const Assignment* delta) override;
1827 
1828  bool FindIndex(IntVar* const var, int64_t* index) const {
1829  DCHECK(index != nullptr);
1830  const int var_index = var->index();
1831  *index = (var_index < var_index_to_index_.size())
1832  ? var_index_to_index_[var_index]
1833  : kUnassigned;
1834  return *index != kUnassigned;
1835  }
1836 
1838  void AddVars(const std::vector<IntVar*>& vars);
1839  int Size() const { return vars_.size(); }
1840  IntVar* Var(int index) const { return vars_[index]; }
1841  int64_t Value(int index) const {
1842  DCHECK(IsVarSynced(index));
1843  return values_[index];
1844  }
1845  bool IsVarSynced(int index) const { return var_synced_[index]; }
1846 
1847  protected:
1848  virtual void OnSynchronize(const Assignment* delta) {}
1849  void SynchronizeOnAssignment(const Assignment* assignment);
1850 
1851  private:
1852  std::vector<IntVar*> vars_;
1853  std::vector<int64_t> values_;
1854  std::vector<bool> var_synced_;
1855  std::vector<int> var_index_to_index_;
1856  static const int kUnassigned;
1857 };
1858 
1860  public:
1861  explicit PropagationMonitor(Solver* const solver);
1863  std::string DebugString() const override { return "PropagationMonitor"; }
1864 
1867  Constraint* const constraint) = 0;
1869  Constraint* const constraint) = 0;
1871  Constraint* const parent, Constraint* const nested) = 0;
1873  Constraint* const parent, Constraint* const nested) = 0;
1874  virtual void RegisterDemon(Demon* const demon) = 0;
1875  virtual void BeginDemonRun(Demon* const demon) = 0;
1876  virtual void EndDemonRun(Demon* const demon) = 0;
1877  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1878  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1879  virtual void PushContext(const std::string& context) = 0;
1880  virtual void PopContext() = 0;
1882  virtual void SetMin(IntExpr* const expr, int64_t new_min) = 0;
1883  virtual void SetMax(IntExpr* const expr, int64_t new_max) = 0;
1884  virtual void SetRange(IntExpr* const expr, int64_t new_min,
1885  int64_t new_max) = 0;
1887  virtual void SetMin(IntVar* const var, int64_t new_min) = 0;
1888  virtual void SetMax(IntVar* const var, int64_t new_max) = 0;
1889  virtual void SetRange(IntVar* const var, int64_t new_min,
1890  int64_t new_max) = 0;
1891  virtual void RemoveValue(IntVar* const var, int64_t value) = 0;
1892  virtual void SetValue(IntVar* const var, int64_t value) = 0;
1893  virtual void RemoveInterval(IntVar* const var, int64_t imin,
1894  int64_t imax) = 0;
1895  virtual void SetValues(IntVar* const var,
1896  const std::vector<int64_t>& values) = 0;
1897  virtual void RemoveValues(IntVar* const var,
1898  const std::vector<int64_t>& values) = 0;
1900  virtual void SetStartMin(IntervalVar* const var, int64_t new_min) = 0;
1901  virtual void SetStartMax(IntervalVar* const var, int64_t new_max) = 0;
1902  virtual void SetStartRange(IntervalVar* const var, int64_t new_min,
1903  int64_t new_max) = 0;
1904  virtual void SetEndMin(IntervalVar* const var, int64_t new_min) = 0;
1905  virtual void SetEndMax(IntervalVar* const var, int64_t new_max) = 0;
1906  virtual void SetEndRange(IntervalVar* const var, int64_t new_min,
1907  int64_t new_max) = 0;
1908  virtual void SetDurationMin(IntervalVar* const var, int64_t new_min) = 0;
1909  virtual void SetDurationMax(IntervalVar* const var, int64_t new_max) = 0;
1910  virtual void SetDurationRange(IntervalVar* const var, int64_t new_min,
1911  int64_t new_max) = 0;
1912  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1914  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1915  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1916  virtual void RankLast(SequenceVar* const var, int index) = 0;
1917  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1918  virtual void RankSequence(SequenceVar* const var,
1919  const std::vector<int>& rank_first,
1920  const std::vector<int>& rank_last,
1921  const std::vector<int>& unperformed) = 0;
1923  void Install() override;
1924 };
1925 
1927  // TODO(user): Add monitoring of local search filters.
1928  public:
1929  explicit LocalSearchMonitor(Solver* const solver);
1931  std::string DebugString() const override { return "LocalSearchMonitor"; }
1932 
1934  virtual void BeginOperatorStart() = 0;
1935  virtual void EndOperatorStart() = 0;
1936  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1938  bool neighbor_found, const Assignment* delta,
1939  const Assignment* deltadelta) = 0;
1940  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1941  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1942  bool neighbor_found) = 0;
1943  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1944  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1945  bool neighbor_found) = 0;
1946  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1947  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1948 
1950  void Install() override;
1951 };
1952 
1953 class BooleanVar : public IntVar {
1954  public:
1955  static const int kUnboundBooleanVarValue;
1956 
1957  explicit BooleanVar(Solver* const s, const std::string& name = "")
1958  : IntVar(s, name), value_(kUnboundBooleanVarValue) {}
1959 
1960  ~BooleanVar() override {}
1961 
1962  int64_t Min() const override { return (value_ == 1); }
1963  void SetMin(int64_t m) override;
1964  int64_t Max() const override { return (value_ != 0); }
1965  void SetMax(int64_t m) override;
1966  void SetRange(int64_t mi, int64_t ma) override;
1967  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1968  int64_t Value() const override {
1969  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1970  return value_;
1971  }
1972  void RemoveValue(int64_t v) override;
1973  void RemoveInterval(int64_t l, int64_t u) override;
1974  void WhenBound(Demon* d) override;
1975  void WhenRange(Demon* d) override { WhenBound(d); }
1976  void WhenDomain(Demon* d) override { WhenBound(d); }
1977  uint64_t Size() const override;
1978  bool Contains(int64_t v) const override;
1979  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1980  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1981  std::string DebugString() const override;
1982  int VarType() const override { return BOOLEAN_VAR; }
1983 
1984  IntVar* IsEqual(int64_t constant) override;
1985  IntVar* IsDifferent(int64_t constant) override;
1986  IntVar* IsGreaterOrEqual(int64_t constant) override;
1987  IntVar* IsLessOrEqual(int64_t constant) override;
1988 
1989  virtual void RestoreValue() = 0;
1990  std::string BaseName() const override { return "BooleanVar"; }
1991 
1992  int RawValue() const { return value_; }
1993 
1994  protected:
1995  int value_;
1998 };
1999 
2000 class SymmetryManager;
2001 
2006  public:
2008  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
2009  ~SymmetryBreaker() override {}
2010 
2011  void AddIntegerVariableEqualValueClause(IntVar* const var, int64_t value);
2013  int64_t value);
2015  int64_t value);
2016 
2017  private:
2018  friend class SymmetryManager;
2019  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
2020  CHECK(symmetry_manager_ == nullptr);
2021  CHECK_EQ(-1, index_in_symmetry_manager_);
2022  symmetry_manager_ = manager;
2023  index_in_symmetry_manager_ = index;
2024  }
2025  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
2026  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
2027 
2028  SymmetryManager* symmetry_manager_;
2030  int index_in_symmetry_manager_;
2031 };
2032 
2035 class SearchLog : public SearchMonitor {
2036  public:
2037  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2038  double scaling_factor, double offset,
2039  std::function<std::string()> display_callback,
2040  bool display_on_new_solutions_only, int period);
2041  ~SearchLog() override;
2042  void EnterSearch() override;
2043  void ExitSearch() override;
2044  bool AtSolution() override;
2045  void BeginFail() override;
2046  void NoMoreSolutions() override;
2047  void AcceptUncheckedNeighbor() override;
2048  void ApplyDecision(Decision* const decision) override;
2049  void RefuteDecision(Decision* const decision) override;
2051  void Maintain();
2052  void BeginInitialPropagation() override;
2053  void EndInitialPropagation() override;
2054  std::string DebugString() const override;
2055 
2056  protected:
2057  /* Bottleneck function used for all UI related output. */
2058  virtual void OutputLine(const std::string& line);
2059 
2060  private:
2061  static std::string MemoryUsage();
2062 
2063  const int period_;
2064  std::unique_ptr<WallTimer> timer_;
2065  IntVar* const var_;
2066  OptimizeVar* const obj_;
2067  const double scaling_factor_;
2068  const double offset_;
2069  std::function<std::string()> display_callback_;
2070  const bool display_on_new_solutions_only_;
2071  int nsol_;
2072  int64_t tick_;
2073  int64_t objective_min_;
2074  int64_t objective_max_;
2075  int min_right_depth_;
2076  int max_depth_;
2077  int sliding_min_depth_;
2078  int sliding_max_depth_;
2079 };
2080 
2085 class ModelCache {
2086  public:
2088  VOID_FALSE_CONSTRAINT = 0,
2091  };
2092 
2094  VAR_CONSTANT_EQUALITY = 0,
2099  };
2100 
2102  VAR_CONSTANT_CONSTANT_BETWEEN = 0,
2104  };
2105 
2107  EXPR_EXPR_EQUALITY = 0,
2114  };
2115 
2117  EXPR_OPPOSITE = 0,
2121  };
2122 
2124  EXPR_EXPR_DIFFERENCE = 0,
2135  };
2136 
2138  EXPR_EXPR_CONSTANT_CONDITIONAL = 0,
2140  };
2141 
2143  EXPR_CONSTANT_DIFFERENCE = 0,
2154  };
2156  VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS = 0,
2158  };
2159 
2161  VAR_CONSTANT_ARRAY_ELEMENT = 0,
2163  };
2164 
2166  VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD = 0,
2168  };
2169 
2171  VAR_ARRAY_MAX = 0,
2175  };
2176 
2178  VAR_ARRAY_CONSTANT_INDEX = 0,
2180  };
2181 
2182  explicit ModelCache(Solver* const solver);
2183  virtual ~ModelCache();
2184 
2185  virtual void Clear() = 0;
2186 
2188 
2190 
2191  virtual void InsertVoidConstraint(Constraint* const ct,
2192  VoidConstraintType type) = 0;
2193 
2196  IntVar* const var, int64_t value,
2197  VarConstantConstraintType type) const = 0;
2198 
2199  virtual void InsertVarConstantConstraint(Constraint* const ct,
2200  IntVar* const var, int64_t value,
2201  VarConstantConstraintType type) = 0;
2202 
2204 
2206  IntVar* const var, int64_t value1, int64_t value2,
2207  VarConstantConstantConstraintType type) const = 0;
2208 
2210  Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2,
2212 
2214 
2216  IntExpr* const expr1, IntExpr* const expr2,
2217  ExprExprConstraintType type) const = 0;
2218 
2219  virtual void InsertExprExprConstraint(Constraint* const ct,
2220  IntExpr* const expr1,
2221  IntExpr* const expr2,
2222  ExprExprConstraintType type) = 0;
2223 
2225 
2226  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2227  ExprExpressionType type) const = 0;
2228 
2229  virtual void InsertExprExpression(IntExpr* const expression,
2230  IntExpr* const expr,
2231  ExprExpressionType type) = 0;
2232 
2234 
2236  IntExpr* const expr, int64_t value,
2237  ExprConstantExpressionType type) const = 0;
2238 
2240  IntExpr* const expression, IntExpr* const var, int64_t value,
2241  ExprConstantExpressionType type) = 0;
2242 
2244 
2246  IntExpr* const var1, IntExpr* const var2,
2247  ExprExprExpressionType type) const = 0;
2248 
2249  virtual void InsertExprExprExpression(IntExpr* const expression,
2250  IntExpr* const var1,
2251  IntExpr* const var2,
2252  ExprExprExpressionType type) = 0;
2253 
2255 
2257  IntExpr* const var1, IntExpr* const var2, int64_t constant,
2258  ExprExprConstantExpressionType type) const = 0;
2259 
2261  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2262  int64_t constant, ExprExprConstantExpressionType type) = 0;
2263 
2265 
2267  IntVar* const var, int64_t value1, int64_t value2,
2268  VarConstantConstantExpressionType type) const = 0;
2269 
2271  IntExpr* const expression, IntVar* const var, int64_t value1,
2272  int64_t value2, VarConstantConstantExpressionType type) = 0;
2273 
2275 
2277  IntVar* const var, const std::vector<int64_t>& values,
2278  VarConstantArrayExpressionType type) const = 0;
2279 
2281  IntExpr* const expression, IntVar* const var,
2282  const std::vector<int64_t>& values,
2284 
2286 
2288  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2289 
2290  virtual void InsertVarArrayExpression(IntExpr* const expression,
2291  const std::vector<IntVar*>& vars,
2292  VarArrayExpressionType type) = 0;
2293 
2295 
2297  const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
2298  VarArrayConstantArrayExpressionType type) const = 0;
2299 
2301  IntExpr* const expression, const std::vector<IntVar*>& var,
2302  const std::vector<int64_t>& values,
2304 
2306 
2308  const std::vector<IntVar*>& vars, int64_t value,
2309  VarArrayConstantExpressionType type) const = 0;
2310 
2312  IntExpr* const expression, const std::vector<IntVar*>& var, int64_t value,
2314 
2315  Solver* solver() const;
2316 
2317  private:
2318  Solver* const solver_;
2319 };
2320 
2322 #if !defined(SWIG)
2324  public:
2326  const std::string& TypeName() const;
2327  void SetTypeName(const std::string& type_name);
2328 
2330  void SetIntegerArgument(const std::string& arg_name, int64_t value);
2331  void SetIntegerArrayArgument(const std::string& arg_name,
2332  const std::vector<int64_t>& values);
2333  void SetIntegerMatrixArgument(const std::string& arg_name,
2334  const IntTupleSet& values);
2335  void SetIntegerExpressionArgument(const std::string& arg_name,
2336  IntExpr* const expr);
2337  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2338  const std::vector<IntVar*>& vars);
2339  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2340  void SetIntervalArrayArgument(const std::string& arg_name,
2341  const std::vector<IntervalVar*>& vars);
2342  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2343  void SetSequenceArrayArgument(const std::string& arg_name,
2344  const std::vector<SequenceVar*>& vars);
2345 
2347  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2348  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2349 
2351  int64_t FindIntegerArgumentWithDefault(const std::string& arg_name,
2352  int64_t def) const;
2353  int64_t FindIntegerArgumentOrDie(const std::string& arg_name) const;
2354  const std::vector<int64_t>& FindIntegerArrayArgumentOrDie(
2355  const std::string& arg_name) const;
2357  const std::string& arg_name) const;
2358 
2360  const std::string& arg_name) const;
2361  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2362  const std::string& arg_name) const;
2363 
2364  private:
2365  std::string type_name_;
2366  absl::flat_hash_map<std::string, int64_t> integer_argument_;
2367  absl::flat_hash_map<std::string, std::vector<int64_t>>
2368  integer_array_argument_;
2369  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2370  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2371  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2372  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2373  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2374  integer_variable_array_argument_;
2375  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2376  interval_array_argument_;
2377  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2378  sequence_array_argument_;
2379 };
2380 
2382 class ModelParser : public ModelVisitor {
2383  public:
2385 
2386  ~ModelParser() override;
2387 
2389  void BeginVisitModel(const std::string& solver_name) override;
2390  void EndVisitModel(const std::string& solver_name) override;
2391  void BeginVisitConstraint(const std::string& type_name,
2392  const Constraint* const constraint) override;
2393  void EndVisitConstraint(const std::string& type_name,
2394  const Constraint* const constraint) override;
2395  void BeginVisitIntegerExpression(const std::string& type_name,
2396  const IntExpr* const expr) override;
2397  void EndVisitIntegerExpression(const std::string& type_name,
2398  const IntExpr* const expr) override;
2399  void VisitIntegerVariable(const IntVar* const variable,
2400  IntExpr* const delegate) override;
2401  void VisitIntegerVariable(const IntVar* const variable,
2402  const std::string& operation, int64_t value,
2403  IntVar* const delegate) override;
2404  void VisitIntervalVariable(const IntervalVar* const variable,
2405  const std::string& operation, int64_t value,
2406  IntervalVar* const delegate) override;
2407  void VisitSequenceVariable(const SequenceVar* const variable) override;
2409  void VisitIntegerArgument(const std::string& arg_name,
2410  int64_t value) override;
2411  void VisitIntegerArrayArgument(const std::string& arg_name,
2412  const std::vector<int64_t>& values) override;
2413  void VisitIntegerMatrixArgument(const std::string& arg_name,
2414  const IntTupleSet& values) override;
2416  void VisitIntegerExpressionArgument(const std::string& arg_name,
2417  IntExpr* const argument) override;
2419  const std::string& arg_name,
2420  const std::vector<IntVar*>& arguments) override;
2422  void VisitIntervalArgument(const std::string& arg_name,
2423  IntervalVar* const argument) override;
2425  const std::string& arg_name,
2426  const std::vector<IntervalVar*>& arguments) override;
2428  void VisitSequenceArgument(const std::string& arg_name,
2429  SequenceVar* const argument) override;
2431  const std::string& arg_name,
2432  const std::vector<SequenceVar*>& arguments) override;
2433 
2434  protected:
2438 
2439  private:
2440  std::vector<ArgumentHolder*> holders_;
2441 };
2442 
2443 template <class T>
2444 class ArrayWithOffset : public BaseObject {
2445  public:
2446  ArrayWithOffset(int64_t index_min, int64_t index_max)
2447  : index_min_(index_min),
2448  index_max_(index_max),
2449  values_(new T[index_max - index_min + 1]) {
2450  DCHECK_LE(index_min, index_max);
2451  }
2452 
2453  ~ArrayWithOffset() override {}
2454 
2455  virtual T Evaluate(int64_t index) const {
2456  DCHECK_GE(index, index_min_);
2457  DCHECK_LE(index, index_max_);
2458  return values_[index - index_min_];
2459  }
2460 
2461  void SetValue(int64_t index, T value) {
2462  DCHECK_GE(index, index_min_);
2463  DCHECK_LE(index, index_max_);
2464  values_[index - index_min_] = value;
2465  }
2466 
2467  std::string DebugString() const override { return "ArrayWithOffset"; }
2468 
2469  private:
2470  const int64_t index_min_;
2471  const int64_t index_max_;
2472  std::unique_ptr<T[]> values_;
2473 };
2474 #endif // SWIG
2475 
2480 template <class T, class C>
2482  public:
2483  explicit RevGrowingArray(int64_t block_size)
2484  : block_size_(block_size), block_offset_(0) {
2485  CHECK_GT(block_size, 0);
2486  }
2487 
2489  for (int i = 0; i < elements_.size(); ++i) {
2490  delete[] elements_[i];
2491  }
2492  }
2493 
2494  T At(int64_t index) const {
2495  const int64_t block_index = ComputeBlockIndex(index);
2496  const int64_t relative_index = block_index - block_offset_;
2497  if (relative_index < 0 || relative_index >= elements_.size()) {
2498  return T();
2499  }
2500  const T* block = elements_[relative_index];
2501  return block != nullptr ? block[index - block_index * block_size_] : T();
2502  }
2503 
2504  void RevInsert(Solver* const solver, int64_t index, T value) {
2505  const int64_t block_index = ComputeBlockIndex(index);
2506  T* const block = GetOrCreateBlock(block_index);
2507  const int64_t residual = index - block_index * block_size_;
2508  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2509  reinterpret_cast<C>(value));
2510  }
2511 
2512  private:
2513  T* NewBlock() const {
2514  T* const result = new T[block_size_];
2515  for (int i = 0; i < block_size_; ++i) {
2516  result[i] = T();
2517  }
2518  return result;
2519  }
2520 
2521  T* GetOrCreateBlock(int block_index) {
2522  if (elements_.size() == 0) {
2523  block_offset_ = block_index;
2524  GrowUp(block_index);
2525  } else if (block_index < block_offset_) {
2526  GrowDown(block_index);
2527  } else if (block_index - block_offset_ >= elements_.size()) {
2528  GrowUp(block_index);
2529  }
2530  T* block = elements_[block_index - block_offset_];
2531  if (block == nullptr) {
2532  block = NewBlock();
2533  elements_[block_index - block_offset_] = block;
2534  }
2535  return block;
2536  }
2537 
2538  int64_t ComputeBlockIndex(int64_t value) const {
2539  return value >= 0 ? value / block_size_
2540  : (value - block_size_ + 1) / block_size_;
2541  }
2542 
2543  void GrowUp(int64_t block_index) {
2544  elements_.resize(block_index - block_offset_ + 1);
2545  }
2546 
2547  void GrowDown(int64_t block_index) {
2548  const int64_t delta = block_offset_ - block_index;
2549  block_offset_ = block_index;
2550  DCHECK_GT(delta, 0);
2551  elements_.insert(elements_.begin(), delta, nullptr);
2552  }
2553 
2554  const int64_t block_size_;
2555  std::vector<T*> elements_;
2556  int block_offset_;
2557 };
2558 
2563 template <class T>
2564 class RevIntSet {
2565  public:
2566  static constexpr int kNoInserted = -1;
2567 
2569  explicit RevIntSet(int capacity)
2570  : elements_(new T[capacity]),
2571  num_elements_(0),
2572  capacity_(capacity),
2573  position_(new int[capacity]),
2574  delete_position_(true) {
2575  for (int i = 0; i < capacity; ++i) {
2576  position_[i] = kNoInserted;
2577  }
2578  }
2579 
2581  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2582  : elements_(new T[capacity]),
2583  num_elements_(0),
2584  capacity_(capacity),
2585  position_(shared_positions),
2586  delete_position_(false) {
2587  for (int i = 0; i < shared_positions_size; ++i) {
2588  position_[i] = kNoInserted;
2589  }
2590  }
2591 
2593  if (delete_position_) {
2594  delete[] position_;
2595  }
2596  }
2597 
2598  int Size() const { return num_elements_.Value(); }
2599 
2600  int Capacity() const { return capacity_; }
2601 
2602  T Element(int i) const {
2603  DCHECK_GE(i, 0);
2604  DCHECK_LT(i, num_elements_.Value());
2605  return elements_[i];
2606  }
2607 
2608  T RemovedElement(int i) const {
2609  DCHECK_GE(i, 0);
2610  DCHECK_LT(i + num_elements_.Value(), capacity_);
2611  return elements_[i + num_elements_.Value()];
2612  }
2613 
2614  void Insert(Solver* const solver, const T& elt) {
2615  const int position = num_elements_.Value();
2616  DCHECK_LT(position, capacity_);
2617  DCHECK(NotAlreadyInserted(elt));
2618  elements_[position] = elt;
2619  position_[elt] = position;
2620  num_elements_.Incr(solver);
2621  }
2622 
2623  void Remove(Solver* const solver, const T& value_index) {
2624  num_elements_.Decr(solver);
2625  SwapTo(value_index, num_elements_.Value());
2626  }
2627 
2628  void Restore(Solver* const solver, const T& value_index) {
2629  SwapTo(value_index, num_elements_.Value());
2630  num_elements_.Incr(solver);
2631  }
2632 
2633  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2634 
2636  typedef const T* const_iterator;
2637  const_iterator begin() const { return elements_.get(); }
2638  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2639 
2640  private:
2642  bool NotAlreadyInserted(const T& elt) {
2643  for (int i = 0; i < num_elements_.Value(); ++i) {
2644  if (elt == elements_[i]) {
2645  return false;
2646  }
2647  }
2648  return true;
2649  }
2650 
2651  void SwapTo(T value_index, int next_position) {
2652  const int current_position = position_[value_index];
2653  if (current_position != next_position) {
2654  const T next_value_index = elements_[next_position];
2655  elements_[current_position] = next_value_index;
2656  elements_[next_position] = value_index;
2657  position_[value_index] = next_position;
2658  position_[next_value_index] = current_position;
2659  }
2660  }
2661 
2663  std::unique_ptr<T[]> elements_;
2665  NumericalRev<int> num_elements_;
2667  const int capacity_;
2669  int* position_;
2671  const bool delete_position_;
2672 };
2673 
2675 
2677  public:
2678  explicit RevPartialSequence(const std::vector<int>& items)
2679  : elements_(items),
2680  first_ranked_(0),
2681  last_ranked_(items.size() - 1),
2682  size_(items.size()),
2683  position_(new int[size_]) {
2684  for (int i = 0; i < size_; ++i) {
2685  elements_[i] = items[i];
2686  position_[i] = i;
2687  }
2688  }
2689 
2690  explicit RevPartialSequence(int size)
2691  : elements_(size),
2692  first_ranked_(0),
2693  last_ranked_(size - 1),
2694  size_(size),
2695  position_(new int[size_]) {
2696  for (int i = 0; i < size_; ++i) {
2697  elements_[i] = i;
2698  position_[i] = i;
2699  }
2700  }
2701 
2703 
2704  int NumFirstRanked() const { return first_ranked_.Value(); }
2705 
2706  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2707 
2708  int Size() const { return size_; }
2709 
2710 #if !defined(SWIG)
2711  const int& operator[](int index) const {
2712  DCHECK_GE(index, 0);
2713  DCHECK_LT(index, size_);
2714  return elements_[index];
2715  }
2716 #endif
2717 
2718  void RankFirst(Solver* const solver, int elt) {
2719  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2720  SwapTo(elt, first_ranked_.Value());
2721  first_ranked_.Incr(solver);
2722  }
2723 
2724  void RankLast(Solver* const solver, int elt) {
2725  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2726  SwapTo(elt, last_ranked_.Value());
2727  last_ranked_.Decr(solver);
2728  }
2729 
2730  bool IsRanked(int elt) const {
2731  const int position = position_[elt];
2732  return (position < first_ranked_.Value() ||
2733  position > last_ranked_.Value());
2734  }
2735 
2736  std::string DebugString() const {
2737  std::string result = "[";
2738  for (int i = 0; i < first_ranked_.Value(); ++i) {
2739  absl::StrAppend(&result, elements_[i]);
2740  if (i != first_ranked_.Value() - 1) {
2741  result.append("-");
2742  }
2743  }
2744  result.append("|");
2745  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2746  absl::StrAppend(&result, elements_[i]);
2747  if (i != last_ranked_.Value()) {
2748  result.append("-");
2749  }
2750  }
2751  result.append("|");
2752  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2753  absl::StrAppend(&result, elements_[i]);
2754  if (i != size_ - 1) {
2755  result.append("-");
2756  }
2757  }
2758  result.append("]");
2759  return result;
2760  }
2761 
2762  private:
2763  void SwapTo(int elt, int next_position) {
2764  const int current_position = position_[elt];
2765  if (current_position != next_position) {
2766  const int next_elt = elements_[next_position];
2767  elements_[current_position] = next_elt;
2768  elements_[next_position] = elt;
2769  position_[elt] = next_position;
2770  position_[next_elt] = current_position;
2771  }
2772  }
2773 
2775  std::vector<int> elements_;
2777  NumericalRev<int> first_ranked_;
2779  NumericalRev<int> last_ranked_;
2781  const int size_;
2783  std::unique_ptr<int[]> position_;
2784 };
2785 
2791  public:
2793  explicit UnsortedNullableRevBitset(int bit_size);
2794 
2796 
2799  void Init(Solver* const solver, const std::vector<uint64_t>& mask);
2800 
2803  bool RevSubtract(Solver* const solver, const std::vector<uint64_t>& mask);
2804 
2807  bool RevAnd(Solver* const solver, const std::vector<uint64_t>& mask);
2808 
2811  int ActiveWordSize() const { return active_words_.Size(); }
2812 
2814  bool Empty() const { return active_words_.Size() == 0; }
2815 
2823  bool Intersects(const std::vector<uint64_t>& mask, int* support_index);
2824 
2826  int64_t bit_size() const { return bit_size_; }
2828  int64_t word_size() const { return word_size_; }
2830  const RevIntSet<int>& active_words() const { return active_words_; }
2831 
2832  private:
2833  void CleanUpActives(Solver* const solver);
2834 
2835  const int64_t bit_size_;
2836  const int64_t word_size_;
2837  RevArray<uint64_t> bits_;
2838  RevIntSet<int> active_words_;
2839  std::vector<int> to_remove_;
2840 };
2841 
2842 template <class T>
2843 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2844  for (int i = 0; i < values.size(); ++i) {
2845  if (values[i] != value) {
2846  return false;
2847  }
2848  }
2849  return true;
2850 }
2851 
2852 template <class T>
2853 bool IsArrayBoolean(const std::vector<T>& values) {
2854  for (int i = 0; i < values.size(); ++i) {
2855  if (values[i] != 0 && values[i] != 1) {
2856  return false;
2857  }
2858  }
2859  return true;
2860 }
2861 
2862 template <class T>
2863 bool AreAllOnes(const std::vector<T>& values) {
2864  return IsArrayConstant(values, T(1));
2865 }
2866 
2867 template <class T>
2868 bool AreAllNull(const std::vector<T>& values) {
2869  return IsArrayConstant(values, T(0));
2870 }
2871 
2872 template <class T>
2873 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2874  for (const T& current_value : values) {
2875  if (current_value < value) {
2876  return false;
2877  }
2878  }
2879  return true;
2880 }
2881 
2882 template <class T>
2883 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2884  for (const T& current_value : values) {
2885  if (current_value > value) {
2886  return false;
2887  }
2888  }
2889  return true;
2890 }
2891 
2892 template <class T>
2893 bool AreAllPositive(const std::vector<T>& values) {
2894  return AreAllGreaterOrEqual(values, T(0));
2895 }
2896 
2897 template <class T>
2898 bool AreAllNegative(const std::vector<T>& values) {
2899  return AreAllLessOrEqual(values, T(0));
2900 }
2901 
2902 template <class T>
2903 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2904  return AreAllGreaterOrEqual(values, T(1));
2905 }
2906 
2907 template <class T>
2908 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2909  return AreAllLessOrEqual(values, T(-1));
2910 }
2911 
2912 template <class T>
2913 bool IsIncreasingContiguous(const std::vector<T>& values) {
2914  for (int i = 0; i < values.size() - 1; ++i) {
2915  if (values[i + 1] != values[i] + 1) {
2916  return false;
2917  }
2918  }
2919  return true;
2920 }
2921 
2922 template <class T>
2923 bool IsIncreasing(const std::vector<T>& values) {
2924  for (int i = 0; i < values.size() - 1; ++i) {
2925  if (values[i + 1] < values[i]) {
2926  return false;
2927  }
2928  }
2929  return true;
2930 }
2931 
2932 template <class T>
2933 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2934  T range_max) {
2935  for (int i = 0; i < vars.size(); ++i) {
2936  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2937  return false;
2938  }
2939  }
2940  return true;
2941 }
2942 
2943 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2944  for (int i = 0; i < vars.size(); ++i) {
2945  if (!vars[i]->Bound()) {
2946  return false;
2947  }
2948  }
2949  return true;
2950 }
2951 
2952 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2953  return IsArrayInRange(vars, 0, 1);
2954 }
2955 
2958 template <class T>
2959 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2960  const std::vector<T>& values) {
2961  for (int i = 0; i < vars.size(); ++i) {
2962  if (values[i] != 0 && !vars[i]->Bound()) {
2963  return false;
2964  }
2965  }
2966  return true;
2967 }
2968 
2970 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64_t value) {
2971  for (int i = 0; i < vars.size(); ++i) {
2972  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2973  return false;
2974  }
2975  }
2976  return true;
2977 }
2978 
2979 inline int64_t MaxVarArray(const std::vector<IntVar*>& vars) {
2980  DCHECK(!vars.empty());
2981  int64_t result = kint64min;
2982  for (int i = 0; i < vars.size(); ++i) {
2984  result = std::max<int64_t>(result, vars[i]->Max());
2985  }
2986  return result;
2987 }
2988 
2989 inline int64_t MinVarArray(const std::vector<IntVar*>& vars) {
2990  DCHECK(!vars.empty());
2991  int64_t result = kint64max;
2992  for (int i = 0; i < vars.size(); ++i) {
2994  result = std::min<int64_t>(result, vars[i]->Min());
2995  }
2996  return result;
2997 }
2998 
2999 inline void FillValues(const std::vector<IntVar*>& vars,
3000  std::vector<int64_t>* const values) {
3001  values->clear();
3002  values->resize(vars.size());
3003  for (int i = 0; i < vars.size(); ++i) {
3004  (*values)[i] = vars[i]->Value();
3005  }
3006 }
3007 
3008 inline int64_t PosIntDivUp(int64_t e, int64_t v) {
3009  DCHECK_GT(v, 0);
3010  return (e < 0 || e % v == 0) ? e / v : e / v + 1;
3011 }
3012 
3013 inline int64_t PosIntDivDown(int64_t e, int64_t v) {
3014  DCHECK_GT(v, 0);
3015  return (e >= 0 || e % v == 0) ? e / v : e / v - 1;
3016 }
3017 
3018 std::vector<int64_t> ToInt64Vector(const std::vector<int>& input);
3019 
3020 #if !defined(SWIG)
3021 // A PathState represents a set of paths and changes made on it.
3022 //
3023 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
3024 // directed graphs with nodes [0, num_nodes) whose connected components are
3025 // paths from starts[i] to ends[i] (for the same i) and loops.
3026 // Let us fix num_nodes, starts and ends, so we call these P-graphs.
3027 //
3028 // A P-graph can be described by the sequence of nodes of each of its paths,
3029 // and its set of loops. To describe a change made on a given P-graph G0 that
3030 // yields another P-graph G1, we choose to describe G1 in terms of G0. When
3031 // the difference between G0 and G1 is small, as is almost always the case in a
3032 // local search setting, the description is compact, allowing for incremental
3033 // filters to be efficient.
3034 //
3035 // In order to describe G1 in terms of G0 succintly, we describe each path of
3036 // G1 as a sequence of chains of G0. A chain of G0 is either a nonempty sequence
3037 // of consecutive nodes of a path of G0, or a node that was a loop in G0.
3038 // For instance, a path that was not modified from G0 to G1 has one chain,
3039 // the sequence of all nodes in the path. Typically, local search operators
3040 // modify one or two paths, and the resulting paths can described as sequences
3041 // of two to four chains of G0. Paths that were modified are listed explicitly,
3042 // allowing to iterate only on changed paths.
3043 // The loops of G1 are described more implicitly: the loops of G1 not in G0
3044 // are listed explicitly, but those in both G1 and G0 are not listed.
3045 //
3046 // A PathState object can be in two states: committed or changed.
3047 // At construction, the object is committed, G0.
3048 // To enter a changed state G1, one can pass modifications with ChangePath() and
3049 // ChangeLoops(). For reasons of efficiency, a chain is described as a range of
3050 // node indices in the representation of the committed graph G0. To that effect,
3051 // the nodes of a path of G0 are guaranteed to have consecutive indices.
3052 //
3053 // Filters can then browse the change efficiently using ChangedPaths(),
3054 // Chains(), Nodes() and ChangedLoops().
3055 //
3056 // Then Commit() or Revert() can be called: Commit() sets the changed state G1
3057 // as the new committed state, Revert() erases all changes.
3058 class PathState {
3059  public:
3060  // A Chain allows to iterate on all nodes of a chain, and access some data:
3061  // first node, last node, number of nodes in the chain.
3062  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3063  // Chains are returned by PathChainIterator's operator*().
3064  class Chain;
3065  // A ChainRange allows to iterate on all chains of a path.
3066  // ChainRange is a range, its iterator Chain*, its value type Chain.
3067  class ChainRange;
3068  // A NodeRange allows to iterate on all nodes of a path.
3069  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3070  class NodeRange;
3071 
3072  struct ChainBounds {
3073  ChainBounds() = default;
3074  ChainBounds(int begin_index, int end_index)
3075  : begin_index(begin_index), end_index(end_index) {}
3078  };
3079  int CommittedIndex(int node) const { return committed_index_[node]; }
3080  ChainBounds CommittedPathRange(int path) const { return chains_[path]; }
3081 
3082  // Path constructor: path_start and path_end must be disjoint,
3083  // their values in [0, num_nodes).
3084  PathState(int num_nodes, std::vector<int> path_start,
3085  std::vector<int> path_end);
3086 
3087  // Instance-constant accessors.
3088 
3089  // Returns the number of nodes in the underlying graph.
3090  int NumNodes() const { return num_nodes_; }
3091  // Returns the number of paths (empty paths included).
3092  int NumPaths() const { return num_paths_; }
3093  // Returns the start of a path.
3094  int Start(int path) const { return path_start_end_[path].start; }
3095  // Returns the end of a path.
3096  int End(int path) const { return path_start_end_[path].end; }
3097 
3098  // State-dependent accessors.
3099 
3100  // Returns the committed path of a given node, -1 if it is a loop.
3101  int Path(int node) const {
3102  return committed_nodes_[committed_index_[node]].path;
3103  }
3104  // Returns the set of paths that actually changed,
3105  // i.e. that have more than one chain.
3106  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3107  // Returns the set of loops that were added by the change.
3108  const std::vector<int>& ChangedLoops() const { return changed_loops_; }
3109  // Returns the current range of chains of path.
3110  ChainRange Chains(int path) const;
3111  // Returns the current range of nodes of path.
3112  NodeRange Nodes(int path) const;
3113 
3114  // State modifiers.
3115 
3116  // Changes the path to the given sequence of chains of the committed state.
3117  // Chains are described by semi-open intervals. No optimization is made in
3118  // case two consecutive chains are actually already consecutive in the
3119  // committed state: they are not merged into one chain, and Chains(path) will
3120  // report the two chains.
3121  void ChangePath(int path, const std::vector<ChainBounds>& chains);
3122  // Same as above, but the initializer_list interface avoids the need to pass
3123  // a vector.
3124  void ChangePath(int path, const std::initializer_list<ChainBounds>& chains) {
3125  changed_paths_.push_back(path);
3126  const int path_begin_index = chains_.size();
3127  chains_.insert(chains_.end(), chains.begin(), chains.end());
3128  const int path_end_index = chains_.size();
3129  paths_[path] = {path_begin_index, path_end_index};
3130  // Always add sentinel, in case this is the last path change.
3131  chains_.emplace_back(0, 0);
3132  }
3133 
3134  // Describes the nodes that are newly loops in this change.
3135  void ChangeLoops(const std::vector<int>& new_loops);
3136 
3137  // Set the current state G1 as committed. See class comment for details.
3138  void Commit();
3139  // Erase incremental changes. See class comment for details.
3140  void Revert();
3141 
3142  // LNS Operators may not fix variables,
3143  // in which case we mark the candidate invalid.
3144  void SetInvalid() { is_invalid_ = true; }
3145  bool IsInvalid() const { return is_invalid_; }
3146 
3147  private:
3148  // Most structs below are named pairs of ints, for typing purposes.
3149 
3150  // Start and end are stored together to optimize (likely) simultaneous access.
3151  struct PathStartEnd {
3152  PathStartEnd(int start, int end) : start(start), end(end) {}
3153  int start;
3154  int end;
3155  };
3156  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3157  struct PathBounds {
3158  int begin_index;
3159  int end_index;
3160  };
3161  struct CommittedNode {
3162  CommittedNode(int node, int path) : node(node), path(path) {}
3163  int node;
3164  // Path of node in the committed state, -1 for loop nodes.
3165  // TODO(user): check if path would be better stored
3166  // with committed_index_, or in its own vector, or just recomputed.
3167  int path;
3168  };
3169 
3170  // Copies nodes in chains of path at the end of nodes,
3171  // and sets those nodes' path member to value path.
3172  void CopyNewPathAtEndOfNodes(int path);
3173  // Commits paths in O(#{changed paths' nodes}) time,
3174  // increasing this object's space usage by O(|changed path nodes|).
3175  void IncrementalCommit();
3176  // Commits paths in O(num_nodes + num_paths) time,
3177  // reducing this object's space usage to O(num_nodes + num_paths).
3178  void FullCommit();
3179 
3180  // Instance-constant data.
3181  const int num_nodes_;
3182  const int num_paths_;
3183  std::vector<PathStartEnd> path_start_end_;
3184 
3185  // Representation of the committed and changed paths.
3186  // A path is a range of chains, which is a range of nodes.
3187  // Ranges are represented internally by indices in vectors:
3188  // ChainBounds are indices in committed_nodes_. PathBounds are indices in
3189  // chains_. When committed (after construction, Revert() or Commit()):
3190  // - path ranges are [path, path+1): they have one chain.
3191  // - chain ranges don't overlap, chains_ has an empty sentinel at the end.
3192  // The sentinel allows the Nodes() iterator to maintain its current pointer
3193  // to committed nodes on NodeRange::operator++().
3194  // - committed_nodes_ contains all nodes, both paths and loops.
3195  // Actually, old duplicates will likely appear,
3196  // the current version of a node is at the index given by
3197  // committed_index_[node]. A Commit() can add nodes at the end of
3198  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3199  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3200  // space by rewriting the path/chain/nodes structure.
3201  // When changed (after ChangePaths() and ChangeLoops()),
3202  // the structure is updated accordingly:
3203  // - path ranges that were changed have nonoverlapping values [begin, end)
3204  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3205  // the committed state.
3206  // - additional chain ranges are stored after the committed chains and its
3207  // sentinel to represent the new chains resulting from the changes.
3208  // Those chains do not overlap with one another or with committed chains.
3209  // - committed_nodes_ are not modified, and still represent the committed
3210  // paths. committed_index_ is not modified either.
3211  std::vector<CommittedNode> committed_nodes_;
3212  std::vector<int> committed_index_;
3213  const int num_nodes_threshold_;
3214  std::vector<ChainBounds> chains_;
3215  std::vector<PathBounds> paths_;
3216 
3217  // Incremental information.
3218  std::vector<int> changed_paths_;
3219  std::vector<int> changed_loops_;
3220 
3221  // See IsInvalid() and SetInvalid().
3222  bool is_invalid_ = false;
3223 };
3224 
3225 // A Chain is a range of committed nodes.
3227  public:
3228  class Iterator {
3229  public:
3231  ++current_node_;
3232  return *this;
3233  }
3234  int operator*() const { return current_node_->node; }
3235  bool operator!=(Iterator other) const {
3236  return current_node_ != other.current_node_;
3237  }
3238 
3239  private:
3240  // Only a Chain can construct its iterator.
3241  friend class PathState::Chain;
3242  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3243  const CommittedNode* current_node_;
3244  };
3245 
3246  // Chains hold CommittedNode* values, a Chain may be invalidated
3247  // if the underlying vector is modified.
3248  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3249  : begin_(begin_node), end_(end_node) {}
3250 
3251  int NumNodes() const { return end_ - begin_; }
3252  int First() const { return begin_->node; }
3253  int Last() const { return (end_ - 1)->node; }
3254  Iterator begin() const { return Iterator(begin_); }
3255  Iterator end() const { return Iterator(end_); }
3256 
3257  Chain WithoutFirstNode() const { return Chain(begin_ + 1, end_); }
3258 
3259  private:
3260  const CommittedNode* const begin_;
3261  const CommittedNode* const end_;
3262 };
3263 
3264 // A ChainRange is a range of Chains, committed or not.
3266  public:
3267  class Iterator {
3268  public:
3270  ++current_chain_;
3271  return *this;
3272  }
3273  Chain operator*() const {
3274  return {first_node_ + current_chain_->begin_index,
3275  first_node_ + current_chain_->end_index};
3276  }
3277  bool operator!=(Iterator other) const {
3278  return current_chain_ != other.current_chain_;
3279  }
3280 
3281  private:
3282  // Only a ChainRange can construct its Iterator.
3283  friend class ChainRange;
3284  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3285  : current_chain_(chain), first_node_(first_node) {}
3286  const ChainBounds* current_chain_;
3287  const CommittedNode* const first_node_;
3288  };
3289 
3290  // ChainRanges hold ChainBounds* and CommittedNode*,
3291  // a ChainRange may be invalidated if on of the underlying vector is modified.
3292  ChainRange(const ChainBounds* const begin_chain,
3293  const ChainBounds* const end_chain,
3294  const CommittedNode* const first_node)
3295  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3296 
3297  Iterator begin() const { return {begin_, first_node_}; }
3298  Iterator end() const { return {end_, first_node_}; }
3299 
3300  private:
3301  const ChainBounds* const begin_;
3302  const ChainBounds* const end_;
3303  const CommittedNode* const first_node_;
3304 };
3305 
3306 // A NodeRange allows to iterate on all nodes of a path,
3307 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3309  public:
3310  class Iterator {
3311  public:
3313  ++current_node_;
3314  if (current_node_ == end_node_) {
3315  ++current_chain_;
3316  // Note: dereferencing bounds is valid because there is a sentinel
3317  // value at the end of PathState::chains_ to that intent.
3318  const ChainBounds bounds = *current_chain_;
3319  current_node_ = first_node_ + bounds.begin_index;
3320  end_node_ = first_node_ + bounds.end_index;
3321  }
3322  return *this;
3323  }
3324  int operator*() const { return current_node_->node; }
3325  bool operator!=(Iterator other) const {
3326  return current_chain_ != other.current_chain_;
3327  }
3328 
3329  private:
3330  // Only a NodeRange can construct its Iterator.
3331  friend class NodeRange;
3332  Iterator(const ChainBounds* current_chain,
3333  const CommittedNode* const first_node)
3334  : current_node_(first_node + current_chain->begin_index),
3335  end_node_(first_node + current_chain->end_index),
3336  current_chain_(current_chain),
3337  first_node_(first_node) {}
3338  const CommittedNode* current_node_;
3339  const CommittedNode* end_node_;
3340  const ChainBounds* current_chain_;
3341  const CommittedNode* const first_node_;
3342  };
3343 
3344  // NodeRanges hold ChainBounds* and CommittedNode*,
3345  // a NodeRange may be invalidated if on of the underlying vector is modified.
3346  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3347  const CommittedNode* first_node)
3348  : begin_chain_(begin_chain),
3349  end_chain_(end_chain),
3350  first_node_(first_node) {}
3351  Iterator begin() const { return {begin_chain_, first_node_}; }
3352  // Note: there is a sentinel value at the end of PathState::chains_,
3353  // so dereferencing chain_range_.end()->begin_ is always valid.
3354  Iterator end() const { return {end_chain_, first_node_}; }
3355 
3356  private:
3357  const ChainBounds* begin_chain_;
3358  const ChainBounds* end_chain_;
3359  const CommittedNode* const first_node_;
3360 };
3361 
3362 // This checker enforces dimension requirements.
3363 // A dimension requires that there is some valuation of
3364 // cumul and demand such that for all paths:
3365 // - cumul[A] is in interval node_capacity[A]
3366 // - if arc A -> B is on a path of path_class p,
3367 // then cumul[A] + demand[p](A, B) = cumul[B].
3368 // - if A is on a path of class p, then
3369 // cumul[A] must be inside interval path_capacity[path].
3371  public:
3372  struct Interval {
3373  int64_t min;
3374  int64_t max;
3375  };
3376 
3377  // TODO(user): benchmark different implementation details for this class:
3378  // - num_negative/positive_infinity to int32_t
3379  // - use int128_t or absl's int128 to avoid counting infinities.
3380  // - use Interval instead of min/max.
3382  int64_t min;
3384  int64_t max;
3386  };
3387 
3388  // TODO(user): the addition of kMinRangeSizeForRIQ slowed down Check().
3389  // See if using a template parameter makes it faster.
3390  DimensionChecker(const PathState* path_state,
3391  std::vector<Interval> path_capacity,
3392  std::vector<int> path_class,
3393  std::vector<std::function<Interval(int64_t, int64_t)>>
3394  demand_per_path_class,
3395  std::vector<Interval> node_capacity,
3396  int min_range_size_for_riq = kOptimalMinRangeSizeForRIQ);
3397 
3398  // Given the change made in PathState, checks that the dimension
3399  // constraint is still feasible.
3400  bool Check() const;
3401 
3402  // Commits to the changes made in PathState,
3403  // must be called before PathState::Commit().
3404  void Commit();
3405 
3406  static constexpr int kOptimalMinRangeSizeForRIQ = 4;
3407 
3408  private:
3409  // Returns the feasible cumul interval at first_node_index, under all
3410  // path capacity and dimension constraints of the chain formed by the
3411  // [first_node_index, last_node_index] range of indices.
3412  ExtendedInterval FirstIndexCumulsFromPathCapacity(
3413  int first_node_index, int last_node_index,
3414  const ExtendedInterval& path_capacity) const;
3415 
3416  // Returns the feasible cumul interval at first_node_index, under all
3417  // node capacity and dimension constraints of the chain formed by the
3418  // [first_node_index, last_node_index] range of indices.
3419  ExtendedInterval FirstIndexCumulsFromNodeCapacities(
3420  int first_node_index, int last_node_index) const;
3421 
3422  // Returns the feasible cumul interval at last_node_index, under all
3423  // node capacity and dimension constraints of the chain formed by the
3424  // [first_node_index, last_node_index] range of indices.
3425  ExtendedInterval LastIndexCumulsFromNodeCapacities(int first_node_index,
3426  int last_node_index) const;
3427 
3428  // Returns the total transit to go from first_node to last_node, which
3429  // must be a subchain of the committed solution.
3430  ExtendedInterval TotalTransit(int first_node_index,
3431  int last_node_index) const;
3432 
3433  // Commits to the current solution and rebuilds structures from scratch.
3434  void FullCommit();
3435  // Commits to the current solution and only build structures for paths that
3436  // changed, using additional space to do so in a time-memory tradeoff.
3437  void IncrementalCommit();
3438  // Adds sums of given path to the bottom layer of the Range Intersection Query
3439  // structure, updates index_ and previous_nontrivial_index_.
3440  void AppendPathDemandsToSums(int path);
3441  // Updates the Range Intersection Query structure from its bottom layer,
3442  // with [begin_index, end_index) the range of the change,
3443  // which must be at the end of the bottom layer.
3444  // Supposes that requests overlapping the range will be inside the range,
3445  // to avoid updating all layers.
3446  void UpdateRIQStructure(int begin_index, int end_index);
3447 
3448  const PathState* const path_state_;
3449  const std::vector<ExtendedInterval> path_capacity_;
3450  const std::vector<int> path_class_;
3451  const std::vector<std::function<Interval(int64_t, int64_t)>>
3452  demand_per_path_class_;
3453  std::vector<ExtendedInterval> cached_demand_;
3454  const std::vector<ExtendedInterval> node_capacity_;
3455 
3456  // Precomputed data.
3457  // Maps nodes to their pre-computed data, except for isolated nodes,
3458  // which do not have precomputed data.
3459  // Only valid for nodes that are in some path in the committed state.
3460  std::vector<int> index_;
3461  // Range intersection query in <O(n log n), O(1)>, with n = #nodes.
3462  // forwards_demand_sums_riq_[0][index_[node]] contains the sum of demands
3463  // from the start of the node's path to the node,
3464  // forwards_demand_sums_riq_[l][i] contains the intersection
3465  // of forwards_demand_sums_riq_[0][i'] for i' in (s, i] where s is the max of
3466  // i - 2**l + 1 and the index of the start node before or at i.
3467  std::vector<std::vector<ExtendedInterval>> forwards_demand_sums_riq_;
3468  // Range intersection query on node capacity + demand constraint, for
3469  // queries on last node.
3470  std::vector<std::vector<ExtendedInterval>> forwards_node_capacity_riq_;
3471  // Range intersection query on node capacity + demand constraint, for
3472  // queries on first node.
3473  std::vector<std::vector<ExtendedInterval>> backwards_node_capacity_riq_;
3474  // The incremental branch of Commit() may waste space in the layers of the
3475  // RIQ structure. This is the upper limit of a layer's size.
3476  const int maximum_riq_layer_size_;
3477  // Range queries are used on a chain only if the range is larger than this.
3478  const int min_range_size_for_riq_;
3479 };
3480 
3481 // Make a filter that takes ownership of a PathState and synchronizes it with
3482 // solver events. The solver represents a graph with array of variables 'nexts'.
3483 // Solver events are embodied by Assignment* deltas, that are translated to node
3484 // changes during Relax(), committed during Synchronize(), and reverted on
3485 // Revert().
3487  std::unique_ptr<PathState> path_state,
3488  const std::vector<IntVar*>& nexts);
3489 
3490 // Make a filter that translates solver events to the input checker's interface.
3491 // Since DimensionChecker has a PathState, the filter returned by this
3492 // must be synchronized to the corresponding PathStateFilter:
3493 // - Relax() must be called after the PathStateFilter's.
3494 // - Accept() must be called after.
3495 // - Synchronize() must be called before.
3496 // - Revert() must be called before.
3498  Solver* solver, std::unique_ptr<DimensionChecker> checker,
3499  const std::string& dimension_name);
3500 
3501 #endif // !defined(SWIG)
3502 
3503 } // namespace operations_research
3504 
3505 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
Argument Holder: useful when visiting a model.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
void SetTypeName(const std::string &type_name)
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
int64_t FindIntegerArgumentOrDie(const std::string &arg_name) const
void SetIntegerArgument(const std::string &arg_name, int64_t value)
Setters.
const std::vector< int64_t > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
const std::string & TypeName() const
Type of the argument.
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
int64_t FindIntegerArgumentWithDefault(const std::string &arg_name, int64_t def) const
Getters.
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
virtual T Evaluate(int64_t index) const
ArrayWithOffset(int64_t index_min, int64_t index_max)
void SetValue(int64_t index, T value)
std::string DebugString() const override
bool Contains(const V *const var) const
const E & Element(const V *const var) const
An Assignment is a variable -> domains mapping, used to report solutions to the user.
const IntContainer & IntVarContainer() const
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
IntVar * Var() override
Creates a variable from the expression.
This is the base class for building an Lns operator.
virtual bool NextFragment()=0
bool HasFragments() const override
void AppendToFragment(int index)
BaseLns(const std::vector< IntVar * > &vars)
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
A BaseObject is the root of all reversibly allocated objects.
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
IntVar * IsDifferent(int64_t constant) override
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
uint64_t Size() const override
This method returns the number of values in the domain of the variable.
void SetRange(int64_t mi, int64_t ma) override
This method sets both the min and the max of the expression.
SimpleRevFIFO< Demon * > delayed_bound_demons_
void WhenDomain(Demon *d) override
This method attaches a demon that will watch any domain modification of the domain of the variable.
bool Contains(int64_t v) const override
This method returns whether the value 'v' is in the domain of the variable.
IntVar * IsEqual(int64_t constant) override
IsEqual.
void RemoveValue(int64_t v) override
This method removes the value 'v' from the domain of the variable.
int64_t Value() const override
This method returns the value of the variable.
void SetMax(int64_t m) override
SimpleRevFIFO< Demon * > bound_demons_
IntVar * IsGreaterOrEqual(int64_t constant) override
void RemoveInterval(int64_t l, int64_t u) override
This method removes the interval 'l' .
std::string BaseName() const override
Returns a base name for automatic naming.
IntVar * IsLessOrEqual(int64_t constant) override
void SetMin(int64_t m) override
std::string DebugString() const override
BooleanVar(Solver *const s, const std::string &name="")
IntVarIterator * MakeDomainIterator(bool reversible) const override
Creates a domain iterator.
Demon proxy to a method on the constraint with no arguments.
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
Demon proxy to a method on the constraint with one argument.
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Demon proxy to a method on the constraint with two arguments.
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
Demon proxy to a method on the constraint with three arguments.
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
Defines operators which change the value of variables; each neighbor corresponds to one modified vari...
ChangeValue(const std::vector< IntVar * > &vars)
virtual int64_t ModifyValue(int64_t index, int64_t value)=0
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
A constraint is the main modeling object.
A Decision represents a choice point in the search tree.
A DecisionVisitor is used to inspect a decision.
Low-priority demon proxy to a method on the constraint with no arguments.
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
void Run(Solver *const s) override
This is the main callback of the demon.
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
std::string DebugString() const override
Low-priority demon proxy to a method on the constraint with one argument.
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)
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
Low-priority demon proxy to a method on the constraint with two arguments.
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
A Demon is the base element of a propagation queue.
DimensionChecker(const PathState *path_state, std::vector< Interval > path_capacity, std::vector< int > path_class, std::vector< std::function< Interval(int64_t, int64_t)>> demand_per_path_class, std::vector< Interval > node_capacity, int min_range_size_for_riq=kOptimalMinRangeSizeForRIQ)
The class IntExpr is the base of all integer expressions in constraint programming.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual int64_t Min() const =0
virtual int64_t Max() const =0
The class IntVar is a subset of IntExpr.
virtual void WhenBound(Demon *d)=0
This method attaches a demon that will be awakened when the variable is bound.
int index() const
Returns the index of the variable.
The class Iterator has two direct subclasses.
void SynchronizeOnAssignment(const Assignment *assignment)
virtual void OnSynchronize(const Assignment *delta)
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
bool FindIndex(IntVar *const var, int64_t *index) const
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
void SetValue(int64_t index, int64_t value)
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
OnStart() should really be protected, but then SWIG doesn't see it.
virtual bool MakeOneNeighbor()
Creates a new neighbor.
void RevertChanges(bool change_was_incremental)
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
int64_t Value(int64_t index) const
Returns the value in the current assignment of the variable of given index.
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
IntVar * Var(int64_t index) const
Returns the variable of given index.
void AddVars(const std::vector< IntVar * > &vars)
void AddToAssignment(IntVar *var, int64_t value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
void Start(const Assignment *assignment) override
This method should not be overridden.
Interval variables are often used in scheduling.
LightIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index, F values, std::function< bool()> deep_serialize)
void Post() override
This method is called when the constraint is processed by the solver.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
void Post() override
This method is called when the constraint is processed by the solver.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
LightIntIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index1, IntVar *const index2, F values, std::function< bool()> deep_serialize)
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Local Search Filters are used for fast neighbor pruning.
virtual void Synchronize(const Assignment *assignment, const Assignment *delta)=0
Synchronizes the filter with the current solution, delta being the difference with the solution passe...
virtual int64_t GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
virtual void Reset()
Sets the filter to empty solution.
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 bool Accept(const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
virtual int64_t GetSynchronizedObjectiveValue() const
Objective value from last time Synchronize() was called.
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
virtual void Commit(const Assignment *delta, const Assignment *deltadelta)
Dual of Relax(), lets the filter know that the delta was accepted.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
LocalSearchFilterManager(std::vector< FilterEvent > filter_events)
LocalSearchFilterManager(std::vector< LocalSearchFilter * > filters)
bool Accept(LocalSearchMonitor *const monitor, const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)
Returns true iff all filters return true, and the sum of their accepted objectives is between objecti...
void Synchronize(const Assignment *assignment, const Assignment *delta)
Synchronizes all filters to assignment.
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
void Install() override
Install itself on the solver.
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual void BeginOperatorStart()=0
Local search operator events.
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
LocalSearchMonitor(Solver *const solver)
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
std::string DebugString() const override
The base class for all local search operators.
virtual const LocalSearchOperator * Self() const
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
virtual void Start(const Assignment *assignment)=0
int64_t CandidateInverseValue(int64_t value) const
void SetCandidateValue(int64_t index, int64_t value)
int64_t CandidateValue(int64_t index) const
Returns the value in the current assignment of the variable of given index.
void SetCandidateActive(int64_t index, bool active)
int64_t CommittedInverseValue(int64_t value) const
const std::vector< int64_t > & IncrementalIndicesChanged() const
const std::vector< int64_t > & CandidateIndicesChanged() const
LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max)
Implements a complete cache for model elements: expressions and constraints.
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64_t constant, ExprExprConstantExpressionType type)=0
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64_t constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type)=0
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64_t value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64_t value, VarArrayConstantExpressionType type)=0
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64_t value, VarConstantConstraintType type)=0
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64_t value, VarConstantConstraintType type) const =0
Var Constant Constraints.
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64_t value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type)=0
ModelCache(Solver *const solver)
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64_t value, ExprConstantExpressionType type)=0
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type)=0
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type)=0
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values) override
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
void VisitSequenceVariable(const SequenceVar *const variable) override
void VisitIntegerArgument(const std::string &arg_name, int64_t value) override
Integer arguments.
void VisitIntegerVariable(const IntVar *const variable, const std::string &operation, int64_t value, IntVar *const delegate) override
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
void EndVisitModel(const std::string &solver_name) override
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate) override
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
ArgumentHolder * Top() const
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint)
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint)
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument)
Visit integer expression argument.
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
This class encapsulates an objective.
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
int64_t StartNode(int i) const
Returns the start node of the ith base node.
bool IsInactive(int64_t node) const
Returns true if node is inactive.
int64_t OldPrev(int64_t node) const
virtual bool ConsiderAlternatives(int64_t base_index) const
Indicates if alternatives should be considered when iterating over base nodes.
int PathClass(int i) const
Returns the class of the path of the ith base node.
virtual void OnNodeInitialization()
Called by OnStart() after initializing node information.
virtual bool OnSamePathAsPreviousBase(int64_t base_index)
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
int64_t OldPath(int64_t node) const
bool IsPathStart(int64_t node) const
Returns true if node is the first node on the path.
int64_t GetActiveAlternativeNode(int node) const
Returns the active node in the alternative set of the given node.
int number_of_nexts() const
Number of next variables.
int AddAlternativeSet(const std::vector< int64_t > &alternative_set)
Handling node alternatives.
bool CheckChainValidity(int64_t before_chain, int64_t chain_end, int64_t exclude) const
Returns true if the chain is a valid path without cycles from before_chain to chain_end and does not ...
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
bool IsPathEnd(int64_t node) const
Returns true if node is the last node on the path; defined by the fact that node is outside the range...
int BaseSiblingAlternative(int i) const
Returns the alternative for the sibling of the ith base node.
int64_t Next(int64_t node) const
Returns the node after node in the current delta.
bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination)
Moves the chain starting after the node before_chain and ending at the node chain_end after the node ...
bool MakeActive(int64_t node, int64_t destination)
Insert the inactive node after destination.
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
bool ReverseChain(int64_t before_chain, int64_t after_chain, int64_t *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
const std::vector< int64_t > & path_starts() const
Returns the vector of path start nodes.
void SetNext(int64_t from, int64_t to, int64_t path)
Sets 'to' to be the node after 'from' on the given path.
int64_t BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
int64_t Prev(int64_t node) const
Returns the node before node in the current delta.
int64_t GetActiveAlternativeSibling(int node) const
Returns the active node in the alternative set of the sibling of the given node.
int64_t OldNext(int64_t node) const
bool SkipUnchanged(int index) const override
bool SwapActiveAndInactive(int64_t active, int64_t inactive)
Replaces active by inactive in the current path, making active inactive.
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
virtual int64_t GetBaseNodeRestartPosition(int base_index)
Returns the index of the node to which the base node of index base_index must be set to when it reach...
int64_t BaseNode(int i) const
Returns the ith base node of the operator.
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, bool accept_path_end_base, std::function< int(int64_t)> start_empty_path_class)
int64_t BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
void AddPairAlternativeSets(const std::vector< std::pair< std::vector< int64_t >, std::vector< int64_t >>> &pair_alternative_sets)
Adds all sets of node alternatives of a vector of alternative pairs.
int64_t Path(int64_t node) const
Returns the index of the path to which node belongs in the current delta.
virtual bool InitPosition() const
Returns true if the operator needs to restart its initial position at each call to Start()
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, IterationParameters iteration_parameters)
Builds an instance of PathOperator from next and path variables.
virtual void SetNextBaseToIncrement(int64_t base_index)
Set the next base to increment on next iteration.
int64_t EndNode(int i) const
Returns the end node of the ith base node.
int64_t PrevNext(int64_t node) const
bool MakeChainInactive(int64_t before_chain, int64_t chain_end)
Makes the nodes on the chain starting after before_chain and ending at chain_end inactive.
Chain(const CommittedNode *begin_node, const CommittedNode *end_node)
ChainRange(const ChainBounds *const begin_chain, const ChainBounds *const end_chain, const CommittedNode *const first_node)
NodeRange(const ChainBounds *begin_chain, const ChainBounds *end_chain, const CommittedNode *first_node)
const std::vector< int > & ChangedPaths() const
ChainRange Chains(int path) const
void ChangePath(int path, const std::vector< ChainBounds > &chains)
void ChangeLoops(const std::vector< int > &new_loops)
ChainBounds CommittedPathRange(int path) const
void ChangePath(int path, const std::initializer_list< ChainBounds > &chains)
NodeRange Nodes(int path) const
const std::vector< int > & ChangedLoops() const
PathState(int num_nodes, std::vector< int > path_start, std::vector< int > path_end)
virtual void SetValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual void SetDurationMax(IntervalVar *const var, int64_t new_max)=0
virtual void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void SetMax(IntExpr *const expr, int64_t new_max)=0
void Install() override
Install itself on the solver.
virtual void RankLast(SequenceVar *const var, int index)=0
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
virtual void SetMin(IntVar *const var, int64_t new_min)=0
IntVar modifiers.
virtual void RemoveValue(IntVar *const var, int64_t value)=0
virtual void SetValue(IntVar *const var, int64_t value)=0
virtual void SetDurationMin(IntervalVar *const var, int64_t new_min)=0
virtual void SetStartMin(IntervalVar *const var, int64_t new_min)=0
IntervalVar modifiers.
virtual void RankNotLast(SequenceVar *const var, int index)=0
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void BeginDemonRun(Demon *const demon)=0
virtual void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max)=0
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 SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void SetEndMax(IntervalVar *const var, int64_t new_max)=0
virtual void PushContext(const std::string &context)=0
virtual void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax)=0
virtual void SetEndMin(IntervalVar *const var, int64_t new_min)=0
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void SetMax(IntVar *const var, int64_t new_max)=0
virtual void SetPerformed(IntervalVar *const var, bool value)=0
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
virtual void SetRange(IntVar *const var, int64_t new_min, int64_t new_max)=0
virtual void SetMin(IntExpr *const expr, int64_t new_min)=0
IntExpr modifiers.
virtual void SetStartMax(IntervalVar *const var, int64_t new_max)=0
virtual void EndDemonRun(Demon *const demon)=0
virtual void RegisterDemon(Demon *const demon)=0
PropagationMonitor(Solver *const solver)
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
virtual void RemoveValues(IntVar *const var, const std::vector< int64_t > &values)=0
std::string DebugString() const override
virtual void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
Matrix version of the RevBitSet class.
void SetToZero(Solver *const solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
bool IsSet(int64_t row, int64_t column) const
Returns whether the 'column' bit in the 'row' row is set.
void SetToOne(Solver *const solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
int64_t Cardinality(int row) const
Returns the number of bits set to one in the 'row' row.
bool IsCardinalityOne(int row) const
Does the 'row' bitset contains only one bit set?
void ClearAll(Solver *const solver)
Cleans all bits.
int64_t GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
RevBitMatrix(int64_t rows, int64_t columns)
bool IsCardinalityZero(int row) const
Is bitset of row 'row' null?
This class represents a reversible bitset.
void SetToOne(Solver *const solver, int64_t index)
Sets the 'index' bit.
bool IsCardinalityOne() const
Does it contains only one bit set?
void SetToZero(Solver *const solver, int64_t index)
Erases the 'index' bit.
int64_t Cardinality() const
Returns the number of bits set to one.
int64_t GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
void ClearAll(Solver *const solver)
Cleans all bits.
bool IsCardinalityZero() const
Is bitset null?
This class is a reversible growing array.
void RevInsert(Solver *const solver, int64_t index, T value)
void SetValue(Solver *const s, const T &val)
Reversible Immutable MultiMap class.
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
RevImmutableMultiMap(Solver *const solver, int initial_size)
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
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.
This is a special class to represent a 'residual' set of T.
void Insert(Solver *const solver, const T &elt)
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
const T * const_iterator
Iterators on the indices.
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
void Restore(Solver *const solver, const T &value_index)
void Remove(Solver *const solver, const T &value_index)
void Clear(Solver *const solver)
--— RevPartialSequence --—
void RankLast(Solver *const solver, int elt)
void RankFirst(Solver *const solver, int elt)
const int & operator[](int index) const
RevPartialSequence(const std::vector< int > &items)
A reversible switch that can switch once from false to true.
void Switch(Solver *const solver)
The base class of all search logs that periodically outputs information when the search is running.
void BeginFail() override
Just when the failure occurs.
void EnterSearch() override
Beginning of the search.
void RefuteDecision(Decision *const decision) override
Before refuting the decision.
void ExitSearch() override
End of the search.
virtual void OutputLine(const std::string &line)
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, double offset, std::function< std::string()> display_callback, bool display_on_new_solutions_only, int period)
void BeginInitialPropagation() override
Before the initial propagation.
void NoMoreSolutions() override
When the search tree is finished.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
bool AtSolution() override
This method is called when a valid solution is found.
std::string DebugString() const override
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
void EndInitialPropagation() override
After the initial propagation.
A search monitor is a simple set of callbacks to monitor all search events.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
This iterator is not stable with respect to deletion.
This class represent a reversible FIFO structure.
void SetLastValue(const T &v)
Sets the last value in the FIFO.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
void Push(Solver *const s, T val)
const T & LastValue() const
Returns the last value in the FIFO.
const T * Last() const
Returns the last item of the FIFO.
This class represents a small reversible bitset (size <= 64).
bool IsCardinalityOne() const
Does it contains only one bit set?
int64_t Cardinality() const
Returns the number of bits set to one.
void SetToZero(Solver *const solver, int64_t pos)
Erases the 'pos' bit.
bool IsCardinalityZero() const
Is bitset null?
int64_t GetFirstOne() const
Gets the index of the first bit set starting from 0.
void SetToOne(Solver *const solver, int64_t pos)
Sets the 'pos' bit.
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
T * RevAlloc(T *object)
Registers the given object as being reversible.
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64_t value)
void AddIntegerVariableEqualValueClause(IntVar *const var, int64_t value)
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64_t value)
This class represents a reversible bitset.
int64_t word_size() const
Returns the number of 64 bit words used to store the bitset.
int64_t bit_size() const
Returns the number of bits given in the constructor of the bitset.
bool RevSubtract(Solver *const solver, const std::vector< uint64_t > &mask)
This method subtracts the mask from the active bitset.
void Init(Solver *const solver, const std::vector< uint64_t > &mask)
This methods overwrites the active bitset with the mask.
bool RevAnd(Solver *const solver, const std::vector< uint64_t > &mask)
This method ANDs the mask with the active bitset.
bool Empty() const
This method returns true if the active bitset is null.
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
This method returns true iff the mask and the active bitset have a non null intersection.
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
Collection of objects used to extend the Constraint Solver library.
std::string ParameterDebugString(P param)
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
bool IsArrayConstant(const std::vector< T > &values, const T &value)
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
bool AreAllNegative(const std::vector< T > &values)
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
bool IsIncreasing(const std::vector< T > &values)
bool AreAllStrictlyPositive(const std::vector< T > &values)
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
bool IsArrayBoolean(const std::vector< T > &values)
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)
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
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 ...
int64_t MaxVarArray(const std::vector< IntVar * > &vars)
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64_t value)
Returns true if all variables are assigned to 'value'.
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64_t > *const values)
bool AreAllBooleans(const std::vector< IntVar * > &vars)
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
bool AreAllStrictlyNegative(const std::vector< T > &values)
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
Operator Factories.
int64_t MinVarArray(const std::vector< IntVar * > &vars)
bool IsIncreasingContiguous(const std::vector< T > &values)
bool AreAllNull(const std::vector< T > &values)
bool AreAllPositive(const std::vector< T > &values)
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
int64_t PosIntDivDown(int64_t e, int64_t v)
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
LocalSearchFilter * MakeDimensionFilter(Solver *solver, std::unique_ptr< DimensionChecker > checker, const std::string &dimension_name)
bool AreAllOnes(const std::vector< T > &values)
bool AreAllBound(const std::vector< IntVar * > &vars)
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
uint64_t Hash1(uint64_t value)
Hash functions.
int64_t PosIntDivUp(int64_t e, int64_t v)
Set of parameters used to configure how the neighnorhood is traversed.
bool accept_path_end_base
True if path ends should be considered when iterating over neighbors.
int number_of_base_nodes
Number of nodes needed to define a neighbor.
std::function< int(int64_t)> start_empty_path_class
Callback returning an index such that if c1 = start_empty_path_class(StartNode(p1)),...
bool skip_locally_optimal_paths
Skip paths which have been proven locally optimal.
ChainBounds(int begin_index, int end_index)