C++ Reference

C++ Reference: Routing

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