OR-Tools  9.0
constraint_solveri.h
Go to the documentation of this file.
1 // Copyright 2010-2021 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 <memory>
58 #include <string>
59 #include <utility>
60 #include <vector>
61 
62 #include "absl/container/flat_hash_map.h"
63 #include "absl/strings/str_cat.h"
65 #include "ortools/base/logging.h"
66 #include "ortools/base/timer.h"
68 #include "ortools/util/bitset.h"
69 #include "ortools/util/tuple_set.h"
70 
71 namespace operations_research {
72 
98 class LocalSearchMonitor;
99 
100 class BaseIntExpr : public IntExpr {
101  public:
102  explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {}
103  ~BaseIntExpr() override {}
104 
105  IntVar* Var() override;
106  virtual IntVar* CastToVar();
107 
108  private:
109  IntVar* var_;
110 };
111 
114 enum VarTypes {
123  TRACE_VAR
124 };
125 
134 #ifndef SWIG
135 template <class T>
137  private:
138  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
139  struct Chunk {
140  T data_[CHUNK_SIZE];
141  const Chunk* const next_;
142  explicit Chunk(const Chunk* next) : next_(next) {}
143  };
144 
145  public:
147  class Iterator {
148  public:
149  explicit Iterator(const SimpleRevFIFO<T>* l)
150  : chunk_(l->chunks_), value_(l->Last()) {}
151  bool ok() const { return (value_ != nullptr); }
152  T operator*() const { return *value_; }
153  void operator++() {
154  ++value_;
155  if (value_ == chunk_->data_ + CHUNK_SIZE) {
156  chunk_ = chunk_->next_;
157  value_ = chunk_ ? chunk_->data_ : nullptr;
158  }
159  }
160 
161  private:
162  const Chunk* chunk_;
163  const T* value_;
164  };
165 
166  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
167 
168  void Push(Solver* const s, T val) {
169  if (pos_.Value() == 0) {
170  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
171  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
172  reinterpret_cast<void*>(chunk));
173  pos_.SetValue(s, CHUNK_SIZE - 1);
174  } else {
175  pos_.Decr(s);
176  }
177  chunks_->data_[pos_.Value()] = val;
178  }
179 
181  void PushIfNotTop(Solver* const s, T val) {
182  if (chunks_ == nullptr || LastValue() != val) {
183  Push(s, val);
184  }
185  }
186 
188  const T* Last() const {
189  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
190  }
191 
192  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
193 
195  const T& LastValue() const {
196  DCHECK(chunks_);
197  return chunks_->data_[pos_.Value()];
198  }
199 
201  void SetLastValue(const T& v) {
202  DCHECK(Last());
203  chunks_->data_[pos_.Value()] = v;
204  }
205 
206  private:
207  Chunk* chunks_;
208  NumericalRev<int> pos_;
209 };
210 
212 // TODO(user): use murmurhash.
213 inline uint64_t Hash1(uint64_t value) {
214  value = (~value) + (value << 21);
215  value ^= value >> 24;
216  value += (value << 3) + (value << 8);
217  value ^= value >> 14;
218  value += (value << 2) + (value << 4);
219  value ^= value >> 28;
220  value += (value << 31);
221  return value;
222 }
223 
224 inline uint64_t Hash1(uint32_t value) {
225  uint64_t a = value;
226  a = (a + 0x7ed55d16) + (a << 12);
227  a = (a ^ 0xc761c23c) ^ (a >> 19);
228  a = (a + 0x165667b1) + (a << 5);
229  a = (a + 0xd3a2646c) ^ (a << 9);
230  a = (a + 0xfd7046c5) + (a << 3);
231  a = (a ^ 0xb55a4f09) ^ (a >> 16);
232  return a;
233 }
234 
235 inline uint64_t Hash1(int64_t value) {
236  return Hash1(static_cast<uint64_t>(value));
237 }
238 
239 inline uint64_t Hash1(int value) { return Hash1(static_cast<uint32_t>(value)); }
240 
241 inline uint64_t Hash1(void* const ptr) {
242 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
243  defined(__aarch64__)
244  return Hash1(reinterpret_cast<uint64_t>(ptr));
245 #else
246  return Hash1(reinterpret_cast<uint32_t>(ptr));
247 #endif
248 }
249 
250 template <class T>
251 uint64_t Hash1(const std::vector<T*>& ptrs) {
252  if (ptrs.empty()) return 0;
253  if (ptrs.size() == 1) return Hash1(ptrs[0]);
254  uint64_t hash = Hash1(ptrs[0]);
255  for (int i = 1; i < ptrs.size(); ++i) {
256  hash = hash * i + Hash1(ptrs[i]);
257  }
258  return hash;
259 }
260 
261 inline uint64_t Hash1(const std::vector<int64_t>& ptrs) {
262  if (ptrs.empty()) return 0;
263  if (ptrs.size() == 1) return Hash1(ptrs[0]);
264  uint64_t hash = Hash1(ptrs[0]);
265  for (int i = 1; i < ptrs.size(); ++i) {
266  hash = hash * i + Hash1(ptrs[i]);
267  }
268  return hash;
269 }
270 
273 template <class K, class V>
275  public:
276  RevImmutableMultiMap(Solver* const solver, int initial_size)
277  : solver_(solver),
278  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
279  size_(initial_size),
280  num_items_(0) {
281  memset(array_, 0, sizeof(*array_) * size_.Value());
282  }
283 
285 
286  int num_items() const { return num_items_.Value(); }
287 
289  bool ContainsKey(const K& key) const {
290  uint64_t code = Hash1(key) % size_.Value();
291  Cell* tmp = array_[code];
292  while (tmp) {
293  if (tmp->key() == key) {
294  return true;
295  }
296  tmp = tmp->next();
297  }
298  return false;
299  }
300 
304  const V& FindWithDefault(const K& key, const V& default_value) const {
305  uint64_t code = Hash1(key) % size_.Value();
306  Cell* tmp = array_[code];
307  while (tmp) {
308  if (tmp->key() == key) {
309  return tmp->value();
310  }
311  tmp = tmp->next();
312  }
313  return default_value;
314  }
315 
317  void Insert(const K& key, const V& value) {
318  const int position = Hash1(key) % size_.Value();
319  Cell* const cell =
320  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
321  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
322  reinterpret_cast<void*>(cell));
323  num_items_.Incr(solver_);
324  if (num_items_.Value() > 2 * size_.Value()) {
325  Double();
326  }
327  }
328 
329  private:
330  class Cell {
331  public:
332  Cell(const K& key, const V& value, Cell* const next)
333  : key_(key), value_(value), next_(next) {}
334 
335  void SetRevNext(Solver* const solver, Cell* const next) {
336  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
337  reinterpret_cast<void*>(next));
338  }
339 
340  Cell* next() const { return next_; }
341 
342  const K& key() const { return key_; }
343 
344  const V& value() const { return value_; }
345 
346  private:
347  const K key_;
348  const V value_;
349  Cell* next_;
350  };
351 
352  void Double() {
353  Cell** const old_cell_array = array_;
354  const int old_size = size_.Value();
355  size_.SetValue(solver_, size_.Value() * 2);
356  solver_->SaveAndSetValue(
357  reinterpret_cast<void**>(&array_),
358  reinterpret_cast<void*>(
359  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
360  memset(array_, 0, size_.Value() * sizeof(*array_));
361  for (int i = 0; i < old_size; ++i) {
362  Cell* tmp = old_cell_array[i];
363  while (tmp != nullptr) {
364  Cell* const to_reinsert = tmp;
365  tmp = tmp->next();
366  const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value();
367  to_reinsert->SetRevNext(solver_, array_[new_position]);
368  solver_->SaveAndSetValue(
369  reinterpret_cast<void**>(&array_[new_position]),
370  reinterpret_cast<void*>(to_reinsert));
371  }
372  }
373  }
374 
375  Solver* const solver_;
376  Cell** array_;
377  NumericalRev<int> size_;
378  NumericalRev<int> num_items_;
379 };
380 
382 class RevSwitch {
383  public:
384  RevSwitch() : value_(false) {}
385 
386  bool Switched() const { return value_; }
387 
388  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
389 
390  private:
391  bool value_;
392 };
393 
397  public:
398  explicit SmallRevBitSet(int64_t size);
400  void SetToOne(Solver* const solver, int64_t pos);
402  void SetToZero(Solver* const solver, int64_t pos);
404  int64_t Cardinality() const;
406  bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; }
408  bool IsCardinalityOne() const {
409  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
410  }
413  int64_t GetFirstOne() const;
414 
415  private:
416  Rev<uint64_t> bits_;
417 };
418 
421 class RevBitSet {
422  public:
423  explicit RevBitSet(int64_t size);
424  ~RevBitSet();
425 
427  void SetToOne(Solver* const solver, int64_t index);
429  void SetToZero(Solver* const solver, int64_t index);
431  bool IsSet(int64_t index) const;
433  int64_t Cardinality() const;
435  bool IsCardinalityZero() const;
437  bool IsCardinalityOne() const;
440  int64_t GetFirstBit(int start) const;
442  void ClearAll(Solver* const solver);
443 
444  friend class RevBitMatrix;
445 
446  private:
448  void Save(Solver* const solver, int offset);
449  const int64_t size_;
450  const int64_t length_;
451  uint64_t* bits_;
452  uint64_t* stamps_;
453 };
454 
456 class RevBitMatrix : private RevBitSet {
457  public:
458  RevBitMatrix(int64_t rows, int64_t columns);
459  ~RevBitMatrix();
460 
462  void SetToOne(Solver* const solver, int64_t row, int64_t column);
464  void SetToZero(Solver* const solver, int64_t row, int64_t column);
466  bool IsSet(int64_t row, int64_t column) const {
467  DCHECK_GE(row, 0);
468  DCHECK_LT(row, rows_);
469  DCHECK_GE(column, 0);
470  DCHECK_LT(column, columns_);
471  return RevBitSet::IsSet(row * columns_ + column);
472  }
474  int64_t Cardinality(int row) const;
476  bool IsCardinalityZero(int row) const;
478  bool IsCardinalityOne(int row) const;
481  int64_t GetFirstBit(int row, int start) const;
483  void ClearAll(Solver* const solver);
484 
485  private:
486  const int64_t rows_;
487  const int64_t columns_;
488 };
489 
495 
497 template <class T>
498 class CallMethod0 : public Demon {
499  public:
500  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
501  : constraint_(ct), method_(method), name_(name) {}
502 
503  ~CallMethod0() override {}
504 
505  void Run(Solver* const s) override { (constraint_->*method_)(); }
506 
507  std::string DebugString() const override {
508  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
509  }
510 
511  private:
512  T* const constraint_;
513  void (T::*const method_)();
514  const std::string name_;
515 };
516 
517 template <class T>
518 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
519  const std::string& name) {
520  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
521 }
522 
523 template <class P>
524 std::string ParameterDebugString(P param) {
525  return absl::StrCat(param);
526 }
527 
529 template <class P>
530 std::string ParameterDebugString(P* param) {
531  return param->DebugString();
532 }
533 
535 template <class T, class P>
536 class CallMethod1 : public Demon {
537  public:
538  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
539  P param1)
540  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
541 
542  ~CallMethod1() override {}
543 
544  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
545 
546  std::string DebugString() const override {
547  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
548  ", ", ParameterDebugString(param1_), ")");
549  }
550 
551  private:
552  T* const constraint_;
553  void (T::*const method_)(P);
554  const std::string name_;
555  P param1_;
556 };
557 
558 template <class T, class P>
559 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
560  const std::string& name, P param1) {
561  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
562 }
563 
565 template <class T, class P, class Q>
566 class CallMethod2 : public Demon {
567  public:
568  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
569  P param1, Q param2)
570  : constraint_(ct),
571  method_(method),
572  name_(name),
573  param1_(param1),
574  param2_(param2) {}
575 
576  ~CallMethod2() override {}
577 
578  void Run(Solver* const s) override {
579  (constraint_->*method_)(param1_, param2_);
580  }
581 
582  std::string DebugString() const override {
583  return absl::StrCat(absl::StrCat("CallMethod_", name_),
584  absl::StrCat("(", constraint_->DebugString()),
585  absl::StrCat(", ", ParameterDebugString(param1_)),
586  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
587  }
588 
589  private:
590  T* const constraint_;
591  void (T::*const method_)(P, Q);
592  const std::string name_;
593  P param1_;
594  Q param2_;
595 };
596 
597 template <class T, class P, class Q>
598 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
599  void (T::*method)(P, Q), const std::string& name,
600  P param1, Q param2) {
601  return s->RevAlloc(
602  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
603 }
605 template <class T, class P, class Q, class R>
606 class CallMethod3 : public Demon {
607  public:
608  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
609  P param1, Q param2, R param3)
610  : constraint_(ct),
611  method_(method),
612  name_(name),
613  param1_(param1),
614  param2_(param2),
615  param3_(param3) {}
616 
617  ~CallMethod3() override {}
618 
619  void Run(Solver* const s) override {
620  (constraint_->*method_)(param1_, param2_, param3_);
621  }
622 
623  std::string DebugString() const override {
624  return absl::StrCat(absl::StrCat("CallMethod_", name_),
625  absl::StrCat("(", constraint_->DebugString()),
626  absl::StrCat(", ", ParameterDebugString(param1_)),
627  absl::StrCat(", ", ParameterDebugString(param2_)),
628  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
629  }
630 
631  private:
632  T* const constraint_;
633  void (T::*const method_)(P, Q, R);
634  const std::string name_;
635  P param1_;
636  Q param2_;
637  R param3_;
638 };
639 
640 template <class T, class P, class Q, class R>
641 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
642  void (T::*method)(P, Q, R), const std::string& name,
643  P param1, Q param2, R param3) {
644  return s->RevAlloc(
645  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
646 }
648 
653 
655 template <class T>
656 class DelayedCallMethod0 : public Demon {
657  public:
658  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
659  : constraint_(ct), method_(method), name_(name) {}
660 
661  ~DelayedCallMethod0() override {}
662 
663  void Run(Solver* const s) override { (constraint_->*method_)(); }
664 
665  Solver::DemonPriority priority() const override {
667  }
668 
669  std::string DebugString() const override {
670  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
671  ")";
672  }
673 
674  private:
675  T* const constraint_;
676  void (T::*const method_)();
677  const std::string name_;
678 };
679 
680 template <class T>
682  void (T::*method)(),
683  const std::string& name) {
684  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
685 }
686 
688 template <class T, class P>
689 class DelayedCallMethod1 : public Demon {
690  public:
691  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
692  P param1)
693  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
694 
695  ~DelayedCallMethod1() override {}
696 
697  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
698 
699  Solver::DemonPriority priority() const override {
701  }
702 
703  std::string DebugString() const override {
704  return absl::StrCat("DelayedCallMethod_", name_, "(",
705  constraint_->DebugString(), ", ",
706  ParameterDebugString(param1_), ")");
707  }
708 
709  private:
710  T* const constraint_;
711  void (T::*const method_)(P);
712  const std::string name_;
713  P param1_;
714 };
715 
716 template <class T, class P>
718  void (T::*method)(P),
719  const std::string& name, P param1) {
720  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
721 }
722 
724 template <class T, class P, class Q>
725 class DelayedCallMethod2 : public Demon {
726  public:
727  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
728  const std::string& name, P param1, Q param2)
729  : constraint_(ct),
730  method_(method),
731  name_(name),
732  param1_(param1),
733  param2_(param2) {}
734 
735  ~DelayedCallMethod2() override {}
736 
737  void Run(Solver* const s) override {
738  (constraint_->*method_)(param1_, param2_);
739  }
740 
741  Solver::DemonPriority priority() const override {
743  }
744 
745  std::string DebugString() const override {
746  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
747  absl::StrCat("(", constraint_->DebugString()),
748  absl::StrCat(", ", ParameterDebugString(param1_)),
749  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
750  }
751 
752  private:
753  T* const constraint_;
754  void (T::*const method_)(P, Q);
755  const std::string name_;
756  P param1_;
757  Q param2_;
758 };
759 
760 template <class T, class P, class Q>
762  void (T::*method)(P, Q),
763  const std::string& name, P param1,
764  Q param2) {
765  return s->RevAlloc(
766  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
767 }
769 
770 #endif // !defined(SWIG)
771 
789 // TODO(user): rename Start to Synchronize ?
790 // TODO(user): decouple the iterating from the defining of a neighbor.
792  public:
794  ~LocalSearchOperator() override {}
795  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
796  virtual void Start(const Assignment* assignment) = 0;
797  virtual void Reset() {}
798 #ifndef SWIG
799  virtual const LocalSearchOperator* Self() const { return this; }
800 #endif // SWIG
801  virtual bool HasFragments() const { return false; }
802  virtual bool HoldsDelta() const { return false; }
803 };
804 
806 template <class V, class Val, class Handler>
808  public:
810  explicit VarLocalSearchOperator(Handler var_handler)
811  : activated_(),
812  was_activated_(),
813  cleared_(true),
814  var_handler_(var_handler) {}
816  bool HoldsDelta() const override { return true; }
819  void Start(const Assignment* assignment) override {
820  const int size = Size();
821  CHECK_LE(size, assignment->Size())
822  << "Assignment contains fewer variables than operator";
823  for (int i = 0; i < size; ++i) {
824  activated_.Set(i, var_handler_.ValueFromAssignment(*assignment, vars_[i],
825  i, &values_[i]));
826  }
830  OnStart();
831  }
832  virtual bool IsIncremental() const { return false; }
833  int Size() const { return vars_.size(); }
836  const Val& Value(int64_t index) const {
837  DCHECK_LT(index, vars_.size());
838  return values_[index];
839  }
841  V* Var(int64_t index) const { return vars_[index]; }
842  virtual bool SkipUnchanged(int index) const { return false; }
843  const Val& OldValue(int64_t index) const { return old_values_[index]; }
844  void SetValue(int64_t index, const Val& value) {
845  values_[index] = value;
846  MarkChange(index);
847  }
848  bool Activated(int64_t index) const { return activated_[index]; }
849  void Activate(int64_t index) {
851  MarkChange(index);
852  }
853  void Deactivate(int64_t index) {
855  MarkChange(index);
856  }
857  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
858  if (IsIncremental() && !cleared_) {
859  for (const int64_t index : delta_changes_.PositionsSetAtLeastOnce()) {
860  V* var = Var(index);
861  const Val& value = Value(index);
862  const bool activated = activated_[index];
863  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
864  deltadelta);
865  var_handler_.AddToAssignment(var, value, activated,
867  }
868  } else {
869  delta->Clear();
870  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
871  const Val& value = Value(index);
872  const bool activated = activated_[index];
873  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
874  var_handler_.AddToAssignment(Var(index), value, activated_[index],
876  }
877  }
878  }
879  return true;
880  }
881  void RevertChanges(bool incremental) {
882  cleared_ = false;
884  if (incremental && IsIncremental()) return;
885  cleared_ = true;
886  for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
888  var_handler_.OnRevertChanges(index, values_[index]);
891  }
893  }
894  void AddVars(const std::vector<V*>& vars) {
895  if (!vars.empty()) {
896  vars_.insert(vars_.end(), vars.begin(), vars.end());
897  const int64_t size = Size();
898  values_.resize(size);
899  old_values_.resize(size);
900  prev_values_.resize(size);
901  assignment_indices_.resize(size, -1);
902  activated_.Resize(size);
903  was_activated_.Resize(size);
904  changes_.ClearAndResize(size);
906  var_handler_.OnAddVars();
907  }
908  }
909 
913  virtual void OnStart() {}
914 
917  protected:
918  void MarkChange(int64_t index) {
920  changes_.Set(index);
921  }
922 
923  std::vector<V*> vars_;
924  std::vector<Val> values_;
925  std::vector<Val> old_values_;
926  std::vector<Val> prev_values_;
927  mutable std::vector<int> assignment_indices_;
932  bool cleared_;
933  Handler var_handler_;
934 };
935 
938 
940  public:
941  IntVarLocalSearchHandler() : op_(nullptr) {}
943  : op_(other.op_) {}
945  void AddToAssignment(IntVar* var, int64_t value, bool active,
946  std::vector<int>* assignment_indices, int64_t index,
947  Assignment* assignment) const {
948  Assignment::IntContainer* const container =
949  assignment->MutableIntVarContainer();
950  IntVarElement* element = nullptr;
951  if (assignment_indices != nullptr) {
952  if ((*assignment_indices)[index] == -1) {
953  (*assignment_indices)[index] = container->Size();
954  element = assignment->FastAdd(var);
955  } else {
956  element = container->MutableElement((*assignment_indices)[index]);
957  }
958  } else {
959  element = assignment->FastAdd(var);
960  }
961  if (active) {
962  element->SetValue(value);
963  element->Activate();
964  } else {
965  element->Deactivate();
966  }
967  }
968  bool ValueFromAssignment(const Assignment& assignment, IntVar* var,
969  int64_t index, int64_t* value);
970  void OnRevertChanges(int64_t index, int64_t value);
971  void OnAddVars() {}
972 
973  private:
974  IntVarLocalSearchOperator* const op_;
975 };
976 
982 
983 #ifdef SWIG
987 // TODO(user): find a way to move this code back to the .i file, where it
991 #if defined(SWIGPYTHON)
992 // clang-format off
993 %unignore VarLocalSearchOperator<IntVar, int64_t,
994  IntVarLocalSearchHandler>::Size;
995 %unignore VarLocalSearchOperator<IntVar, int64_t,
996  IntVarLocalSearchHandler>::Value;
997 %unignore VarLocalSearchOperator<IntVar, int64_t,
998  IntVarLocalSearchHandler>::OldValue;
999 %unignore VarLocalSearchOperator<IntVar, int64_t,
1000  IntVarLocalSearchHandler>::SetValue;
1001 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1002  IntVarLocalSearchHandler>::IsIncremental;
1003 %feature("director") VarLocalSearchOperator<IntVar, int64_t,
1004  IntVarLocalSearchHandler>::OnStart;
1005 %unignore VarLocalSearchOperator<IntVar, int64_t,
1006  IntVarLocalSearchHandler>::IsIncremental;
1007 %unignore VarLocalSearchOperator<IntVar, int64_t,
1008  IntVarLocalSearchHandler>::OnStart;
1009 // clang-format on
1010 #endif // SWIGPYTHON
1011 
1012 // clang-format off
1013 %rename(IntVarLocalSearchOperatorTemplate)
1014  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1015 %template(IntVarLocalSearchOperatorTemplate)
1016  VarLocalSearchOperator<IntVar, int64_t, IntVarLocalSearchHandler>;
1017 // clang-format on
1018 #endif // SWIG
1019 
1022  public:
1023  IntVarLocalSearchOperator() : max_inverse_value_(-1) {}
1024  // If keep_inverse_values is true, assumes that vars models an injective
1025  // function f with domain [0, vars.size()) in which case the operator will
1026  // maintain the inverse function.
1027  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars,
1028  bool keep_inverse_values = false)
1030  IntVarLocalSearchHandler(this)),
1031  max_inverse_value_(keep_inverse_values ? vars.size() - 1 : -1) {
1032  AddVars(vars);
1033  if (keep_inverse_values) {
1034  int64_t max_value = -1;
1035  for (const IntVar* const var : vars) {
1036  max_value = std::max(max_value, var->Max());
1037  }
1038  inverse_values_.resize(max_value + 1, -1);
1039  old_inverse_values_.resize(max_value + 1, -1);
1040  }
1041  }
1049  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1050 
1051  protected:
1053 
1056  // TODO(user): make it pure virtual, implies porting all apps overriding
1058  virtual bool MakeOneNeighbor();
1059 
1060  bool IsInverseValue(int64_t index) const {
1061  DCHECK_GE(index, 0);
1062  return index <= max_inverse_value_;
1063  }
1064 
1065  int64_t InverseValue(int64_t index) const { return inverse_values_[index]; }
1066 
1067  int64_t OldInverseValue(int64_t index) const {
1068  return old_inverse_values_[index];
1069  }
1070 
1071  void SetInverseValue(int64_t index, int64_t value) {
1072  inverse_values_[index] = value;
1073  }
1074 
1075  void SetOldInverseValue(int64_t index, int64_t value) {
1076  old_inverse_values_[index] = value;
1077  }
1078 
1079  private:
1080  const int64_t max_inverse_value_;
1081  std::vector<int64_t> old_inverse_values_;
1082  std::vector<int64_t> inverse_values_;
1083 };
1084 
1086  const Assignment& assignment, IntVar* var, int64_t index, int64_t* value) {
1087  const Assignment::IntContainer& container = assignment.IntVarContainer();
1088  const IntVarElement* element = &(container.Element(index));
1089  if (element->Var() != var) {
1090  CHECK(container.Contains(var))
1091  << "Assignment does not contain operator variable " << var;
1092  element = &(container.Element(var));
1093  }
1094  *value = element->Value();
1095  if (op_->IsInverseValue(index)) {
1096  op_->SetInverseValue(*value, index);
1097  op_->SetOldInverseValue(*value, index);
1098  }
1099  return element->Activated();
1100 }
1101 
1103  int64_t value) {
1104  if (op_->IsInverseValue(index)) {
1105  op_->SetInverseValue(value, index);
1106  }
1107 }
1108 
1111 
1113  public:
1114  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1116  : op_(other.op_) {}
1118  : op_(op) {}
1119  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1120  bool active, std::vector<int>* assignment_indices,
1121  int64_t index, Assignment* assignment) const;
1122  bool ValueFromAssignment(const Assignment& assignment, SequenceVar* var,
1123  int64_t index, std::vector<int>* value);
1124  void OnRevertChanges(int64_t index, const std::vector<int>& value);
1125  void OnAddVars();
1126 
1127  private:
1128  SequenceVarLocalSearchOperator* const op_;
1129 };
1130 
1131 #ifdef SWIG
1135 // TODO(user): find a way to move this code back to the .i file, where it
1137 // clang-format off
1138 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1139  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1140 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1141  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1142 // clang-format on
1143 #endif
1144 
1145 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1146  SequenceVarLocalSearchHandler>
1148 
1151  public:
1153  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1156  AddVars(vars);
1157  }
1161  const std::vector<int>& Sequence(int64_t index) const { return Value(index); }
1162  const std::vector<int>& OldSequence(int64_t index) const {
1163  return OldValue(index);
1164  }
1165  void SetForwardSequence(int64_t index, const std::vector<int>& value) {
1166  SetValue(index, value);
1167  }
1168  void SetBackwardSequence(int64_t index, const std::vector<int>& value) {
1170  MarkChange(index);
1171  }
1172 
1173  protected:
1175 
1176  std::vector<std::vector<int>> backward_values_;
1177 };
1178 
1180  SequenceVar* var, const std::vector<int>& value, bool active,
1181  std::vector<int>* assignment_indices, int64_t index,
1182  Assignment* assignment) const {
1183  Assignment::SequenceContainer* const container =
1184  assignment->MutableSequenceVarContainer();
1185  SequenceVarElement* element = nullptr;
1186  if (assignment_indices != nullptr) {
1187  if ((*assignment_indices)[index] == -1) {
1188  (*assignment_indices)[index] = container->Size();
1189  element = assignment->FastAdd(var);
1190  } else {
1191  element = container->MutableElement((*assignment_indices)[index]);
1192  }
1193  } else {
1194  element = assignment->FastAdd(var);
1195  }
1196  if (active) {
1197  element->SetForwardSequence(value);
1198  element->SetBackwardSequence(op_->backward_values_[index]);
1199  element->Activate();
1200  } else {
1201  element->Deactivate();
1202  }
1203 }
1204 
1206  const Assignment& assignment, SequenceVar* var, int64_t index,
1207  std::vector<int>* value) {
1208  const Assignment::SequenceContainer& container =
1209  assignment.SequenceVarContainer();
1210  const SequenceVarElement* element = &(container.Element(index));
1211  if (element->Var() != var) {
1212  CHECK(container.Contains(var))
1213  << "Assignment does not contain operator variable " << var;
1214  element = &(container.Element(var));
1215  }
1216  const std::vector<int>& element_value = element->ForwardSequence();
1217  CHECK_GE(var->size(), element_value.size());
1218  op_->backward_values_[index].clear();
1219  *value = element_value;
1220  return element->Activated();
1221 }
1222 
1224  int64_t index, const std::vector<int>& value) {
1225  op_->backward_values_[index].clear();
1226 }
1227 
1229  op_->backward_values_.resize(op_->Size());
1230 }
1231 
1260  public:
1261  explicit BaseLns(const std::vector<IntVar*>& vars);
1262  ~BaseLns() override;
1263  virtual void InitFragments();
1264  virtual bool NextFragment() = 0;
1265  void AppendToFragment(int index);
1266  int FragmentSize() const;
1267  bool HasFragments() const override { return true; }
1268 
1269  protected:
1271  bool MakeOneNeighbor() override;
1272 
1273  private:
1275  void OnStart() override;
1276  std::vector<int> fragment_;
1277 };
1278 
1284  public:
1285  explicit ChangeValue(const std::vector<IntVar*>& vars);
1286  ~ChangeValue() override;
1287  virtual int64_t ModifyValue(int64_t index, int64_t value) = 0;
1288 
1289  protected:
1291  bool MakeOneNeighbor() override;
1292 
1293  private:
1294  void OnStart() override;
1295 
1296  int index_;
1297 };
1298 
1313  public:
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() override {}
1332  virtual bool MakeNeighbor() = 0;
1333  void Reset() override;
1334 
1335  // TODO(user): Make the following methods protected.
1336  bool SkipUnchanged(int index) const override;
1337 
1339  int64_t Next(int64_t node) const {
1340  DCHECK(!IsPathEnd(node));
1341  return Value(node);
1342  }
1343 
1345  int64_t Prev(int64_t node) const {
1346  DCHECK(!IsPathStart(node));
1347  DCHECK_EQ(Next(InverseValue(node)), node);
1348  return InverseValue(node);
1349  }
1350 
1353  int64_t Path(int64_t node) const {
1354  return ignore_path_vars_ ? 0LL : Value(node + number_of_nexts_);
1355  }
1356 
1358  int number_of_nexts() const { return number_of_nexts_; }
1359 
1360  protected:
1362  bool MakeOneNeighbor() override;
1366  virtual void OnNodeInitialization() {}
1367 
1369  int64_t BaseNode(int i) const { return base_nodes_[i]; }
1371  int BaseAlternative(int i) const { return base_alternatives_[i]; }
1373  int64_t BaseAlternativeNode(int i) const {
1374  if (!ConsiderAlternatives(i)) return BaseNode(i);
1375  const int alternative_index = alternative_index_[BaseNode(i)];
1376  return alternative_index >= 0
1377  ? alternative_sets_[alternative_index][base_alternatives_[i]]
1378  : BaseNode(i);
1379  }
1381  int BaseSiblingAlternative(int i) const {
1382  return base_sibling_alternatives_[i];
1383  }
1385  int64_t BaseSiblingAlternativeNode(int i) const {
1386  if (!ConsiderAlternatives(i)) return BaseNode(i);
1387  const int sibling_alternative_index =
1389  return sibling_alternative_index >= 0
1390  ? alternative_sets_[sibling_alternative_index]
1391  [base_sibling_alternatives_[i]]
1392  : BaseNode(i);
1393  }
1395  int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1397  const std::vector<int64_t>& path_starts() const { return path_starts_; }
1399  int PathClass(int i) const {
1400  return start_empty_path_class_ != nullptr
1401  ? start_empty_path_class_(StartNode(i))
1402  : StartNode(i);
1403  }
1404 
1411  // TODO(user): remove this when automatic detection of such cases in done.
1412  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1416  // TODO(user): ideally this should be OnSamePath(int64_t node1, int64_t
1417  // node2);
1419  virtual bool OnSamePathAsPreviousBase(int64_t base_index) { return false; }
1425  virtual int64_t GetBaseNodeRestartPosition(int base_index) {
1426  return StartNode(base_index);
1427  }
1430  virtual void SetNextBaseToIncrement(int64_t base_index) {
1431  next_base_to_increment_ = base_index;
1432  }
1435  virtual bool ConsiderAlternatives(int64_t base_index) const { return false; }
1436 
1437  int64_t OldNext(int64_t node) const {
1438  DCHECK(!IsPathEnd(node));
1439  return OldValue(node);
1440  }
1441 
1442  int64_t OldPrev(int64_t node) const {
1443  DCHECK(!IsPathStart(node));
1444  return OldInverseValue(node);
1445  }
1446 
1447  int64_t OldPath(int64_t node) const {
1448  return ignore_path_vars_ ? 0LL : OldValue(node + number_of_nexts_);
1449  }
1450 
1453  bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination);
1454 
1457  bool ReverseChain(int64_t before_chain, int64_t after_chain,
1458  int64_t* chain_last);
1459 
1461  bool MakeActive(int64_t node, int64_t destination);
1464  bool MakeChainInactive(int64_t before_chain, int64_t chain_end);
1466  bool SwapActiveAndInactive(int64_t active, int64_t inactive);
1467 
1469  void SetNext(int64_t from, int64_t to, int64_t path) {
1470  DCHECK_LT(from, number_of_nexts_);
1471  SetValue(from, to);
1472  SetInverseValue(to, from);
1473  if (!ignore_path_vars_) {
1474  DCHECK_LT(from + number_of_nexts_, Size());
1475  SetValue(from + number_of_nexts_, path);
1476  }
1477  }
1478 
1481  bool IsPathEnd(int64_t node) const { return node >= number_of_nexts_; }
1482 
1484  bool IsPathStart(int64_t node) const { return OldInverseValue(node) == -1; }
1485 
1487  bool IsInactive(int64_t node) const {
1488  return !IsPathEnd(node) && inactives_[node];
1489  }
1490 
1493  virtual bool InitPosition() const { return false; }
1497  void ResetPosition() { just_started_ = true; }
1498 
1502  int AddAlternativeSet(const std::vector<int64_t>& alternative_set) {
1503  const int alternative = alternative_sets_.size();
1504  for (int64_t node : alternative_set) {
1505  DCHECK_EQ(-1, alternative_index_[node]);
1506  alternative_index_[node] = alternative;
1507  }
1508  alternative_sets_.push_back(alternative_set);
1509  sibling_alternative_.push_back(-1);
1510  return alternative;
1511  }
1512 #ifndef SWIG
1516  const std::vector<std::pair<std::vector<int64_t>, std::vector<int64_t>>>&
1517  pair_alternative_sets) {
1518  for (const auto& pair_alternative_set : pair_alternative_sets) {
1519  const int alternative = AddAlternativeSet(pair_alternative_set.first);
1520  sibling_alternative_.back() = alternative + 1;
1521  AddAlternativeSet(pair_alternative_set.second);
1522  }
1523  }
1524 #endif // SWIG
1526  int64_t GetActiveInAlternativeSet(int alternative_index) const {
1527  return alternative_index >= 0
1528  ? active_in_alternative_set_[alternative_index]
1529  : -1;
1530  }
1532  int64_t GetActiveAlternativeNode(int node) const {
1533  return GetActiveInAlternativeSet(alternative_index_[node]);
1534  }
1536  int GetSiblingAlternativeIndex(int node) const {
1537  if (node >= alternative_index_.size()) return -1;
1538  const int alternative = alternative_index_[node];
1539  return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1540  }
1543  int64_t GetActiveAlternativeSibling(int node) const {
1544  if (node >= alternative_index_.size()) return -1;
1545  const int alternative = alternative_index_[node];
1546  const int sibling_alternative =
1547  alternative >= 0 ? sibling_alternative_[alternative] : -1;
1548  return GetActiveInAlternativeSet(sibling_alternative);
1549  }
1552  bool CheckChainValidity(int64_t before_chain, int64_t chain_end,
1553  int64_t exclude) const;
1554 
1555  const int number_of_nexts_;
1556  const bool ignore_path_vars_;
1558  int num_paths_ = 0;
1559  std::vector<int64_t> start_to_path_;
1560 
1561  private:
1562  void OnStart() override;
1564  bool OnSamePath(int64_t node1, int64_t node2) const;
1565 
1566  bool CheckEnds() const {
1567  const int base_node_size = base_nodes_.size();
1568  for (int i = base_node_size - 1; i >= 0; --i) {
1569  if (base_nodes_[i] != end_nodes_[i]) {
1570  return true;
1571  }
1572  }
1573  return false;
1574  }
1575  bool IncrementPosition();
1576  void InitializePathStarts();
1577  void InitializeInactives();
1578  void InitializeBaseNodes();
1579  void InitializeAlternatives();
1580  void Synchronize();
1581 
1582  std::vector<int> base_nodes_;
1583  std::vector<int> base_alternatives_;
1584  std::vector<int> base_sibling_alternatives_;
1585  std::vector<int> end_nodes_;
1586  std::vector<int> base_paths_;
1587  std::vector<int64_t> path_starts_;
1588  std::vector<bool> inactives_;
1589  bool just_started_;
1590  bool first_start_;
1591  const bool accept_path_end_base_;
1592  std::function<int(int64_t)> start_empty_path_class_;
1593  bool skip_locally_optimal_paths_;
1594  bool optimal_paths_enabled_;
1595  std::vector<int> path_basis_;
1596  std::vector<bool> optimal_paths_;
1598 #ifndef SWIG
1599  std::vector<std::vector<int64_t>> alternative_sets_;
1600 #endif // SWIG
1601  std::vector<int> alternative_index_;
1602  std::vector<int64_t> active_in_alternative_set_;
1603  std::vector<int> sibling_alternative_;
1604 };
1605 
1607 template <class T>
1608 LocalSearchOperator* MakeLocalSearchOperator(
1609  Solver* solver, const std::vector<IntVar*>& vars,
1610  const std::vector<IntVar*>& secondary_vars,
1611  std::function<int(int64_t)> start_empty_path_class);
1612 
1627 
1628 #if !defined(SWIG)
1629 // A LocalSearchState is a container for variables with bounds that can be
1630 // relaxed and tightened, saved and restored. It represents the solution state
1631 // of a local search engine, and allows it to go from solution to solution by
1632 // relaxing some variables to form a new subproblem, then tightening those
1633 // variables to move to a new solution representation. That state may be saved
1634 // to an internal copy, or reverted to the last saved internal copy.
1635 // Relaxing a variable returns its bounds to their initial state.
1636 // Tightening a variable's bounds may make its min larger than its max,
1637 // in that case, the tightening function will return false, and the state will
1638 // be marked as invalid. No other operations than Revert() can be called on an
1639 // invalid state: in particular, an invalid state cannot be saved.
1640 class LocalSearchVariable;
1641 
1643  public:
1644  LocalSearchVariable AddVariable(int64_t initial_min, int64_t initial_max);
1645  void Commit();
1646  void Revert();
1647  bool StateIsValid() const { return state_is_valid_; }
1648 
1649  private:
1650  friend class LocalSearchVariable;
1651 
1652  struct Bounds {
1653  int64_t min;
1654  int64_t max;
1655  };
1656 
1657  void RelaxVariableBounds(int variable_index);
1658  bool TightenVariableMin(int variable_index, int64_t value);
1659  bool TightenVariableMax(int variable_index, int64_t value);
1660  int64_t VariableMin(int variable_index) const;
1661  int64_t VariableMax(int variable_index) const;
1662 
1663  std::vector<Bounds> initial_variable_bounds_;
1664  std::vector<Bounds> variable_bounds_;
1665  std::vector<std::pair<Bounds, int>> saved_variable_bounds_trail_;
1666  std::vector<bool> variable_is_relaxed_;
1667  bool state_is_valid_ = true;
1668 };
1669 
1670 // A LocalSearchVariable can only be created by a LocalSearchState, then it is
1671 // meant to be passed by copy. If at some point the duplication of
1672 // LocalSearchState pointers is too expensive, we could switch to index only,
1673 // and the user would have to know the relevant state. The present setup allows
1674 // to ensure that variable users will not misuse the state.
1676  public:
1677  int64_t Min() const { return state_->VariableMin(variable_index_); }
1678  int64_t Max() const { return state_->VariableMax(variable_index_); }
1679  bool SetMin(int64_t new_min) {
1680  return state_->TightenVariableMin(variable_index_, new_min);
1681  }
1682  bool SetMax(int64_t new_max) {
1683  return state_->TightenVariableMax(variable_index_, new_max);
1684  }
1685  void Relax() { state_->RelaxVariableBounds(variable_index_); }
1686 
1687  private:
1688  // Only LocalSearchState can construct LocalSearchVariables.
1689  friend class LocalSearchState;
1690 
1691  LocalSearchVariable(LocalSearchState* state, int variable_index)
1692  : state_(state), variable_index_(variable_index) {}
1693 
1694  LocalSearchState* const state_;
1695  const int variable_index_;
1696 };
1697 #endif // !defined(SWIG)
1698 
1716  public:
1719  virtual void Relax(const Assignment* delta, const Assignment* deltadelta) {}
1721  virtual void Commit(const Assignment* delta, const Assignment* deltadelta) {}
1722 
1732  virtual bool Accept(const Assignment* delta, const Assignment* deltadelta,
1733  int64_t objective_min, int64_t objective_max) = 0;
1734  virtual bool IsIncremental() const { return false; }
1735 
1741  virtual void Synchronize(const Assignment* assignment,
1742  const Assignment* delta) = 0;
1744  virtual void Revert() {}
1745 
1747  virtual void Reset() {}
1748 
1750  virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; }
1752  // If the last Accept() call returned false, returns an undefined value.
1753  virtual int64_t GetAcceptedObjectiveValue() const { return 0LL; }
1754 };
1755 
1760  public:
1761  // This class is responsible for calling filters methods in a correct order.
1762  // For now, an order is specified explicitly by the user.
1763  enum FilterEventType { kAccept, kRelax };
1764  struct FilterEvent {
1767  };
1768 
1769  std::string DebugString() const override {
1770  return "LocalSearchFilterManager";
1771  }
1772  // Builds a manager that calls filter methods using an explicit ordering.
1773  explicit LocalSearchFilterManager(std::vector<FilterEvent> filter_events);
1774  // Builds a manager that calls filter methods using the following ordering:
1775  // first Relax() in vector order, then Accept() in vector order.
1776  // Note that some filters might appear only once, if their Relax() or Accept()
1777  // are trivial.
1778  explicit LocalSearchFilterManager(std::vector<LocalSearchFilter*> filters);
1779 
1780  // Calls Revert() of filters, in reverse order of Relax events.
1781  void Revert();
1785  bool Accept(LocalSearchMonitor* const monitor, const Assignment* delta,
1786  const Assignment* deltadelta, int64_t objective_min,
1787  int64_t objective_max);
1789  void Synchronize(const Assignment* assignment, const Assignment* delta);
1790  int64_t GetSynchronizedObjectiveValue() const { return synchronized_value_; }
1791  int64_t GetAcceptedObjectiveValue() const { return accepted_value_; }
1792 
1793  private:
1794  void InitializeForcedEvents();
1795 
1796  std::vector<FilterEvent> filter_events_;
1797  int last_event_called_ = -1;
1798  // If a filter is incremental, its Relax() and Accept() must be called for
1799  // every candidate, even if a previous Accept() rejected it.
1800  // To ensure that those filters have consistent inputs, all intermediate
1801  // Relax events are also triggered. All those events are called 'forced'.
1802  std::vector<int> next_forced_events_;
1803  int64_t synchronized_value_;
1804  int64_t accepted_value_;
1805 };
1806 
1808  public:
1809  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1810  ~IntVarLocalSearchFilter() override;
1813  void Synchronize(const Assignment* assignment,
1814  const Assignment* delta) override;
1815 
1816  bool FindIndex(IntVar* const var, int64_t* index) const {
1817  DCHECK(index != nullptr);
1818  const int var_index = var->index();
1819  *index = (var_index < var_index_to_index_.size())
1820  ? var_index_to_index_[var_index]
1821  : kUnassigned;
1822  return *index != kUnassigned;
1823  }
1824 
1826  void AddVars(const std::vector<IntVar*>& vars);
1827  int Size() const { return vars_.size(); }
1828  IntVar* Var(int index) const { return vars_[index]; }
1829  int64_t Value(int index) const {
1830  DCHECK(IsVarSynced(index));
1831  return values_[index];
1832  }
1833  bool IsVarSynced(int index) const { return var_synced_[index]; }
1834 
1835  protected:
1836  virtual void OnSynchronize(const Assignment* delta) {}
1837  void SynchronizeOnAssignment(const Assignment* assignment);
1838 
1839  private:
1840  std::vector<IntVar*> vars_;
1841  std::vector<int64_t> values_;
1842  std::vector<bool> var_synced_;
1843  std::vector<int> var_index_to_index_;
1844  static const int kUnassigned;
1845 };
1846 
1848  public:
1849  explicit PropagationMonitor(Solver* const solver);
1850  ~PropagationMonitor() override;
1851  std::string DebugString() const override { return "PropagationMonitor"; }
1852 
1855  Constraint* const constraint) = 0;
1857  Constraint* const constraint) = 0;
1859  Constraint* const parent, Constraint* const nested) = 0;
1861  Constraint* const parent, Constraint* const nested) = 0;
1862  virtual void RegisterDemon(Demon* const demon) = 0;
1863  virtual void BeginDemonRun(Demon* const demon) = 0;
1864  virtual void EndDemonRun(Demon* const demon) = 0;
1865  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1866  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1867  virtual void PushContext(const std::string& context) = 0;
1868  virtual void PopContext() = 0;
1870  virtual void SetMin(IntExpr* const expr, int64_t new_min) = 0;
1871  virtual void SetMax(IntExpr* const expr, int64_t new_max) = 0;
1872  virtual void SetRange(IntExpr* const expr, int64_t new_min,
1873  int64_t new_max) = 0;
1875  virtual void SetMin(IntVar* const var, int64_t new_min) = 0;
1876  virtual void SetMax(IntVar* const var, int64_t new_max) = 0;
1877  virtual void SetRange(IntVar* const var, int64_t new_min,
1878  int64_t new_max) = 0;
1879  virtual void RemoveValue(IntVar* const var, int64_t value) = 0;
1880  virtual void SetValue(IntVar* const var, int64_t value) = 0;
1881  virtual void RemoveInterval(IntVar* const var, int64_t imin,
1882  int64_t imax) = 0;
1883  virtual void SetValues(IntVar* const var,
1884  const std::vector<int64_t>& values) = 0;
1885  virtual void RemoveValues(IntVar* const var,
1886  const std::vector<int64_t>& values) = 0;
1888  virtual void SetStartMin(IntervalVar* const var, int64_t new_min) = 0;
1889  virtual void SetStartMax(IntervalVar* const var, int64_t new_max) = 0;
1890  virtual void SetStartRange(IntervalVar* const var, int64_t new_min,
1891  int64_t new_max) = 0;
1892  virtual void SetEndMin(IntervalVar* const var, int64_t new_min) = 0;
1893  virtual void SetEndMax(IntervalVar* const var, int64_t new_max) = 0;
1894  virtual void SetEndRange(IntervalVar* const var, int64_t new_min,
1895  int64_t new_max) = 0;
1896  virtual void SetDurationMin(IntervalVar* const var, int64_t new_min) = 0;
1897  virtual void SetDurationMax(IntervalVar* const var, int64_t new_max) = 0;
1898  virtual void SetDurationRange(IntervalVar* const var, int64_t new_min,
1899  int64_t new_max) = 0;
1900  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1902  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1903  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1904  virtual void RankLast(SequenceVar* const var, int index) = 0;
1905  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1906  virtual void RankSequence(SequenceVar* const var,
1907  const std::vector<int>& rank_first,
1908  const std::vector<int>& rank_last,
1909  const std::vector<int>& unperformed) = 0;
1911  void Install() override;
1912 };
1913 
1915  // TODO(user): Add monitoring of local search filters.
1916  public:
1917  explicit LocalSearchMonitor(Solver* const solver);
1918  ~LocalSearchMonitor() override;
1919  std::string DebugString() const override { return "LocalSearchMonitor"; }
1920 
1922  virtual void BeginOperatorStart() = 0;
1923  virtual void EndOperatorStart() = 0;
1924  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1926  bool neighbor_found, const Assignment* delta,
1927  const Assignment* deltadelta) = 0;
1928  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1929  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1930  bool neighbor_found) = 0;
1931  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1932  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1933  bool neighbor_found) = 0;
1934  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1935  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1936 
1938  void Install() override;
1939 };
1940 
1941 class BooleanVar : public IntVar {
1942  public:
1943  static const int kUnboundBooleanVarValue;
1944 
1945  explicit BooleanVar(Solver* const s, const std::string& name = "")
1946  : IntVar(s, name), value_(kUnboundBooleanVarValue) {}
1947 
1948  ~BooleanVar() override {}
1949 
1950  int64_t Min() const override { return (value_ == 1); }
1951  void SetMin(int64_t m) override;
1952  int64_t Max() const override { return (value_ != 0); }
1953  void SetMax(int64_t m) override;
1954  void SetRange(int64_t mi, int64_t ma) override;
1955  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1956  int64_t Value() const override {
1957  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1958  return value_;
1959  }
1960  void RemoveValue(int64_t v) override;
1961  void RemoveInterval(int64_t l, int64_t u) override;
1962  void WhenBound(Demon* d) override;
1963  void WhenRange(Demon* d) override { WhenBound(d); }
1964  void WhenDomain(Demon* d) override { WhenBound(d); }
1965  uint64_t Size() const override;
1966  bool Contains(int64_t v) const override;
1967  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1968  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1969  std::string DebugString() const override;
1970  int VarType() const override { return BOOLEAN_VAR; }
1971 
1972  IntVar* IsEqual(int64_t constant) override;
1973  IntVar* IsDifferent(int64_t constant) override;
1974  IntVar* IsGreaterOrEqual(int64_t constant) override;
1975  IntVar* IsLessOrEqual(int64_t constant) override;
1976 
1977  virtual void RestoreValue() = 0;
1978  std::string BaseName() const override { return "BooleanVar"; }
1979 
1980  int RawValue() const { return value_; }
1981 
1982  protected:
1983  int value_;
1986 };
1987 
1988 class SymmetryManager;
1989 
1994  public:
1996  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1997  ~SymmetryBreaker() override {}
1998 
1999  void AddIntegerVariableEqualValueClause(IntVar* const var, int64_t value);
2000  void AddIntegerVariableGreaterOrEqualValueClause(IntVar* const var,
2001  int64_t value);
2002  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var,
2003  int64_t value);
2004 
2005  private:
2006  friend class SymmetryManager;
2007  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
2008  CHECK(symmetry_manager_ == nullptr);
2009  CHECK_EQ(-1, index_in_symmetry_manager_);
2010  symmetry_manager_ = manager;
2011  index_in_symmetry_manager_ = index;
2012  }
2013  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
2014  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
2015 
2016  SymmetryManager* symmetry_manager_;
2018  int index_in_symmetry_manager_;
2019 };
2020 
2023 class SearchLog : public SearchMonitor {
2024  public:
2025  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
2026  double scaling_factor, double offset,
2027  std::function<std::string()> display_callback,
2028  bool display_on_new_solutions_only, int period);
2029  ~SearchLog() override;
2030  void EnterSearch() override;
2031  void ExitSearch() override;
2032  bool AtSolution() override;
2033  void BeginFail() override;
2034  void NoMoreSolutions() override;
2035  void AcceptUncheckedNeighbor() override;
2036  void ApplyDecision(Decision* const decision) override;
2037  void RefuteDecision(Decision* const decision) override;
2038  void OutputDecision();
2039  void Maintain();
2040  void BeginInitialPropagation() override;
2041  void EndInitialPropagation() override;
2042  std::string DebugString() const override;
2043 
2044  protected:
2045  /* Bottleneck function used for all UI related output. */
2046  virtual void OutputLine(const std::string& line);
2047 
2048  private:
2049  static std::string MemoryUsage();
2050 
2051  const int period_;
2052  std::unique_ptr<WallTimer> timer_;
2053  IntVar* const var_;
2054  OptimizeVar* const obj_;
2055  const double scaling_factor_;
2056  const double offset_;
2057  std::function<std::string()> display_callback_;
2058  const bool display_on_new_solutions_only_;
2059  int nsol_;
2060  int64_t tick_;
2061  int64_t objective_min_;
2062  int64_t objective_max_;
2063  int min_right_depth_;
2064  int max_depth_;
2065  int sliding_min_depth_;
2066  int sliding_max_depth_;
2067 };
2068 
2073 class ModelCache {
2074  public:
2076  VOID_FALSE_CONSTRAINT = 0,
2079  };
2080 
2082  VAR_CONSTANT_EQUALITY = 0,
2087  };
2088 
2090  VAR_CONSTANT_CONSTANT_BETWEEN = 0,
2092  };
2093 
2095  EXPR_EXPR_EQUALITY = 0,
2102  };
2103 
2105  EXPR_OPPOSITE = 0,
2109  };
2110 
2112  EXPR_EXPR_DIFFERENCE = 0,
2123  };
2124 
2126  EXPR_EXPR_CONSTANT_CONDITIONAL = 0,
2128  };
2129 
2131  EXPR_CONSTANT_DIFFERENCE = 0,
2142  };
2144  VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS = 0,
2146  };
2147 
2149  VAR_CONSTANT_ARRAY_ELEMENT = 0,
2151  };
2152 
2154  VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD = 0,
2156  };
2157 
2159  VAR_ARRAY_MAX = 0,
2163  };
2164 
2166  VAR_ARRAY_CONSTANT_INDEX = 0,
2168  };
2169 
2170  explicit ModelCache(Solver* const solver);
2171  virtual ~ModelCache();
2172 
2173  virtual void Clear() = 0;
2174 
2176 
2178 
2179  virtual void InsertVoidConstraint(Constraint* const ct,
2180  VoidConstraintType type) = 0;
2181 
2184  IntVar* const var, int64_t value,
2185  VarConstantConstraintType type) const = 0;
2186 
2188  IntVar* const var, int64_t value,
2189  VarConstantConstraintType type) = 0;
2190 
2192 
2194  IntVar* const var, int64_t value1, int64_t value2,
2195  VarConstantConstantConstraintType type) const = 0;
2196 
2198  Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2,
2200 
2202 
2204  IntExpr* const expr1, IntExpr* const expr2,
2205  ExprExprConstraintType type) const = 0;
2206 
2208  IntExpr* const expr1,
2209  IntExpr* const expr2,
2210  ExprExprConstraintType type) = 0;
2211 
2213 
2214  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2215  ExprExpressionType type) const = 0;
2216 
2217  virtual void InsertExprExpression(IntExpr* const expression,
2218  IntExpr* const expr,
2219  ExprExpressionType type) = 0;
2220 
2222 
2224  IntExpr* const expr, int64_t value,
2225  ExprConstantExpressionType type) const = 0;
2226 
2228  IntExpr* const expression, IntExpr* const var, int64_t value,
2229  ExprConstantExpressionType type) = 0;
2230 
2232 
2234  IntExpr* const var1, IntExpr* const var2,
2235  ExprExprExpressionType type) const = 0;
2236 
2237  virtual void InsertExprExprExpression(IntExpr* const expression,
2238  IntExpr* const var1,
2239  IntExpr* const var2,
2240  ExprExprExpressionType type) = 0;
2241 
2243 
2245  IntExpr* const var1, IntExpr* const var2, int64_t constant,
2246  ExprExprConstantExpressionType type) const = 0;
2247 
2249  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2250  int64_t constant, ExprExprConstantExpressionType type) = 0;
2251 
2253 
2255  IntVar* const var, int64_t value1, int64_t value2,
2256  VarConstantConstantExpressionType type) const = 0;
2257 
2259  IntExpr* const expression, IntVar* const var, int64_t value1,
2260  int64_t value2, VarConstantConstantExpressionType type) = 0;
2261 
2263 
2265  IntVar* const var, const std::vector<int64_t>& values,
2266  VarConstantArrayExpressionType type) const = 0;
2267 
2269  IntExpr* const expression, IntVar* const var,
2270  const std::vector<int64_t>& values,
2272 
2274 
2276  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2277 
2278  virtual void InsertVarArrayExpression(IntExpr* const expression,
2279  const std::vector<IntVar*>& vars,
2280  VarArrayExpressionType type) = 0;
2281 
2283 
2285  const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
2286  VarArrayConstantArrayExpressionType type) const = 0;
2287 
2289  IntExpr* const expression, const std::vector<IntVar*>& var,
2290  const std::vector<int64_t>& values,
2292 
2294 
2296  const std::vector<IntVar*>& vars, int64_t value,
2297  VarArrayConstantExpressionType type) const = 0;
2298 
2300  IntExpr* const expression, const std::vector<IntVar*>& var, int64_t value,
2302 
2303  Solver* solver() const;
2304 
2305  private:
2306  Solver* const solver_;
2307 };
2308 
2310 #if !defined(SWIG)
2312  public:
2314  const std::string& TypeName() const;
2315  void SetTypeName(const std::string& type_name);
2316 
2318  void SetIntegerArgument(const std::string& arg_name, int64_t value);
2319  void SetIntegerArrayArgument(const std::string& arg_name,
2320  const std::vector<int64_t>& values);
2321  void SetIntegerMatrixArgument(const std::string& arg_name,
2322  const IntTupleSet& values);
2323  void SetIntegerExpressionArgument(const std::string& arg_name,
2324  IntExpr* const expr);
2325  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2326  const std::vector<IntVar*>& vars);
2327  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2328  void SetIntervalArrayArgument(const std::string& arg_name,
2329  const std::vector<IntervalVar*>& vars);
2330  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2331  void SetSequenceArrayArgument(const std::string& arg_name,
2332  const std::vector<SequenceVar*>& vars);
2333 
2335  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2336  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2337 
2339  int64_t FindIntegerArgumentWithDefault(const std::string& arg_name,
2340  int64_t def) const;
2341  int64_t FindIntegerArgumentOrDie(const std::string& arg_name) const;
2342  const std::vector<int64_t>& FindIntegerArrayArgumentOrDie(
2343  const std::string& arg_name) const;
2344  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2345  const std::string& arg_name) const;
2346 
2347  IntExpr* FindIntegerExpressionArgumentOrDie(
2348  const std::string& arg_name) const;
2349  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2350  const std::string& arg_name) const;
2351 
2352  private:
2353  std::string type_name_;
2354  absl::flat_hash_map<std::string, int64_t> integer_argument_;
2355  absl::flat_hash_map<std::string, std::vector<int64_t>>
2356  integer_array_argument_;
2357  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2358  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2359  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2360  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2361  absl::flat_hash_map<std::string, std::vector<IntVar*>>
2362  integer_variable_array_argument_;
2363  absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2364  interval_array_argument_;
2365  absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2366  sequence_array_argument_;
2367 };
2368 
2370 class ModelParser : public ModelVisitor {
2371  public:
2372  ModelParser();
2373 
2374  ~ModelParser() override;
2375 
2377  void BeginVisitModel(const std::string& solver_name) override;
2378  void EndVisitModel(const std::string& solver_name) override;
2379  void BeginVisitConstraint(const std::string& type_name,
2380  const Constraint* const constraint) override;
2381  void EndVisitConstraint(const std::string& type_name,
2382  const Constraint* const constraint) override;
2383  void BeginVisitIntegerExpression(const std::string& type_name,
2384  const IntExpr* const expr) override;
2385  void EndVisitIntegerExpression(const std::string& type_name,
2386  const IntExpr* const expr) override;
2387  void VisitIntegerVariable(const IntVar* const variable,
2388  IntExpr* const delegate) override;
2389  void VisitIntegerVariable(const IntVar* const variable,
2390  const std::string& operation, int64_t value,
2391  IntVar* const delegate) override;
2392  void VisitIntervalVariable(const IntervalVar* const variable,
2393  const std::string& operation, int64_t value,
2394  IntervalVar* const delegate) override;
2395  void VisitSequenceVariable(const SequenceVar* const variable) override;
2397  void VisitIntegerArgument(const std::string& arg_name,
2398  int64_t value) override;
2399  void VisitIntegerArrayArgument(const std::string& arg_name,
2400  const std::vector<int64_t>& values) override;
2401  void VisitIntegerMatrixArgument(const std::string& arg_name,
2402  const IntTupleSet& values) override;
2404  void VisitIntegerExpressionArgument(const std::string& arg_name,
2405  IntExpr* const argument) override;
2406  void VisitIntegerVariableArrayArgument(
2407  const std::string& arg_name,
2408  const std::vector<IntVar*>& arguments) override;
2410  void VisitIntervalArgument(const std::string& arg_name,
2411  IntervalVar* const argument) override;
2412  void VisitIntervalArrayArgument(
2413  const std::string& arg_name,
2414  const std::vector<IntervalVar*>& arguments) override;
2416  void VisitSequenceArgument(const std::string& arg_name,
2417  SequenceVar* const argument) override;
2418  void VisitSequenceArrayArgument(
2419  const std::string& arg_name,
2420  const std::vector<SequenceVar*>& arguments) override;
2421 
2422  protected:
2423  void PushArgumentHolder();
2424  void PopArgumentHolder();
2425  ArgumentHolder* Top() const;
2426 
2427  private:
2428  std::vector<ArgumentHolder*> holders_;
2429 };
2430 
2431 template <class T>
2432 class ArrayWithOffset : public BaseObject {
2433  public:
2434  ArrayWithOffset(int64_t index_min, int64_t index_max)
2435  : index_min_(index_min),
2436  index_max_(index_max),
2437  values_(new T[index_max - index_min + 1]) {
2438  DCHECK_LE(index_min, index_max);
2439  }
2440 
2441  ~ArrayWithOffset() override {}
2442 
2443  virtual T Evaluate(int64_t index) const {
2444  DCHECK_GE(index, index_min_);
2445  DCHECK_LE(index, index_max_);
2446  return values_[index - index_min_];
2447  }
2448 
2449  void SetValue(int64_t index, T value) {
2450  DCHECK_GE(index, index_min_);
2451  DCHECK_LE(index, index_max_);
2452  values_[index - index_min_] = value;
2453  }
2454 
2455  std::string DebugString() const override { return "ArrayWithOffset"; }
2456 
2457  private:
2458  const int64_t index_min_;
2459  const int64_t index_max_;
2460  std::unique_ptr<T[]> values_;
2461 };
2462 #endif // SWIG
2463 
2468 template <class T, class C>
2470  public:
2471  explicit RevGrowingArray(int64_t block_size)
2472  : block_size_(block_size), block_offset_(0) {
2473  CHECK_GT(block_size, 0);
2474  }
2475 
2477  for (int i = 0; i < elements_.size(); ++i) {
2478  delete[] elements_[i];
2479  }
2480  }
2481 
2482  T At(int64_t index) const {
2483  const int64_t block_index = ComputeBlockIndex(index);
2484  const int64_t relative_index = block_index - block_offset_;
2485  if (relative_index < 0 || relative_index >= elements_.size()) {
2486  return T();
2487  }
2488  const T* block = elements_[relative_index];
2489  return block != nullptr ? block[index - block_index * block_size_] : T();
2490  }
2491 
2492  void RevInsert(Solver* const solver, int64_t index, T value) {
2493  const int64_t block_index = ComputeBlockIndex(index);
2494  T* const block = GetOrCreateBlock(block_index);
2495  const int64_t residual = index - block_index * block_size_;
2496  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2497  reinterpret_cast<C>(value));
2498  }
2499 
2500  private:
2501  T* NewBlock() const {
2502  T* const result = new T[block_size_];
2503  for (int i = 0; i < block_size_; ++i) {
2504  result[i] = T();
2505  }
2506  return result;
2507  }
2508 
2509  T* GetOrCreateBlock(int block_index) {
2510  if (elements_.size() == 0) {
2511  block_offset_ = block_index;
2512  GrowUp(block_index);
2513  } else if (block_index < block_offset_) {
2514  GrowDown(block_index);
2515  } else if (block_index - block_offset_ >= elements_.size()) {
2516  GrowUp(block_index);
2517  }
2518  T* block = elements_[block_index - block_offset_];
2519  if (block == nullptr) {
2520  block = NewBlock();
2521  elements_[block_index - block_offset_] = block;
2522  }
2523  return block;
2524  }
2525 
2526  int64_t ComputeBlockIndex(int64_t value) const {
2527  return value >= 0 ? value / block_size_
2528  : (value - block_size_ + 1) / block_size_;
2529  }
2530 
2531  void GrowUp(int64_t block_index) {
2532  elements_.resize(block_index - block_offset_ + 1);
2533  }
2534 
2535  void GrowDown(int64_t block_index) {
2536  const int64_t delta = block_offset_ - block_index;
2537  block_offset_ = block_index;
2538  DCHECK_GT(delta, 0);
2539  elements_.insert(elements_.begin(), delta, nullptr);
2540  }
2541 
2542  const int64_t block_size_;
2543  std::vector<T*> elements_;
2544  int block_offset_;
2545 };
2546 
2551 template <class T>
2552 class RevIntSet {
2553  public:
2554  static constexpr int kNoInserted = -1;
2555 
2557  explicit RevIntSet(int capacity)
2558  : elements_(new T[capacity]),
2559  num_elements_(0),
2560  capacity_(capacity),
2561  position_(new int[capacity]),
2562  delete_position_(true) {
2563  for (int i = 0; i < capacity; ++i) {
2564  position_[i] = kNoInserted;
2565  }
2566  }
2567 
2569  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2570  : elements_(new T[capacity]),
2571  num_elements_(0),
2572  capacity_(capacity),
2573  position_(shared_positions),
2574  delete_position_(false) {
2575  for (int i = 0; i < shared_positions_size; ++i) {
2576  position_[i] = kNoInserted;
2577  }
2578  }
2579 
2581  if (delete_position_) {
2582  delete[] position_;
2583  }
2584  }
2585 
2586  int Size() const { return num_elements_.Value(); }
2587 
2588  int Capacity() const { return capacity_; }
2589 
2590  T Element(int i) const {
2591  DCHECK_GE(i, 0);
2592  DCHECK_LT(i, num_elements_.Value());
2593  return elements_[i];
2594  }
2595 
2596  T RemovedElement(int i) const {
2597  DCHECK_GE(i, 0);
2598  DCHECK_LT(i + num_elements_.Value(), capacity_);
2599  return elements_[i + num_elements_.Value()];
2600  }
2601 
2602  void Insert(Solver* const solver, const T& elt) {
2603  const int position = num_elements_.Value();
2604  DCHECK_LT(position, capacity_);
2605  DCHECK(NotAlreadyInserted(elt));
2606  elements_[position] = elt;
2607  position_[elt] = position;
2608  num_elements_.Incr(solver);
2609  }
2610 
2611  void Remove(Solver* const solver, const T& value_index) {
2612  num_elements_.Decr(solver);
2613  SwapTo(value_index, num_elements_.Value());
2614  }
2615 
2616  void Restore(Solver* const solver, const T& value_index) {
2617  SwapTo(value_index, num_elements_.Value());
2618  num_elements_.Incr(solver);
2619  }
2620 
2621  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2622 
2624  typedef const T* const_iterator;
2625  const_iterator begin() const { return elements_.get(); }
2626  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2627 
2628  private:
2630  bool NotAlreadyInserted(const T& elt) {
2631  for (int i = 0; i < num_elements_.Value(); ++i) {
2632  if (elt == elements_[i]) {
2633  return false;
2634  }
2635  }
2636  return true;
2637  }
2638 
2639  void SwapTo(T value_index, int next_position) {
2640  const int current_position = position_[value_index];
2641  if (current_position != next_position) {
2642  const T next_value_index = elements_[next_position];
2643  elements_[current_position] = next_value_index;
2644  elements_[next_position] = value_index;
2645  position_[value_index] = next_position;
2646  position_[next_value_index] = current_position;
2647  }
2648  }
2649 
2651  std::unique_ptr<T[]> elements_;
2653  NumericalRev<int> num_elements_;
2655  const int capacity_;
2657  int* position_;
2659  const bool delete_position_;
2660 };
2661 
2663 
2665  public:
2666  explicit RevPartialSequence(const std::vector<int>& items)
2667  : elements_(items),
2668  first_ranked_(0),
2669  last_ranked_(items.size() - 1),
2670  size_(items.size()),
2671  position_(new int[size_]) {
2672  for (int i = 0; i < size_; ++i) {
2673  elements_[i] = items[i];
2674  position_[i] = i;
2675  }
2676  }
2677 
2678  explicit RevPartialSequence(int size)
2679  : elements_(size),
2680  first_ranked_(0),
2681  last_ranked_(size - 1),
2682  size_(size),
2683  position_(new int[size_]) {
2684  for (int i = 0; i < size_; ++i) {
2685  elements_[i] = i;
2686  position_[i] = i;
2687  }
2688  }
2689 
2691 
2692  int NumFirstRanked() const { return first_ranked_.Value(); }
2693 
2694  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2695 
2696  int Size() const { return size_; }
2697 
2698 #if !defined(SWIG)
2699  const int& operator[](int index) const {
2700  DCHECK_GE(index, 0);
2701  DCHECK_LT(index, size_);
2702  return elements_[index];
2703  }
2704 #endif
2705 
2706  void RankFirst(Solver* const solver, int elt) {
2707  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2708  SwapTo(elt, first_ranked_.Value());
2709  first_ranked_.Incr(solver);
2710  }
2711 
2712  void RankLast(Solver* const solver, int elt) {
2713  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2714  SwapTo(elt, last_ranked_.Value());
2715  last_ranked_.Decr(solver);
2716  }
2717 
2718  bool IsRanked(int elt) const {
2719  const int position = position_[elt];
2720  return (position < first_ranked_.Value() ||
2721  position > last_ranked_.Value());
2722  }
2723 
2724  std::string DebugString() const {
2725  std::string result = "[";
2726  for (int i = 0; i < first_ranked_.Value(); ++i) {
2727  absl::StrAppend(&result, elements_[i]);
2728  if (i != first_ranked_.Value() - 1) {
2729  result.append("-");
2730  }
2731  }
2732  result.append("|");
2733  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2734  absl::StrAppend(&result, elements_[i]);
2735  if (i != last_ranked_.Value()) {
2736  result.append("-");
2737  }
2738  }
2739  result.append("|");
2740  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2741  absl::StrAppend(&result, elements_[i]);
2742  if (i != size_ - 1) {
2743  result.append("-");
2744  }
2745  }
2746  result.append("]");
2747  return result;
2748  }
2749 
2750  private:
2751  void SwapTo(int elt, int next_position) {
2752  const int current_position = position_[elt];
2753  if (current_position != next_position) {
2754  const int next_elt = elements_[next_position];
2755  elements_[current_position] = next_elt;
2756  elements_[next_position] = elt;
2757  position_[elt] = next_position;
2758  position_[next_elt] = current_position;
2759  }
2760  }
2761 
2763  std::vector<int> elements_;
2765  NumericalRev<int> first_ranked_;
2767  NumericalRev<int> last_ranked_;
2769  const int size_;
2771  std::unique_ptr<int[]> position_;
2772 };
2773 
2779  public:
2781  explicit UnsortedNullableRevBitset(int bit_size);
2782 
2784 
2787  void Init(Solver* const solver, const std::vector<uint64_t>& mask);
2788 
2791  bool RevSubtract(Solver* const solver, const std::vector<uint64_t>& mask);
2792 
2795  bool RevAnd(Solver* const solver, const std::vector<uint64_t>& mask);
2796 
2799  int ActiveWordSize() const { return active_words_.Size(); }
2800 
2802  bool Empty() const { return active_words_.Size() == 0; }
2803 
2811  bool Intersects(const std::vector<uint64_t>& mask, int* support_index);
2812 
2814  int64_t bit_size() const { return bit_size_; }
2816  int64_t word_size() const { return word_size_; }
2818  const RevIntSet<int>& active_words() const { return active_words_; }
2819 
2820  private:
2821  void CleanUpActives(Solver* const solver);
2822 
2823  const int64_t bit_size_;
2824  const int64_t word_size_;
2825  RevArray<uint64_t> bits_;
2826  RevIntSet<int> active_words_;
2827  std::vector<int> to_remove_;
2828 };
2829 
2830 template <class T>
2831 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2832  for (int i = 0; i < values.size(); ++i) {
2833  if (values[i] != value) {
2834  return false;
2835  }
2836  }
2837  return true;
2838 }
2839 
2840 template <class T>
2841 bool IsArrayBoolean(const std::vector<T>& values) {
2842  for (int i = 0; i < values.size(); ++i) {
2843  if (values[i] != 0 && values[i] != 1) {
2844  return false;
2845  }
2846  }
2847  return true;
2848 }
2849 
2850 template <class T>
2851 bool AreAllOnes(const std::vector<T>& values) {
2852  return IsArrayConstant(values, T(1));
2853 }
2854 
2855 template <class T>
2856 bool AreAllNull(const std::vector<T>& values) {
2857  return IsArrayConstant(values, T(0));
2858 }
2859 
2860 template <class T>
2861 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2862  for (const T& current_value : values) {
2863  if (current_value < value) {
2864  return false;
2865  }
2866  }
2867  return true;
2868 }
2869 
2870 template <class T>
2871 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2872  for (const T& current_value : values) {
2873  if (current_value > value) {
2874  return false;
2875  }
2876  }
2877  return true;
2878 }
2879 
2880 template <class T>
2881 bool AreAllPositive(const std::vector<T>& values) {
2882  return AreAllGreaterOrEqual(values, T(0));
2883 }
2884 
2885 template <class T>
2886 bool AreAllNegative(const std::vector<T>& values) {
2887  return AreAllLessOrEqual(values, T(0));
2888 }
2889 
2890 template <class T>
2891 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2892  return AreAllGreaterOrEqual(values, T(1));
2893 }
2894 
2895 template <class T>
2896 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2897  return AreAllLessOrEqual(values, T(-1));
2898 }
2899 
2900 template <class T>
2901 bool IsIncreasingContiguous(const std::vector<T>& values) {
2902  for (int i = 0; i < values.size() - 1; ++i) {
2903  if (values[i + 1] != values[i] + 1) {
2904  return false;
2905  }
2906  }
2907  return true;
2908 }
2909 
2910 template <class T>
2911 bool IsIncreasing(const std::vector<T>& values) {
2912  for (int i = 0; i < values.size() - 1; ++i) {
2913  if (values[i + 1] < values[i]) {
2914  return false;
2915  }
2916  }
2917  return true;
2918 }
2919 
2920 template <class T>
2921 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2922  T range_max) {
2923  for (int i = 0; i < vars.size(); ++i) {
2924  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2925  return false;
2926  }
2927  }
2928  return true;
2929 }
2930 
2931 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2932  for (int i = 0; i < vars.size(); ++i) {
2933  if (!vars[i]->Bound()) {
2934  return false;
2935  }
2936  }
2937  return true;
2938 }
2939 
2940 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2941  return IsArrayInRange(vars, 0, 1);
2942 }
2943 
2946 template <class T>
2947 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2948  const std::vector<T>& values) {
2949  for (int i = 0; i < vars.size(); ++i) {
2950  if (values[i] != 0 && !vars[i]->Bound()) {
2951  return false;
2952  }
2953  }
2954  return true;
2955 }
2956 
2958 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64_t value) {
2959  for (int i = 0; i < vars.size(); ++i) {
2960  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2961  return false;
2962  }
2963  }
2964  return true;
2965 }
2966 
2967 inline int64_t MaxVarArray(const std::vector<IntVar*>& vars) {
2968  DCHECK(!vars.empty());
2969  int64_t result = kint64min;
2970  for (int i = 0; i < vars.size(); ++i) {
2972  result = std::max<int64_t>(result, vars[i]->Max());
2973  }
2974  return result;
2975 }
2976 
2977 inline int64_t MinVarArray(const std::vector<IntVar*>& vars) {
2978  DCHECK(!vars.empty());
2979  int64_t result = kint64max;
2980  for (int i = 0; i < vars.size(); ++i) {
2982  result = std::min<int64_t>(result, vars[i]->Min());
2983  }
2984  return result;
2985 }
2986 
2987 inline void FillValues(const std::vector<IntVar*>& vars,
2988  std::vector<int64_t>* const values) {
2989  values->clear();
2990  values->resize(vars.size());
2991  for (int i = 0; i < vars.size(); ++i) {
2992  (*values)[i] = vars[i]->Value();
2993  }
2994 }
2995 
2996 inline int64_t PosIntDivUp(int64_t e, int64_t v) {
2997  DCHECK_GT(v, 0);
2998  return (e < 0 || e % v == 0) ? e / v : e / v + 1;
2999 }
3000 
3001 inline int64_t PosIntDivDown(int64_t e, int64_t v) {
3002  DCHECK_GT(v, 0);
3003  return (e >= 0 || e % v == 0) ? e / v : e / v - 1;
3004 }
3005 
3006 std::vector<int64_t> ToInt64Vector(const std::vector<int>& input);
3007 
3008 #if !defined(SWIG)
3009 // A PathState represents a set of paths and changed made on it.
3010 //
3011 // More accurately, let us define P_{num_nodes, starts, ends}-graphs the set of
3012 // directed graphs with nodes [0, num_nodes) whose connected components are
3013 // paths from starts[i] to ends[i] (for the same i) and loops.
3014 // Let us fix num_nodes, starts and ends so we call these P-graphs.
3015 //
3016 // Let us define some notions on graphs with the same set of nodes:
3017 // tails(D) is the set of nodes that are the tail of some arc of D.
3018 // P0 inter P1 is the graph of all arcs both in P0 and P1.
3019 // P0 union P1 is the graph of all arcs either in P0 or P1.
3020 // P1 - P0 is the graph with arcs in P1 and not in P0.
3021 // P0 |> D is the graph with arcs of P0 whose tail is not in tails(D).
3022 // P0 + D is (P0 |> D) union D.
3023 //
3024 // Now suppose P0 and P1 are P-graphs.
3025 // P0 + (P1 - P0) is exactly P1.
3026 // Moreover, note that P0 |> D is not a union of paths from some starts[i] to
3027 // ends[i] and loops like P0, because the operation removes arcs from P0.
3028 // P0 |> D is a union of generic paths, loops, and isolated nodes.
3029 // Let us call the generic paths and isolated nodes "chains".
3030 // Then the paths of P0 + D are chains linked by arcs of D.
3031 // Those chains are particularly interesting when examining a P-graph change.
3032 //
3033 // A PathState represents a P-graph for a fixed {num_nodes, starts, ends}.
3034 // The value of a PathState can be changed incrementally from P0 to P1
3035 // by passing the arcs of P1 - P0 to ChangeNext() and marking the end of the
3036 // change with a call to CutChains().
3037 // If P0 + D is not a P-graph, the behaviour is undefined.
3038 // TODO(user): check whether we want to have a DCHECK that P0 + D
3039 // is a P-graph or if CutChains() should return false.
3040 //
3041 // After CutChains(), tails(D) can be traversed using an iterator,
3042 // and the chains of P0 |> D can be browsed by chain-based iterators.
3043 // An iterator allows to browse the set of paths that have changed.
3044 // Then Commit() or Revert() can be called: Commit() changes the PathState to
3045 // represent P1 = P0 + D, all further changes are made from P1; Revert() changes
3046 // the PathState to forget D completely and return the state to P0.
3047 //
3048 // After a Commit(), Revert() or at initial state, the same iterators are
3049 // available and represent the change by an empty D: the set of changed paths
3050 // and the set of changed nodes is empty. Still, the chain-based iterator allows
3051 // to browse paths: each path has exactly one chain.
3052 class PathState {
3053  public:
3054  // A Chain allows to iterate on all nodes of a chain, and access some data:
3055  // first node, last node, number of nodes in the chain.
3056  // Chain is a range, its iterator ChainNodeIterator, its value type int.
3057  // Chains are returned by PathChainIterator's operator*().
3058  class Chain;
3059  // A ChainRange allows to iterate on all chains of a path.
3060  // ChainRange is a range, its iterator Chain*, its value type Chain.
3061  class ChainRange;
3062  // A NodeRange allows to iterate on all nodes of a path.
3063  // NodeRange is a range, its iterator PathNodeIterator, its value type int.
3064  class NodeRange;
3065 
3066  // Path constructor: path_start and path_end must be disjoint,
3067  // their values in [0, num_nodes).
3068  PathState(int num_nodes, std::vector<int> path_start,
3069  std::vector<int> path_end);
3070 
3071  // Instance-constant accessors.
3072 
3073  // Returns the number of nodes in the underlying graph.
3074  int NumNodes() const { return num_nodes_; }
3075  // Returns the number of paths (empty paths included).
3076  int NumPaths() const { return num_paths_; }
3077  // Returns the start of a path.
3078  int Start(int path) const { return path_start_end_[path].start; }
3079  // Returns the end of a path.
3080  int End(int path) const { return path_start_end_[path].end; }
3081 
3082  // State-dependent accessors.
3083 
3084  // Returns the committed path of a given node, -1 if it is a loop.
3085  int Path(int node) const {
3086  return committed_nodes_[committed_index_[node]].path;
3087  }
3088  // Returns the set of arcs that have been added,
3089  // i.e. that were changed and were not in the committed state.
3090  const std::vector<std::pair<int, int>>& ChangedArcs() const {
3091  return changed_arcs_;
3092  }
3093  // Returns the set of paths that actually changed,
3094  // i.e. that have an arc in ChangedArcs().
3095  const std::vector<int>& ChangedPaths() const { return changed_paths_; }
3096  // Returns the current range of chains of path.
3097  ChainRange Chains(int path) const;
3098  // Returns the current range of nodes of path.
3099  NodeRange Nodes(int path) const;
3100 
3101  // State modifiers.
3102 
3103  // Adds arc (node, new_next) to the changed state, more formally,
3104  // changes the state from (P0, D) to (P0, D + (node, new_next)).
3105  void ChangeNext(int node, int new_next) {
3106  changed_arcs_.emplace_back(node, new_next);
3107  }
3108  // Marks the end of ChangeNext() sequence, more formally,
3109  // changes the state from (P0, D) to (P0 |> D, D).
3110  void CutChains();
3111  // Makes the current temporary state permanent, more formally,
3112  // changes the state from (P0 |> D, D) to (P0 + D, \emptyset),
3113  void Commit();
3114  // Erase incremental changes made by ChangeNext() and CutChains(),
3115  // more formally, changes the state from (P0 |> D, D) to (P0, \emptyset).
3116  void Revert();
3117 
3118  // LNS Operators may not fix variables,
3119  // in which case we mark the candidate invalid.
3120  void SetInvalid() { is_invalid_ = true; }
3121  bool IsInvalid() const { return is_invalid_; }
3122 
3123  private:
3124  // Most structs below are named pairs of ints, for typing purposes.
3125 
3126  // Start and end are stored together to optimize (likely) simultaneous access.
3127  struct PathStartEnd {
3128  PathStartEnd(int start, int end) : start(start), end(end) {}
3129  int start;
3130  int end;
3131  };
3132  // Paths are ranges of chains, which are ranges of committed nodes, see below.
3133  struct PathBounds {
3134  int begin_index;
3135  int end_index;
3136  };
3137  struct ChainBounds {
3138  ChainBounds() = default;
3139  ChainBounds(int begin_index, int end_index)
3140  : begin_index(begin_index), end_index(end_index) {}
3141  int begin_index;
3142  int end_index;
3143  };
3144  struct CommittedNode {
3145  CommittedNode(int node, int path) : node(node), path(path) {}
3146  int node;
3147  // Path of node in the committed state, -1 for loop nodes.
3148  // TODO(user): check if path would be better stored
3149  // with committed_index_, or in its own vector, or just recomputed.
3150  int path;
3151  };
3152  // Used in temporary structures, see below.
3153  struct TailHeadIndices {
3154  int tail_index;
3155  int head_index;
3156  };
3157  struct IndexArc {
3158  int index;
3159  int arc;
3160  bool operator<(const IndexArc& other) const { return index < other.index; }
3161  };
3162 
3163  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3164  // Selection-based algorithm in O(n^2), to use for small change sets.
3165  void MakeChainsFromChangedPathsAndArcsWithSelectionAlgorithm();
3166  // From changed_paths_ and changed_arcs_, fill chains_ and paths_.
3167  // Generic algorithm in O(std::sort(n)+n), to use for larger change sets.
3168  void MakeChainsFromChangedPathsAndArcsWithGenericAlgorithm();
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  // - committed_nodes_ contains all nodes and old duplicates may appear,
3193  // the current version of a node is at the index given by
3194  // committed_index_[node]. A Commit() can add nodes at the end of
3195  // committed_nodes_ in a space/time tradeoff, but if committed_nodes_' size
3196  // is above num_nodes_threshold_, Commit() must reclaim useless duplicates'
3197  // space by rewriting the path/chain/nodes structure.
3198  // When changed (after CutChains()), new chains are computed,
3199  // and the structure is updated accordingly:
3200  // - path ranges that were changed have nonoverlapping values [begin, end)
3201  // where begin is >= num_paths_ + 1, i.e. new chains are stored after
3202  // committed state.
3203  // - additional chain ranges are stored after the committed chains
3204  // to represent the new chains resulting from the changes.
3205  // Those chains do not overlap with each other or with unchanged chains.
3206  // An empty sentinel chain is added at the end of additional chains.
3207  // - committed_nodes_ are not modified, and still represent the committed
3208  // paths.
3209  // committed_index_ is not modified either.
3210  std::vector<CommittedNode> committed_nodes_;
3211  std::vector<int> committed_index_;
3212  const int num_nodes_threshold_;
3213  std::vector<ChainBounds> chains_;
3214  std::vector<PathBounds> paths_;
3215 
3216  // Incremental information: indices of nodes whose successor have changed,
3217  // path that have changed nodes.
3218  std::vector<std::pair<int, int>> changed_arcs_;
3219  std::vector<int> changed_paths_;
3220  std::vector<bool> path_has_changed_;
3221 
3222  // Temporary structures, since they will be reused heavily,
3223  // those are members in order to be allocated once and for all.
3224  std::vector<TailHeadIndices> tail_head_indices_;
3225  std::vector<IndexArc> arcs_by_tail_index_;
3226  std::vector<IndexArc> arcs_by_head_index_;
3227  std::vector<int> next_arc_;
3228 
3229  // See IsInvalid() and SetInvalid().
3230  bool is_invalid_ = false;
3231 };
3232 
3233 // A Chain is a range of committed nodes.
3235  public:
3236  class Iterator {
3237  public:
3239  ++current_node_;
3240  return *this;
3241  }
3242  int operator*() const { return current_node_->node; }
3243  bool operator!=(Iterator other) const {
3244  return current_node_ != other.current_node_;
3245  }
3246 
3247  private:
3248  // Only a Chain can construct its iterator.
3249  friend class PathState::Chain;
3250  explicit Iterator(const CommittedNode* node) : current_node_(node) {}
3251  const CommittedNode* current_node_;
3252  };
3253 
3254  // Chains hold CommittedNode* values, a Chain may be invalidated
3255  // if the underlying vector is modified.
3256  Chain(const CommittedNode* begin_node, const CommittedNode* end_node)
3257  : begin_(begin_node), end_(end_node) {}
3258 
3259  int NumNodes() const { return end_ - begin_; }
3260  int First() const { return begin_->node; }
3261  int Last() const { return (end_ - 1)->node; }
3262  Iterator begin() const { return Iterator(begin_); }
3263  Iterator end() const { return Iterator(end_); }
3264 
3265  private:
3266  const CommittedNode* const begin_;
3267  const CommittedNode* const end_;
3268 };
3269 
3270 // A ChainRange is a range of Chains, committed or not.
3272  public:
3273  class Iterator {
3274  public:
3276  ++current_chain_;
3277  return *this;
3278  }
3279  Chain operator*() const {
3280  return {first_node_ + current_chain_->begin_index,
3281  first_node_ + current_chain_->end_index};
3282  }
3283  bool operator!=(Iterator other) const {
3284  return current_chain_ != other.current_chain_;
3285  }
3286 
3287  private:
3288  // Only a ChainRange can construct its Iterator.
3289  friend class ChainRange;
3290  Iterator(const ChainBounds* chain, const CommittedNode* const first_node)
3291  : current_chain_(chain), first_node_(first_node) {}
3292  const ChainBounds* current_chain_;
3293  const CommittedNode* const first_node_;
3294  };
3295 
3296  // ChainRanges hold ChainBounds* and CommittedNode*,
3297  // a ChainRange may be invalidated if on of the underlying vector is modified.
3298  ChainRange(const ChainBounds* const begin_chain,
3299  const ChainBounds* const end_chain,
3300  const CommittedNode* const first_node)
3301  : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3302 
3303  Iterator begin() const { return {begin_, first_node_}; }
3304  Iterator end() const { return {end_, first_node_}; }
3305 
3306  private:
3307  const ChainBounds* const begin_;
3308  const ChainBounds* const end_;
3309  const CommittedNode* const first_node_;
3310 };
3311 
3312 // A NodeRange allows to iterate on all nodes of a path,
3313 // by a two-level iteration on ChainBounds* and CommittedNode* of a PathState.
3315  public:
3316  class Iterator {
3317  public:
3319  ++current_node_;
3320  if (current_node_ == end_node_) {
3321  ++current_chain_;
3322  // Note: dereferencing bounds is valid because there is a sentinel
3323  // value at the end of PathState::chains_ to that intent.
3324  const ChainBounds bounds = *current_chain_;
3325  current_node_ = first_node_ + bounds.begin_index;
3326  end_node_ = first_node_ + bounds.end_index;
3327  }
3328  return *this;
3329  }
3330  int operator*() const { return current_node_->node; }
3331  bool operator!=(Iterator other) const {
3332  return current_chain_ != other.current_chain_;
3333  }
3334 
3335  private:
3336  // Only a NodeRange can construct its Iterator.
3337  friend class NodeRange;
3338  Iterator(const ChainBounds* current_chain,
3339  const CommittedNode* const first_node)
3340  : current_node_(first_node + current_chain->begin_index),
3341  end_node_(first_node + current_chain->end_index),
3342  current_chain_(current_chain),
3343  first_node_(first_node) {}
3344  const CommittedNode* current_node_;
3345  const CommittedNode* end_node_;
3346  const ChainBounds* current_chain_;
3347  const CommittedNode* const first_node_;
3348  };
3349 
3350  // NodeRanges hold ChainBounds* and CommittedNode*,
3351  // a NodeRange may be invalidated if on of the underlying vector is modified.
3352  NodeRange(const ChainBounds* begin_chain, const ChainBounds* end_chain,
3353  const CommittedNode* first_node)
3354  : begin_chain_(begin_chain),
3355  end_chain_(end_chain),
3356  first_node_(first_node) {}
3357  Iterator begin() const { return {begin_chain_, first_node_}; }
3358  // Note: there is a sentinel value at the end of PathState::chains_,
3359  // so dereferencing chain_range_.end()->begin_ is always valid.
3360  Iterator end() const { return {end_chain_, first_node_}; }
3361 
3362  private:
3363  const ChainBounds* begin_chain_;
3364  const ChainBounds* end_chain_;
3365  const CommittedNode* const first_node_;
3366 };
3367 
3368 // This checker enforces unary dimension requirements.
3369 // A unary dimension requires that there is some valuation of
3370 // node_capacity and demand such that for all paths,
3371 // if arc A -> B is on a path of path_class p,
3372 // then node_capacity[A] + demand[p][A] = node_capacity[B].
3373 // Moreover, all node_capacities of a path must be inside interval
3374 // path_capacity[path].
3375 // Note that Intervals have two meanings:
3376 // - for demand and node_capacity, those are values allowed for each associated
3377 // decision variable.
3378 // - for path_capacity, those are set of values that node_capacities of the path
3379 // must respect.
3380 // If the path capacity of a path is [kint64min, kint64max],
3381 // then the unary dimension requirements are not enforced on this path.
3383  public:
3384  struct Interval {
3385  int64_t min;
3386  int64_t max;
3387  };
3388 
3389  UnaryDimensionChecker(const PathState* path_state,
3390  std::vector<Interval> path_capacity,
3391  std::vector<int> path_class,
3392  std::vector<std::vector<Interval>> demand,
3393  std::vector<Interval> node_capacity);
3394 
3395  // Given the change made in PathState, checks that the unary dimension
3396  // constraint is still feasible.
3397  bool Check() const;
3398 
3399  // Commits to the changes made in PathState,
3400  // must be called before PathState::Commit().
3401  void Commit();
3402 
3403  private:
3404  // Range min/max query on partial_demand_sums_.
3405  // The first_node and last_node MUST form a subpath in the committed state.
3406  // Nodes first_node and last_node are passed by their index in precomputed
3407  // data, they must be committed in some path, and it has to be the same path.
3408  // See partial_demand_sums_.
3409  Interval GetMinMaxPartialDemandSum(int first_node_index,
3410  int last_node_index) const;
3411 
3412  // Queries whether all nodes in the committed subpath [first_node, last_node]
3413  // have fixed demands and trivial node_capacity [kint64min, kint64max].
3414  // first_node and last_node MUST form a subpath in the committed state.
3415  // Nodes are passed by their index in precomputed data.
3416  bool SubpathOnlyHasTrivialNodes(int first_node_index,
3417  int last_node_index) const;
3418 
3419  // Commits to the current solution and rebuilds structures from scratch.
3420  void FullCommit();
3421  // Commits to the current solution and only build structures for paths that
3422  // changed, using additional space to do so in a time-memory tradeoff.
3423  void IncrementalCommit();
3424  // Adds sums of given path to the bottom layer of the RMQ structure,
3425  // updates index_ and previous_nontrivial_index_.
3426  void AppendPathDemandsToSums(int path);
3427  // Updates the RMQ structure from its bottom layer,
3428  // with [begin_index, end_index) the range of the change,
3429  // which must be at the end of the bottom layer.
3430  // Supposes that requests overlapping the range will be inside the range,
3431  // to avoid updating all layers.
3432  void UpdateRMQStructure(int begin_index, int end_index);
3433 
3434  const PathState* const path_state_;
3435  const std::vector<Interval> path_capacity_;
3436  const std::vector<int> path_class_;
3437  const std::vector<std::vector<Interval>> demand_;
3438  const std::vector<Interval> node_capacity_;
3439 
3440  // Precomputed data.
3441  // Maps nodes to their pre-computed data, except for isolated nodes,
3442  // which do not have precomputed data.
3443  // Only valid for nodes that are in some path in the committed state.
3444  std::vector<int> index_;
3445  // Implementation of a <O(n log n), O(1)> range min/max query, n = #nodes.
3446  // partial_demand_sums_rmq_[0][index_[node]] contains the sum of demands
3447  // from the start of the node's path to the node.
3448  // If node is the start of path, the sum is demand_[path_class_[path]][node],
3449  // moreover partial_demand_sums_rmq_[0][index_[node]-1] is {0, 0}.
3450  // partial_demand_sums_rmq_[layer][index] contains an interval
3451  // [min_value, max_value] such that min_value is
3452  // min(partial_demand_sums_rmq_[0][index+i].min | i in [0, 2^layer)),
3453  // similarly max_value is the maximum of .max on the same range.
3454  std::vector<std::vector<Interval>> partial_demand_sums_rmq_;
3455  // The incremental branch of Commit() may waste space in the layers of the
3456  // RMQ structure. This is the upper limit of a layer's size.
3457  const int maximum_partial_demand_layer_size_;
3458  // previous_nontrivial_index_[index_[node]] has the index of the previous
3459  // node on its committed path that has nonfixed demand or nontrivial node
3460  // capacity. This allows for O(1) queries that all nodes on a subpath
3461  // are nonfixed and nontrivial.
3462  std::vector<int> previous_nontrivial_index_;
3463 };
3464 
3465 // Make a filter that takes ownership of a PathState and synchronizes it with
3466 // solver events. The solver represents a graph with array of variables 'nexts'.
3467 // Solver events are embodied by Assignment* deltas, that are translated to node
3468 // changes during Relax(), committed during Synchronize(), and reverted on
3469 // Revert().
3471  std::unique_ptr<PathState> path_state,
3472  const std::vector<IntVar*>& nexts);
3473 
3474 // Make a filter that translates solver events to the input checker's interface.
3475 // Since UnaryDimensionChecker has a PathState, the filter returned by this
3476 // must be synchronized to the corresponding PathStateFilter:
3477 // - Relax() must be called after the PathStateFilter's.
3478 // - Accept() must be called after.
3479 // - Synchronize() must be called before.
3480 // - Revert() must be called before.
3482  Solver* solver, std::unique_ptr<UnaryDimensionChecker> checker);
3483 
3484 #endif // !defined(SWIG)
3485 
3486 } // namespace operations_research
3487 
3488 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
const std::vector< IntVar * > vars_
Definition: alldiff_cst.cc:44
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define CHECK(condition)
Definition: base/logging.h:498
#define DCHECK_LE(val1, val2)
Definition: base/logging.h:895
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:705
#define CHECK_GE(val1, val2)
Definition: base/logging.h:709
#define CHECK_GT(val1, val2)
Definition: base/logging.h:710
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:897
#define CHECK_NE(val1, val2)
Definition: base/logging.h:706
#define DCHECK_GT(val1, val2)
Definition: base/logging.h:898
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:896
#define DCHECK(condition)
Definition: base/logging.h:892
#define CHECK_LE(val1, val2)
Definition: base/logging.h:707
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:893
int64_t MemoryUsage(int unused)
Definition: base/sysinfo.h:24
Argument Holder: useful when visiting a model.
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
const SequenceContainer & SequenceVarContainer() const
SequenceContainer * MutableSequenceVarContainer()
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.
void SetContentFromBitsetOfSameSize(const Bitset64< OtherIndexType > &other)
Definition: bitset.h:535
void Clear(IndexType i)
Definition: bitset.h:457
void Set(IndexType i)
Definition: bitset.h:495
void Resize(IndexType size)
Definition: bitset.h:433
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
Definition: bitset.h:511
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void WhenRange(Demon *d) override
Attach a demon that will watch the min or 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.
int64_t Value() const override
This method returns the value of the variable.
SimpleRevFIFO< Demon * > bound_demons_
std::string BaseName() const override
Returns a base name for automatic naming.
BooleanVar(Solver *const s, const std::string &name="")
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.
The class IntExpr is the base of all integer expressions in constraint programming.
virtual int64_t Max() const =0
The class IntVar is a subset of IntExpr.
The class Iterator has two direct subclasses.
virtual void OnSynchronize(const Assignment *delta)
bool FindIndex(IntVar *const var, int64_t *index) const
bool ValueFromAssignment(const Assignment &assignment, IntVar *var, int64_t index, int64_t *value)
IntVarLocalSearchHandler(const IntVarLocalSearchHandler &other)
IntVarLocalSearchHandler(IntVarLocalSearchOperator *op)
void OnRevertChanges(int64_t index, int64_t value)
void AddToAssignment(IntVar *var, int64_t value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
void SetOldInverseValue(int64_t index, int64_t value)
void SetInverseValue(int64_t index, int64_t value)
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
Interval variables are often used in scheduling.
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 ...
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
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
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
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
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
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.
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)
Builds an instance of PathOperator from next and path variables.
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()
virtual void SetNextBaseToIncrement(int64_t base_index)
Set the next base to increment on next iteration.
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
const std::vector< std::pair< int, int > > & ChangedArcs() const
void ChangeNext(int node, int new_next)
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
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
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.
Definition: utilities.cc:178
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.
Definition: utilities.cc:170
void ClearAll(Solver *const solver)
Cleans all bits.
Definition: utilities.cc:220
int64_t GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
Definition: utilities.cc:204
This class represents a reversible bitset.
void SetToOne(Solver *const solver, int64_t index)
Sets the 'index' bit.
Definition: utilities.cc:84
bool IsCardinalityOne() const
Does it contains only one bit set?
Definition: utilities.cc:129
void SetToZero(Solver *const solver, int64_t index)
Erases the 'index' bit.
Definition: utilities.cc:95
int64_t Cardinality() const
Returns the number of bits set to one.
Definition: utilities.cc:112
int64_t GetFirstBit(int start) const
Gets the index of the first bit set starting from start.
Definition: utilities.cc:147
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
Definition: utilities.cc:106
void ClearAll(Solver *const solver)
Cleans all bits.
Definition: utilities.cc:151
bool IsCardinalityZero() const
Is bitset null?
Definition: utilities.cc:120
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.
A search monitor is a simple set of callbacks to monitor all search events.
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
void SetBackwardSequence(const std::vector< int > &backward_sequence)
const std::vector< int > & ForwardSequence() const
void SetForwardSequence(const std::vector< int > &forward_sequence)
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
void OnRevertChanges(int64_t index, const std::vector< int > &value)
bool ValueFromAssignment(const Assignment &assignment, SequenceVar *var, int64_t index, std::vector< int > *value)
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
void SetBackwardSequence(int64_t index, const std::vector< int > &value)
void SetForwardSequence(int64_t index, const std::vector< int > &value)
const std::vector< int > & Sequence(int64_t index) const
Returns the value in the current assignment of the variable of given index.
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
const std::vector< int > & OldSequence(int64_t index) const
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.
Definition: utilities.cc:48
void SetToZero(Solver *const solver, int64_t pos)
Erases the 'pos' bit.
Definition: utilities.cc:43
bool IsCardinalityZero() const
Is bitset null?
int64_t GetFirstOne() const
Gets the index of the first bit set starting from 0.
Definition: utilities.cc:52
void SetToOne(Solver *const solver, int64_t pos)
Sets the 'pos' bit.
Definition: utilities.cc:38
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...
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
T * RevAlloc(T *object)
Registers the given object as being reversible.
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
Definition: bitset.h:814
void Set(IntegerType index)
Definition: bitset.h:804
void ClearAndResize(IntegerType size)
Definition: bitset.h:779
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
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 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.
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
Base operator class for operators manipulating variables.
virtual bool SkipUnchanged(int index) const
void SetValue(int64_t index, const Val &value)
const Val & Value(int64_t index) const
Returns the value in the current assignment of the variable of given index.
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
void MarkChange(int64_t index)
OnStart() should really be protected, but then SWIG doesn't see it.
const Val & OldValue(int64_t index) const
V * Var(int64_t index) const
Returns the variable of given index.
void AddVars(const std::vector< V * > &vars)
void Start(const Assignment *assignment) override
This method should not be overridden.
int64_t a
std::vector< int64_t > to_remove_
Block * next
SharedBoundsManager * bounds
const std::string name
const Constraint * ct
int64_t value
IntVar * var
Definition: expr_array.cc:1874
GurobiMPCallbackContext * context
static const int64_t kint64max
static const int64_t kint64min
const int64_t offset_
Definition: interval.cc:2108
RowIndex row
Definition: markowitz.cc:182
int64_t hash
Definition: matrix_utils.cc:61
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1492
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)
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.
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)
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)
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)
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
Definition: utilities.cc:828
LocalSearchFilter * MakeUnaryDimensionFilter(Solver *solver, std::unique_ptr< UnaryDimensionChecker > checker)
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
int64_t PosIntDivDown(int64_t e, int64_t v)
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
static const int kUnassigned
Definition: routing.cc:676
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
bool AreAllOnes(const std::vector< T > &values)
bool AreAllBound(const std::vector< IntVar * > &vars)
uint64_t Hash1(uint64_t value)
Hash functions.
void AcceptUncheckedNeighbor(Search *const search)
int64_t PosIntDivUp(int64_t e, int64_t v)
int index
Definition: pack.cc:509
static int input(yyscan_t yyscanner)
int64_t demand
Definition: resource.cc:125
int64_t delta
Definition: resource.cc:1692
int64_t capacity