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 
14 // Collection of objects used to extend the Constraint Solver library.
15 //
16 // This file contains a set of objects that simplifies writing extensions
17 // of the library.
18 //
19 // The main objects that define extensions are:
20 // - BaseIntExpr, the base class of all expressions that are not variables.
21 // - SimpleRevFIFO, a reversible FIFO list with templatized values.
22 // A reversible data structure is a data structure that reverts its
23 // modifications when the search is going up in the search tree, usually
24 // after a failure occurs.
25 // - RevImmutableMultiMap, a reversible immutable multimap.
26 // - MakeConstraintDemon<n> and MakeDelayedConstraintDemon<n> to wrap methods
27 // of a constraint as a demon.
28 // - RevSwitch, a reversible flip-once switch.
29 // - SmallRevBitSet, RevBitSet, and RevBitMatrix: reversible 1D or 2D
30 // bitsets.
31 // - LocalSearchOperator, IntVarLocalSearchOperator, ChangeValue and
32 // PathOperator, to create new local search operators.
33 // - LocalSearchFilter and IntVarLocalSearchFilter, to create new local
34 // search filters.
35 // - BaseLns, to write Large Neighborhood Search operators.
36 // - SymmetryBreaker, to describe model symmetries that will be broken during
37 // search using the 'Symmetry Breaking During Search' framework
38 // see Gent, I. P., Harvey, W., & Kelsey, T. (2002).
39 // Groups and Constraints: Symmetry Breaking During Search.
40 // Principles and Practice of Constraint Programming CP2002
41 // (Vol. 2470, pp. 415-430). Springer. Retrieved from
42 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.11.1442.
43 //
44 // Then, there are some internal classes that are used throughout the solver
45 // and exposed in this file:
46 // - SearchLog, the root class of all periodic outputs during search.
47 // - ModelCache, A caching layer to avoid creating twice the same object.
48 
49 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
51 
52 #include <algorithm>
53 #include <cmath>
54 #include <cstddef>
55 #include <functional>
56 #include <memory>
57 #include <string>
58 #include <vector>
59 
60 #include "absl/container/flat_hash_map.h"
61 #include "absl/strings/str_cat.h"
62 #include "absl/strings/str_format.h"
63 #include "absl/strings/str_join.h"
64 #include "ortools/base/commandlineflags.h"
65 #include "ortools/base/hash.h"
66 #include "ortools/base/integral_types.h"
67 #include "ortools/base/logging.h"
68 #include "ortools/base/map_util.h"
69 #include "ortools/base/sysinfo.h"
70 #include "ortools/base/timer.h"
72 #include "ortools/util/bitset.h"
73 #include "ortools/util/tuple_set.h"
74 #include "ortools/util/vector_map.h"
75 
76 class WallTimer;
77 
78 namespace operations_research {
79 class CPArgumentProto;
80 class CPConstraintProto;
81 class CPIntegerExpressionProto;
82 class CPIntervalVariableProto;
83 
84 // This is the base class for all expressions that are not variables.
85 // It provides a basic 'CastToVar()' implementation.
86 //
87 // The class of expressions represent two types of objects: variables
88 // and subclasses of BaseIntExpr. Variables are stateful objects that
89 // provide a rich API (remove values, WhenBound...). On the other hand,
90 // subclasses of BaseIntExpr represent range-only stateless objects.
91 // That is, min(A + B) is recomputed each time as min(A) + min(B).
92 //
93 // Furthermore, sometimes, the propagation on an expression is not complete,
94 // and Min(), Max() are not monotonic with respect to SetMin() and SetMax().
95 // For instance, if A is a var with domain [0 .. 5], and B another variable
96 // with domain [0 .. 5], then Plus(A, B) has domain [0, 10].
97 //
98 // If we apply SetMax(Plus(A, B), 4)), we will deduce that both A
99 // and B have domain [0 .. 4]. In that case, Max(Plus(A, B)) is 8
100 // and not 4. To get back monotonicity, we 'cast' the expression
101 // into a variable using the Var() method (that will call CastToVar()
102 // internally). The resulting variable will be stateful and monotonic.
103 //
104 // Finally, one should never store a pointer to a IntExpr, or
105 // BaseIntExpr in the code. The safe code should always call Var() on an
106 // expression built by the solver, and store the object as an IntVar*.
107 // This is a consequence of the stateless nature of the expressions that
108 // makes the code error-prone.
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 
121 // This enum is used internally to do dynamic typing on subclasses of integer
122 // variables.
123 enum VarTypes {
133 };
134 
135 // ----- utility classes -----
136 
137 // This class represent a reversible FIFO structure.
138 // The main difference w.r.t a standard FIFO structure is that a Solver is
139 // given as parameter to the modifiers such that the solver can store the
140 // backtrack information
141 // Iterator's traversing order should not be changed, as some algorithm
142 // depend on it to be consistent.
143 // It's main use is to store a list of demons in the various classes of
144 // variables.
145 #ifndef SWIG
146 template <class T>
147 class SimpleRevFIFO {
148  private:
149  enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param
150  struct Chunk {
151  T data_[CHUNK_SIZE];
152  const Chunk* const next_;
153  explicit Chunk(const Chunk* next) : next_(next) {}
154  };
155 
156  public:
157  // This iterator is not stable with respect to deletion.
158  class Iterator {
159  public:
160  explicit Iterator(const SimpleRevFIFO<T>* l)
161  : chunk_(l->chunks_), value_(l->Last()) {}
162  bool ok() const { return (value_ != nullptr); }
163  T operator*() const { return *value_; }
164  void operator++() {
165  ++value_;
166  if (value_ == chunk_->data_ + CHUNK_SIZE) {
167  chunk_ = chunk_->next_;
168  value_ = chunk_ ? chunk_->data_ : nullptr;
169  }
170  }
171 
172  private:
173  const Chunk* chunk_;
174  const T* value_;
175  };
176 
177  SimpleRevFIFO() : chunks_(nullptr), pos_(0) {}
178 
179  void Push(Solver* const s, T val) {
180  if (pos_.Value() == 0) {
181  Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
182  s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
183  reinterpret_cast<void*>(chunk));
184  pos_.SetValue(s, CHUNK_SIZE - 1);
185  } else {
186  pos_.Decr(s);
187  }
188  chunks_->data_[pos_.Value()] = val;
189  }
190 
191  // Pushes the var on top if is not a duplicate of the current top object.
192  void PushIfNotTop(Solver* const s, T val) {
193  if (chunks_ == nullptr || LastValue() != val) {
194  Push(s, val);
195  }
196  }
197 
198  // Returns the last item of the FIFO.
199  const T* Last() const {
200  return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr;
201  }
202 
203  T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; }
204 
205  // Returns the last value in the FIFO.
206  const T& LastValue() const {
207  DCHECK(chunks_);
208  return chunks_->data_[pos_.Value()];
209  }
210 
211  // Sets the last value in the FIFO.
212  void SetLastValue(const T& v) {
213  DCHECK(Last());
214  chunks_->data_[pos_.Value()] = v;
215  }
216 
217  private:
218  Chunk* chunks_;
219  NumericalRev<int> pos_;
220 };
221 
222 // ---------- Reversible Hash Table ----------
223 
224 // ----- Hash functions -----
225 // TODO(user): use murmurhash.
226 inline uint64 Hash1(uint64 value) {
227  value = (~value) + (value << 21); // value = (value << 21) - value - 1;
228  value ^= value >> 24;
229  value += (value << 3) + (value << 8); // value * 265
230  value ^= value >> 14;
231  value += (value << 2) + (value << 4); // value * 21
232  value ^= value >> 28;
233  value += (value << 31);
234  return value;
235 }
236 
237 inline uint64 Hash1(uint32 value) {
238  uint64 a = value;
239  a = (a + 0x7ed55d16) + (a << 12);
240  a = (a ^ 0xc761c23c) ^ (a >> 19);
241  a = (a + 0x165667b1) + (a << 5);
242  a = (a + 0xd3a2646c) ^ (a << 9);
243  a = (a + 0xfd7046c5) + (a << 3);
244  a = (a ^ 0xb55a4f09) ^ (a >> 16);
245  return a;
246 }
247 
248 inline uint64 Hash1(int64 value) { return Hash1(static_cast<uint64>(value)); }
249 
250 inline uint64 Hash1(int value) { return Hash1(static_cast<uint32>(value)); }
251 
252 inline uint64 Hash1(void* const ptr) {
253 #if defined(ARCH_K8) || defined(__powerpc64__) || defined(__aarch64__)
254  return Hash1(reinterpret_cast<uint64>(ptr));
255 #else
256  return Hash1(reinterpret_cast<uint32>(ptr));
257 #endif
258 }
259 
260 template <class T>
261 uint64 Hash1(const std::vector<T*>& ptrs) {
262  if (ptrs.empty()) {
263  return 0;
264  } else if (ptrs.size() == 1) {
265  return Hash1(ptrs[0]);
266  } else {
267  uint64 hash = Hash1(ptrs[0]);
268  for (int i = 1; i < ptrs.size(); ++i) {
269  hash = hash * i + Hash1(ptrs[i]);
270  }
271  return hash;
272  }
273 }
274 
275 inline uint64 Hash1(const std::vector<int64>& ptrs) {
276  if (ptrs.empty()) {
277  return 0;
278  } else if (ptrs.size() == 1) {
279  return Hash1(ptrs[0]);
280  } else {
281  uint64 hash = Hash1(ptrs[0]);
282  for (int i = 1; i < ptrs.size(); ++i) {
283  hash = hash * i + Hash1(ptrs[i]);
284  }
285  return hash;
286  }
287 }
288 
289 // ----- Immutable Multi Map -----
290 
291 // Reversible Immutable MultiMap class.
292 // Represents an immutable multi-map that backtracks with the solver.
293 template <class K, class V>
295  public:
296  RevImmutableMultiMap(Solver* const solver, int initial_size)
297  : solver_(solver),
298  array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
299  size_(initial_size),
300  num_items_(0) {
301  memset(array_, 0, sizeof(*array_) * size_.Value());
302  }
303 
305 
306  int num_items() const { return num_items_.Value(); }
307 
308  // Returns true if the multi-map contains at least one instance of 'key'.
309  bool ContainsKey(const K& key) const {
310  uint64 code = Hash1(key) % size_.Value();
311  Cell* tmp = array_[code];
312  while (tmp) {
313  if (tmp->key() == key) {
314  return true;
315  }
316  tmp = tmp->next();
317  }
318  return false;
319  }
320 
321  // Returns one value attached to 'key', or 'default_value' if 'key'
322  // is not in the multi-map. The actual value returned if more than one
323  // values is attached to the same key is not specified.
324  const V& FindWithDefault(const K& key, const V& default_value) const {
325  uint64 code = Hash1(key) % size_.Value();
326  Cell* tmp = array_[code];
327  while (tmp) {
328  if (tmp->key() == key) {
329  return tmp->value();
330  }
331  tmp = tmp->next();
332  }
333  return default_value;
334  }
335 
336  // Inserts (key, value) in the multi-map.
337  void Insert(const K& key, const V& value) {
338  const int position = Hash1(key) % size_.Value();
339  Cell* const cell =
340  solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
341  solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
342  reinterpret_cast<void*>(cell));
343  num_items_.Incr(solver_);
344  if (num_items_.Value() > 2 * size_.Value()) {
345  Double();
346  }
347  }
348 
349  private:
350  class Cell {
351  public:
352  Cell(const K& key, const V& value, Cell* const next)
353  : key_(key), value_(value), next_(next) {}
354 
355  void SetRevNext(Solver* const solver, Cell* const next) {
356  solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
357  reinterpret_cast<void*>(next));
358  }
359 
360  Cell* next() const { return next_; }
361 
362  const K& key() const { return key_; }
363 
364  const V& value() const { return value_; }
365 
366  private:
367  const K key_;
368  const V value_;
369  Cell* next_;
370  };
371 
372  void Double() {
373  Cell** const old_cell_array = array_;
374  const int old_size = size_.Value();
375  size_.SetValue(solver_, size_.Value() * 2);
376  solver_->SaveAndSetValue(
377  reinterpret_cast<void**>(&array_),
378  reinterpret_cast<void*>(
379  solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
380  memset(array_, 0, size_.Value() * sizeof(*array_));
381  for (int i = 0; i < old_size; ++i) {
382  Cell* tmp = old_cell_array[i];
383  while (tmp != nullptr) {
384  Cell* const to_reinsert = tmp;
385  tmp = tmp->next();
386  const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value();
387  to_reinsert->SetRevNext(solver_, array_[new_position]);
388  solver_->SaveAndSetValue(
389  reinterpret_cast<void**>(&array_[new_position]),
390  reinterpret_cast<void*>(to_reinsert));
391  }
392  }
393  }
394 
395  Solver* const solver_;
396  Cell** array_;
397  NumericalRev<int> size_;
398  NumericalRev<int> num_items_;
399 };
400 
401 // A reversible switch that can switch once from false to true.
402 class RevSwitch {
403  public:
404  RevSwitch() : value_(false) {}
405 
406  bool Switched() const { return value_; }
407 
408  void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); }
409 
410  private:
411  bool value_;
412 };
413 
414 // This class represents a small reversible bitset (size <= 64).
415 // This class is useful to maintain supports.
417  public:
418  explicit SmallRevBitSet(int64 size);
419  // Sets the 'pos' bit.
420  void SetToOne(Solver* const solver, int64 pos);
421  // Erases the 'pos' bit.
422  void SetToZero(Solver* const solver, int64 pos);
423  // Returns the number of bits set to one.
424  int64 Cardinality() const;
425  // Is bitset null?
426  bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); }
427  // Does it contains only one bit set?
428  bool IsCardinalityOne() const {
429  return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
430  }
431  // Gets the index of the first bit set starting from 0.
432  // It returns -1 if the bitset is empty.
433  int64 GetFirstOne() const;
434 
435  private:
436  Rev<uint64> bits_;
437 };
438 
439 // This class represents a reversible bitset.
440 // This class is useful to maintain supports.
441 class RevBitSet {
442  public:
443  explicit RevBitSet(int64 size);
444  ~RevBitSet();
445 
446  // Sets the 'index' bit.
447  void SetToOne(Solver* const solver, int64 index);
448  // Erases the 'index' bit.
449  void SetToZero(Solver* const solver, int64 index);
450  // Returns whether the 'index' bit is set.
451  bool IsSet(int64 index) const;
452  // Returns the number of bits set to one.
453  int64 Cardinality() const;
454  // Is bitset null?
455  bool IsCardinalityZero() const;
456  // Does it contains only one bit set?
457  bool IsCardinalityOne() const;
458  // Gets the index of the first bit set starting from start.
459  // It returns -1 if the bitset is empty after start.
460  int64 GetFirstBit(int start) const;
461  // Cleans all bits.
462  void ClearAll(Solver* const solver);
463 
464  friend class RevBitMatrix;
465 
466  private:
467  // Save the offset's part of the bitset.
468  void Save(Solver* const solver, int offset);
469  const int64 size_;
470  const int64 length_;
471  uint64* bits_;
472  uint64* stamps_;
473 };
474 
475 // Matrix version of the RevBitSet class.
476 class RevBitMatrix : private RevBitSet {
477  public:
478  RevBitMatrix(int64 rows, int64 columns);
479  ~RevBitMatrix();
480 
481  // Sets the 'column' bit in the 'row' row.
482  void SetToOne(Solver* const solver, int64 row, int64 column);
483  // Erases the 'column' bit in the 'row' row.
484  void SetToZero(Solver* const solver, int64 row, int64 column);
485  // Returns whether the 'column' bit in the 'row' row is set.
486  bool IsSet(int64 row, int64 column) const {
487  DCHECK_GE(row, 0);
488  DCHECK_LT(row, rows_);
489  DCHECK_GE(column, 0);
490  DCHECK_LT(column, columns_);
491  return RevBitSet::IsSet(row * columns_ + column);
492  }
493  // Returns the number of bits set to one in the 'row' row.
494  int64 Cardinality(int row) const;
495  // Is bitset of row 'row' null?
496  bool IsCardinalityZero(int row) const;
497  // Does the 'row' bitset contains only one bit set?
498  bool IsCardinalityOne(int row) const;
499  // Returns the first bit in the row 'row' which position is >= 'start'.
500  // It returns -1 if there are none.
501  int64 GetFirstBit(int row, int start) const;
502  // Cleans all bits.
503  void ClearAll(Solver* const solver);
504 
505  private:
506  const int64 rows_;
507  const int64 columns_;
508 };
509 
510 // @{
511 // These methods represent generic demons that will call back a
512 // method on the constraint during their Run method.
513 // This way, all propagation methods are members of the constraint class,
514 // and demons are just proxies with a priority of NORMAL_PRIORITY.
515 
516 // Demon proxy to a method on the constraint with no arguments.
517 template <class T>
518 class CallMethod0 : public Demon {
519  public:
520  CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
521  : constraint_(ct), method_(method), name_(name) {}
522 
523  ~CallMethod0() override {}
524 
525  void Run(Solver* const s) override { (constraint_->*method_)(); }
526 
527  std::string DebugString() const override {
528  return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")";
529  }
530 
531  private:
532  T* const constraint_;
533  void (T::*const method_)();
534  const std::string name_;
535 };
536 
537 template <class T>
538 Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(),
539  const std::string& name) {
540  return s->RevAlloc(new CallMethod0<T>(ct, method, name));
541 }
542 
543 template <class P>
544 std::string ParameterDebugString(P param) {
545  return absl::StrCat(param);
546 }
547 
548 // Support limited to pointers to classes which define DebugString().
549 template <class P>
550 std::string ParameterDebugString(P* param) {
551  return param->DebugString();
552 }
553 
554 // Demon proxy to a method on the constraint with one argument.
555 template <class T, class P>
556 class CallMethod1 : public Demon {
557  public:
558  CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
559  P param1)
560  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
561 
562  ~CallMethod1() override {}
563 
564  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
565 
566  std::string DebugString() const override {
567  return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
568  ", ", ParameterDebugString(param1_), ")");
569  }
570 
571  private:
572  T* const constraint_;
573  void (T::*const method_)(P);
574  const std::string name_;
575  P param1_;
576 };
577 
578 template <class T, class P>
579 Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P),
580  const std::string& name, P param1) {
581  return s->RevAlloc(new CallMethod1<T, P>(ct, method, name, param1));
582 }
583 
584 // Demon proxy to a method on the constraint with two arguments.
585 template <class T, class P, class Q>
586 class CallMethod2 : public Demon {
587  public:
588  CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
589  P param1, Q param2)
590  : constraint_(ct),
591  method_(method),
592  name_(name),
593  param1_(param1),
594  param2_(param2) {}
595 
596  ~CallMethod2() override {}
597 
598  void Run(Solver* const s) override {
599  (constraint_->*method_)(param1_, param2_);
600  }
601 
602  std::string DebugString() const override {
603  return absl::StrCat(absl::StrCat("CallMethod_", name_),
604  absl::StrCat("(", constraint_->DebugString()),
605  absl::StrCat(", ", ParameterDebugString(param1_)),
606  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
607  }
608 
609  private:
610  T* const constraint_;
611  void (T::*const method_)(P, Q);
612  const std::string name_;
613  P param1_;
614  Q param2_;
615 };
616 
617 template <class T, class P, class Q>
618 Demon* MakeConstraintDemon2(Solver* const s, T* const ct,
619  void (T::*method)(P, Q), const std::string& name,
620  P param1, Q param2) {
621  return s->RevAlloc(
622  new CallMethod2<T, P, Q>(ct, method, name, param1, param2));
623 }
624 // Demon proxy to a method on the constraint with three arguments.
625 template <class T, class P, class Q, class R>
626 class CallMethod3 : public Demon {
627  public:
628  CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
629  P param1, Q param2, R param3)
630  : constraint_(ct),
631  method_(method),
632  name_(name),
633  param1_(param1),
634  param2_(param2),
635  param3_(param3) {}
636 
637  ~CallMethod3() override {}
638 
639  void Run(Solver* const s) override {
640  (constraint_->*method_)(param1_, param2_, param3_);
641  }
642 
643  std::string DebugString() const override {
644  return absl::StrCat(absl::StrCat("CallMethod_", name_),
645  absl::StrCat("(", constraint_->DebugString()),
646  absl::StrCat(", ", ParameterDebugString(param1_)),
647  absl::StrCat(", ", ParameterDebugString(param2_)),
648  absl::StrCat(", ", ParameterDebugString(param3_), ")"));
649  }
650 
651  private:
652  T* const constraint_;
653  void (T::*const method_)(P, Q, R);
654  const std::string name_;
655  P param1_;
656  Q param2_;
657  R param3_;
658 };
659 
660 template <class T, class P, class Q, class R>
661 Demon* MakeConstraintDemon3(Solver* const s, T* const ct,
662  void (T::*method)(P, Q, R), const std::string& name,
663  P param1, Q param2, R param3) {
664  return s->RevAlloc(
665  new CallMethod3<T, P, Q, R>(ct, method, name, param1, param2, param3));
666 }
667 // @}
668 
669 // @{
670 // These methods represents generic demons that will call back a
671 // method on the constraint during their Run method. This demon will
672 // have a priority DELAYED_PRIORITY.
673 
674 // Low-priority demon proxy to a method on the constraint with no arguments.
675 template <class T>
676 class DelayedCallMethod0 : public Demon {
677  public:
678  DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
679  : constraint_(ct), method_(method), name_(name) {}
680 
681  ~DelayedCallMethod0() override {}
682 
683  void Run(Solver* const s) override { (constraint_->*method_)(); }
684 
685  Solver::DemonPriority priority() const override {
687  }
688 
689  std::string DebugString() const override {
690  return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() +
691  ")";
692  }
693 
694  private:
695  T* const constraint_;
696  void (T::*const method_)();
697  const std::string name_;
698 };
699 
700 template <class T>
701 Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct,
702  void (T::*method)(),
703  const std::string& name) {
704  return s->RevAlloc(new DelayedCallMethod0<T>(ct, method, name));
705 }
706 
707 // Low-priority demon proxy to a method on the constraint with one argument.
708 template <class T, class P>
709 class DelayedCallMethod1 : public Demon {
710  public:
711  DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
712  P param1)
713  : constraint_(ct), method_(method), name_(name), param1_(param1) {}
714 
715  ~DelayedCallMethod1() override {}
716 
717  void Run(Solver* const s) override { (constraint_->*method_)(param1_); }
718 
719  Solver::DemonPriority priority() const override {
721  }
722 
723  std::string DebugString() const override {
724  return absl::StrCat("DelayedCallMethod_", name_, "(",
725  constraint_->DebugString(), ", ",
726  ParameterDebugString(param1_), ")");
727  }
728 
729  private:
730  T* const constraint_;
731  void (T::*const method_)(P);
732  const std::string name_;
733  P param1_;
734 };
735 
736 template <class T, class P>
737 Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct,
738  void (T::*method)(P),
739  const std::string& name, P param1) {
740  return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
741 }
742 
743 // Low-priority demon proxy to a method on the constraint with two arguments.
744 template <class T, class P, class Q>
745 class DelayedCallMethod2 : public Demon {
746  public:
747  DelayedCallMethod2(T* const ct, void (T::*method)(P, Q),
748  const std::string& name, P param1, Q param2)
749  : constraint_(ct),
750  method_(method),
751  name_(name),
752  param1_(param1),
753  param2_(param2) {}
754 
755  ~DelayedCallMethod2() override {}
756 
757  void Run(Solver* const s) override {
758  (constraint_->*method_)(param1_, param2_);
759  }
760 
761  Solver::DemonPriority priority() const override {
763  }
764 
765  std::string DebugString() const override {
766  return absl::StrCat(absl::StrCat("DelayedCallMethod_", name_),
767  absl::StrCat("(", constraint_->DebugString()),
768  absl::StrCat(", ", ParameterDebugString(param1_)),
769  absl::StrCat(", ", ParameterDebugString(param2_), ")"));
770  }
771 
772  private:
773  T* const constraint_;
774  void (T::*const method_)(P, Q);
775  const std::string name_;
776  P param1_;
777  Q param2_;
778 };
779 
780 template <class T, class P, class Q>
781 Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct,
782  void (T::*method)(P, Q),
783  const std::string& name, P param1,
784  Q param2) {
785  return s->RevAlloc(
786  new DelayedCallMethod2<T, P, Q>(ct, method, name, param1, param2));
787 }
788 // @}
789 
790 #endif // !defined(SWIG)
791 
792 // ---------- Local search operators ----------
793 
794 // The base class for all local search operators.
795 //
796 // A local search operator is an object that defines the neighborhood of a
797 // solution. In other words, a neighborhood is the set of solutions which can
798 // be reached from a given solution using an operator.
799 //
800 // The behavior of the LocalSearchOperator class is similar to iterators.
801 // The operator is synchronized with an assignment (gives the
802 // current values of the variables); this is done in the Start() method.
803 //
804 // Then one can iterate over the neighbors using the MakeNextNeighbor method.
805 // This method returns an assignment which represents the incremental changes
806 // to the current solution. It also returns a second assignment representing the
807 // changes to the last solution defined by the neighborhood operator; this
808 // assignment is empty if the neighborhood operator cannot track this
809 // information.
810 //
811 // TODO(user): rename Start to Synchronize ?
812 // TODO(user): decouple the iterating from the defining of a neighbor.
814  public:
816  ~LocalSearchOperator() override {}
817  virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
818  virtual void Start(const Assignment* assignment) = 0;
819  virtual void Reset() {}
820 #ifndef SWIG
821  virtual const LocalSearchOperator* Self() const { return this; }
822 #endif // SWIG
823  virtual bool HasFragments() const { return false; }
824  virtual bool HoldsDelta() const { return false; }
825 };
826 
827 // ----- Base operator class for operators manipulating variables -----
828 
829 template <class V, class Val, class Handler>
831  public:
833  VarLocalSearchOperator(std::vector<V*> vars, Handler var_handler)
834  : activated_(),
835  was_activated_(),
836  cleared_(true),
837  var_handler_(var_handler) {}
839  bool HoldsDelta() const override { return true; }
840  // This method should not be overridden. Override OnStart() instead which is
841  // called before exiting this method.
842  void Start(const Assignment* assignment) override {
843  const int size = Size();
844  CHECK_LE(size, assignment->Size())
845  << "Assignment contains fewer variables than operator";
846  for (int i = 0; i < size; ++i) {
847  activated_.Set(i, var_handler_.ValueFromAssignent(*assignment, vars_[i],
848  i, &values_[i]));
849  }
852  was_activated_.SetContentFromBitsetOfSameSize(activated_);
853  OnStart();
854  }
855  virtual bool IsIncremental() const { return false; }
856  int Size() const { return vars_.size(); }
857  // Returns the value in the current assignment of the variable of given index.
858  const Val& Value(int64 index) const {
859  DCHECK_LT(index, vars_.size());
860  return values_[index];
861  }
862  // Returns the variable of given index.
863  V* Var(int64 index) const { return vars_[index]; }
864  virtual bool SkipUnchanged(int index) const { return false; }
865  const Val& OldValue(int64 index) const { return old_values_[index]; }
866  void SetValue(int64 index, const Val& value) {
867  values_[index] = value;
868  MarkChange(index);
869  }
870  bool Activated(int64 index) const { return activated_[index]; }
871  void Activate(int64 index) {
872  activated_.Set(index);
873  MarkChange(index);
874  }
875  void Deactivate(int64 index) {
876  activated_.Clear(index);
877  MarkChange(index);
878  }
879  bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const {
880  if (IsIncremental() && !cleared_) {
881  for (const int64 index : delta_changes_.PositionsSetAtLeastOnce()) {
882  V* var = Var(index);
883  const Val& value = Value(index);
884  const bool activated = activated_[index];
885  var_handler_.AddToAssignment(var, value, activated, nullptr, index,
886  deltadelta);
887  var_handler_.AddToAssignment(var, value, activated,
888  &assignment_indices_, index, delta);
889  }
890  } else {
891  delta->Clear();
892  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
893  const Val& value = Value(index);
894  const bool activated = activated_[index];
895  if (!activated || value != OldValue(index) || !SkipUnchanged(index)) {
896  var_handler_.AddToAssignment(Var(index), value, activated_[index],
897  &assignment_indices_, index, delta);
898  }
899  }
900  }
901  return true;
902  }
903  void RevertChanges(bool incremental) {
904  cleared_ = false;
905  delta_changes_.SparseClearAll();
906  if (incremental && IsIncremental()) return;
907  cleared_ = true;
908  for (const int64 index : changes_.PositionsSetAtLeastOnce()) {
909  values_[index] = old_values_[index];
910  var_handler_.OnRevertChanges(index);
911  activated_.CopyBucket(was_activated_, index);
912  assignment_indices_[index] = -1;
913  }
914  changes_.SparseClearAll();
915  }
916  void AddVars(const std::vector<V*>& vars) {
917  if (!vars.empty()) {
918  vars_.insert(vars_.end(), vars.begin(), vars.end());
919  const int64 size = Size();
920  values_.resize(size);
921  old_values_.resize(size);
922  prev_values_.resize(size);
923  assignment_indices_.resize(size, -1);
924  activated_.Resize(size);
925  was_activated_.Resize(size);
926  changes_.ClearAndResize(size);
927  delta_changes_.ClearAndResize(size);
928  var_handler_.OnAddVars();
929  }
930  }
931 
932  // Called by Start() after synchronizing the operator with the current
933  // assignment. Should be overridden instead of Start() to avoid calling
934  // VarLocalSearchOperator::Start explicitly.
935  virtual void OnStart() {}
936 
937  // OnStart() should really be protected, but then SWIG doesn't see it. So we
938  // make it public, but only subclasses should access to it (to override it).
939  protected:
940  void MarkChange(int64 index) {
941  delta_changes_.Set(index);
942  changes_.Set(index);
943  }
944 
945  std::vector<V*> vars_;
946  std::vector<Val> values_;
947  std::vector<Val> old_values_;
948  std::vector<Val> prev_values_;
949  mutable std::vector<int> assignment_indices_;
950  Bitset64<> activated_;
951  Bitset64<> was_activated_;
952  SparseBitset<> changes_;
953  SparseBitset<> delta_changes_;
954  bool cleared_;
955  Handler var_handler_;
956 };
957 
958 // ----- Base operator class for operators manipulating IntVars -----
959 
961  public:
962  void AddToAssignment(IntVar* var, int64 value, bool active,
963  std::vector<int>* assignment_indices, int64 index,
964  Assignment* assignment) const {
965  Assignment::IntContainer* const container =
966  assignment->MutableIntVarContainer();
967  IntVarElement* element = nullptr;
968  if (assignment_indices != nullptr) {
969  if ((*assignment_indices)[index] == -1) {
970  (*assignment_indices)[index] = container->Size();
971  element = assignment->FastAdd(var);
972  } else {
973  element = container->MutableElement((*assignment_indices)[index]);
974  }
975  } else {
976  element = assignment->FastAdd(var);
977  }
978  if (active) {
979  element->SetValue(value);
980  element->Activate();
981  } else {
982  element->Deactivate();
983  }
984  }
985  bool ValueFromAssignent(const Assignment& assignment, IntVar* var,
986  int64 index, int64* value) {
987  const Assignment::IntContainer& container = assignment.IntVarContainer();
988  const IntVarElement* element = &(container.Element(index));
989  if (element->Var() != var) {
990  CHECK(container.Contains(var))
991  << "Assignment does not contain operator variable " << var;
992  element = &(container.Element(var));
993  }
994  *value = element->Value();
995  return element->Activated();
996  }
997  void OnRevertChanges(int64 index) {}
998  void OnAddVars() {}
999 };
1000 
1001 // Specialization of LocalSearchOperator built from an array of IntVars
1002 // which specifies the scope of the operator.
1003 // This class also takes care of storing current variable values in Start(),
1004 // keeps track of changes done by the operator and builds the delta.
1005 // The Deactivate() method can be used to perform Large Neighborhood Search.
1006 
1007 #ifdef SWIG
1008 // Unfortunately, we must put this code here and not in
1009 // */constraint_solver.i, because it must be parsed by SWIG before the
1010 // derived C++ class.
1011 // TODO(user): find a way to move this code back to the .i file, where it
1012 // belongs.
1013 // In python, we use a whitelist to expose the API. This whitelist must also
1014 // be extended here.
1015 #if defined(SWIGPYTHON)
1016 %unignore VarLocalSearchOperator<IntVar, int64,
1017  IntVarLocalSearchHandler>::Size;
1018 %unignore VarLocalSearchOperator<IntVar, int64,
1019  IntVarLocalSearchHandler>::Value;
1020 %unignore VarLocalSearchOperator<IntVar, int64,
1021  IntVarLocalSearchHandler>::OldValue;
1022 %unignore VarLocalSearchOperator<IntVar, int64,
1023  IntVarLocalSearchHandler>::SetValue;
1024 %feature("director") VarLocalSearchOperator<IntVar, int64,
1025  IntVarLocalSearchHandler>::IsIncremental;
1026 %feature("director") VarLocalSearchOperator<IntVar, int64,
1027  IntVarLocalSearchHandler>::OnStart;
1028 %unignore VarLocalSearchOperator<IntVar, int64,
1029  IntVarLocalSearchHandler>::IsIncremental;
1030 %unignore VarLocalSearchOperator<IntVar, int64,
1031  IntVarLocalSearchHandler>::OnStart;
1032 #endif // SWIGPYTHON
1033 
1034 // clang-format off
1035 %rename(IntVarLocalSearchOperatorTemplate)
1036  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1037 %template(IntVarLocalSearchOperatorTemplate)
1038  VarLocalSearchOperator<IntVar, int64, IntVarLocalSearchHandler>;
1039 // clang-format on
1040 #endif // SWIG
1041 
1044  public:
1046  explicit IntVarLocalSearchOperator(const std::vector<IntVar*>& vars)
1048  vars, IntVarLocalSearchHandler()) {
1049  AddVars(vars);
1050  }
1052  // Redefines MakeNextNeighbor to export a simpler interface. The calls to
1053  // ApplyChanges() and RevertChanges() are factored in this method, hiding both
1054  // delta and deltadelta from subclasses which only need to override
1055  // MakeOneNeighbor().
1056  // Therefore this method should not be overridden. Override MakeOneNeighbor()
1057  // instead.
1058  bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
1059 
1060  protected:
1061  // Creates a new neighbor. It returns false when the neighborhood is
1062  // completely explored.
1063  // TODO(user): make it pure virtual, implies porting all apps overriding
1064  // MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.
1065  virtual bool MakeOneNeighbor();
1066 };
1067 
1068 // ----- SequenceVarLocalSearchOperator -----
1069 
1070 class SequenceVarLocalSearchOperator;
1071 
1073  public:
1074  SequenceVarLocalSearchHandler() : op_(nullptr) {}
1076  : op_(other.op_) {}
1078  : op_(op) {}
1079  void AddToAssignment(SequenceVar* var, const std::vector<int>& value,
1080  bool active, std::vector<int>* assignment_indices,
1081  int64 index, Assignment* assignment) const;
1082  bool ValueFromAssignent(const Assignment& assignment, SequenceVar* var,
1083  int64 index, std::vector<int>* value);
1084  void OnRevertChanges(int64 index);
1085  void OnAddVars();
1086 
1087  private:
1088  SequenceVarLocalSearchOperator* const op_;
1089 };
1090 
1091 #ifdef SWIG
1092 // Unfortunately, we must put this code here and not in
1093 // */constraint_solver.i, because it must be parsed by SWIG before the
1094 // derived C++ class.
1095 // TODO(user): find a way to move this code back to the .i file, where it
1096 // belongs.
1097 // clang-format off
1098 %rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1099  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1100 %template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator<
1101  SequenceVar, std::vector<int>, SequenceVarLocalSearchHandler>;
1102 // clang-format on
1103 #endif
1104 
1105 typedef VarLocalSearchOperator<SequenceVar, std::vector<int>,
1106  SequenceVarLocalSearchHandler>
1108 
1111  public:
1113  explicit SequenceVarLocalSearchOperator(const std::vector<SequenceVar*>& vars)
1115  vars, SequenceVarLocalSearchHandler(this)) {
1116  AddVars(vars);
1117  }
1119  // Returns the value in the current assignment of the variable of given index.
1120  const std::vector<int>& Sequence(int64 index) const { return Value(index); }
1121  const std::vector<int>& OldSequence(int64 index) const {
1122  return OldValue(index);
1123  }
1124  void SetForwardSequence(int64 index, const std::vector<int>& value) {
1125  SetValue(index, value);
1126  }
1127  void SetBackwardSequence(int64 index, const std::vector<int>& value) {
1128  backward_values_[index] = value;
1129  MarkChange(index);
1130  }
1131 
1132  protected:
1134 
1135  std::vector<std::vector<int> > backward_values_;
1136 };
1137 
1139  SequenceVar* var, const std::vector<int>& value, bool active,
1140  std::vector<int>* assignment_indices, int64 index,
1141  Assignment* assignment) const {
1142  Assignment::SequenceContainer* const container =
1143  assignment->MutableSequenceVarContainer();
1144  SequenceVarElement* element = nullptr;
1145  if (assignment_indices != nullptr) {
1146  if ((*assignment_indices)[index] == -1) {
1147  (*assignment_indices)[index] = container->Size();
1148  element = assignment->FastAdd(var);
1149  } else {
1150  element = container->MutableElement((*assignment_indices)[index]);
1151  }
1152  } else {
1153  element = assignment->FastAdd(var);
1154  }
1155  if (active) {
1156  element->SetForwardSequence(value);
1157  element->SetBackwardSequence(op_->backward_values_[index]);
1158  element->Activate();
1159  } else {
1160  element->Deactivate();
1161  }
1162 }
1163 
1165  const Assignment& assignment, SequenceVar* var, int64 index,
1166  std::vector<int>* value) {
1167  const Assignment::SequenceContainer& container =
1168  assignment.SequenceVarContainer();
1169  const SequenceVarElement* element = &(container.Element(index));
1170  if (element->Var() != var) {
1171  CHECK(container.Contains(var))
1172  << "Assignment does not contain operator variable " << var;
1173  element = &(container.Element(var));
1174  }
1175  const std::vector<int>& element_value = element->ForwardSequence();
1176  CHECK_GE(var->size(), element_value.size());
1177  op_->backward_values_[index].clear();
1178  *value = element_value;
1179  return element->Activated();
1180 }
1181 
1183  op_->backward_values_[index].clear();
1184 }
1185 
1187  op_->backward_values_.resize(op_->Size());
1188 }
1189 
1190 // ----- Base Large Neighborhood Search operator class ----
1191 
1192 // This is the base class for building an Lns operator. An Lns fragment is a
1193 // collection of variables which will be relaxed. Fragments are built with
1194 // NextFragment(), which returns false if there are no more fragments to build.
1195 // Optionally one can override InitFragments, which is called from
1196 // LocalSearchOperator::Start to initialize fragment data.
1197 //
1198 // Here's a sample relaxing one variable at a time:
1199 //
1200 // class OneVarLns : public BaseLns {
1201 // public:
1202 // OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {}
1203 // virtual ~OneVarLns() {}
1204 // virtual void InitFragments() { index_ = 0; }
1205 // virtual bool NextFragment() {
1206 // const int size = Size();
1207 // if (index_ < size) {
1208 // AppendToFragment(index_);
1209 // ++index_;
1210 // return true;
1211 // } else {
1212 // return false;
1213 // }
1214 // }
1215 //
1216 // private:
1217 // int index_;
1218 // };
1220  public:
1221  explicit BaseLns(const std::vector<IntVar*>& vars);
1222  ~BaseLns() override;
1223  virtual void InitFragments();
1224  virtual bool NextFragment() = 0;
1225  void AppendToFragment(int index);
1226  int FragmentSize() const;
1227  bool HasFragments() const override { return true; }
1228 
1229  protected:
1230  // This method should not be overridden. Override NextFragment() instead.
1231  bool MakeOneNeighbor() override;
1232 
1233  private:
1234  // This method should not be overridden. Override InitFragments() instead.
1235  void OnStart() override;
1236  std::vector<int> fragment_;
1237 };
1238 
1239 // ----- ChangeValue Operators -----
1240 
1241 // Defines operators which change the value of variables;
1242 // each neighbor corresponds to *one* modified variable.
1243 // Sub-classes have to define ModifyValue which determines what the new
1244 // variable value is going to be (given the current value and the variable).
1246  public:
1247  explicit ChangeValue(const std::vector<IntVar*>& vars);
1248  ~ChangeValue() override;
1249  virtual int64 ModifyValue(int64 index, int64 value) = 0;
1250 
1251  protected:
1252  // This method should not be overridden. Override ModifyValue() instead.
1253  bool MakeOneNeighbor() override;
1254 
1255  private:
1256  void OnStart() override;
1257 
1258  int index_;
1259 };
1260 
1261 // ----- Path-based Operators -----
1262 
1263 // Base class of the local search operators dedicated to path modifications
1264 // (a path is a set of nodes linked together by arcs).
1265 // This family of neighborhoods supposes they are handling next variables
1266 // representing the arcs (var[i] represents the node immediately after i on
1267 // a path).
1268 // Several services are provided:
1269 // - arc manipulators (SetNext(), ReverseChain(), MoveChain())
1270 // - path inspectors (Next(), IsPathEnd())
1271 // - path iterators: operators need a given number of nodes to define a
1272 // neighbor; this class provides the iteration on a given number of (base)
1273 // nodes which can be used to define a neighbor (through the BaseNode method)
1274 // Subclasses only need to override MakeNeighbor to create neighbors using
1275 // the services above (no direct manipulation of assignments).
1277  public:
1278  // Builds an instance of PathOperator from next and path variables.
1279  // 'number_of_base_nodes' is the number of nodes needed to define a
1280  // neighbor. 'start_empty_path_class' is a callback returning an index such
1281  // that if
1282  // c1 = start_empty_path_class(StartNode(p1)),
1283  // c2 = start_empty_path_class(StartNode(p2)),
1284  // p1 and p2 are path indices,
1285  // then if c1 == c2, p1 and p2 are equivalent if they are empty.
1286  // This is used to remove neighborhood symmetries on equivalent empty paths;
1287  // for instance if a node cannot be moved to an empty path, then all moves
1288  // moving the same node to equivalent empty paths will be skipped.
1289  // 'start_empty_path_class' can be nullptr in which case no symmetries will be
1290  // removed.
1291  PathOperator(const std::vector<IntVar*>& next_vars,
1292  const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1293  bool skip_locally_optimal_paths,
1294  std::function<int(int64)> start_empty_path_class);
1295  ~PathOperator() override {}
1296  virtual bool MakeNeighbor() = 0;
1297  void Reset() override;
1298 
1299  // TODO(user): Make the following methods protected.
1300  bool SkipUnchanged(int index) const override;
1301 
1302  // Returns the index of the node after the node of index node_index in the
1303  // current assignment.
1304  int64 Next(int64 node_index) const {
1305  DCHECK(!IsPathEnd(node_index));
1306  return Value(node_index);
1307  }
1308 
1309  // Returns the index of the path to which the node of index node_index
1310  // belongs in the current assignment.
1311  int64 Path(int64 node_index) const {
1312  return ignore_path_vars_ ? 0LL : Value(node_index + number_of_nexts_);
1313  }
1314 
1315  // Number of next variables.
1316  int number_of_nexts() const { return number_of_nexts_; }
1317 
1318  protected:
1319  // This method should not be overridden. Override MakeNeighbor() instead.
1320  bool MakeOneNeighbor() override;
1321 
1322  // Returns the index of the variable corresponding to the ith base node.
1323  int64 BaseNode(int i) const { return base_nodes_[i]; }
1324  // Returns the index of the variable corresponding to the current path
1325  // of the ith base node.
1326  int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1327  // Returns the vector of path start nodes.
1328  const std::vector<int64>& path_starts() const { return path_starts_; }
1329  // Returns the class of the current path of the ith base node.
1330  int PathClass(int i) const {
1331  return start_empty_path_class_ != nullptr
1332  ? start_empty_path_class_(StartNode(i))
1333  : StartNode(i);
1334  }
1335 
1336  // When the operator is being synchronized with a new solution (when Start()
1337  // is called), returns true to restart the exploration of the neighborhood
1338  // from the start of the last paths explored; returns false to restart the
1339  // exploration at the last nodes visited.
1340  // This is used to avoid restarting on base nodes which have changed paths,
1341  // leading to potentially skipping neighbors.
1342  // TODO(user): remove this when automatic detection of such cases in done.
1343  virtual bool RestartAtPathStartOnSynchronize() { return false; }
1344  // Returns true if a base node has to be on the same path as the "previous"
1345  // base node (base node of index base_index - 1).
1346  // Useful to limit neighborhood exploration to nodes on the same path.
1347  // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2);
1348  // it's currently way more complicated to implement.
1349  virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; }
1350  // Returns the index of the node to which the base node of index base_index
1351  // must be set to when it reaches the end of a path.
1352  // By default, it is set to the start of the current path.
1353  // When this method is called, one can only assume that base nodes with
1354  // indices < base_index have their final position.
1355  virtual int64 GetBaseNodeRestartPosition(int base_index) {
1356  return StartNode(base_index);
1357  }
1358  // Set the next base to increment on next iteration. All base > base_index
1359  // will be reset to their start value.
1360  virtual void SetNextBaseToIncrement(int64 base_index) {
1361  next_base_to_increment_ = base_index;
1362  }
1363 
1364  int64 OldNext(int64 node_index) const {
1365  DCHECK(!IsPathEnd(node_index));
1366  return OldValue(node_index);
1367  }
1368 
1369  int64 OldPath(int64 node_index) const {
1370  return ignore_path_vars_ ? 0LL : OldValue(node_index + number_of_nexts_);
1371  }
1372 
1373  // Moves the chain starting after the node before_chain and ending at the node
1374  // chain_end after the node destination
1375  bool MoveChain(int64 before_chain, int64 chain_end, int64 destination);
1376 
1377  // Reverses the chain starting after before_chain and ending before
1378  // after_chain
1379  bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last);
1380 
1381  bool MakeActive(int64 node, int64 destination);
1382  bool MakeChainInactive(int64 before_chain, int64 chain_end);
1383 
1384  // Sets the to to be the node after from
1385  void SetNext(int64 from, int64 to, int64 path) {
1386  DCHECK_LT(from, number_of_nexts_);
1387  SetValue(from, to);
1388  if (!ignore_path_vars_) {
1389  DCHECK_LT(from + number_of_nexts_, Size());
1390  SetValue(from + number_of_nexts_, path);
1391  }
1392  }
1393 
1394  // Returns true if i is the last node on the path; defined by the fact that
1395  // i outside the range of the variable array
1396  bool IsPathEnd(int64 i) const { return i >= number_of_nexts_; }
1397 
1398  // Returns true if node is inactive
1399  bool IsInactive(int64 i) const { return !IsPathEnd(i) && inactives_[i]; }
1400 
1401  // Returns true if operator needs to restart its initial position at each
1402  // call to Start()
1403  virtual bool InitPosition() const { return false; }
1404  // Reset the position of the operator to its position when Start() was last
1405  // called; this can be used to let an operator iterate more than once over
1406  // the paths.
1407  void ResetPosition() { just_started_ = true; }
1408 
1409  const int number_of_nexts_;
1410  const bool ignore_path_vars_;
1412  int num_paths_ = 0;
1413  std::vector<int64> start_to_path_;
1414 
1415  private:
1416  void OnStart() override;
1417  // Called by OnStart() after initializing node information. Should be
1418  // overridden instead of OnStart() to avoid calling PathOperator::OnStart
1419  // explicitly.
1420  virtual void OnNodeInitialization() {}
1421  // Returns true if two nodes are on the same path in the current assignment.
1422  bool OnSamePath(int64 node1, int64 node2) const;
1423 
1424  bool CheckEnds() const {
1425  const int base_node_size = base_nodes_.size();
1426  for (int i = base_node_size - 1; i >= 0; --i) {
1427  if (base_nodes_[i] != end_nodes_[i]) {
1428  return true;
1429  }
1430  }
1431  return false;
1432  }
1433  bool IncrementPosition();
1434  void InitializePathStarts();
1435  void InitializeInactives();
1436  void InitializeBaseNodes();
1437  bool CheckChainValidity(int64 before_chain, int64 chain_end,
1438  int64 exclude) const;
1439  void Synchronize();
1440 
1441  std::vector<int> base_nodes_;
1442  std::vector<int> end_nodes_;
1443  std::vector<int> base_paths_;
1444  std::vector<int64> path_starts_;
1445  std::vector<bool> inactives_;
1446  bool just_started_;
1447  bool first_start_;
1448  std::function<int(int64)> start_empty_path_class_;
1449  bool skip_locally_optimal_paths_;
1450  bool optimal_paths_enabled_;
1451  std::vector<int> path_basis_;
1452  std::vector<bool> optimal_paths_;
1453 };
1454 
1455 // Simple PathOperator wrapper that also stores the current previous nodes,
1456 // and is thus able to provide the "Prev" and "IsPathStart" functions.
1458  public:
1460  const std::vector<IntVar*>& vars,
1461  const std::vector<IntVar*>& secondary_vars, int number_of_base_nodes,
1462  std::function<int(int64)> start_empty_path_class);
1464 
1465  bool IsPathStart(int64 node_index) const { return prevs_[node_index] == -1; }
1466 
1467  int64 Prev(int64 node_index) const {
1468  DCHECK(!IsPathStart(node_index));
1469  return prevs_[node_index];
1470  }
1471 
1472  std::string DebugString() const override {
1473  return "PathWithPreviousNodesOperator";
1474  }
1475 
1476  protected:
1477  void OnNodeInitialization() override; // Initializes the "prevs_" array.
1478 
1479  private:
1480  std::vector<int64> prevs_;
1481 };
1482 
1483 // ----- Operator Factories ------
1484 
1485 template <class T>
1486 LocalSearchOperator* MakeLocalSearchOperator(
1487  Solver* solver, const std::vector<IntVar*>& vars,
1488  const std::vector<IntVar*>& secondary_vars,
1489  std::function<int(int64)> start_empty_path_class);
1490 
1491 // Classes to which this template function can be applied to as of 04/2014.
1492 // Usage: LocalSearchOperator* op = MakeLocalSearchOperator<Relocate>(...);
1493 class TwoOpt;
1494 class Relocate;
1495 class Exchange;
1496 class Cross;
1497 class MakeActiveOperator;
1498 class MakeInactiveOperator;
1499 class MakeChainInactiveOperator;
1500 class SwapActiveOperator;
1501 class ExtendedSwapActiveOperator;
1502 class MakeActiveAndRelocate;
1503 class RelocateAndMakeActiveOperator;
1504 class RelocateAndMakeInactiveOperator;
1505 
1506 // ----- Local Search Filters ------
1507 
1508 // For fast neighbor pruning
1510  public:
1511  // Accepts a "delta" given the assignment with which the filter has been
1512  // synchronized; the delta holds the variables which have been modified and
1513  // their new value.
1514  // Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1,
1515  // for the assignment (a,1), (b,0), the delta (b,1) will be rejected
1516  // but the delta (a,0) will be accepted.
1517  virtual bool Accept(Assignment* delta, Assignment* deltadelta) = 0;
1518 
1519  // Synchronizes the filter with the current solution, delta being the
1520  // difference with the solution passed to the previous call to Synchronize()
1521  // or IncrementalSynchronize(). 'delta' can be used to incrementally
1522  // synchronizing the filter with the new solution by only considering the
1523  // changes in delta.
1524  virtual void Synchronize(const Assignment* assignment,
1525  const Assignment* delta) = 0;
1526  virtual bool IsIncremental() const { return false; }
1527 
1528  // DO NOT USE. Objective value from last time Synchronize() was called.
1529  virtual int64 GetSynchronizedObjectiveValue() const { return 0LL; }
1530  // DO NOT USE. Objective value from the last time Accept() was called and
1531  // returned true. If the last Accept() call returned false, returns an
1532  // undefined value.
1533  virtual int64 GetAcceptedObjectiveValue() const { return 0LL; }
1534 };
1535 
1536 #if !defined(SWIG)
1537 // Filter manager: when a move is made, filters are executed to decide whether
1538 // the solution is feasible and compute parts of the new cost. This class
1539 // schedules filter execution and composes costs as a sum.
1541  public:
1543  const std::vector<LocalSearchFilter*>& filters,
1544  IntVar* objective);
1545  std::string DebugString() const override {
1546  return "LocalSearchFilterManager";
1547  }
1548  // Returns true iff all filters return true, and the sum of their accepted
1549  // objectives is smaller or equal to the target objective. This target
1550  // objective is:
1551  // (objective_ == nullptr) ?
1552  // kint64max :
1553  // ((objective_ != delta->Objective()) ?
1554  // objective_.Max() :
1555  // min(objective_.Max(), delta->ObjectiveMax()))
1556  bool Accept(Assignment* delta, Assignment* deltadelta) override;
1557  // Synchronizes all filters to assignment.
1558  void Synchronize(const Assignment* assignment,
1559  const Assignment* delta) override;
1560  bool IsIncremental() const override { return is_incremental_; }
1561  int64 GetSynchronizedObjectiveValue() const override {
1562  return synchronized_value_;
1563  }
1564  int64 GetAcceptedObjectiveValue() const override { return accepted_value_; }
1565 
1566  private:
1567  Solver* const solver_;
1568  std::vector<LocalSearchFilter*> filters_;
1569  IntVar* const objective_;
1570  bool is_incremental_;
1571  int64 synchronized_value_;
1572  int64 accepted_value_;
1573 };
1574 #endif
1575 
1576 // ----- IntVarLocalSearchFilter -----
1577 
1579  public:
1580  IntVarLocalSearchFilter(const std::vector<IntVar*>& vars,
1581  Solver::ObjectiveWatcher objective_callback);
1582  explicit IntVarLocalSearchFilter(const std::vector<IntVar*>& vars);
1583  ~IntVarLocalSearchFilter() override;
1584  // This method should not be overridden. Override OnSynchronize() instead
1585  // which is called before exiting this method.
1586  void Synchronize(const Assignment* assignment,
1587  const Assignment* delta) override;
1588 
1589  bool FindIndex(IntVar* const var, int64* index) const {
1590  DCHECK(index != nullptr);
1591  const int var_index = var->index();
1592  *index = (var_index < var_index_to_index_.size())
1593  ? var_index_to_index_[var_index]
1594  : kUnassigned;
1595  return *index != kUnassigned;
1596  }
1597 
1598  virtual void InjectObjectiveValue(int64 objective_value) {
1599  injected_objective_value_ = objective_value;
1600  }
1601 
1602  // Add variables to "track" to the filter.
1603  void AddVars(const std::vector<IntVar*>& vars);
1604  int Size() const { return vars_.size(); }
1605  IntVar* Var(int index) const { return vars_[index]; }
1606  int64 Value(int index) const {
1607  DCHECK(IsVarSynced(index));
1608  return values_[index];
1609  }
1610  bool IsVarSynced(int index) const { return var_synced_[index]; }
1611 
1612  protected:
1613  virtual void OnSynchronize(const Assignment* delta) {}
1614  void SynchronizeOnAssignment(const Assignment* assignment);
1615 
1617  return objective_callback_ != nullptr;
1618  }
1619  void PropagateObjectiveValue(int64 objective_value) {
1620  if (objective_callback_ != nullptr) {
1621  objective_callback_(objective_value);
1622  }
1623  }
1625 
1626  private:
1627  std::vector<IntVar*> vars_;
1628  std::vector<int64> values_;
1629  std::vector<bool> var_synced_;
1630  std::vector<int> var_index_to_index_;
1631  static const int kUnassigned;
1632  Solver::ObjectiveWatcher objective_callback_;
1633 };
1634 
1635 // ---------- PropagationMonitor ----------
1636 
1638  public:
1639  explicit PropagationMonitor(Solver* const solver);
1640  ~PropagationMonitor() override;
1641  std::string DebugString() const override { return "PropagationMonitor"; }
1642 
1643  // Propagation events.
1644  virtual void BeginConstraintInitialPropagation(
1645  Constraint* const constraint) = 0;
1646  virtual void EndConstraintInitialPropagation(
1647  Constraint* const constraint) = 0;
1649  Constraint* const parent, Constraint* const nested) = 0;
1651  Constraint* const parent, Constraint* const nested) = 0;
1652  virtual void RegisterDemon(Demon* const demon) = 0;
1653  virtual void BeginDemonRun(Demon* const demon) = 0;
1654  virtual void EndDemonRun(Demon* const demon) = 0;
1655  virtual void StartProcessingIntegerVariable(IntVar* const var) = 0;
1656  virtual void EndProcessingIntegerVariable(IntVar* const var) = 0;
1657  virtual void PushContext(const std::string& context) = 0;
1658  virtual void PopContext() = 0;
1659  // IntExpr modifiers.
1660  virtual void SetMin(IntExpr* const expr, int64 new_min) = 0;
1661  virtual void SetMax(IntExpr* const expr, int64 new_max) = 0;
1662  virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0;
1663  // IntVar modifiers.
1664  virtual void SetMin(IntVar* const var, int64 new_min) = 0;
1665  virtual void SetMax(IntVar* const var, int64 new_max) = 0;
1666  virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0;
1667  virtual void RemoveValue(IntVar* const var, int64 value) = 0;
1668  virtual void SetValue(IntVar* const var, int64 value) = 0;
1669  virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0;
1670  virtual void SetValues(IntVar* const var,
1671  const std::vector<int64>& values) = 0;
1672  virtual void RemoveValues(IntVar* const var,
1673  const std::vector<int64>& values) = 0;
1674  // IntervalVar modifiers.
1675  virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0;
1676  virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0;
1677  virtual void SetStartRange(IntervalVar* const var, int64 new_min,
1678  int64 new_max) = 0;
1679  virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0;
1680  virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0;
1681  virtual void SetEndRange(IntervalVar* const var, int64 new_min,
1682  int64 new_max) = 0;
1683  virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0;
1684  virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0;
1685  virtual void SetDurationRange(IntervalVar* const var, int64 new_min,
1686  int64 new_max) = 0;
1687  virtual void SetPerformed(IntervalVar* const var, bool value) = 0;
1688  // SequenceVar modifiers
1689  virtual void RankFirst(SequenceVar* const var, int index) = 0;
1690  virtual void RankNotFirst(SequenceVar* const var, int index) = 0;
1691  virtual void RankLast(SequenceVar* const var, int index) = 0;
1692  virtual void RankNotLast(SequenceVar* const var, int index) = 0;
1693  virtual void RankSequence(SequenceVar* const var,
1694  const std::vector<int>& rank_first,
1695  const std::vector<int>& rank_last,
1696  const std::vector<int>& unperformed) = 0;
1697  // Install itself on the solver.
1698  void Install() override;
1699 };
1700 
1701 // ---------- LocalSearchMonitor ----------
1702 
1704  // TODO(user): Add monitoring of local search filters.
1705  public:
1706  explicit LocalSearchMonitor(Solver* const solver);
1707  ~LocalSearchMonitor() override;
1708  std::string DebugString() const override { return "LocalSearchMonitor"; }
1709 
1710  // Local search operator events.
1711  virtual void BeginOperatorStart() = 0;
1712  virtual void EndOperatorStart() = 0;
1713  virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0;
1714  virtual void EndMakeNextNeighbor(const LocalSearchOperator* op,
1715  bool neighbor_found, const Assignment* delta,
1716  const Assignment* deltadelta) = 0;
1717  virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0;
1718  virtual void EndFilterNeighbor(const LocalSearchOperator* op,
1719  bool neighbor_found) = 0;
1720  virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0;
1721  virtual void EndAcceptNeighbor(const LocalSearchOperator* op,
1722  bool neighbor_found) = 0;
1723  virtual void BeginFiltering(const LocalSearchFilter* filter) = 0;
1724  virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0;
1725 
1726  // Install itself on the solver.
1727  void Install() override;
1728 };
1729 
1730 // ----- Boolean Variable -----
1731 
1732 class BooleanVar : public IntVar {
1733  public:
1734  static const int kUnboundBooleanVarValue;
1735 
1736  explicit BooleanVar(Solver* const s, const std::string& name = "")
1738 
1739  ~BooleanVar() override {}
1740 
1741  int64 Min() const override { return (value_ == 1); }
1742  void SetMin(int64 m) override;
1743  int64 Max() const override { return (value_ != 0); }
1744  void SetMax(int64 m) override;
1745  void SetRange(int64 mi, int64 ma) override;
1746  bool Bound() const override { return (value_ != kUnboundBooleanVarValue); }
1747  int64 Value() const override {
1748  CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound";
1749  return value_;
1750  }
1751  void RemoveValue(int64 v) override;
1752  void RemoveInterval(int64 l, int64 u) override;
1753  void WhenBound(Demon* d) override;
1754  void WhenRange(Demon* d) override { WhenBound(d); }
1755  void WhenDomain(Demon* d) override { WhenBound(d); }
1756  uint64 Size() const override;
1757  bool Contains(int64 v) const override;
1758  IntVarIterator* MakeHoleIterator(bool reversible) const override;
1759  IntVarIterator* MakeDomainIterator(bool reversible) const override;
1760  std::string DebugString() const override;
1761  int VarType() const override { return BOOLEAN_VAR; }
1762 
1763  IntVar* IsEqual(int64 constant) override;
1764  IntVar* IsDifferent(int64 constant) override;
1765  IntVar* IsGreaterOrEqual(int64 constant) override;
1766  IntVar* IsLessOrEqual(int64 constant) override;
1767 
1768  virtual void RestoreValue() = 0;
1769  std::string BaseName() const override { return "BooleanVar"; }
1770 
1771  int RawValue() const { return value_; }
1772 
1773  protected:
1774  int value_;
1777 };
1778 
1779 // ---------- SymmetryBreaker ----------
1780 
1781 class SymmetryManager;
1782 
1783 // A symmetry breaker is an object that will visit a decision and
1784 // create the 'symmetrical' decision in return.
1785 // Each symmetry breaker represents one class of symmetry.
1787  public:
1789  : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
1790  ~SymmetryBreaker() override {}
1791 
1792  void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value);
1794  int64 value);
1795  void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value);
1796 
1797  private:
1798  friend class SymmetryManager;
1799  void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
1800  CHECK(symmetry_manager_ == nullptr);
1801  CHECK_EQ(-1, index_in_symmetry_manager_);
1802  symmetry_manager_ = manager;
1803  index_in_symmetry_manager_ = index;
1804  }
1805  SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
1806  int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
1807 
1808  SymmetryManager* symmetry_manager_;
1809  // Index of the symmetry breaker when used inside the symmetry manager.
1810  int index_in_symmetry_manager_;
1811 };
1812 
1813 // ---------- Search Log ---------
1814 
1815 // The base class of all search logs that periodically outputs information when
1816 // the search is running.
1817 class SearchLog : public SearchMonitor {
1818  public:
1819  SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var,
1820  double scaling_factor,
1821  std::function<std::string()> display_callback, int period);
1822  ~SearchLog() override;
1823  void EnterSearch() override;
1824  void ExitSearch() override;
1825  bool AtSolution() override;
1826  void BeginFail() override;
1827  void NoMoreSolutions() override;
1828  void AcceptUncheckedNeighbor() override;
1829  void ApplyDecision(Decision* const decision) override;
1830  void RefuteDecision(Decision* const decision) override;
1831  void OutputDecision();
1832  void Maintain();
1833  void BeginInitialPropagation() override;
1834  void EndInitialPropagation() override;
1835  std::string DebugString() const override;
1836 
1837  protected:
1838  /* Bottleneck function used for all UI related output. */
1839  virtual void OutputLine(const std::string& line);
1840 
1841  private:
1842  static std::string MemoryUsage();
1843 
1844  const int period_;
1845  std::unique_ptr<WallTimer> timer_;
1846  IntVar* const var_;
1847  OptimizeVar* const obj_;
1848  const double scaling_factor_;
1849  std::function<std::string()> display_callback_;
1850  int nsol_;
1851  int64 tick_;
1852  int64 objective_min_;
1853  int64 objective_max_;
1854  int min_right_depth_;
1855  int max_depth_;
1856  int sliding_min_depth_;
1857  int sliding_max_depth_;
1858 };
1859 
1860 // Implements a complete cache for model elements: expressions and
1861 // constraints. Caching is based on the signatures of the elements, as
1862 // well as their types. This class is used internally to avoid creating
1863 // duplicate objects.
1864 class ModelCache {
1865  public:
1870  };
1871 
1878  };
1879 
1883  };
1884 
1893  };
1894 
1900  };
1901 
1914  };
1915 
1919  };
1920 
1933  };
1937  };
1938 
1942  };
1943 
1947  };
1948 
1954  };
1955 
1959  };
1960 
1961  explicit ModelCache(Solver* const solver);
1962  virtual ~ModelCache();
1963 
1964  virtual void Clear() = 0;
1965 
1966  // Void constraints.
1967 
1968  virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0;
1969 
1970  virtual void InsertVoidConstraint(Constraint* const ct,
1971  VoidConstraintType type) = 0;
1972 
1973  // Var Constant Constraints.
1975  IntVar* const var, int64 value, VarConstantConstraintType type) const = 0;
1976 
1977  virtual void InsertVarConstantConstraint(Constraint* const ct,
1978  IntVar* const var, int64 value,
1979  VarConstantConstraintType type) = 0;
1980 
1981  // Var Constant Constant Constraints.
1982 
1984  IntVar* const var, int64 value1, int64 value2,
1985  VarConstantConstantConstraintType type) const = 0;
1986 
1988  Constraint* const ct, IntVar* const var, int64 value1, int64 value2,
1990 
1991  // Expr Expr Constraints.
1992 
1994  IntExpr* const expr1, IntExpr* const expr2,
1995  ExprExprConstraintType type) const = 0;
1996 
1997  virtual void InsertExprExprConstraint(Constraint* const ct,
1998  IntExpr* const expr1,
1999  IntExpr* const expr2,
2000  ExprExprConstraintType type) = 0;
2001 
2002  // Expr Expressions.
2003 
2004  virtual IntExpr* FindExprExpression(IntExpr* const expr,
2005  ExprExpressionType type) const = 0;
2006 
2007  virtual void InsertExprExpression(IntExpr* const expression,
2008  IntExpr* const expr,
2009  ExprExpressionType type) = 0;
2010 
2011  // Expr Constant Expressions.
2012 
2014  IntExpr* const expr, int64 value,
2015  ExprConstantExpressionType type) const = 0;
2016 
2017  virtual void InsertExprConstantExpression(
2018  IntExpr* const expression, IntExpr* const var, int64 value,
2019  ExprConstantExpressionType type) = 0;
2020 
2021  // Expr Expr Expressions.
2022 
2024  IntExpr* const var1, IntExpr* const var2,
2025  ExprExprExpressionType type) const = 0;
2026 
2027  virtual void InsertExprExprExpression(IntExpr* const expression,
2028  IntExpr* const var1,
2029  IntExpr* const var2,
2030  ExprExprExpressionType type) = 0;
2031 
2032  // Expr Expr Constant Expressions.
2033 
2035  IntExpr* const var1, IntExpr* const var2, int64 constant,
2036  ExprExprConstantExpressionType type) const = 0;
2037 
2038  virtual void InsertExprExprConstantExpression(
2039  IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
2040  int64 constant, ExprExprConstantExpressionType type) = 0;
2041 
2042  // Var Constant Constant Expressions.
2043 
2045  IntVar* const var, int64 value1, int64 value2,
2046  VarConstantConstantExpressionType type) const = 0;
2047 
2049  IntExpr* const expression, IntVar* const var, int64 value1, int64 value2,
2051 
2052  // Var Constant Array Expressions.
2053 
2055  IntVar* const var, const std::vector<int64>& values,
2056  VarConstantArrayExpressionType type) const = 0;
2057 
2058  virtual void InsertVarConstantArrayExpression(
2059  IntExpr* const expression, IntVar* const var,
2060  const std::vector<int64>& values,
2062 
2063  // Var Array Expressions.
2064 
2066  const std::vector<IntVar*>& vars, VarArrayExpressionType type) const = 0;
2067 
2068  virtual void InsertVarArrayExpression(IntExpr* const expression,
2069  const std::vector<IntVar*>& vars,
2070  VarArrayExpressionType type) = 0;
2071 
2072  // Var Array Constant Array Expressions.
2073 
2075  const std::vector<IntVar*>& vars, const std::vector<int64>& values,
2076  VarArrayConstantArrayExpressionType type) const = 0;
2077 
2079  IntExpr* const expression, const std::vector<IntVar*>& var,
2080  const std::vector<int64>& values,
2082 
2083  // Var Array Constant Expressions.
2084 
2086  const std::vector<IntVar*>& vars, int64 value,
2087  VarArrayConstantExpressionType type) const = 0;
2088 
2089  virtual void InsertVarArrayConstantExpression(
2090  IntExpr* const expression, const std::vector<IntVar*>& var, int64 value,
2092 
2093  Solver* solver() const;
2094 
2095  private:
2096  Solver* const solver_;
2097 };
2098 
2099 // Argument Holder: useful when visiting a model.
2100 #if !defined(SWIG)
2102  public:
2103  // Type of the argument.
2104  const std::string& TypeName() const;
2105  void SetTypeName(const std::string& type_name);
2106 
2107  // Setters.
2108  void SetIntegerArgument(const std::string& arg_name, int64 value);
2109  void SetIntegerArrayArgument(const std::string& arg_name,
2110  const std::vector<int64>& values);
2111  void SetIntegerMatrixArgument(const std::string& arg_name,
2112  const IntTupleSet& values);
2113  void SetIntegerExpressionArgument(const std::string& arg_name,
2114  IntExpr* const expr);
2115  void SetIntegerVariableArrayArgument(const std::string& arg_name,
2116  const std::vector<IntVar*>& vars);
2117  void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var);
2118  void SetIntervalArrayArgument(const std::string& arg_name,
2119  const std::vector<IntervalVar*>& vars);
2120  void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var);
2121  void SetSequenceArrayArgument(const std::string& arg_name,
2122  const std::vector<SequenceVar*>& vars);
2123 
2124  // Checks if arguments exist.
2125  bool HasIntegerExpressionArgument(const std::string& arg_name) const;
2126  bool HasIntegerVariableArrayArgument(const std::string& arg_name) const;
2127 
2128  // Getters.
2129  int64 FindIntegerArgumentWithDefault(const std::string& arg_name,
2130  int64 def) const;
2131  int64 FindIntegerArgumentOrDie(const std::string& arg_name) const;
2132  const std::vector<int64>& FindIntegerArrayArgumentOrDie(
2133  const std::string& arg_name) const;
2134  const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2135  const std::string& arg_name) const;
2136 
2138  const std::string& arg_name) const;
2139  const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2140  const std::string& arg_name) const;
2141 
2142  private:
2143  std::string type_name_;
2144  absl::flat_hash_map<std::string, int64> integer_argument_;
2145  absl::flat_hash_map<std::string, std::vector<int64> > integer_array_argument_;
2146  absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2147  absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2148  absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2149  absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2150  absl::flat_hash_map<std::string, std::vector<IntVar*> >
2151  integer_variable_array_argument_;
2152  absl::flat_hash_map<std::string, std::vector<IntervalVar*> >
2153  interval_array_argument_;
2154  absl::flat_hash_map<std::string, std::vector<SequenceVar*> >
2155  sequence_array_argument_;
2156 };
2157 
2158 // Model Parser
2159 
2160 class ModelParser : public ModelVisitor {
2161  public:
2162  ModelParser();
2163 
2164  ~ModelParser() override;
2165 
2166  // Header/footers.
2167  void BeginVisitModel(const std::string& solver_name) override;
2168  void EndVisitModel(const std::string& solver_name) override;
2169  void BeginVisitConstraint(const std::string& type_name,
2170  const Constraint* const constraint) override;
2171  void EndVisitConstraint(const std::string& type_name,
2172  const Constraint* const constraint) override;
2173  void BeginVisitIntegerExpression(const std::string& type_name,
2174  const IntExpr* const expr) override;
2175  void EndVisitIntegerExpression(const std::string& type_name,
2176  const IntExpr* const expr) override;
2177  void VisitIntegerVariable(const IntVar* const variable,
2178  IntExpr* const delegate) override;
2179  void VisitIntegerVariable(const IntVar* const variable,
2180  const std::string& operation, int64 value,
2181  IntVar* const delegate) override;
2182  void VisitIntervalVariable(const IntervalVar* const variable,
2183  const std::string& operation, int64 value,
2184  IntervalVar* const delegate) override;
2185  void VisitSequenceVariable(const SequenceVar* const variable) override;
2186  // Integer arguments
2187  void VisitIntegerArgument(const std::string& arg_name, int64 value) override;
2188  void VisitIntegerArrayArgument(const std::string& arg_name,
2189  const std::vector<int64>& values) override;
2190  void VisitIntegerMatrixArgument(const std::string& arg_name,
2191  const IntTupleSet& values) override;
2192  // Variables.
2193  void VisitIntegerExpressionArgument(const std::string& arg_name,
2194  IntExpr* const argument) override;
2196  const std::string& arg_name,
2197  const std::vector<IntVar*>& arguments) override;
2198  // Visit interval argument.
2199  void VisitIntervalArgument(const std::string& arg_name,
2200  IntervalVar* const argument) override;
2202  const std::string& arg_name,
2203  const std::vector<IntervalVar*>& arguments) override;
2204  // Visit sequence argument.
2205  void VisitSequenceArgument(const std::string& arg_name,
2206  SequenceVar* const argument) override;
2208  const std::string& arg_name,
2209  const std::vector<SequenceVar*>& arguments) override;
2210 
2211  protected:
2212  void PushArgumentHolder();
2213  void PopArgumentHolder();
2214  ArgumentHolder* Top() const;
2215 
2216  private:
2217  std::vector<ArgumentHolder*> holders_;
2218 };
2219 
2220 // ----- Utility Class for Callbacks -----
2221 
2222 template <class T>
2223 class ArrayWithOffset : public BaseObject {
2224  public:
2225  ArrayWithOffset(int64 index_min, int64 index_max)
2226  : index_min_(index_min),
2227  index_max_(index_max),
2228  values_(new T[index_max - index_min + 1]) {
2229  DCHECK_LE(index_min, index_max);
2230  }
2231 
2232  ~ArrayWithOffset() override {}
2233 
2234  virtual T Evaluate(int64 index) const {
2235  DCHECK_GE(index, index_min_);
2236  DCHECK_LE(index, index_max_);
2237  return values_[index - index_min_];
2238  }
2239 
2240  void SetValue(int64 index, T value) {
2241  DCHECK_GE(index, index_min_);
2242  DCHECK_LE(index, index_max_);
2243  values_[index - index_min_] = value;
2244  }
2245 
2246  std::string DebugString() const override { return "ArrayWithOffset"; }
2247 
2248  private:
2249  const int64 index_min_;
2250  const int64 index_max_;
2251  std::unique_ptr<T[]> values_;
2252 };
2253 #endif // SWIG
2254 
2255 // This class is a reversible growing array. In can grow in both
2256 // directions, and even accept negative indices. The objects stored
2257 // have a type T. As it relies on the solver for reversibility, these
2258 // objects can be up-casted to 'C' when using Solver::SaveValue().
2259 template <class T, class C>
2261  public:
2262  explicit RevGrowingArray(int64 block_size)
2263  : block_size_(block_size), block_offset_(0) {
2264  CHECK_GT(block_size, 0);
2265  }
2266 
2268  for (int i = 0; i < elements_.size(); ++i) {
2269  delete[] elements_[i];
2270  }
2271  }
2272 
2273  T At(int64 index) const {
2274  const int64 block_index = ComputeBlockIndex(index);
2275  const int64 relative_index = block_index - block_offset_;
2276  if (relative_index < 0 || relative_index >= elements_.size()) {
2277  return T();
2278  }
2279  const T* block = elements_[relative_index];
2280  return block != nullptr ? block[index - block_index * block_size_] : T();
2281  }
2282 
2283  void RevInsert(Solver* const solver, int64 index, T value) {
2284  const int64 block_index = ComputeBlockIndex(index);
2285  T* const block = GetOrCreateBlock(block_index);
2286  const int64 residual = index - block_index * block_size_;
2287  solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
2288  reinterpret_cast<C>(value));
2289  }
2290 
2291  private:
2292  T* NewBlock() const {
2293  T* const result = new T[block_size_];
2294  for (int i = 0; i < block_size_; ++i) {
2295  result[i] = T();
2296  }
2297  return result;
2298  }
2299 
2300  T* GetOrCreateBlock(int block_index) {
2301  if (elements_.size() == 0) {
2302  block_offset_ = block_index;
2303  GrowUp(block_index);
2304  } else if (block_index < block_offset_) {
2305  GrowDown(block_index);
2306  } else if (block_index - block_offset_ >= elements_.size()) {
2307  GrowUp(block_index);
2308  }
2309  T* block = elements_[block_index - block_offset_];
2310  if (block == nullptr) {
2311  block = NewBlock();
2312  elements_[block_index - block_offset_] = block;
2313  }
2314  return block;
2315  }
2316 
2317  int64 ComputeBlockIndex(int64 value) const {
2318  return value >= 0 ? value / block_size_
2319  : (value - block_size_ + 1) / block_size_;
2320  }
2321 
2322  void GrowUp(int64 block_index) {
2323  elements_.resize(block_index - block_offset_ + 1);
2324  }
2325 
2326  void GrowDown(int64 block_index) {
2327  const int64 delta = block_offset_ - block_index;
2328  block_offset_ = block_index;
2329  DCHECK_GT(delta, 0);
2330  elements_.insert(elements_.begin(), delta, nullptr);
2331  }
2332 
2333  const int64 block_size_;
2334  std::vector<T*> elements_;
2335  int block_offset_;
2336 };
2337 
2338 // ----- RevIntSet -----
2339 
2340 // This is a special class to represent a 'residual' set of T. T must
2341 // be an integer type. You fill it at first, and then during search,
2342 // you can efficiently remove an element, and query the removed
2343 // elements.
2344 template <class T>
2345 class RevIntSet {
2346  public:
2347  static const int kNoInserted = -1;
2348 
2349  // Capacity is the fixed size of the set (it cannot grow).
2350  explicit RevIntSet(int capacity)
2351  : elements_(new T[capacity]),
2352  num_elements_(0),
2353  capacity_(capacity),
2354  position_(new int[capacity]),
2355  delete_position_(true) {
2356  for (int i = 0; i < capacity; ++i) {
2357  position_[i] = kNoInserted;
2358  }
2359  }
2360 
2361  // Capacity is the fixed size of the set (it cannot grow).
2362  RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
2363  : elements_(new T[capacity]),
2364  num_elements_(0),
2365  capacity_(capacity),
2366  position_(shared_positions),
2367  delete_position_(false) {
2368  for (int i = 0; i < shared_positions_size; ++i) {
2369  position_[i] = kNoInserted;
2370  }
2371  }
2372 
2374  if (delete_position_) {
2375  delete[] position_;
2376  }
2377  }
2378 
2379  int Size() const { return num_elements_.Value(); }
2380 
2381  int Capacity() const { return capacity_; }
2382 
2383  T Element(int i) const {
2384  DCHECK_GE(i, 0);
2385  DCHECK_LT(i, num_elements_.Value());
2386  return elements_[i];
2387  }
2388 
2389  T RemovedElement(int i) const {
2390  DCHECK_GE(i, 0);
2391  DCHECK_LT(i + num_elements_.Value(), capacity_);
2392  return elements_[i + num_elements_.Value()];
2393  }
2394 
2395  void Insert(Solver* const solver, const T& elt) {
2396  const int position = num_elements_.Value();
2397  DCHECK_LT(position, capacity_); // Valid.
2398  DCHECK(NotAlreadyInserted(elt));
2399  elements_[position] = elt;
2400  position_[elt] = position;
2401  num_elements_.Incr(solver);
2402  }
2403 
2404  void Remove(Solver* const solver, const T& value_index) {
2405  num_elements_.Decr(solver);
2406  SwapTo(value_index, num_elements_.Value());
2407  }
2408 
2409  void Restore(Solver* const solver, const T& value_index) {
2410  SwapTo(value_index, num_elements_.Value());
2411  num_elements_.Incr(solver);
2412  }
2413 
2414  void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
2415 
2416  // Iterators on the indices.
2417  typedef const T* const_iterator;
2418  const_iterator begin() const { return elements_.get(); }
2419  const_iterator end() const { return elements_.get() + num_elements_.Value(); }
2420 
2421  private:
2422  // Used in DCHECK.
2423  bool NotAlreadyInserted(const T& elt) {
2424  for (int i = 0; i < num_elements_.Value(); ++i) {
2425  if (elt == elements_[i]) {
2426  return false;
2427  }
2428  }
2429  return true;
2430  }
2431 
2432  void SwapTo(T value_index, int next_position) {
2433  const int current_position = position_[value_index];
2434  if (current_position != next_position) {
2435  const T next_value_index = elements_[next_position];
2436  elements_[current_position] = next_value_index;
2437  elements_[next_position] = value_index;
2438  position_[value_index] = next_position;
2439  position_[next_value_index] = current_position;
2440  }
2441  }
2442 
2443  // Set of elements.
2444  std::unique_ptr<T[]> elements_;
2445  // Number of elements in the set.
2446  NumericalRev<int> num_elements_;
2447  // Number of elements in the set.
2448  const int capacity_;
2449  // Reverse mapping.
2450  int* position_;
2451  // Does the set owns the position array.
2452  const bool delete_position_;
2453 };
2454 
2455 // ----- RevPartialSequence -----
2456 
2458  public:
2459  explicit RevPartialSequence(const std::vector<int>& items)
2460  : elements_(items),
2461  first_ranked_(0),
2462  last_ranked_(items.size() - 1),
2463  size_(items.size()),
2464  position_(new int[size_]) {
2465  for (int i = 0; i < size_; ++i) {
2466  elements_[i] = items[i];
2467  position_[i] = i;
2468  }
2469  }
2470 
2471  explicit RevPartialSequence(int size)
2472  : elements_(size),
2473  first_ranked_(0),
2474  last_ranked_(size - 1),
2475  size_(size),
2476  position_(new int[size_]) {
2477  for (int i = 0; i < size_; ++i) {
2478  elements_[i] = i;
2479  position_[i] = i;
2480  }
2481  }
2482 
2484 
2485  int NumFirstRanked() const { return first_ranked_.Value(); }
2486 
2487  int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
2488 
2489  int Size() const { return size_; }
2490 
2491 #if !defined(SWIG)
2492  const int& operator[](int index) const {
2493  DCHECK_GE(index, 0);
2494  DCHECK_LT(index, size_);
2495  return elements_[index];
2496  }
2497 #endif
2498 
2499  void RankFirst(Solver* const solver, int elt) {
2500  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2501  SwapTo(elt, first_ranked_.Value());
2502  first_ranked_.Incr(solver);
2503  }
2504 
2505  void RankLast(Solver* const solver, int elt) {
2506  DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
2507  SwapTo(elt, last_ranked_.Value());
2508  last_ranked_.Decr(solver);
2509  }
2510 
2511  bool IsRanked(int elt) const {
2512  const int position = position_[elt];
2513  return (position < first_ranked_.Value() ||
2514  position > last_ranked_.Value());
2515  }
2516 
2517  std::string DebugString() const {
2518  std::string result = "[";
2519  for (int i = 0; i < first_ranked_.Value(); ++i) {
2520  absl::StrAppend(&result, elements_[i]);
2521  if (i != first_ranked_.Value() - 1) {
2522  result.append("-");
2523  }
2524  }
2525  result.append("|");
2526  for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
2527  absl::StrAppend(&result, elements_[i]);
2528  if (i != last_ranked_.Value()) {
2529  result.append("-");
2530  }
2531  }
2532  result.append("|");
2533  for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
2534  absl::StrAppend(&result, elements_[i]);
2535  if (i != size_ - 1) {
2536  result.append("-");
2537  }
2538  }
2539  result.append("]");
2540  return result;
2541  }
2542 
2543  private:
2544  void SwapTo(int elt, int next_position) {
2545  const int current_position = position_[elt];
2546  if (current_position != next_position) {
2547  const int next_elt = elements_[next_position];
2548  elements_[current_position] = next_elt;
2549  elements_[next_position] = elt;
2550  position_[elt] = next_position;
2551  position_[next_elt] = current_position;
2552  }
2553  }
2554 
2555  // Set of elements.
2556  std::vector<int> elements_;
2557  // Position of the element after the last element ranked from the start.
2558  NumericalRev<int> first_ranked_;
2559  // Position of the element before the last element ranked from the end.
2560  NumericalRev<int> last_ranked_;
2561  // Number of elements in the sequence.
2562  const int size_;
2563  // Reverse mapping.
2564  std::unique_ptr<int[]> position_;
2565 };
2566 
2567 // This class represents a reversible bitset. It is meant to represent a set of
2568 // active bits. It does not offer direct access, but just methods that can
2569 // reversibly subtract another bitset, or check if the current active bitset
2570 // intersects with another bitset.
2572  public:
2573  // Size is the number of bits to store in the bitset.
2574  explicit UnsortedNullableRevBitset(int bit_size);
2575 
2577 
2578  // This methods overwrites the active bitset with the mask. This method should
2579  // be called only once.
2580  void Init(Solver* const solver, const std::vector<uint64>& mask);
2581 
2582  // This method subtracts the mask from the active bitset. It returns true if
2583  // the active bitset was changed in the process.
2584  bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
2585 
2586  // This method ANDs the mask with the active bitset. It returns true if
2587  // the active bitset was changed in the process.
2588  bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
2589 
2590  // This method returns the number of non null 64 bit words in the bitset
2591  // representation.
2592  int ActiveWordSize() const { return active_words_.Size(); }
2593 
2594  // This method returns true if the active bitset is null.
2595  bool Empty() const { return active_words_.Size() == 0; }
2596 
2597  // This method returns true iff the mask and the active bitset have a non
2598  // null intersection. support_index is used as an accelerator:
2599  // - The first word tested to check the intersection will be the
2600  // '*support_index'th one.
2601  // - If the intersection is not null, the support_index will be filled with
2602  // the index of the word that does intersect with the mask. This can be
2603  // reused later to speed-up the check.
2604  bool Intersects(const std::vector<uint64>& mask, int* support_index);
2605 
2606  // Returns the number of bits given in the constructor of the bitset.
2607  int64 bit_size() const { return bit_size_; }
2608  // Returns the number of 64 bit words used to store the bitset.
2609  int64 word_size() const { return word_size_; }
2610  // Returns the set of active word indices.
2611  const RevIntSet<int>& active_words() const { return active_words_; }
2612 
2613  private:
2614  void CleanUpActives(Solver* const solver);
2615 
2616  const int64 bit_size_;
2617  const int64 word_size_;
2618  RevArray<uint64> bits_;
2619  RevIntSet<int> active_words_;
2620  std::vector<int> to_remove_;
2621 };
2622 
2623 // ---------- Helpers ----------
2624 
2625 // ----- On integer vectors -----
2626 
2627 template <class T>
2628 bool IsArrayConstant(const std::vector<T>& values, const T& value) {
2629  for (int i = 0; i < values.size(); ++i) {
2630  if (values[i] != value) {
2631  return false;
2632  }
2633  }
2634  return true;
2635 }
2636 
2637 template <class T>
2638 bool IsArrayBoolean(const std::vector<T>& values) {
2639  for (int i = 0; i < values.size(); ++i) {
2640  if (values[i] != 0 && values[i] != 1) {
2641  return false;
2642  }
2643  }
2644  return true;
2645 }
2646 
2647 template <class T>
2648 bool AreAllOnes(const std::vector<T>& values) {
2649  return IsArrayConstant(values, T(1));
2650 }
2651 
2652 template <class T>
2653 bool AreAllNull(const std::vector<T>& values) {
2654  return IsArrayConstant(values, T(0));
2655 }
2656 
2657 template <class T>
2658 bool AreAllGreaterOrEqual(const std::vector<T>& values, const T& value) {
2659  for (const T& current_value : values) {
2660  if (current_value < value) {
2661  return false;
2662  }
2663  }
2664  return true;
2665 }
2666 
2667 template <class T>
2668 bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
2669  for (const T& current_value : values) {
2670  if (current_value > value) {
2671  return false;
2672  }
2673  }
2674  return true;
2675 }
2676 
2677 template <class T>
2678 bool AreAllPositive(const std::vector<T>& values) {
2679  return AreAllGreaterOrEqual(values, T(0));
2680 }
2681 
2682 template <class T>
2683 bool AreAllNegative(const std::vector<T>& values) {
2684  return AreAllLessOrEqual(values, T(0));
2685 }
2686 
2687 template <class T>
2688 bool AreAllStrictlyPositive(const std::vector<T>& values) {
2689  return AreAllGreaterOrEqual(values, T(1));
2690 }
2691 
2692 template <class T>
2693 bool AreAllStrictlyNegative(const std::vector<T>& values) {
2694  return AreAllLessOrEqual(values, T(-1));
2695 }
2696 
2697 template <class T>
2698 bool IsIncreasingContiguous(const std::vector<T>& values) {
2699  for (int i = 0; i < values.size() - 1; ++i) {
2700  if (values[i + 1] != values[i] + 1) {
2701  return false;
2702  }
2703  }
2704  return true;
2705 }
2706 
2707 template <class T>
2708 bool IsIncreasing(const std::vector<T>& values) {
2709  for (int i = 0; i < values.size() - 1; ++i) {
2710  if (values[i + 1] < values[i]) {
2711  return false;
2712  }
2713  }
2714  return true;
2715 }
2716 
2717 // ----- On integer variable vector -----
2718 
2719 template <class T>
2720 bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
2721  T range_max) {
2722  for (int i = 0; i < vars.size(); ++i) {
2723  if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
2724  return false;
2725  }
2726  }
2727  return true;
2728 }
2729 
2730 inline bool AreAllBound(const std::vector<IntVar*>& vars) {
2731  for (int i = 0; i < vars.size(); ++i) {
2732  if (!vars[i]->Bound()) {
2733  return false;
2734  }
2735  }
2736  return true;
2737 }
2738 
2739 inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
2740  return IsArrayInRange(vars, 0, 1);
2741 }
2742 
2743 // Returns true if all the variables are assigned to a single value,
2744 // or if their corresponding value is null.
2745 template <class T>
2746 bool AreAllBoundOrNull(const std::vector<IntVar*>& vars,
2747  const std::vector<T>& values) {
2748  for (int i = 0; i < vars.size(); ++i) {
2749  if (values[i] != 0 && !vars[i]->Bound()) {
2750  return false;
2751  }
2752  }
2753  return true;
2754 }
2755 
2756 // Returns true if all variables are assigned to 'value'.
2757 inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64 value) {
2758  for (int i = 0; i < vars.size(); ++i) {
2759  if (!vars[i]->Bound() || vars[i]->Min() != value) {
2760  return false;
2761  }
2762  }
2763  return true;
2764 }
2765 
2766 inline int64 MaxVarArray(const std::vector<IntVar*>& vars) {
2767  DCHECK(!vars.empty());
2768  int64 result = kint64min;
2769  for (int i = 0; i < vars.size(); ++i) {
2770  // The std::max<int64> is needed for compilation on MSVC.
2771  result = std::max<int64>(result, vars[i]->Max());
2772  }
2773  return result;
2774 }
2775 
2776 inline int64 MinVarArray(const std::vector<IntVar*>& vars) {
2777  DCHECK(!vars.empty());
2778  int64 result = kint64max;
2779  for (int i = 0; i < vars.size(); ++i) {
2780  // The std::min<int64> is needed for compilation on MSVC.
2781  result = std::min<int64>(result, vars[i]->Min());
2782  }
2783  return result;
2784 }
2785 
2786 inline void FillValues(const std::vector<IntVar*>& vars,
2787  std::vector<int64>* const values) {
2788  values->clear();
2789  values->resize(vars.size());
2790  for (int i = 0; i < vars.size(); ++i) {
2791  (*values)[i] = vars[i]->Value();
2792  }
2793 }
2794 
2795 // ----- Arithmetic operations -----
2796 
2797 inline int64 PosIntDivUp(int64 e, int64 v) {
2798  DCHECK_GT(v, 0);
2799  if (e >= 0) {
2800  return e % v == 0 ? e / v : e / v + 1;
2801  } else {
2802  return e / v;
2803  }
2804 }
2805 
2806 inline int64 PosIntDivDown(int64 e, int64 v) {
2807  DCHECK_GT(v, 0);
2808  if (e >= 0) {
2809  return e / v;
2810  } else {
2811  return e % v == 0 ? e / v : e / v - 1;
2812  }
2813 }
2814 
2815 // ----- Vector of integer manipulations -----
2816 std::vector<int64> ToInt64Vector(const std::vector<int>& input);
2817 } // namespace operations_research
2818 
2819 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
Implements a complete cache for model elements: expressions and constraints.
IntVar * IsGreaterOrEqual(int64 constant) override
void SetForwardSequence(int64 index, const std::vector< int > &value)
void SetToZero(Solver *const solver, int64 row, int64 column)
Erases the 'column' bit in the 'row' row.
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
virtual void SetDurationMin(IntervalVar *const var, int64 new_min)=0
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars, Solver::ObjectiveWatcher objective_callback)
virtual void InsertExprExprConstraint(Constraint *const ct, IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type)=0
void AddIntegerVariableEqualValueClause(IntVar *const var, int64 value)
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 ...
const std::vector< int > & ForwardSequence() const
void Switch(Solver *const solver)
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Low-priority demon proxy to a method on the constraint with two arguments.
virtual void SetPerformed(IntervalVar *const var, bool value)=0
bool SkipUnchanged(int index) const override
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
virtual void SetDurationRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
--— utility classes --—
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
void VisitSequenceVariable(const SequenceVar *const variable) override
std::string DebugString() const override
Matrix version of the RevBitSet class.
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument) override
Variables.
bool Bound() const override
Returns true if the min and the max of the expression are equal.
void ClearAll(Solver *const solver)
Cleans all bits.
void BeginVisitModel(const std::string &solver_name) override
Header/footers.
virtual std::string name() const
Object naming.
bool IsArrayBoolean(const std::vector< T > &values)
std::string DebugString() const override
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
std::string BaseName() const override
Returns a base name for automatic naming.
virtual void RemoveInterval(IntVar *const var, int64 imin, int64 imax)=0
const Val & Value(int64 index) const
Returns the value in the current assignment of the variable of given index.
virtual int64 ModifyValue(int64 index, int64 value)=0
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
virtual void RankLast(SequenceVar *const var, int index)=0
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
bool MakeChainInactive(int64 before_chain, int64 chain_end)
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values) override
void SetIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values)
virtual IntExpr * FindVarConstantArrayExpression(IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
bool AreAllStrictlyNegative(const std::vector< T > &values)
--— Base operator class for operators manipulating variables --—
int64 FindIntegerArgumentWithDefault(const std::string &arg_name, int64 def) const
Getters.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
VarTypes
This enum is used internally to do dynamic typing on subclasses of integer variables.
virtual void SetStartRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
virtual Constraint * FindExprExprConstraint(IntExpr *const expr1, IntExpr *const expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
virtual void InsertExprConstantExpression(IntExpr *const expression, IntExpr *const var, int64 value, ExprConstantExpressionType type)=0
--— IntVarLocalSearchFilter --—
void SetMax(int64 m) override
virtual void RemoveValue(IntVar *const var, int64 value)=0
void SetSequenceArgument(const std::string &arg_name, SequenceVar *const var)
ModelCache(Solver *const solver)
std::string DebugString() const override
virtual void InsertVarArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
void SetToOne(Solver *const solver, int64 pos)
Sets the 'pos' bit.
virtual int64 GetSynchronizedObjectiveValue() const
DO NOT USE. Objective value from last time Synchronize() was called.
void AddVars(const std::vector< V * > &vars)
virtual void SetEndRange(IntervalVar *const var, int64 new_min, int64 new_max)=0
Demon proxy to a method on the constraint with no arguments.
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
void AddToAssignment(SequenceVar *var, const std::vector< int > &value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
const int & operator[](int index) const
virtual void InsertVarConstantConstantExpression(IntExpr *const expression, IntVar *const var, int64 value1, int64 value2, VarConstantConstantExpressionType type)=0
void AddVars(const std::vector< IntVar * > &vars)
Add variables to "track" to the filter.
RevBitMatrix(int64 rows, int64 columns)
SimpleRevFIFO< Demon * > bound_demons_
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
bool MakeActive(int64 node, int64 destination)
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.
LocalSearchFilterManager(Solver *const solver, const std::vector< LocalSearchFilter * > &filters, IntVar *objective)
IntVarIterator * MakeDomainIterator(bool reversible) const override
Creates a domain iterator.
bool FindIndex(IntVar *const var, int64 *index) const
void WhenDomain(Demon *d) override
This method attaches a demon that will watch any domain modification of the domain of the variable.
virtual void Start(const Assignment *assignment)=0
void SetLastValue(const T &v)
Sets the last value in the FIFO.
void ClearAll(Solver *const solver)
Cleans all bits.
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
-------— PropagationMonitor -------—
virtual bool NextFragment()=0
-------— LocalSearchMonitor -------—
void Synchronize(const Assignment *assignment, const Assignment *delta) override
Synchronizes all filters to assignment.
const T & LastValue() const
Returns the last value in the FIFO.
virtual void SetStartMin(IntervalVar *const var, int64 new_min)=0
IntervalVar modifiers.
bool HasFragments() const override
-------— Objective Management -------—
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
const T * Last() const
Returns the last item of the FIFO.
This is the base class for all expressions that are not variables.
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
-------— Search Log ------—
virtual void InsertVarConstantConstantConstraint(Constraint *const ct, IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
virtual const LocalSearchOperator * Self() const
int64 PosIntDivUp(int64 e, int64 v)
--— Arithmetic operations --—
Demon proxy to a method on the constraint with three arguments.
A Demon is the base element of a propagation queue.
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
bool ValueFromAssignent(const Assignment &assignment, IntVar *var, int64 index, int64 *value)
int64 Cardinality() const
Returns the number of bits set to one.
Low-priority demon proxy to a method on the constraint with one argument.
void Run(Solver *const s) override
This is the main callback of the demon.
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
--— On integer variable vector --—
bool IsCardinalityZero() const
Is bitset null?
bool Accept(Assignment *delta, Assignment *deltadelta) override
Returns true iff all filters return true, and the sum of their accepted objectives is smaller or equa...
virtual void BeginDemonRun(Demon *const demon)=0
void Init(Solver *const solver, const std::vector< uint64 > &mask)
This methods overwrites the active bitset with the mask.
void SetToOne(Solver *const solver, int64 row, int64 column)
Sets the 'column' bit in the 'row' row.
const std::vector< int > & OldSequence(int64 index) const
int64 BaseNode(int i) const
Returns the index of the variable corresponding to the ith base node.
std::string DebugString() const override
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, int number_of_base_nodes, bool skip_locally_optimal_paths, std::function< int(int64)> start_empty_path_class)
Builds an instance of PathOperator from next and path variables.
virtual void InsertVarConstantConstraint(Constraint *const ct, IntVar *const var, int64 value, VarConstantConstraintType type)=0
uint64 Hash1(uint64 value)
-------— Reversible Hash Table -------—
int number_of_nexts() const
Number of next variables.
bool Contains(int64 v) const override
This method returns whether the value 'v' is in the domain of the variable.
virtual bool Accept(Assignment *delta, Assignment *deltadelta)=0
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
int ActiveWordSize() const
This method returns the number of non null 64 bit words in the bitset representation.
IntVar * IsDifferent(int64 constant) override
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
void RankFirst(Solver *const solver, int elt)
--— Path-based Operators --—
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...
bool IsSet(int64 index) const
Returns whether the 'index' bit is set.
void Start(const Assignment *assignment) override
This method should not be overridden.
virtual void InsertVarArrayConstantExpression(IntExpr *const expression, const std::vector< IntVar * > &var, int64 value, VarArrayConstantExpressionType type)=0
void Push(Solver *const s, T val)
std::string DebugString() const override
void ResetPosition()
Reset the position of the operator to its position when Start() was last called; this can be used to ...
const std::vector< int > & Sequence(int64 index) const
Returns the value in the current assignment of the variable of given index.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
bool IsInactive(int64 i) const
Returns true if node is inactive.
void SetTypeName(const std::string &type_name)
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64 value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
int64 StartNode(int i) const
Returns the index of the variable corresponding to the current path of the ith base node.
void MarkChange(int64 index)
OnStart() should really be protected, but then SWIG doesn't see it.
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument) override
Visit interval argument.
bool IsCardinalityOne() const
Does it contains only one bit set?
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
int64 GetFirstBit(int row, int start) const
Returns the first bit in the row 'row' which position is >= 'start'.
--— Utility Class for Callbacks --—
virtual void InsertExprExprExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type)=0
This iterator is not stable with respect to deletion.
void AddToAssignment(IntVar *var, int64 value, bool active, std::vector< int > *assignment_indices, int64 index, Assignment *assignment) const
bool AreAllBooleans(const std::vector< IntVar * > &vars)
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
LocalSearchMonitor(Solver *const solver)
void OnNodeInitialization() override
Called by OnStart() after initializing node information.
virtual void SetMax(IntExpr *const expr, int64 new_max)=0
bool IsCardinalityOne() const
Does it contains only one bit set?
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
const IntContainer & IntVarContainer() const
int64 bit_size() const
Returns the number of bits given in the constructor of the bitset.
virtual void OnSynchronize(const Assignment *delta)
std::string DebugString() const override
RevPartialSequence(const std::vector< int > &items)
Argument Holder: useful when visiting a model.
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
void SynchronizeOnAssignment(const Assignment *assignment)
virtual void SetRange(IntExpr *const expr, int64 new_min, int64 new_max)=0
virtual void PushContext(const std::string &context)=0
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *const expr)
virtual void SetValues(IntVar *const var, const std::vector< int64 > &values)=0
virtual void InsertVarConstantArrayExpression(IntExpr *const expression, IntVar *const var, const std::vector< int64 > &values, VarConstantArrayExpressionType type)=0
virtual void BeginOperatorStart()=0
Local search operator events.
int64 Path(int64 node_index) const
Returns the index of the path to which the node of index node_index belongs in the current assignment...
void SetValue(Solver *const s, const T &val)
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
void SetIntervalArgument(const std::string &arg_name, IntervalVar *const var)
BooleanVar(Solver *const s, const std::string &name="")
void RankLast(Solver *const solver, int elt)
const std::vector< int64 > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
void BeginInitialPropagation() override
Before the initial propagation.
void SetNext(int64 from, int64 to, int64 path)
Sets the to to be the node after from.
void ApplyDecision(Decision *const decision) override
Before applying the decision.
PathWithPreviousNodesOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, int number_of_base_nodes, std::function< int(int64)> start_empty_path_class)
void SetToOne(Solver *const solver, int64 index)
Sets the 'index' bit.
bool IsSet(int64 row, int64 column) const
Returns whether the 'column' bit in the 'row' row is set.
virtual void SetStartMax(IntervalVar *const var, int64 new_max)=0
void AddIntegerVariableGreaterOrEqualValueClause(IntVar *const var, int64 value)
ArrayWithOffset(int64 index_min, int64 index_max)
virtual Constraint * FindVarConstantConstraint(IntVar *const var, int64 value, VarConstantConstraintType type) const =0
Var Constant Constraints.
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
VarLocalSearchOperator< SequenceVar, std::vector< int >, SequenceVarLocalSearchHandler > SequenceVarLocalSearchOperatorTemplate
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.
virtual IntExpr * FindExprExpression(IntExpr *const expr, ExprExpressionType type) const =0
Expr Expressions.
Simple PathOperator wrapper that also stores the current previous nodes, and is thus able to provide ...
void EndVisitModel(const std::string &solver_name) override
bool AreAllStrictlyPositive(const std::vector< T > &values)
std::string ParameterDebugString(P param)
PropagationMonitor(Solver *const solver)
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 ...
virtual void OnStart()
Called by Start() after synchronizing the operator with the current assignment.
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
void ExitSearch() override
End of the search.
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument) override
Visit sequence argument.
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars)
bool IsIncreasingContiguous(const std::vector< T > &values)
void Clear(Solver *const solver)
void RemoveInterval(int64 l, int64 u) override
This method removes the interval 'l' .
--— Local Search Filters ---—
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
bool ValueFromAssignent(const Assignment &assignment, SequenceVar *var, int64 index, std::vector< int > *value)
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
uint64 Size() const override
This method returns the number of values in the domain of the variable.
IntVar * IsEqual(int64 constant) override
IsEqual.
int64 MinVarArray(const std::vector< IntVar * > &vars)
A constraint is the main modeling object.
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator *op)
void Run(Solver *const s) override
This is the main callback of the demon.
bool IsArrayConstant(const std::vector< T > &values, const T &value)
-------— Helpers -------—
std::vector< int64 > ToInt64Vector(const std::vector< int > &input)
--— Vector of integer manipulations --—
void Run(Solver *const s) override
This is the main callback of the demon.
bool AreAllOnes(const std::vector< T > &values)
const E & Element(const V *const var) const
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
This class represents a small reversible bitset (size <= 64).
virtual void InsertVarArrayConstantArrayExpression(IntExpr *const expression, const std::vector< IntVar * > &var, const std::vector< int64 > &values, VarArrayConstantArrayExpressionType type)=0
void Run(Solver *const s) override
This is the main callback of the demon.
SequenceContainer * MutableSequenceVarContainer()
const SequenceContainer & SequenceVarContainer() const
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
bool IsPathEnd(int64 i) const
Returns true if i is the last node on the path; defined by the fact that i outside the range of the v...
Demon proxy to a method on the constraint with two arguments.
--— Boolean Variable --—
bool AreAllNegative(const std::vector< T > &values)
void PropagateObjectiveValue(int64 objective_value)
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
Low-priority demon proxy to a method on the constraint with no arguments.
void SetBackwardSequence(int64 index, const std::vector< int > &value)
A DecisionVisitor is used to inspect a decision.
bool IsCardinalityZero() const
Is bitset null?
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
VarLocalSearchOperator(std::vector< V * > vars, Handler var_handler)
SearchLog(Solver *const s, OptimizeVar *const obj, IntVar *const var, double scaling_factor, std::function< std::string()> display_callback, int period)
IntVar * Var() override
Creates a variable from the expression.
int64 GetFirstOne() const
Gets the index of the first bit set starting from 0.
virtual void EndDemonRun(Demon *const demon)=0
virtual bool SkipUnchanged(int index) const
void BeginFail() override
Just when the failure occurs.
SequenceVarLocalSearchOperator(const std::vector< SequenceVar * > &vars)
int64 OldPath(int64 node_index) const
bool AtSolution() override
This method is called when a valid solution is found.
void VisitIntegerArgument(const std::string &arg_name, int64 value) override
Integer arguments.
virtual void SetNextBaseToIncrement(int64 base_index)
Set the next base to increment on next iteration.
void Run(Solver *const s) override
This is the main callback of the demon.
void Install() override
Install itself on the solver.
std::string DebugString() const override
This class is a reversible growing array.
void RemoveValue(int64 v) override
This method removes the value 'v' from the domain of the variable.
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
bool AreAllBound(const std::vector< IntVar * > &vars)
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr) override
BaseLns(const std::vector< IntVar * > &vars)
void SetValue(int64 index, const Val &value)
ChangeValue(const std::vector< IntVar * > &vars)
virtual void OutputLine(const std::string &line)
std::string DebugString() const override
int64 OldNext(int64 node_index) const
V * Var(int64 index) const
Returns the variable of given index.
int64 FindIntegerArgumentOrDie(const std::string &arg_name) const
--— ChangeValue Operators --—
void Run(Solver *const s) override
This is the main callback of the demon.
int index() const
Returns the index of the variable.
void SetRange(int64 mi, int64 ma) override
This method sets both the min and the max of the expression.
IntVarIterator * MakeHoleIterator(bool reversible) const override
Creates a hole iterator.
virtual bool RestartAtPathStartOnSynchronize()
When the operator is being synchronized with a new solution (when Start() is called),...
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
void RevInsert(Solver *const solver, int64 index, T value)
int64 Value() const override
This method returns the value of the variable.
SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler &other)
const T * const_iterator
Iterators on the indices.
const RevIntSet< int > & active_words() const
Returns the set of active word indices.
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void InsertExprExpression(IntExpr *const expression, IntExpr *const expr, ExprExpressionType type)=0
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
int64 Cardinality() const
Returns the number of bits set to one.
bool RevAnd(Solver *const solver, const std::vector< uint64 > &mask)
This method ANDs the mask with the active bitset.
Useful Search and Modeling Objects.
T * RevAlloc(T *object)
Registers the given object as being reversible.
The class IntExpr is the base of all integer expressions in constraint programming.
bool Empty() const
This method returns true if the active bitset is null.
ArgumentHolder * Top() const
A reversible switch that can switch once from false to true.
A search monitor is a simple set of callbacks to monitor all search events.
RevImmutableMultiMap(Solver *const solver, int initial_size)
int64 size() const
Returns the number of interval vars in the sequence.
virtual T Evaluate(int64 index) const
virtual IntExpr * FindExprConstantExpression(IntExpr *const expr, int64 value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
RevIntSet(int capacity, int *shared_positions, int shared_positions_size)
Capacity is the fixed size of the set (it cannot grow).
int64 word_size() const
Returns the number of 64 bit words used to store the bitset.
std::function< void(int64)> ObjectiveWatcher
The class IntVar is a subset of IntExpr.
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
void WhenBound(Demon *d) override
This method attaches a demon that will be awakened when the variable is bound.
virtual void RemoveValues(IntVar *const var, const std::vector< int64 > &values)=0
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in c...
void Insert(Solver *const solver, const T &elt)
The class Iterator has two direct subclasses.
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void SetDurationMax(IntervalVar *const var, int64 new_max)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
std::string DebugString() const override
void SetBackwardSequence(const std::vector< int > &backward_sequence)
bool AreAllNull(const std::vector< T > &values)
void SetMin(int64 m) override
virtual IntExpr * FindExprExprConstantExpression(IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
void EndInitialPropagation() override
After the initial propagation.
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1170
void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate) override
virtual bool InitPosition() const
Returns true if operator needs to restart its initial position at each call to Start()
void SetToZero(Solver *const solver, int64 pos)
Erases the 'pos' bit.
int64 GetAcceptedObjectiveValue() const override
DO NOT USE.
void SetForwardSequence(const std::vector< int > &forward_sequence)
std::string DebugString() const override
Demon proxy to a method on the constraint with one argument.
bool AreAllPositive(const std::vector< T > &values)
int64 MaxVarArray(const std::vector< IntVar * > &vars)
virtual Constraint * FindVarConstantConstantConstraint(IntVar *const var, int64 value1, int64 value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
void RefuteDecision(Decision *const decision) override
Before refuting the decision.
void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint) override
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
std::string DebugString() const override
void SetToZero(Solver *const solver, int64 index)
Erases the 'index' bit.
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
virtual void RankNotLast(SequenceVar *const var, int index)=0
UnsortedNullableRevBitset(int bit_size)
Size is the number of bits to store in the bitset.
virtual int64 GetAcceptedObjectiveValue() const
DO NOT USE.
virtual void SetMin(IntExpr *const expr, int64 new_min)=0
IntExpr modifiers.
This class represents a reversible bitset.
void NoMoreSolutions() override
When the search tree is finished.
virtual void SetValue(IntVar *const var, int64 value)=0
void Install() override
Install itself on the solver.
A Decision represents a choice point in the search tree.
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
bool Contains(const V *const var) const
--— Base operator class for operators manipulating IntVars --—
-------— Interval Var -------—
const std::vector< int64 > & path_starts() const
Returns the vector of path start nodes.
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
int PathClass(int i) const
Returns the class of the current path of the ith base node.
SimpleRevFIFO< Demon * > delayed_bound_demons_
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64 value)
Returns true if all variables are assigned to 'value'.
std::string DebugString() const override
int64 PosIntDivDown(int64 e, int64 v)
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
virtual void SetEndMin(IntervalVar *const var, int64 new_min)=0
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
int64 GetSynchronizedObjectiveValue() const override
DO NOT USE. Objective value from last time Synchronize() was called.
virtual void InsertExprExprConstantExpression(IntExpr *const expression, IntExpr *const var1, IntExpr *const var2, int64 constant, ExprExprConstantExpressionType type)=0
Solver::DemonPriority priority() const override
This method returns the priority of the demon.
This class represents a reversible bitset.
--— Base Large Neighborhood Search operator class -—
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 RegisterDemon(Demon *const demon)=0
virtual void InsertVoidConstraint(Constraint *const ct, VoidConstraintType type)=0
virtual IntExpr * FindExprExprExpression(IntExpr *const var1, IntExpr *const var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
void Synchronize(const Assignment *assignment, const Assignment *delta) override
This method should not be overridden.
bool ReverseChain(int64 before_chain, int64 after_chain, int64 *chain_last)
Reverses the chain starting after before_chain and ending before after_chain.
void EnterSearch() override
Beginning of the search.
bool RevSubtract(Solver *const solver, const std::vector< uint64 > &mask)
This method subtracts the mask from the active bitset.
void AppendToFragment(int index)
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64 value, IntervalVar *const delegate) override
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
int64 Next(int64 node_index) const
Returns the index of the node after the node of index node_index in the current assignment.
--— SequenceVarElement --—
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
void SetIntegerArgument(const std::string &arg_name, int64 value)
Setters.
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
void SetIntegerArrayArgument(const std::string &arg_name, const std::vector< int64 > &values)
void Remove(Solver *const solver, const T &value_index)
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1190
-------— Local search operators -------—
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
void AddIntegerVariableLessOrEqualValueClause(IntVar *const var, int64 value)
virtual void InjectObjectiveValue(int64 objective_value)
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
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.
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
IntVar * IsLessOrEqual(int64 constant) override
void Run(Solver *const s) override
This is the main callback of the demon.
virtual void SetEndMax(IntervalVar *const var, int64 new_max)=0
void Restore(Solver *const solver, const T &value_index)
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 ---—
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64 > *const values)
bool IsIncreasing(const std::vector< T > &values)
const std::string & TypeName() const
Type of the argument.
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...