C++ Reference

C++ Reference: Routing

constraint_solver.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
67 
68 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
69 #define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
70 
71 #include <stddef.h>
72 #include <stdint.h>
73 
74 #include <deque>
75 #include <functional>
76 #include <memory>
77 #include <random>
78 #include <string>
79 #include <tuple>
80 #include <utility>
81 #include <vector>
82 
83 #include "absl/base/attributes.h"
84 #include "absl/base/log_severity.h"
85 #include "absl/container/flat_hash_map.h"
86 #include "absl/container/flat_hash_set.h"
87 #include "absl/flags/declare.h"
88 #include "absl/flags/flag.h"
89 #include "absl/random/random.h"
90 #include "absl/strings/str_format.h"
91 #include "absl/time/time.h"
92 #include "ortools/base/integral_types.h"
93 #include "ortools/base/logging.h"
94 #include "ortools/base/macros.h"
95 #include "ortools/base/map_util.h"
96 #include "ortools/base/timer.h"
97 #include "ortools/constraint_solver/search_stats.pb.h"
98 #include "ortools/constraint_solver/solver_parameters.pb.h"
99 #include "ortools/util/piecewise_linear_function.h"
100 #include "ortools/util/sorted_interval_list.h"
101 #include "ortools/util/tuple_set.h"
102 
103 #if !defined(SWIG)
104 ABSL_DECLARE_FLAG(int64_t, cp_random_seed);
105 #endif // !defined(SWIG)
106 
107 class File;
108 
110 
111 class Assignment;
112 class AssignmentProto;
113 class BaseObject;
114 class CastConstraint;
115 class Constraint;
116 class Decision;
117 class DecisionBuilder;
118 class DecisionVisitor;
119 class Demon;
120 class DemonProfiler;
121 class Dimension;
124 class IntExpr;
125 class IntVar;
126 class IntVarAssignment;
128 class IntervalVar;
129 class IntervalVarAssignment;
130 class LocalSearchFilter;
132 class LocalSearchMonitor;
133 class LocalSearchOperator;
134 class LocalSearchPhaseParameters;
135 class LocalSearchProfiler;
136 class ModelCache;
137 class ModelVisitor;
138 class OptimizeVar;
139 class Pack;
142 class PropagationMonitor;
143 class Queue;
144 class RegularLimit;
145 class RegularLimitParameters;
146 class RevBitMatrix;
147 class Search;
148 class SearchLimit;
149 class SearchMonitor;
150 class SequenceVar;
151 class SequenceVarAssignment;
152 class SolutionCollector;
153 class SolutionPool;
154 class SymmetryBreaker;
155 struct StateInfo;
156 struct Trail;
157 template <class T>
158 class SimpleRevFIFO;
159 template <typename F>
161 template <typename F>
163 
164 inline int64_t CpRandomSeed() {
165  return absl::GetFlag(FLAGS_cp_random_seed) == -1
166  ? absl::Uniform<int64_t>(absl::BitGen(), 0, kint64max)
167  : absl::GetFlag(FLAGS_cp_random_seed);
168 }
169 
174  public:
179  };
180 
184  };
185 
186  enum DisplayLevel { NONE = 0, NORMAL = 1, VERBOSE = 2 };
187 
191 
194 
198 
203 
208 
211 
215 
218 
222 
225 
228 
230 };
231 
249 class Solver {
250  public:
257  : variable(nullptr), expression(nullptr), maintainer(nullptr) {}
258  IntegerCastInfo(IntVar* const v, IntExpr* const e, Constraint* const c)
259  : variable(v), expression(e), maintainer(c) {}
263  };
264 
266  static constexpr int kNumPriorities = 3;
267 
273 
276 
281 
284 
292 
300 
308 
316 
322 
328 
333 
338 
342 
346  };
347  // TODO(user): add HIGHEST_MIN and LOWEST_MAX.
348 
354 
357 
360 
363 
366 
371 
375 
379  };
380 
397 
403  };
404 
411  };
412 
426  };
427 
441 
457 
460 
469 
480 
488 
495 
503 
510 
522 
531 
535 
540 
550 
555 
563  SIMPLELNS
564  };
565 
573  LK,
574 
582 
589  TSPLNS
590  };
591 
598  GE,
600  LE,
603  EQ
604  };
605 
613 
616 
619  };
620 
626 
629 
632 
635 
638 
641 
644 
647 
652  };
653 
659 
662 
665 
668 
671 
674 
679 
683  AVOID_DATE
684  };
685 
695 
700 
705 
709 
713  };
714 
718 
720  enum SolverState {
733  };
734 
737 
738 #ifndef SWIG
740  enum class MonitorEvent : int {
741  kEnterSearch = 0,
743  kExitSearch,
749  kBeginFail,
750  kEndFail,
754  kAtSolution,
757  kAcceptDelta,
763  kAccept,
764  // Dummy event whose underlying int is the number of MonitorEvent enums.
765  kLast,
766  };
767 #endif // SWIG
768 
770  typedef std::function<int64_t(int64_t)> IndexEvaluator1;
771  typedef std::function<int64_t(int64_t, int64_t)> IndexEvaluator2;
772  typedef std::function<int64_t(int64_t, int64_t, int64_t)> IndexEvaluator3;
773 
774  typedef std::function<bool(int64_t)> IndexFilter1;
775 
776  typedef std::function<IntVar*(int64_t)> Int64ToIntVar;
777 
778  typedef std::function<int64_t(Solver* solver,
779  const std::vector<IntVar*>& vars,
780  int64_t first_unbound, int64_t last_unbound)>
782 
783  typedef std::function<int64_t(const IntVar* v, int64_t id)>
785  typedef std::function<bool(int64_t, int64_t, int64_t)>
787  typedef std::function<DecisionModification()> BranchSelector;
788  // TODO(user): wrap in swig.
789  typedef std::function<void(Solver*)> Action;
790  typedef std::function<void()> Closure;
791 
793  explicit Solver(const std::string& name);
794  Solver(const std::string& name, const ConstraintSolverParameters& parameters);
796 
798  ConstraintSolverParameters parameters() const { return parameters_; }
799  // Read-only.
800  const ConstraintSolverParameters& const_parameters() const {
801  return parameters_;
802  }
804  // TODO(user): Move to constraint_solver_parameters.h.
805  static ConstraintSolverParameters DefaultSolverParameters();
806 
808 
812  template <class T>
813  void SaveValue(T* o) {
814  InternalSaveValue(o);
815  }
816 
829  template <typename T>
830  T* RevAlloc(T* object) {
831  return reinterpret_cast<T*>(SafeRevAlloc(object));
832  }
833 
840  template <typename T>
841  T* RevAllocArray(T* object) {
842  return reinterpret_cast<T*>(SafeRevAllocArray(object));
843  }
844 
878  void AddConstraint(Constraint* const c);
882  void AddCastConstraint(CastConstraint* const constraint,
883  IntVar* const target_var, IntExpr* const expr);
884 
926  bool Solve(DecisionBuilder* const db,
927  const std::vector<SearchMonitor*>& monitors);
928  bool Solve(DecisionBuilder* const db);
929  bool Solve(DecisionBuilder* const db, SearchMonitor* const m1);
930  bool Solve(DecisionBuilder* const db, SearchMonitor* const m1,
931  SearchMonitor* const m2);
932  bool Solve(DecisionBuilder* const db, SearchMonitor* const m1,
933  SearchMonitor* const m2, SearchMonitor* const m3);
934  bool Solve(DecisionBuilder* const db, SearchMonitor* const m1,
935  SearchMonitor* const m2, SearchMonitor* const m3,
936  SearchMonitor* const m4);
938 
947 
948  void NewSearch(DecisionBuilder* const db,
949  const std::vector<SearchMonitor*>& monitors);
950  void NewSearch(DecisionBuilder* const db);
951  void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1);
952  void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
953  SearchMonitor* const m2);
954  void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
955  SearchMonitor* const m2, SearchMonitor* const m3);
956  void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1,
957  SearchMonitor* const m2, SearchMonitor* const m3,
958  SearchMonitor* const m4);
959 
960  bool NextSolution();
962  void EndSearch();
964 
974  const std::vector<SearchMonitor*>& monitors);
976  bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1);
977  bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1,
978  SearchMonitor* const m2);
979  bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1,
980  SearchMonitor* const m2, SearchMonitor* const m3);
981 
983  bool CheckAssignment(Assignment* const solution);
984 
988  bool CheckConstraint(Constraint* const ct);
989 
991  SolverState state() const { return state_; }
992 
994  void Fail();
995 
996 #if !defined(SWIG)
1001  void AddBacktrackAction(Action a, bool fast);
1002 #endif
1003 
1005  std::string DebugString() const;
1006 
1008  static int64_t MemoryUsage();
1009 
1014  absl::Time Now() const;
1015 
1018  int64_t wall_time() const;
1019 
1021  int64_t branches() const { return branches_; }
1022 
1024  int64_t solutions() const;
1025 
1027  int64_t unchecked_solutions() const;
1028 
1030  int64_t demon_runs(DemonPriority p) const { return demon_runs_[p]; }
1031 
1033  int64_t failures() const { return fails_; }
1034 
1036  int64_t neighbors() const { return neighbors_; }
1037 
1039  int64_t filtered_neighbors() const { return filtered_neighbors_; }
1040 
1042  int64_t accepted_neighbors() const { return accepted_neighbors_; }
1043 
1046  uint64_t stamp() const;
1047 
1049  uint64_t fail_stamp() const;
1050 
1052  void set_context(const std::string& context) { context_ = context; }
1053 
1055  const std::string& context() const { return context_; }
1056 
1059  return optimization_direction_;
1060  }
1062  optimization_direction_ = direction;
1063  }
1064 
1065  // All factories (MakeXXX methods) encapsulate creation of objects
1066  // through RevAlloc(). Hence, the Solver used for allocating the
1067  // returned object will retain ownership of the allocated memory.
1068  // Destructors are called upon backtrack, or when the Solver is
1069  // itself destructed.
1070 
1071  // ----- Int Variables and Constants -----
1072 
1074  IntVar* MakeIntVar(int64_t min, int64_t max, const std::string& name);
1075 
1077  IntVar* MakeIntVar(const std::vector<int64_t>& values,
1078  const std::string& name);
1079 
1081  IntVar* MakeIntVar(const std::vector<int>& values, const std::string& name);
1082 
1084  IntVar* MakeIntVar(int64_t min, int64_t max);
1085 
1087  IntVar* MakeIntVar(const std::vector<int64_t>& values);
1088 
1090  IntVar* MakeIntVar(const std::vector<int>& values);
1091 
1093  IntVar* MakeBoolVar(const std::string& name);
1094 
1097 
1099  IntVar* MakeIntConst(int64_t val, const std::string& name);
1100 
1102  IntVar* MakeIntConst(int64_t val);
1103 
1107  void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1108  const std::string& name, std::vector<IntVar*>* vars);
1111  void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1112  std::vector<IntVar*>* vars);
1114  IntVar** MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1115  const std::string& name);
1116 
1120  void MakeBoolVarArray(int var_count, const std::string& name,
1121  std::vector<IntVar*>* vars);
1124  void MakeBoolVarArray(int var_count, std::vector<IntVar*>* vars);
1126  IntVar** MakeBoolVarArray(int var_count, const std::string& name);
1127 
1128  // ----- Integer Expressions -----
1129 
1131  IntExpr* MakeSum(IntExpr* const left, IntExpr* const right);
1133  IntExpr* MakeSum(IntExpr* const expr, int64_t value);
1135  IntExpr* MakeSum(const std::vector<IntVar*>& vars);
1136 
1138  IntExpr* MakeScalProd(const std::vector<IntVar*>& vars,
1139  const std::vector<int64_t>& coefs);
1141  IntExpr* MakeScalProd(const std::vector<IntVar*>& vars,
1142  const std::vector<int>& coefs);
1143 
1145  IntExpr* MakeDifference(IntExpr* const left, IntExpr* const right);
1147  IntExpr* MakeDifference(int64_t value, IntExpr* const expr);
1150 
1152  IntExpr* MakeProd(IntExpr* const left, IntExpr* const right);
1154  IntExpr* MakeProd(IntExpr* const expr, int64_t value);
1155 
1157  IntExpr* MakeDiv(IntExpr* const expr, int64_t value);
1159  IntExpr* MakeDiv(IntExpr* const numerator, IntExpr* const denominator);
1160 
1162  IntExpr* MakeAbs(IntExpr* const expr);
1164  IntExpr* MakeSquare(IntExpr* const expr);
1166  IntExpr* MakePower(IntExpr* const expr, int64_t n);
1167 
1169  IntExpr* MakeElement(const std::vector<int64_t>& values, IntVar* const index);
1171  IntExpr* MakeElement(const std::vector<int>& values, IntVar* const index);
1172 
1176  IntExpr* MakeElement(IndexEvaluator1 values, IntVar* const index);
1184  IntVar* const index);
1186  IntExpr* MakeElement(IndexEvaluator2 values, IntVar* const index1,
1187  IntVar* const index2);
1188 
1190  IntExpr* MakeElement(const std::vector<IntVar*>& vars, IntVar* const index);
1191 
1192 #if !defined(SWIG)
1194  IntExpr* MakeElement(Int64ToIntVar vars, int64_t range_start,
1195  int64_t range_end, IntVar* argument);
1196 #endif // SWIG
1197 
1202 
1209  template <typename F>
1210  Constraint* MakeLightElement(F values, IntVar* const var, IntVar* const index,
1211  std::function<bool()> deep_serialize = nullptr) {
1213  this, var, index, std::move(values), std::move(deep_serialize)));
1214  }
1215 
1222  template <typename F>
1223  Constraint* MakeLightElement(F values, IntVar* const var,
1224  IntVar* const index1, IntVar* const index2,
1225  std::function<bool()> deep_serialize = nullptr) {
1227  this, var, index1, index2, std::move(values),
1228  std::move(deep_serialize)));
1229  }
1230 
1233  IntExpr* MakeIndexExpression(const std::vector<IntVar*>& vars, int64_t value);
1234 
1237  IntExpr* const then_expr,
1238  IntExpr* const else_expr,
1239  IntVar* const target_var);
1240 
1242  IntExpr* MakeMin(const std::vector<IntVar*>& vars);
1244  IntExpr* MakeMin(IntExpr* const left, IntExpr* const right);
1246  IntExpr* MakeMin(IntExpr* const expr, int64_t value);
1248  IntExpr* MakeMin(IntExpr* const expr, int value);
1249 
1251  IntExpr* MakeMax(const std::vector<IntVar*>& vars);
1253  IntExpr* MakeMax(IntExpr* const left, IntExpr* const right);
1255  IntExpr* MakeMax(IntExpr* const expr, int64_t value);
1257  IntExpr* MakeMax(IntExpr* const expr, int value);
1258 
1260  IntExpr* MakeConvexPiecewiseExpr(IntExpr* expr, int64_t early_cost,
1261  int64_t early_date, int64_t late_date,
1262  int64_t late_cost);
1263 
1266  IntExpr* MakeSemiContinuousExpr(IntExpr* const expr, int64_t fixed_charge,
1267  int64_t step);
1268 
1271  // TODO(user): Investigate if we can merge all three piecewise linear
1273 #ifndef SWIG
1275  const PiecewiseLinearFunction& f);
1276 #endif
1277 
1279  IntExpr* MakeModulo(IntExpr* const x, int64_t mod);
1280 
1282  IntExpr* MakeModulo(IntExpr* const x, IntExpr* const mod);
1283 
1286  IntExpr* const expr,
1287  int64_t unperformed_value);
1288 
1293  Constraint* MakeFalseConstraint(const std::string& explanation);
1294 
1296  Constraint* MakeIsEqualCstCt(IntExpr* const var, int64_t value,
1297  IntVar* const boolvar);
1299  IntVar* MakeIsEqualCstVar(IntExpr* const var, int64_t value);
1301  Constraint* MakeIsEqualCt(IntExpr* const v1, IntExpr* v2, IntVar* const b);
1305  Constraint* MakeEquality(IntExpr* const left, IntExpr* const right);
1307  Constraint* MakeEquality(IntExpr* const expr, int64_t value);
1309  Constraint* MakeEquality(IntExpr* const expr, int value);
1310 
1312  Constraint* MakeIsDifferentCstCt(IntExpr* const var, int64_t value,
1313  IntVar* const boolvar);
1315  IntVar* MakeIsDifferentCstVar(IntExpr* const var, int64_t value);
1317  IntVar* MakeIsDifferentVar(IntExpr* const v1, IntExpr* const v2);
1320  IntVar* const b);
1322  Constraint* MakeNonEquality(IntExpr* const left, IntExpr* const right);
1324  Constraint* MakeNonEquality(IntExpr* const expr, int64_t value);
1326  Constraint* MakeNonEquality(IntExpr* const expr, int value);
1327 
1329  Constraint* MakeIsLessOrEqualCstCt(IntExpr* const var, int64_t value,
1330  IntVar* const boolvar);
1332  IntVar* MakeIsLessOrEqualCstVar(IntExpr* const var, int64_t value);
1334  IntVar* MakeIsLessOrEqualVar(IntExpr* const left, IntExpr* const right);
1336  Constraint* MakeIsLessOrEqualCt(IntExpr* const left, IntExpr* const right,
1337  IntVar* const b);
1339  Constraint* MakeLessOrEqual(IntExpr* const left, IntExpr* const right);
1341  Constraint* MakeLessOrEqual(IntExpr* const expr, int64_t value);
1343  Constraint* MakeLessOrEqual(IntExpr* const expr, int value);
1344 
1346  Constraint* MakeIsGreaterOrEqualCstCt(IntExpr* const var, int64_t value,
1347  IntVar* const boolvar);
1349  IntVar* MakeIsGreaterOrEqualCstVar(IntExpr* const var, int64_t value);
1351  IntVar* MakeIsGreaterOrEqualVar(IntExpr* const left, IntExpr* const right);
1353  Constraint* MakeIsGreaterOrEqualCt(IntExpr* const left, IntExpr* const right,
1354  IntVar* const b);
1356  Constraint* MakeGreaterOrEqual(IntExpr* const left, IntExpr* const right);
1358  Constraint* MakeGreaterOrEqual(IntExpr* const expr, int64_t value);
1360  Constraint* MakeGreaterOrEqual(IntExpr* const expr, int value);
1361 
1363  Constraint* MakeIsGreaterCstCt(IntExpr* const v, int64_t c, IntVar* const b);
1365  IntVar* MakeIsGreaterCstVar(IntExpr* const var, int64_t value);
1367  IntVar* MakeIsGreaterVar(IntExpr* const left, IntExpr* const right);
1369  Constraint* MakeIsGreaterCt(IntExpr* const left, IntExpr* const right,
1370  IntVar* const b);
1372  Constraint* MakeGreater(IntExpr* const left, IntExpr* const right);
1374  Constraint* MakeGreater(IntExpr* const expr, int64_t value);
1376  Constraint* MakeGreater(IntExpr* const expr, int value);
1377 
1379  Constraint* MakeIsLessCstCt(IntExpr* const v, int64_t c, IntVar* const b);
1381  IntVar* MakeIsLessCstVar(IntExpr* const var, int64_t value);
1383  IntVar* MakeIsLessVar(IntExpr* const left, IntExpr* const right);
1385  Constraint* MakeIsLessCt(IntExpr* const left, IntExpr* const right,
1386  IntVar* const b);
1388  Constraint* MakeLess(IntExpr* const left, IntExpr* const right);
1390  Constraint* MakeLess(IntExpr* const expr, int64_t value);
1392  Constraint* MakeLess(IntExpr* const expr, int value);
1393 
1395  Constraint* MakeSumLessOrEqual(const std::vector<IntVar*>& vars, int64_t cst);
1396  Constraint* MakeSumGreaterOrEqual(const std::vector<IntVar*>& vars,
1397  int64_t cst);
1398  Constraint* MakeSumEquality(const std::vector<IntVar*>& vars, int64_t cst);
1399  Constraint* MakeSumEquality(const std::vector<IntVar*>& vars,
1400  IntVar* const var);
1401  Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1402  const std::vector<int64_t>& coefficients,
1403  int64_t cst);
1404  Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1405  const std::vector<int>& coefficients,
1406  int64_t cst);
1407  Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1408  const std::vector<int64_t>& coefficients,
1409  IntVar* const target);
1410  Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1411  const std::vector<int>& coefficients,
1412  IntVar* const target);
1413  Constraint* MakeScalProdGreaterOrEqual(const std::vector<IntVar*>& vars,
1414  const std::vector<int64_t>& coeffs,
1415  int64_t cst);
1416  Constraint* MakeScalProdGreaterOrEqual(const std::vector<IntVar*>& vars,
1417  const std::vector<int>& coeffs,
1418  int64_t cst);
1419  Constraint* MakeScalProdLessOrEqual(const std::vector<IntVar*>& vars,
1420  const std::vector<int64_t>& coefficients,
1421  int64_t cst);
1422  Constraint* MakeScalProdLessOrEqual(const std::vector<IntVar*>& vars,
1423  const std::vector<int>& coefficients,
1424  int64_t cst);
1425 
1426  Constraint* MakeMinEquality(const std::vector<IntVar*>& vars,
1427  IntVar* const min_var);
1428  Constraint* MakeMaxEquality(const std::vector<IntVar*>& vars,
1429  IntVar* const max_var);
1430 
1431  Constraint* MakeElementEquality(const std::vector<int64_t>& vals,
1432  IntVar* const index, IntVar* const target);
1433  Constraint* MakeElementEquality(const std::vector<int>& vals,
1434  IntVar* const index, IntVar* const target);
1435  Constraint* MakeElementEquality(const std::vector<IntVar*>& vars,
1436  IntVar* const index, IntVar* const target);
1437  Constraint* MakeElementEquality(const std::vector<IntVar*>& vars,
1438  IntVar* const index, int64_t target);
1440  Constraint* MakeAbsEquality(IntVar* const var, IntVar* const abs_var);
1445  Constraint* MakeIndexOfConstraint(const std::vector<IntVar*>& vars,
1446  IntVar* const index, int64_t target);
1447 
1455 #if !defined(SWIG)
1458 #endif
1461 
1462  // ----- Between and related constraints -----
1463 
1465  Constraint* MakeBetweenCt(IntExpr* const expr, int64_t l, int64_t u);
1466 
1471  Constraint* MakeNotBetweenCt(IntExpr* const expr, int64_t l, int64_t u);
1472 
1474  Constraint* MakeIsBetweenCt(IntExpr* const expr, int64_t l, int64_t u,
1475  IntVar* const b);
1476  IntVar* MakeIsBetweenVar(IntExpr* const v, int64_t l, int64_t u);
1477 
1478  // ----- Member and related constraints -----
1479 
1483  const std::vector<int64_t>& values);
1484  Constraint* MakeMemberCt(IntExpr* const expr, const std::vector<int>& values);
1485 
1488  const std::vector<int64_t>& values);
1490  const std::vector<int>& values);
1491 
1493  Constraint* MakeNotMemberCt(IntExpr* const expr, std::vector<int64_t> starts,
1494  std::vector<int64_t> ends);
1496  Constraint* MakeNotMemberCt(IntExpr* const expr, std::vector<int> starts,
1497  std::vector<int> ends);
1498 #if !defined(SWIG)
1501  SortedDisjointIntervalList intervals);
1502 #endif // !defined(SWIG)
1503 
1506  const std::vector<int64_t>& values,
1507  IntVar* const boolvar);
1509  const std::vector<int>& values,
1510  IntVar* const boolvar);
1512  const std::vector<int64_t>& values);
1513  IntVar* MakeIsMemberVar(IntExpr* const expr, const std::vector<int>& values);
1514 
1516  Constraint* MakeAtMost(std::vector<IntVar*> vars, int64_t value,
1517  int64_t max_count);
1519  Constraint* MakeCount(const std::vector<IntVar*>& vars, int64_t value,
1520  int64_t max_count);
1522  Constraint* MakeCount(const std::vector<IntVar*>& vars, int64_t value,
1523  IntVar* const max_count);
1524 
1526  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1527  const std::vector<int64_t>& values,
1528  const std::vector<IntVar*>& cards);
1530  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1531  const std::vector<int>& values,
1532  const std::vector<IntVar*>& cards);
1534  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1535  const std::vector<IntVar*>& cards);
1538  Constraint* MakeDistribute(const std::vector<IntVar*>& vars, int64_t card_min,
1539  int64_t card_max, int64_t card_size);
1543  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1544  const std::vector<int64_t>& card_min,
1545  const std::vector<int64_t>& card_max);
1549  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1550  const std::vector<int>& card_min,
1551  const std::vector<int>& card_max);
1555  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1556  const std::vector<int64_t>& values,
1557  const std::vector<int64_t>& card_min,
1558  const std::vector<int64_t>& card_max);
1562  Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1563  const std::vector<int>& values,
1564  const std::vector<int>& card_min,
1565  const std::vector<int>& card_max);
1566 
1571  Constraint* MakeDeviation(const std::vector<IntVar*>& vars,
1572  IntVar* const deviation_var, int64_t total_sum);
1573 
1576  Constraint* MakeAllDifferent(const std::vector<IntVar*>& vars);
1577 
1581  Constraint* MakeAllDifferent(const std::vector<IntVar*>& vars,
1582  bool stronger_propagation);
1583 
1586  Constraint* MakeAllDifferentExcept(const std::vector<IntVar*>& vars,
1587  int64_t escape_value);
1588  // TODO(user): Do we need a version with an array of escape values.
1589 
1605  Constraint* MakeSortingConstraint(const std::vector<IntVar*>& vars,
1606  const std::vector<IntVar*>& sorted);
1607  // TODO(user): Add void MakeSortedArray(
1608  // const std::vector<IntVar*>& vars,
1609  // std::vector<IntVar*>* const sorted);
1610 
1613  Constraint* MakeLexicalLess(const std::vector<IntVar*>& left,
1614  const std::vector<IntVar*>& right);
1615 
1618  Constraint* MakeLexicalLessOrEqual(const std::vector<IntVar*>& left,
1619  const std::vector<IntVar*>& right);
1620 
1626  const std::vector<IntVar*>& left, const std::vector<IntVar*>& right);
1627 
1631  IntVar* index, const std::vector<IntVar*>& vars);
1632 
1636  IntVar* index, const std::vector<IntVar*>& vars);
1637 
1642  Constraint* MakeNullIntersect(const std::vector<IntVar*>& first_vars,
1643  const std::vector<IntVar*>& second_vars);
1644 
1650  Constraint* MakeNullIntersectExcept(const std::vector<IntVar*>& first_vars,
1651  const std::vector<IntVar*>& second_vars,
1652  int64_t escape_value);
1653 
1654  // TODO(user): Implement MakeAllNullIntersect taking an array of
1655  // variable vectors.
1656 
1666  Constraint* MakeNoCycle(const std::vector<IntVar*>& nexts,
1667  const std::vector<IntVar*>& active,
1668  IndexFilter1 sink_handler = nullptr);
1669  Constraint* MakeNoCycle(const std::vector<IntVar*>& nexts,
1670  const std::vector<IntVar*>& active,
1671  IndexFilter1 sink_handler, bool assume_paths);
1672 
1674  Constraint* MakeCircuit(const std::vector<IntVar*>& nexts);
1675 
1678  Constraint* MakeSubCircuit(const std::vector<IntVar*>& nexts);
1679 
1684  Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1685  const std::vector<IntVar*>& active,
1686  const std::vector<IntVar*>& cumuls,
1687  const std::vector<IntVar*>& transits);
1690  // TODO(user): Merge with other path-cumuls constraints.
1691  Constraint* MakeDelayedPathCumul(const std::vector<IntVar*>& nexts,
1692  const std::vector<IntVar*>& active,
1693  const std::vector<IntVar*>& cumuls,
1694  const std::vector<IntVar*>& transits);
1701  Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1702  const std::vector<IntVar*>& active,
1703  const std::vector<IntVar*>& cumuls,
1704  IndexEvaluator2 transit_evaluator);
1705 
1712  Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1713  const std::vector<IntVar*>& active,
1714  const std::vector<IntVar*>& cumuls,
1715  const std::vector<IntVar*>& slacks,
1716  IndexEvaluator2 transit_evaluator);
1719  // TODO(user): Only does checking on WhenBound events on next variables.
1721  Constraint* MakePathConnected(std::vector<IntVar*> nexts,
1722  std::vector<int64_t> sources,
1723  std::vector<int64_t> sinks,
1724  std::vector<IntVar*> status);
1725 #ifndef SWIG
1728  // TODO(user): This constraint does not make holes in variable domains;
1732  std::vector<IntVar*> nexts,
1733  const std::vector<std::pair<int, int>>& precedences);
1743  std::vector<IntVar*> nexts,
1744  const std::vector<std::pair<int, int>>& precedences,
1745  const std::vector<int>& lifo_path_starts,
1746  const std::vector<int>& fifo_path_starts);
1750  std::vector<IntVar*> nexts, std::vector<IntVar*> transits,
1751  const std::vector<std::pair<int, int>>& precedences);
1752 #endif // !SWIG
1756  Constraint* MakeMapDomain(IntVar* const var,
1757  const std::vector<IntVar*>& actives);
1758 
1763  Constraint* MakeAllowedAssignments(const std::vector<IntVar*>& vars,
1764  const IntTupleSet& tuples);
1765 
1774  const std::vector<IntVar*>& vars, const IntTupleSet& transition_table,
1775  int64_t initial_state, const std::vector<int64_t>& final_states);
1776 
1784  Constraint* MakeTransitionConstraint(const std::vector<IntVar*>& vars,
1785  const IntTupleSet& transition_table,
1786  int64_t initial_state,
1787  const std::vector<int>& final_states);
1788 
1789 #if defined(SWIGPYTHON)
1792  const std::vector<IntVar*>& vars,
1793  const std::vector<std::vector<int64_t> /*keep for swig*/>& raw_tuples) {
1794  IntTupleSet tuples(vars.size());
1795  tuples.InsertAll(raw_tuples);
1796  return MakeAllowedAssignments(vars, tuples);
1797  }
1798 
1800  const std::vector<IntVar*>& vars,
1801  const std::vector<std::vector<int64_t> /*keep for swig*/>&
1802  raw_transitions,
1803  int64_t initial_state, const std::vector<int>& final_states) {
1804  IntTupleSet transitions(3);
1805  transitions.InsertAll(raw_transitions);
1806  return MakeTransitionConstraint(vars, transitions, initial_state,
1807  final_states);
1808  }
1809 #endif
1810 
1820  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1821  const std::vector<IntVar*>& x_size, const std::vector<IntVar*>& y_size);
1823  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1824  const std::vector<int64_t>& x_size, const std::vector<int64_t>& y_size);
1826  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1827  const std::vector<int>& x_size, const std::vector<int>& y_size);
1828 
1838  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1839  const std::vector<IntVar*>& x_size, const std::vector<IntVar*>& y_size);
1841  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1842  const std::vector<int64_t>& x_size, const std::vector<int64_t>& y_size);
1844  const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1845  const std::vector<int>& x_size, const std::vector<int>& y_size);
1846 
1852  Pack* MakePack(const std::vector<IntVar*>& vars, int number_of_bins);
1853 
1859  int64_t start_max, int64_t duration,
1860  bool optional,
1861  const std::string& name);
1862 
1866  int count, int64_t start_min, int64_t start_max, int64_t duration,
1867  bool optional, const std::string& name,
1868  std::vector<IntervalVar*>* const array);
1869 
1873  int64_t duration,
1874  const std::string& name);
1875 
1879  int64_t duration,
1880  IntVar* const performed_variable,
1881  const std::string& name);
1882 
1886  const std::vector<IntVar*>& start_variables, int64_t duration,
1887  const std::string& name, std::vector<IntervalVar*>* const array);
1888 
1892  const std::vector<IntVar*>& start_variables,
1893  const std::vector<int64_t>& durations, const std::string& name,
1894  std::vector<IntervalVar*>* const array);
1898  const std::vector<IntVar*>& start_variables,
1899  const std::vector<int>& durations, const std::string& name,
1900  std::vector<IntervalVar*>* const array);
1901 
1905  const std::vector<IntVar*>& start_variables,
1906  const std::vector<int64_t>& durations,
1907  const std::vector<IntVar*>& performed_variables, const std::string& name,
1908  std::vector<IntervalVar*>* const array);
1909 
1913  const std::vector<IntVar*>& start_variables,
1914  const std::vector<int>& durations,
1915  const std::vector<IntVar*>& performed_variables, const std::string& name,
1916  std::vector<IntervalVar*>* const array);
1917 
1919  IntervalVar* MakeFixedInterval(int64_t start, int64_t duration,
1920  const std::string& name);
1921 
1924  IntervalVar* MakeIntervalVar(int64_t start_min, int64_t start_max,
1925  int64_t duration_min, int64_t duration_max,
1926  int64_t end_min, int64_t end_max, bool optional,
1927  const std::string& name);
1928 
1931  void MakeIntervalVarArray(int count, int64_t start_min, int64_t start_max,
1932  int64_t duration_min, int64_t duration_max,
1933  int64_t end_min, int64_t end_max, bool optional,
1934  const std::string& name,
1935  std::vector<IntervalVar*>* const array);
1936 
1940 
1946  IntervalVar* const interval_var, int64_t duration, int64_t offset);
1947 
1953  IntervalVar* const interval_var, int64_t duration, int64_t offset);
1954 
1960  IntervalVar* const interval_var, int64_t duration, int64_t offset);
1961 
1967  IntervalVar* const interval_var, int64_t duration, int64_t offset);
1968 
1987 
2006 
2010  UnaryIntervalRelation r, int64_t d);
2011 
2015  IntervalVar* const t2);
2016 
2023  IntervalVar* const t2,
2024  int64_t delay);
2025 
2030  IntervalVar* const t2, IntVar* const alt);
2031 
2035  IntervalVar* const t2);
2036 
2040  const std::vector<IntervalVar*>& intervals, const std::string& name);
2041 
2046  const std::vector<IntervalVar*>& intervals, const std::string& name);
2047 
2057  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2058  const std::vector<int64_t>& demands,
2059  int64_t capacity, const std::string& name);
2060 
2070  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2071  const std::vector<int>& demands, int64_t capacity,
2072  const std::string& name);
2073 
2083  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2084  const std::vector<int64_t>& demands,
2085  IntVar* const capacity, const std::string& name);
2086 
2096  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2097  const std::vector<int>& demands,
2098  IntVar* const capacity, const std::string& name);
2099 
2107  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2108  const std::vector<IntVar*>& demands,
2109  int64_t capacity, const std::string& name);
2110 
2118  Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2119  const std::vector<IntVar*>& demands,
2120  IntVar* const capacity, const std::string& name);
2121 
2127  Constraint* MakeCover(const std::vector<IntervalVar*>& vars,
2128  IntervalVar* const target_var);
2129 
2131  Constraint* MakeEquality(IntervalVar* const var1, IntervalVar* const var2);
2132 
2135 
2138 
2141  const Assignment* const assignment);
2145 
2148  const Assignment* const assignment);
2152 
2158  const Assignment* const assignment, bool maximize);
2165 
2170  const Assignment* const assignment, int solution_count, bool maximize);
2172  bool maximize);
2173 
2176  const Assignment* const assignment);
2180 
2182  OptimizeVar* MakeMinimize(IntVar* const v, int64_t step);
2183 
2185  OptimizeVar* MakeMaximize(IntVar* const v, int64_t step);
2186 
2188  OptimizeVar* MakeOptimize(bool maximize, IntVar* const v, int64_t step);
2189 
2192  OptimizeVar* MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
2193  const std::vector<int64_t>& weights,
2194  int64_t step);
2195 
2198  OptimizeVar* MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
2199  const std::vector<int>& weights,
2200  int64_t step);
2201 
2203  OptimizeVar* MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
2204  const std::vector<int64_t>& weights,
2205  int64_t step);
2206 
2208  OptimizeVar* MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
2209  const std::vector<int>& weights,
2210  int64_t step);
2211 
2214  const std::vector<IntVar*>& sub_objectives,
2215  const std::vector<int64_t>& weights,
2216  int64_t step);
2217 
2220  const std::vector<IntVar*>& sub_objectives,
2221  const std::vector<int>& weights,
2222  int64_t step);
2223 
2225 
2241 
2242  SearchMonitor* MakeTabuSearch(bool maximize, IntVar* const v, int64_t step,
2243  const std::vector<IntVar*>& vars,
2244  int64_t keep_tenure, int64_t forbid_tenure,
2245  double tabu_factor);
2246 
2249  SearchMonitor* MakeGenericTabuSearch(bool maximize, IntVar* const v,
2250  int64_t step,
2251  const std::vector<IntVar*>& tabu_vars,
2252  int64_t forbid_tenure);
2253 
2255  // TODO(user): document behavior
2256  SearchMonitor* MakeSimulatedAnnealing(bool maximize, IntVar* const v,
2257  int64_t step,
2258  int64_t initial_temperature);
2259 
2263  bool maximize, IntVar* objective, IndexEvaluator2 objective_function,
2264  int64_t step, const std::vector<IntVar*>& vars, double penalty_factor,
2265  bool reset_penalties_on_new_best_solution = false);
2267  bool maximize, IntVar* objective, IndexEvaluator3 objective_function,
2268  int64_t step, const std::vector<IntVar*>& vars,
2269  const std::vector<IntVar*>& secondary_vars, double penalty_factor,
2270  bool reset_penalties_on_new_best_solution = false);
2271 
2275  SearchMonitor* MakeLubyRestart(int scale_factor);
2276 
2280 
2282  ABSL_MUST_USE_RESULT RegularLimit* MakeTimeLimit(absl::Duration time);
2283 #if !defined(SWIG)
2284  ABSL_DEPRECATED("Use the version taking absl::Duration() as argument")
2285 #endif // !defined(SWIG)
2286  ABSL_MUST_USE_RESULT RegularLimit* MakeTimeLimit(int64_t time_in_ms) {
2287  return MakeTimeLimit(time_in_ms == kint64max
2288  ? absl::InfiniteDuration()
2289  : absl::Milliseconds(time_in_ms));
2290  }
2291 
2294  ABSL_MUST_USE_RESULT RegularLimit* MakeBranchesLimit(int64_t branches);
2295 
2298  ABSL_MUST_USE_RESULT RegularLimit* MakeFailuresLimit(int64_t failures);
2299 
2302  ABSL_MUST_USE_RESULT RegularLimit* MakeSolutionsLimit(int64_t solutions);
2303 
2306  // timer by estimating the number of remaining calls, and 'cumulative' means
2307  // that the limit applies cumulatively, instead of search-by-search.
2308  ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(absl::Duration time,
2309  int64_t branches,
2310  int64_t failures,
2311  int64_t solutions,
2312  bool smart_time_check = false,
2313  bool cumulative = false);
2315  ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(
2316  const RegularLimitParameters& proto);
2317 
2318 #if !defined(SWIG)
2319  ABSL_DEPRECATED("Use other MakeLimit() versions")
2320 #endif // !defined(SWIG)
2321  ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(int64_t time, int64_t branches,
2322  int64_t failures,
2323  int64_t solutions,
2324  bool smart_time_check = false,
2325  bool cumulative = false);
2326 
2328  RegularLimitParameters MakeDefaultRegularLimitParameters() const;
2329 
2333  ABSL_MUST_USE_RESULT SearchLimit* MakeLimit(SearchLimit* const limit_1,
2334  SearchLimit* const limit_2);
2335 
2341  IntVar* objective_var, bool maximize, double objective_scaling_factor,
2342  double objective_offset, double improvement_rate_coefficient,
2343  int improvement_rate_solutions_distance);
2344 
2347  ABSL_MUST_USE_RESULT SearchLimit* MakeCustomLimit(
2348  std::function<bool()> limiter);
2349 
2350  // TODO(user): DEPRECATE API of MakeSearchLog(.., IntVar* var,..).
2351 
2354  SearchMonitor* MakeSearchLog(int branch_period);
2355 
2357  SearchMonitor* MakeSearchLog(int branch_period, IntVar* const var);
2358 
2361  SearchMonitor* MakeSearchLog(int branch_period,
2362  std::function<std::string()> display_callback);
2363 
2366  SearchMonitor* MakeSearchLog(int branch_period, IntVar* var,
2367  std::function<std::string()> display_callback);
2368 
2371  SearchMonitor* MakeSearchLog(int branch_period, OptimizeVar* const opt_var);
2372 
2375  SearchMonitor* MakeSearchLog(int branch_period, OptimizeVar* const opt_var,
2376  std::function<std::string()> display_callback);
2377 
2382  int branch_period = 1;
2386  IntVar* variable = nullptr;
2390  double scaling_factor = 1.0;
2391  double offset = 0;
2395  std::function<std::string()> display_callback;
2399  };
2401 
2404  SearchMonitor* MakeSearchTrace(const std::string& prefix);
2405 
2407  SearchMonitor* MakeEnterSearchCallback(std::function<void()> callback);
2408  SearchMonitor* MakeExitSearchCallback(std::function<void()> callback);
2409  SearchMonitor* MakeAtSolutionCallback(std::function<void()> callback);
2410 
2415 #if !defined(SWIG)
2418  absl::flat_hash_map<const IntVar*, int>* const map);
2419 #endif // !defined(SWIG)
2420 
2423  const std::vector<SymmetryBreaker*>& visitors);
2426  SymmetryBreaker* const v2);
2428  SymmetryBreaker* const v2,
2429  SymmetryBreaker* const v3);
2431  SymmetryBreaker* const v2,
2432  SymmetryBreaker* const v3,
2433  SymmetryBreaker* const v4);
2434 
2436  Decision* MakeAssignVariableValue(IntVar* const var, int64_t val);
2437  Decision* MakeVariableLessOrEqualValue(IntVar* const var, int64_t value);
2438  Decision* MakeVariableGreaterOrEqualValue(IntVar* const var, int64_t value);
2439  Decision* MakeSplitVariableDomain(IntVar* const var, int64_t val,
2440  bool start_with_lower_half);
2441  Decision* MakeAssignVariableValueOrFail(IntVar* const var, int64_t value);
2443  int64_t value);
2444  Decision* MakeAssignVariablesValues(const std::vector<IntVar*>& vars,
2445  const std::vector<int64_t>& values);
2447  const std::vector<IntVar*>& vars, const std::vector<int64_t>& values);
2448  Decision* MakeAssignVariablesValuesOrFail(const std::vector<IntVar*>& vars,
2449  const std::vector<int64_t>& values);
2452 
2462  DecisionBuilder* const db2);
2464  DecisionBuilder* const db2,
2465  DecisionBuilder* const db3);
2467  DecisionBuilder* const db2,
2468  DecisionBuilder* const db3,
2469  DecisionBuilder* const db4);
2470  DecisionBuilder* Compose(const std::vector<DecisionBuilder*>& dbs);
2471 
2483  // TODO(user): The search tree can be balanced by using binary
2490  DecisionBuilder* const db3);
2492  DecisionBuilder* const db3, DecisionBuilder* const db4);
2493  DecisionBuilder* Try(const std::vector<DecisionBuilder*>& dbs);
2494 
2496  // TODO(user): name each of them differently, and document them (and do that
2498  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2499  IntVarStrategy var_str, IntValueStrategy val_str);
2500  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2501  IndexEvaluator1 var_evaluator,
2502  IntValueStrategy val_str);
2503 
2504  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2505  IntVarStrategy var_str,
2506  IndexEvaluator2 value_evaluator);
2507 
2510  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2511  IntVarStrategy var_str,
2512  VariableValueComparator var_val1_val2_comparator);
2513 
2514  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2515  IndexEvaluator1 var_evaluator,
2516  IndexEvaluator2 value_evaluator);
2517 
2518  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2519  IntVarStrategy var_str,
2520  IndexEvaluator2 value_evaluator,
2521  IndexEvaluator1 tie_breaker);
2522 
2523  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2524  IndexEvaluator1 var_evaluator,
2525  IndexEvaluator2 value_evaluator,
2526  IndexEvaluator1 tie_breaker);
2527 
2528  DecisionBuilder* MakeDefaultPhase(const std::vector<IntVar*>& vars);
2529  DecisionBuilder* MakeDefaultPhase(const std::vector<IntVar*>& vars,
2531 
2534  IntValueStrategy val_str);
2535  DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1,
2536  IntVarStrategy var_str, IntValueStrategy val_str);
2537  DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1,
2538  IntVar* const v2, IntVarStrategy var_str,
2539  IntValueStrategy val_str);
2540  DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1,
2541  IntVar* const v2, IntVar* const v3,
2542  IntVarStrategy var_str, IntValueStrategy val_str);
2543 
2549  Decision* MakeScheduleOrPostpone(IntervalVar* const var, int64_t est,
2550  int64_t* const marker);
2551 
2557  Decision* MakeScheduleOrExpedite(IntervalVar* const var, int64_t est,
2558  int64_t* const marker);
2559 
2562  Decision* MakeRankFirstInterval(SequenceVar* const sequence, int index);
2563 
2566  Decision* MakeRankLastInterval(SequenceVar* const sequence, int index);
2567 
2573  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2575 
2583  DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2584  IndexEvaluator2 eval, IndexEvaluator1 tie_breaker,
2585  EvaluatorStrategy str);
2586 
2588  DecisionBuilder* MakePhase(const std::vector<IntervalVar*>& intervals,
2589  IntervalStrategy str);
2590 
2591  DecisionBuilder* MakePhase(const std::vector<SequenceVar*>& sequences,
2592  SequenceStrategy str);
2593 
2597  Assignment* const assignment, DecisionBuilder* const db,
2598  const std::vector<IntVar*>& vars);
2599 
2603 
2610  SearchMonitor* const monitor1);
2612  SearchMonitor* const monitor1,
2613  SearchMonitor* const monitor2);
2615  SearchMonitor* const monitor1,
2616  SearchMonitor* const monitor2,
2617  SearchMonitor* const monitor3);
2619  SearchMonitor* const monitor1,
2620  SearchMonitor* const monitor2,
2621  SearchMonitor* const monitor3,
2622  SearchMonitor* const monitor4);
2624  const std::vector<SearchMonitor*>& monitors);
2625 
2634  Assignment* const solution, bool maximize,
2635  int64_t step);
2637  Assignment* const solution, bool maximize,
2638  int64_t step,
2639  SearchMonitor* const monitor1);
2641  Assignment* const solution, bool maximize,
2642  int64_t step,
2643  SearchMonitor* const monitor1,
2644  SearchMonitor* const monitor2);
2646  Assignment* const solution, bool maximize,
2647  int64_t step,
2648  SearchMonitor* const monitor1,
2649  SearchMonitor* const monitor2,
2650  SearchMonitor* const monitor3);
2652  Assignment* const solution, bool maximize,
2653  int64_t step,
2654  SearchMonitor* const monitor1,
2655  SearchMonitor* const monitor2,
2656  SearchMonitor* const monitor3,
2657  SearchMonitor* const monitor4);
2659  DecisionBuilder* const db, Assignment* const solution, bool maximize,
2660  int64_t step, const std::vector<SearchMonitor*>& monitors);
2661 
2665 
2669 
2671  LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2673  LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2674  const std::vector<IntVar*>& secondary_vars,
2676  // TODO(user): Make the callback an IndexEvaluator2 when there are no
2677  // secondary variables.
2678  LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2679  IndexEvaluator3 evaluator,
2681  LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2682  const std::vector<IntVar*>& secondary_vars,
2683  IndexEvaluator3 evaluator,
2685 
2693  LocalSearchOperator* MakeRandomLnsOperator(const std::vector<IntVar*>& vars,
2694  int number_of_variables);
2695  LocalSearchOperator* MakeRandomLnsOperator(const std::vector<IntVar*>& vars,
2696  int number_of_variables,
2697  int32_t seed);
2698 
2705 
2713  const std::vector<IntVar*>& variables,
2714  const std::vector<int64_t>& target_values);
2715 
2747  const std::vector<LocalSearchOperator*>& ops);
2749  const std::vector<LocalSearchOperator*>& ops, bool restart);
2751  const std::vector<LocalSearchOperator*>& ops,
2752  std::function<int64_t(int, int)> evaluator);
2756  const std::vector<LocalSearchOperator*>& ops);
2757 
2762  const std::vector<LocalSearchOperator*>& ops, int32_t seed);
2763 
2772  const std::vector<LocalSearchOperator*>& ops, double memory_coefficient,
2773  double exploration_coefficient, bool maximize);
2774 
2781  int64_t limit);
2782 
2807  // TODO(user): Make a variant which runs a local search after each
2808  // solution found in a DFS.
2809 
2811  Assignment* const assignment,
2812  LocalSearchPhaseParameters* const parameters);
2814  const std::vector<IntVar*>& vars, DecisionBuilder* const first_solution,
2815  LocalSearchPhaseParameters* const parameters);
2818  const std::vector<IntVar*>& vars, DecisionBuilder* const first_solution,
2819  DecisionBuilder* const first_solution_sub_decision_builder,
2820  LocalSearchPhaseParameters* const parameters);
2822  const std::vector<SequenceVar*>& vars,
2823  DecisionBuilder* const first_solution,
2824  LocalSearchPhaseParameters* const parameters);
2825 
2828 
2830  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2831  IntVar* objective, LocalSearchOperator* const ls_operator,
2832  DecisionBuilder* const sub_decision_builder);
2833  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2834  IntVar* objective, LocalSearchOperator* const ls_operator,
2835  DecisionBuilder* const sub_decision_builder, RegularLimit* const limit);
2836  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2837  IntVar* objective, LocalSearchOperator* const ls_operator,
2838  DecisionBuilder* const sub_decision_builder, RegularLimit* const limit,
2839  LocalSearchFilterManager* filter_manager);
2840 
2841  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2842  IntVar* objective, SolutionPool* const pool,
2843  LocalSearchOperator* const ls_operator,
2844  DecisionBuilder* const sub_decision_builder);
2845  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2846  IntVar* objective, SolutionPool* const pool,
2847  LocalSearchOperator* const ls_operator,
2848  DecisionBuilder* const sub_decision_builder, RegularLimit* const limit);
2849  LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters(
2850  IntVar* objective, SolutionPool* const pool,
2851  LocalSearchOperator* const ls_operator,
2852  DecisionBuilder* const sub_decision_builder, RegularLimit* const limit,
2853  LocalSearchFilterManager* filter_manager);
2854 
2860  const std::vector<IntVar*>& vars, IndexEvaluator2 values,
2861  Solver::LocalSearchFilterBound filter_enum);
2863  const std::vector<IntVar*>& vars,
2864  const std::vector<IntVar*>& secondary_vars, IndexEvaluator3 values,
2865  Solver::LocalSearchFilterBound filter_enum);
2866 
2874 
2878  void PushState();
2879  void PopState();
2880 
2883  int SearchDepth() const;
2884 
2887  int SearchLeftDepth() const;
2888 
2891  int SolveDepth() const;
2892 
2895 
2898 
2900  template <class T>
2901  void SaveAndSetValue(T* adr, T val) {
2902  if (*adr != val) {
2903  InternalSaveValue(adr);
2904  *adr = val;
2905  }
2906  }
2907 
2909  template <class T>
2910  void SaveAndAdd(T* adr, T val) {
2911  if (val != 0) {
2912  InternalSaveValue(adr);
2913  (*adr) += val;
2914  }
2915  }
2916 
2918  int64_t Rand64(int64_t size) {
2919  DCHECK_GT(size, 0);
2920  return absl::Uniform<int64_t>(random_, 0, size);
2921  }
2922 
2924  int32_t Rand32(int32_t size) {
2925  DCHECK_GT(size, 0);
2926  return absl::Uniform<int32_t>(random_, 0, size);
2927  }
2928 
2930  void ReSeed(int32_t seed) { random_.seed(seed); }
2931 
2935  void ExportProfilingOverview(const std::string& filename);
2936 
2938  // TODO(user): Merge demon and local search profiles.
2939  std::string LocalSearchProfile() const;
2940 
2941 #if !defined(SWIG)
2943  ConstraintSolverStatistics GetConstraintSolverStatistics() const;
2945  LocalSearchStatistics GetLocalSearchStatistics() const;
2946 #endif // !defined(SWIG)
2947 
2951  bool CurrentlyInSolve() const;
2952 
2955  int constraints() const { return constraints_list_.size(); }
2956 
2958  void Accept(ModelVisitor* const visitor) const;
2959 
2960  Decision* balancing_decision() const { return balancing_decision_.get(); }
2961 
2963 #if !defined(SWIG)
2964  void set_fail_intercept(std::function<void()> fail_intercept) {
2965  fail_intercept_ = std::move(fail_intercept);
2966  }
2967 #endif // !defined(SWIG)
2968  void clear_fail_intercept() { fail_intercept_ = nullptr; }
2970  DemonProfiler* demon_profiler() const { return demon_profiler_; }
2971  // TODO(user): Get rid of the following methods once fast local search is
2974  void SetUseFastLocalSearch(bool use_fast_local_search) {
2975  use_fast_local_search_ = use_fast_local_search;
2976  }
2978  bool UseFastLocalSearch() const { return use_fast_local_search_; }
2980  bool HasName(const PropagationBaseObject* object) const;
2982  Demon* RegisterDemon(Demon* const demon);
2990 
2992  Search* ActiveSearch() const;
2994  ModelCache* Cache() const;
2996  bool InstrumentsDemons() const;
2998  bool IsProfilingEnabled() const;
3002  bool InstrumentsVariables() const;
3004  bool NameAllVariables() const;
3006  std::string model_name() const;
3017  void SetSearchContext(Search* search, const std::string& search_context);
3018  std::string SearchContext() const;
3019  std::string SearchContext(const Search* search) const;
3021  // TODO(user): Investigate if this should be moved to Search.
3024  void ClearLocalSearchState() { local_search_state_.reset(nullptr); }
3025 
3030  std::vector<int64_t> tmp_vector_;
3031 
3032  friend class BaseIntExpr;
3033  friend class Constraint;
3034  friend class DemonProfiler;
3035  friend class FindOneNeighbor;
3036  friend class IntVar;
3038  friend class Queue;
3039  friend class SearchMonitor;
3040  friend class SearchLimit;
3041  friend class RoutingModel;
3042  friend class LocalSearchProfiler;
3043 
3044 #if !defined(SWIG)
3045  friend void InternalSaveBooleanVarValue(Solver* const, IntVar* const);
3046  template <class>
3047  friend class SimpleRevFIFO;
3048  template <class K, class V>
3049  friend class RevImmutableMultiMap;
3050 
3055  bool IsBooleanVar(IntExpr* const expr, IntVar** inner_var,
3056  bool* is_negated) const;
3057 
3062  bool IsProduct(IntExpr* const expr, IntExpr** inner_expr,
3063  int64_t* coefficient);
3064 #endif
3065 
3068  IntExpr* CastExpression(const IntVar* const var) const;
3069 
3073 
3076  void ShouldFail() { should_fail_ = true; }
3077  void CheckFail() {
3078  if (!should_fail_) return;
3079  should_fail_ = false;
3080  Fail();
3081  }
3082 
3085 
3086  private:
3087  void Init();
3088  void PushState(MarkerType t, const StateInfo& info);
3089  MarkerType PopState(StateInfo* info);
3090  void PushSentinel(int magic_code);
3091  void BacktrackToSentinel(int magic_code);
3092  void ProcessConstraints();
3093  bool BacktrackOneLevel(Decision** fail_decision);
3094  void JumpToSentinelWhenNested();
3095  void JumpToSentinel();
3096  void check_alloc_state();
3097  void FreezeQueue();
3098  void EnqueueVar(Demon* const d);
3099  void EnqueueDelayedDemon(Demon* const d);
3100  void ExecuteAll(const SimpleRevFIFO<Demon*>& demons);
3101  void EnqueueAll(const SimpleRevFIFO<Demon*>& demons);
3102  void UnfreezeQueue();
3103  void reset_action_on_fail();
3104  void set_action_on_fail(Action a);
3105  void set_variable_to_clean_on_fail(IntVar* v);
3106  void IncrementUncheckedSolutionCounter();
3107  bool IsUncheckedSolutionLimitReached();
3108 
3109  void InternalSaveValue(int* valptr);
3110  void InternalSaveValue(int64_t* valptr);
3111  void InternalSaveValue(uint64_t* valptr);
3112  void InternalSaveValue(double* valptr);
3113  void InternalSaveValue(bool* valptr);
3114  void InternalSaveValue(void** valptr);
3115  void InternalSaveValue(int64_t** valptr) {
3116  InternalSaveValue(reinterpret_cast<void**>(valptr));
3117  }
3118 
3119  BaseObject* SafeRevAlloc(BaseObject* ptr);
3120 
3121  int* SafeRevAllocArray(int* ptr);
3122  int64_t* SafeRevAllocArray(int64_t* ptr);
3123  uint64_t* SafeRevAllocArray(uint64_t* ptr);
3124  double* SafeRevAllocArray(double* ptr);
3125  BaseObject** SafeRevAllocArray(BaseObject** ptr);
3126  IntVar** SafeRevAllocArray(IntVar** ptr);
3127  IntExpr** SafeRevAllocArray(IntExpr** ptr);
3128  Constraint** SafeRevAllocArray(Constraint** ptr);
3131  void* UnsafeRevAllocAux(void* ptr);
3132  template <class T>
3133  T* UnsafeRevAlloc(T* ptr) {
3134  return reinterpret_cast<T*>(
3135  UnsafeRevAllocAux(reinterpret_cast<void*>(ptr)));
3136  }
3137  void** UnsafeRevAllocArrayAux(void** ptr);
3138  template <class T>
3139  T** UnsafeRevAllocArray(T** ptr) {
3140  return reinterpret_cast<T**>(
3141  UnsafeRevAllocArrayAux(reinterpret_cast<void**>(ptr)));
3142  }
3143 
3144  void InitCachedIntConstants();
3145  void InitCachedConstraint();
3146 
3150  Search* TopLevelSearch() const { return searches_.at(1); }
3154  Search* ParentSearch() const {
3155  const size_t search_size = searches_.size();
3156  DCHECK_GT(search_size, 1);
3157  return searches_[search_size - 2];
3158  }
3159 
3161  std::string GetName(const PropagationBaseObject* object);
3162  void SetName(const PropagationBaseObject* object, const std::string& name);
3163 
3166  int GetNewIntVarIndex() { return num_int_vars_++; }
3167 
3169  bool IsADifference(IntExpr* expr, IntExpr** const left,
3170  IntExpr** const right);
3171 
3172  const std::string name_;
3173  const ConstraintSolverParameters parameters_;
3174  absl::flat_hash_map<const PropagationBaseObject*, std::string>
3175  propagation_object_names_;
3176  absl::flat_hash_map<const PropagationBaseObject*, IntegerCastInfo>
3177  cast_information_;
3178  absl::flat_hash_set<const Constraint*> cast_constraints_;
3179  const std::string empty_name_;
3180  std::unique_ptr<Queue> queue_;
3181  std::unique_ptr<Trail> trail_;
3182  std::vector<Constraint*> constraints_list_;
3183  std::vector<Constraint*> additional_constraints_list_;
3184  std::vector<int> additional_constraints_parent_list_;
3185  SolverState state_;
3186  int64_t branches_;
3187  int64_t fails_;
3188  int64_t decisions_;
3189  int64_t demon_runs_[kNumPriorities];
3190  int64_t neighbors_;
3191  int64_t filtered_neighbors_;
3192  int64_t accepted_neighbors_;
3193  std::string context_;
3194  OptimizationDirection optimization_direction_;
3195  std::unique_ptr<ClockTimer> timer_;
3196  std::vector<Search*> searches_;
3197  std::mt19937 random_;
3198  uint64_t fail_stamp_;
3199  std::unique_ptr<Decision> balancing_decision_;
3201  std::function<void()> fail_intercept_;
3203  DemonProfiler* const demon_profiler_;
3205  bool use_fast_local_search_;
3207  LocalSearchProfiler* const local_search_profiler_;
3209  std::unique_ptr<Assignment> local_search_state_;
3210 
3212  enum { MIN_CACHED_INT_CONST = -8, MAX_CACHED_INT_CONST = 8 };
3213  IntVar* cached_constants_[MAX_CACHED_INT_CONST + 1 - MIN_CACHED_INT_CONST];
3214 
3216  Constraint* true_constraint_;
3217  Constraint* false_constraint_;
3218 
3219  std::unique_ptr<Decision> fail_decision_;
3220  int constraint_index_;
3221  int additional_constraint_index_;
3222  int num_int_vars_;
3223 
3224  std::unique_ptr<ModelCache> model_cache_;
3225  std::unique_ptr<PropagationMonitor> propagation_monitor_;
3226  PropagationMonitor* print_trace_;
3227  std::unique_ptr<LocalSearchMonitor> local_search_monitor_;
3228  int anonymous_variable_index_;
3229  bool should_fail_;
3230 
3231  DISALLOW_COPY_AND_ASSIGN(Solver);
3232 };
3233 
3234 std::ostream& operator<<(std::ostream& out, const Solver* const s);
3235 
3239 inline int64_t Zero() { return 0; }
3240 
3242 inline int64_t One() { return 1; }
3243 
3247 class BaseObject {
3248  public:
3250  virtual ~BaseObject() {}
3251  virtual std::string DebugString() const { return "BaseObject"; }
3252 
3253  private:
3254  DISALLOW_COPY_AND_ASSIGN(BaseObject);
3255 };
3256 
3257 std::ostream& operator<<(std::ostream& out, const BaseObject* o);
3258 
3263  public:
3264  explicit PropagationBaseObject(Solver* const s) : solver_(s) {}
3266 
3267  std::string DebugString() const override {
3268  if (name().empty()) {
3269  return "PropagationBaseObject";
3270  } else {
3271  return absl::StrFormat("PropagationBaseObject: %s", name());
3272  }
3273  }
3274  Solver* solver() const { return solver_; }
3275 
3278  void FreezeQueue() { solver_->FreezeQueue(); }
3279 
3282  void UnfreezeQueue() { solver_->UnfreezeQueue(); }
3283 
3287  void EnqueueDelayedDemon(Demon* const d) { solver_->EnqueueDelayedDemon(d); }
3288  void EnqueueVar(Demon* const d) { solver_->EnqueueVar(d); }
3289  void ExecuteAll(const SimpleRevFIFO<Demon*>& demons);
3290  void EnqueueAll(const SimpleRevFIFO<Demon*>& demons);
3291 
3292 #if !defined(SWIG)
3293  // This method sets a callback that will be called if a failure
3294  // happens during the propagation of the queue.
3296  solver_->set_action_on_fail(std::move(a));
3297  }
3298 #endif // !defined(SWIG)
3299 
3301  void reset_action_on_fail() { solver_->reset_action_on_fail(); }
3302 
3305  solver_->set_variable_to_clean_on_fail(v);
3306  }
3307 
3309  virtual std::string name() const;
3310  void set_name(const std::string& name);
3312  bool HasName() const;
3314  virtual std::string BaseName() const;
3315 
3316  private:
3317  Solver* const solver_;
3318  DISALLOW_COPY_AND_ASSIGN(PropagationBaseObject);
3319 };
3320 
3323 class Decision : public BaseObject {
3324  public:
3326  ~Decision() override {}
3327 
3329  virtual void Apply(Solver* const s) = 0;
3330 
3332  virtual void Refute(Solver* const s) = 0;
3333 
3334  std::string DebugString() const override { return "Decision"; }
3336  virtual void Accept(DecisionVisitor* const visitor) const;
3337 
3338  private:
3339  DISALLOW_COPY_AND_ASSIGN(Decision);
3340 };
3341 
3344 class DecisionVisitor : public BaseObject {
3345  public:
3347  ~DecisionVisitor() override {}
3348  virtual void VisitSetVariableValue(IntVar* const var, int64_t value);
3349  virtual void VisitSplitVariableDomain(IntVar* const var, int64_t value,
3350  bool start_with_lower_half);
3351  virtual void VisitScheduleOrPostpone(IntervalVar* const var, int64_t est);
3352  virtual void VisitScheduleOrExpedite(IntervalVar* const var, int64_t est);
3353  virtual void VisitRankFirstInterval(SequenceVar* const sequence, int index);
3354  virtual void VisitRankLastInterval(SequenceVar* const sequence, int index);
3355  virtual void VisitUnknownDecision();
3356 
3357  private:
3358  DISALLOW_COPY_AND_ASSIGN(DecisionVisitor);
3359 };
3360 
3363 class DecisionBuilder : public BaseObject {
3364  public:
3366  ~DecisionBuilder() override {}
3371  virtual Decision* Next(Solver* const s) = 0;
3372  std::string DebugString() const override;
3373 #if !defined(SWIG)
3378  virtual void AppendMonitors(Solver* const solver,
3379  std::vector<SearchMonitor*>* const extras);
3380  virtual void Accept(ModelVisitor* const visitor) const;
3381 #endif
3382  void set_name(const std::string& name) { name_ = name; }
3383  std::string GetName() const;
3384 
3385  private:
3386  std::string name_;
3387  DISALLOW_COPY_AND_ASSIGN(DecisionBuilder);
3388 };
3389 
3390 #if !defined(SWIG)
3392  public:
3395  const std::string& name() const { return name_; }
3396  double seconds() const { return seconds_; }
3397  Decision* Next(Solver* const solver) override;
3398  std::string DebugString() const override;
3399  void AppendMonitors(Solver* const solver,
3400  std::vector<SearchMonitor*>* const extras) override;
3401  void Accept(ModelVisitor* const visitor) const override;
3402 
3403  private:
3404  DecisionBuilder* const db_;
3405  const std::string name_;
3406  SimpleCycleTimer timer_;
3407  double seconds_;
3408 };
3409 #endif
3410 
3420 class Demon : public BaseObject {
3421  public:
3424  Demon() : stamp_(uint64_t{0}) {}
3425  ~Demon() override {}
3426 
3428  virtual void Run(Solver* const s) = 0;
3429 
3434 
3435  std::string DebugString() const override;
3436 
3439  void inhibit(Solver* const s);
3440 
3442  void desinhibit(Solver* const s);
3443 
3444  private:
3445  friend class Queue;
3446  void set_stamp(int64_t stamp) { stamp_ = stamp; }
3447  uint64_t stamp() const { return stamp_; }
3448  uint64_t stamp_;
3449  DISALLOW_COPY_AND_ASSIGN(Demon);
3450 };
3451 
3453 class ModelVisitor : public BaseObject {
3454  public:
3456  static const char kAbs[];
3457  static const char kAbsEqual[];
3458  static const char kAllDifferent[];
3459  static const char kAllowedAssignments[];
3460  static const char kAtMost[];
3461  static const char kIndexOf[];
3462  static const char kBetween[];
3463  static const char kConditionalExpr[];
3464  static const char kCircuit[];
3465  static const char kConvexPiecewise[];
3466  static const char kCountEqual[];
3467  static const char kCover[];
3468  static const char kCumulative[];
3469  static const char kDeviation[];
3470  static const char kDifference[];
3471  static const char kDisjunctive[];
3472  static const char kDistribute[];
3473  static const char kDivide[];
3474  static const char kDurationExpr[];
3475  static const char kElement[];
3476  static const char kLightElementEqual[];
3477  static const char kElementEqual[];
3478  static const char kEndExpr[];
3479  static const char kEquality[];
3480  static const char kFalseConstraint[];
3481  static const char kGlobalCardinality[];
3482  static const char kGreater[];
3483  static const char kGreaterOrEqual[];
3484  static const char kIntegerVariable[];
3485  static const char kIntervalBinaryRelation[];
3486  static const char kIntervalDisjunction[];
3487  static const char kIntervalUnaryRelation[];
3488  static const char kIntervalVariable[];
3489  static const char kInversePermutation[];
3490  static const char kIsBetween[];
3491  static const char kIsDifferent[];
3492  static const char kIsEqual[];
3493  static const char kIsGreater[];
3494  static const char kIsGreaterOrEqual[];
3495  static const char kIsLess[];
3496  static const char kIsLessOrEqual[];
3497  static const char kIsMember[];
3498  static const char kLess[];
3499  static const char kLessOrEqual[];
3500  static const char kLexLess[];
3501  static const char kLinkExprVar[];
3502  static const char kMapDomain[];
3503  static const char kMax[];
3504  static const char kMaxEqual[];
3505  static const char kMember[];
3506  static const char kMin[];
3507  static const char kMinEqual[];
3508  static const char kModulo[];
3509  static const char kNoCycle[];
3510  static const char kNonEqual[];
3511  static const char kNotBetween[];
3512  static const char kNotMember[];
3513  static const char kNullIntersect[];
3514  static const char kOpposite[];
3515  static const char kPack[];
3516  static const char kPathCumul[];
3517  static const char kDelayedPathCumul[];
3518  static const char kPerformedExpr[];
3519  static const char kPower[];
3520  static const char kProduct[];
3521  static const char kScalProd[];
3522  static const char kScalProdEqual[];
3523  static const char kScalProdGreaterOrEqual[];
3524  static const char kScalProdLessOrEqual[];
3525  static const char kSemiContinuous[];
3526  static const char kSequenceVariable[];
3527  static const char kSortingConstraint[];
3528  static const char kSquare[];
3529  static const char kStartExpr[];
3530  static const char kSum[];
3531  static const char kSumEqual[];
3532  static const char kSumGreaterOrEqual[];
3533  static const char kSumLessOrEqual[];
3534  static const char kTrace[];
3535  static const char kTransition[];
3536  static const char kTrueConstraint[];
3537  static const char kVarBoundWatcher[];
3538  static const char kVarValueWatcher[];
3539 
3541  static const char kCountAssignedItemsExtension[];
3542  static const char kCountUsedBinsExtension[];
3543  static const char kInt64ToBoolExtension[];
3544  static const char kInt64ToInt64Extension[];
3545  static const char kObjectiveExtension[];
3546  static const char kSearchLimitExtension[];
3547  static const char kUsageEqualVariableExtension[];
3548 
3549  static const char kUsageLessConstantExtension[];
3550  static const char kVariableGroupExtension[];
3553 
3555  static const char kActiveArgument[];
3556  static const char kAssumePathsArgument[];
3557  static const char kBranchesLimitArgument[];
3558  static const char kCapacityArgument[];
3559  static const char kCardsArgument[];
3560  static const char kCoefficientsArgument[];
3561  static const char kCountArgument[];
3562  static const char kCumulativeArgument[];
3563  static const char kCumulsArgument[];
3564  static const char kDemandsArgument[];
3565  static const char kDurationMaxArgument[];
3566  static const char kDurationMinArgument[];
3567  static const char kEarlyCostArgument[];
3568  static const char kEarlyDateArgument[];
3569  static const char kEndMaxArgument[];
3570  static const char kEndMinArgument[];
3571  static const char kEndsArgument[];
3572  static const char kExpressionArgument[];
3573  static const char kFailuresLimitArgument[];
3574  static const char kFinalStatesArgument[];
3575  static const char kFixedChargeArgument[];
3576  static const char kIndex2Argument[];
3577  static const char kIndexArgument[];
3578  static const char kInitialState[];
3579  static const char kIntervalArgument[];
3580  static const char kIntervalsArgument[];
3581  static const char kLateCostArgument[];
3582  static const char kLateDateArgument[];
3583  static const char kLeftArgument[];
3584  static const char kMaxArgument[];
3585  static const char kMaximizeArgument[];
3586  static const char kMinArgument[];
3587  static const char kModuloArgument[];
3588  static const char kNextsArgument[];
3589  static const char kOptionalArgument[];
3590  static const char kPartialArgument[];
3591  static const char kPositionXArgument[];
3592  static const char kPositionYArgument[];
3593  static const char kRangeArgument[];
3594  static const char kRelationArgument[];
3595  static const char kRightArgument[];
3596  static const char kSequenceArgument[];
3597  static const char kSequencesArgument[];
3598  static const char kSizeArgument[];
3599  static const char kSizeXArgument[];
3600  static const char kSizeYArgument[];
3601  static const char kSmartTimeCheckArgument[];
3602  static const char kSolutionLimitArgument[];
3603  static const char kStartMaxArgument[];
3604  static const char kStartMinArgument[];
3605  static const char kStartsArgument[];
3606  static const char kStepArgument[];
3607  static const char kTargetArgument[];
3608  static const char kTimeLimitArgument[];
3609  static const char kTransitsArgument[];
3610  static const char kTuplesArgument[];
3611  static const char kValueArgument[];
3612  static const char kValuesArgument[];
3613  static const char kVariableArgument[];
3614  static const char kVarsArgument[];
3615  static const char kEvaluatorArgument[];
3616 
3618  static const char kMirrorOperation[];
3619  static const char kRelaxedMaxOperation[];
3620  static const char kRelaxedMinOperation[];
3621  static const char kSumOperation[];
3622  static const char kDifferenceOperation[];
3623  static const char kProductOperation[];
3624  static const char kStartSyncOnStartOperation[];
3625  static const char kStartSyncOnEndOperation[];
3626  static const char kTraceOperation[];
3627 
3628  ~ModelVisitor() override;
3629 
3631 
3633  virtual void BeginVisitModel(const std::string& type_name);
3634  virtual void EndVisitModel(const std::string& type_name);
3635  virtual void BeginVisitConstraint(const std::string& type_name,
3636  const Constraint* const constraint);
3637  virtual void EndVisitConstraint(const std::string& type_name,
3638  const Constraint* const constraint);
3639  virtual void BeginVisitExtension(const std::string& type);
3640  virtual void EndVisitExtension(const std::string& type);
3641  virtual void BeginVisitIntegerExpression(const std::string& type_name,
3642  const IntExpr* const expr);
3643  virtual void EndVisitIntegerExpression(const std::string& type_name,
3644  const IntExpr* const expr);
3645  virtual void VisitIntegerVariable(const IntVar* const variable,
3646  IntExpr* const delegate);
3647  virtual void VisitIntegerVariable(const IntVar* const variable,
3648  const std::string& operation, int64_t value,
3649  IntVar* const delegate);
3650  virtual void VisitIntervalVariable(const IntervalVar* const variable,
3651  const std::string& operation,
3652  int64_t value,
3653  IntervalVar* const delegate);
3654  virtual void VisitSequenceVariable(const SequenceVar* const variable);
3655 
3657  virtual void VisitIntegerArgument(const std::string& arg_name, int64_t value);
3658  virtual void VisitIntegerArrayArgument(const std::string& arg_name,
3659  const std::vector<int64_t>& values);
3660  virtual void VisitIntegerMatrixArgument(const std::string& arg_name,
3661  const IntTupleSet& tuples);
3662 
3664  virtual void VisitIntegerExpressionArgument(const std::string& arg_name,
3665  IntExpr* const argument);
3666 
3668  const std::string& arg_name, const std::vector<IntVar*>& arguments);
3669 
3671  virtual void VisitIntervalArgument(const std::string& arg_name,
3672  IntervalVar* const argument);
3673 
3675  const std::string& arg_name, const std::vector<IntervalVar*>& arguments);
3677  virtual void VisitSequenceArgument(const std::string& arg_name,
3678  SequenceVar* const argument);
3679 
3681  const std::string& arg_name, const std::vector<SequenceVar*>& arguments);
3682 #if !defined(SWIG)
3685  const std::string& arg_name, const Solver::Int64ToIntVar& arguments);
3686 
3689  void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min,
3690  int64_t index_max);
3692  int64_t index_min, int64_t index_max);
3695  const std::string& arg_name, int64_t index_max);
3696 #endif // #if !defined(SWIG)
3697 };
3698 
3706  public:
3708  ~Constraint() override {}
3709 
3712  virtual void Post() = 0;
3713 
3716  virtual void InitialPropagate() = 0;
3717  std::string DebugString() const override;
3718 
3722 
3724  virtual void Accept(ModelVisitor* const visitor) const;
3725 
3727  bool IsCastConstraint() const;
3728 
3732  virtual IntVar* Var();
3733 
3734  private:
3735  DISALLOW_COPY_AND_ASSIGN(Constraint);
3736 };
3737 
3741 class CastConstraint : public Constraint {
3742  public:
3745  CHECK(target_var != nullptr);
3746  }
3747  ~CastConstraint() override {}
3748 
3749  IntVar* target_var() const { return target_var_; }
3750 
3751  protected:
3753 };
3754 
3756 class SearchMonitor : public BaseObject {
3757  public:
3758  static constexpr int kNoProgress = -1;
3759 
3760  explicit SearchMonitor(Solver* const s) : solver_(s) {}
3761  ~SearchMonitor() override {}
3763  virtual void EnterSearch();
3764 
3766  virtual void RestartSearch();
3767 
3769  virtual void ExitSearch();
3770 
3772  virtual void BeginNextDecision(DecisionBuilder* const b);
3773 
3775  virtual void EndNextDecision(DecisionBuilder* const b, Decision* const d);
3776 
3778  virtual void ApplyDecision(Decision* const d);
3779 
3781  virtual void RefuteDecision(Decision* const d);
3782 
3785  virtual void AfterDecision(Decision* const d, bool apply);
3786 
3788  virtual void BeginFail();
3789 
3791  virtual void EndFail();
3792 
3794  virtual void BeginInitialPropagation();
3795 
3797  virtual void EndInitialPropagation();
3798 
3802  virtual bool AcceptSolution();
3803 
3807  virtual bool AtSolution();
3808 
3810  virtual void NoMoreSolutions();
3811 
3814  virtual bool LocalOptimum();
3815 
3817  virtual bool AcceptDelta(Assignment* delta, Assignment* deltadelta);
3818 
3820  virtual void AcceptNeighbor();
3821 
3823  virtual void AcceptUncheckedNeighbor();
3824 
3827  virtual bool IsUncheckedSolutionLimitReached() { return false; }
3828 
3830  virtual void PeriodicCheck();
3831 
3834  virtual int ProgressPercent() { return kNoProgress; }
3835 
3837  virtual void Accept(ModelVisitor* const visitor) const;
3838 
3842  virtual void Install();
3843 
3844  Solver* solver() const { return solver_; }
3845 
3846  protected:
3848 
3849  private:
3850  Solver* const solver_;
3851  DISALLOW_COPY_AND_ASSIGN(SearchMonitor);
3852 };
3853 
3859 template <class T>
3860 class Rev {
3861  public:
3862  explicit Rev(const T& val) : stamp_(0), value_(val) {}
3863 
3864  const T& Value() const { return value_; }
3865 
3866  void SetValue(Solver* const s, const T& val) {
3867  if (val != value_) {
3868  if (stamp_ < s->stamp()) {
3869  s->SaveValue(&value_);
3870  stamp_ = s->stamp();
3871  }
3872  value_ = val;
3873  }
3874  }
3875 
3876  private:
3877  uint64_t stamp_;
3878  T value_;
3879 };
3880 
3882 template <class T>
3883 class NumericalRev : public Rev<T> {
3884  public:
3885  explicit NumericalRev(const T& val) : Rev<T>(val) {}
3886 
3887  void Add(Solver* const s, const T& to_add) {
3888  this->SetValue(s, this->Value() + to_add);
3889  }
3890 
3891  void Incr(Solver* const s) { Add(s, 1); }
3892 
3893  void Decr(Solver* const s) { Add(s, -1); }
3894 };
3895 
3901 template <class T>
3902 class RevArray {
3903  public:
3904  RevArray(int size, const T& val)
3905  : stamps_(new uint64_t[size]), values_(new T[size]), size_(size) {
3906  for (int i = 0; i < size; ++i) {
3907  stamps_[i] = 0;
3908  values_[i] = val;
3909  }
3910  }
3911 
3913 
3914  int64_t size() const { return size_; }
3915 
3916  const T& Value(int index) const { return values_[index]; }
3917 
3918 #if !defined(SWIG)
3919  const T& operator[](int index) const { return values_[index]; }
3920 #endif
3921 
3922  void SetValue(Solver* const s, int index, const T& val) {
3923  DCHECK_LT(index, size_);
3924  if (val != values_[index]) {
3925  if (stamps_[index] < s->stamp()) {
3926  s->SaveValue(&values_[index]);
3927  stamps_[index] = s->stamp();
3928  }
3929  values_[index] = val;
3930  }
3931  }
3932 
3933  private:
3934  std::unique_ptr<uint64_t[]> stamps_;
3935  std::unique_ptr<T[]> values_;
3936  const int size_;
3937 };
3938 
3940 template <class T>
3941 class NumericalRevArray : public RevArray<T> {
3942  public:
3943  NumericalRevArray(int size, const T& val) : RevArray<T>(size, val) {}
3944 
3945  void Add(Solver* const s, int index, const T& to_add) {
3946  this->SetValue(s, index, this->Value(index) + to_add);
3947  }
3948 
3949  void Incr(Solver* const s, int index) { Add(s, index, 1); }
3950 
3951  void Decr(Solver* const s, int index) { Add(s, index, -1); }
3952 };
3953 
3962  public:
3963  explicit IntExpr(Solver* const s) : PropagationBaseObject(s) {}
3964  ~IntExpr() override {}
3965 
3966  virtual int64_t Min() const = 0;
3967  virtual void SetMin(int64_t m) = 0;
3968  virtual int64_t Max() const = 0;
3969  virtual void SetMax(int64_t m) = 0;
3970 
3973  virtual void Range(int64_t* l, int64_t* u) {
3974  *l = Min();
3975  *u = Max();
3976  }
3978  virtual void SetRange(int64_t l, int64_t u) {
3979  SetMin(l);
3980  SetMax(u);
3981  }
3982 
3984  virtual void SetValue(int64_t v) { SetRange(v, v); }
3985 
3987  virtual bool Bound() const { return (Min() == Max()); }
3988 
3990  virtual bool IsVar() const { return false; }
3991 
3993  virtual IntVar* Var() = 0;
3994 
3999  IntVar* VarWithName(const std::string& name);
4000 
4002  virtual void WhenRange(Demon* d) = 0;
4004  void WhenRange(Solver::Closure closure) {
4005  WhenRange(solver()->MakeClosureDemon(std::move(closure)));
4006  }
4007 
4008 #if !defined(SWIG)
4010  void WhenRange(Solver::Action action) {
4011  WhenRange(solver()->MakeActionDemon(std::move(action)));
4012  }
4013 #endif // SWIG
4014 
4016  virtual void Accept(ModelVisitor* const visitor) const;
4017 
4018  private:
4019  DISALLOW_COPY_AND_ASSIGN(IntExpr);
4020 };
4021 
4029 
4032 
4038 
4039 class IntVarIterator : public BaseObject {
4040  public:
4041  ~IntVarIterator() override {}
4042 
4044  virtual void Init() = 0;
4045 
4047  virtual bool Ok() const = 0;
4048 
4050  virtual int64_t Value() const = 0;
4051 
4053  virtual void Next() = 0;
4054 
4056  std::string DebugString() const override { return "IntVar::Iterator"; }
4057 };
4058 
4059 #ifndef SWIG
4067  public:
4069  : it_(it), begin_was_called_(false) {
4070  it_->Init();
4071  }
4072  struct Iterator;
4073 
4075  if (DEBUG_MODE) {
4076  DCHECK(!begin_was_called_);
4077  begin_was_called_ = true;
4078  }
4079  return Iterator::Begin(it_);
4080  }
4081  Iterator end() { return Iterator::End(it_); }
4082 
4083  struct Iterator {
4086  return Iterator(it, /*is_end=*/false);
4087  }
4089  return Iterator(it, /*is_end=*/true);
4090  }
4091 
4092  int64_t operator*() const {
4093  DCHECK(it_->Ok());
4094  return it_->Value();
4095  }
4097  DCHECK(it_->Ok());
4098  it_->Next();
4099  return *this;
4100  }
4101  bool operator!=(const Iterator& other) const {
4102  DCHECK(other.it_ == it_);
4103  DCHECK(other.is_end_);
4104  return it_->Ok();
4105  }
4106 
4107  private:
4108  Iterator(IntVarIterator* it, bool is_end) : it_(it), is_end_(is_end) {}
4109 
4110  IntVarIterator* const it_;
4111  const bool is_end_;
4112  };
4113 
4114  private:
4115  IntVarIterator* const it_;
4116  bool begin_was_called_;
4117 };
4118 #endif // SWIG
4119 
4123 class IntVar : public IntExpr {
4124  public:
4125  explicit IntVar(Solver* const s);
4126  IntVar(Solver* const s, const std::string& name);
4127  ~IntVar() override {}
4128 
4129  bool IsVar() const override { return true; }
4130  IntVar* Var() override { return this; }
4131 
4134  virtual int64_t Value() const = 0;
4135 
4137  virtual void RemoveValue(int64_t v) = 0;
4138 
4141  virtual void RemoveInterval(int64_t l, int64_t u) = 0;
4142 
4144  virtual void RemoveValues(const std::vector<int64_t>& values);
4145 
4147  virtual void SetValues(const std::vector<int64_t>& values);
4148 
4151  virtual void WhenBound(Demon* d) = 0;
4154  void WhenBound(Solver::Closure closure) {
4155  WhenBound(solver()->MakeClosureDemon(std::move(closure)));
4156  }
4157 
4158 #if !defined(SWIG)
4161  void WhenBound(Solver::Action action) {
4162  WhenBound(solver()->MakeActionDemon(std::move(action)));
4163  }
4164 #endif // SWIG
4165 
4168  virtual void WhenDomain(Demon* d) = 0;
4171  void WhenDomain(Solver::Closure closure) {
4172  WhenDomain(solver()->MakeClosureDemon(std::move(closure)));
4173  }
4174 #if !defined(SWIG)
4178  WhenDomain(solver()->MakeActionDemon(std::move(action)));
4179  }
4180 #endif // SWIG
4181 
4183  virtual uint64_t Size() const = 0;
4184 
4187  virtual bool Contains(int64_t v) const = 0;
4188 
4192  virtual IntVarIterator* MakeHoleIterator(bool reversible) const = 0;
4193 
4197  virtual IntVarIterator* MakeDomainIterator(bool reversible) const = 0;
4198 
4200  virtual int64_t OldMin() const = 0;
4201 
4203  virtual int64_t OldMax() const = 0;
4204 
4205  virtual int VarType() const;
4206 
4208  void Accept(ModelVisitor* const visitor) const override;
4209 
4211  virtual IntVar* IsEqual(int64_t constant) = 0;
4212  virtual IntVar* IsDifferent(int64_t constant) = 0;
4213  virtual IntVar* IsGreaterOrEqual(int64_t constant) = 0;
4214  virtual IntVar* IsLessOrEqual(int64_t constant) = 0;
4215 
4217  int index() const { return index_; }
4218 
4219  private:
4220  const int index_;
4221  DISALLOW_COPY_AND_ASSIGN(IntVar);
4222 };
4223 
4228  public:
4229  SolutionCollector(Solver* const solver, const Assignment* assignment);
4230  explicit SolutionCollector(Solver* const solver);
4232  void Install() override;
4233  std::string DebugString() const override { return "SolutionCollector"; }
4234 
4236  void Add(IntVar* const var);
4237  void Add(const std::vector<IntVar*>& vars);
4238  void Add(IntervalVar* const var);
4239  void Add(const std::vector<IntervalVar*>& vars);
4240  void Add(SequenceVar* const var);
4241  void Add(const std::vector<SequenceVar*>& vars);
4242  void AddObjective(IntVar* const objective);
4243 
4245  void EnterSearch() override;
4246 
4248  int solution_count() const;
4249 
4251  Assignment* solution(int n) const;
4252 
4254  int64_t wall_time(int n) const;
4255 
4257  int64_t branches(int n) const;
4258 
4261  int64_t failures(int n) const;
4262 
4264  int64_t objective_value(int n) const;
4265 
4267  int64_t Value(int n, IntVar* const var) const;
4268 
4270  int64_t StartValue(int n, IntervalVar* const var) const;
4271 
4273  int64_t EndValue(int n, IntervalVar* const var) const;
4274 
4276  int64_t DurationValue(int n, IntervalVar* const var) const;
4277 
4279  int64_t PerformedValue(int n, IntervalVar* const var) const;
4280 
4284  const std::vector<int>& ForwardSequence(int n, SequenceVar* const var) const;
4288  const std::vector<int>& BackwardSequence(int n, SequenceVar* const var) const;
4291  const std::vector<int>& Unperformed(int n, SequenceVar* const var) const;
4292 
4293  protected:
4294  struct SolutionData {
4296  int64_t time;
4297  int64_t branches;
4298  int64_t failures;
4300  bool operator<(const SolutionData& other) const {
4301  return std::tie(solution, time, branches, failures, objective_value) <
4302  std::tie(other.solution, other.time, other.branches,
4303  other.failures, other.objective_value);
4304  }
4305  };
4306 
4309  void Push(const SolutionData& data) { solution_data_.push_back(data); }
4311  void PopSolution();
4314  void check_index(int n) const;
4315 
4316  std::unique_ptr<Assignment> prototype_;
4317  std::vector<SolutionData> solution_data_;
4318  std::vector<Assignment*> recycle_solutions_;
4319 
4320  private:
4321  DISALLOW_COPY_AND_ASSIGN(SolutionCollector);
4322 };
4323 
4324 // TODO(user): Refactor this into an Objective class:
4325 // - print methods for AtNode and AtSolution.
4326 // - support for weighted objective and lexicographical objective.
4327 
4331 class OptimizeVar : public SearchMonitor {
4332  public:
4333  OptimizeVar(Solver* const s, bool maximize, IntVar* const a, int64_t step);
4334  ~OptimizeVar() override;
4335 
4337  int64_t best() const { return best_; }
4338 
4340  IntVar* Var() const { return var_; }
4342  bool AcceptDelta(Assignment* delta, Assignment* deltadelta) override;
4343  void EnterSearch() override;
4344  void BeginNextDecision(DecisionBuilder* const db) override;
4345  void RefuteDecision(Decision* const d) override;
4346  bool AtSolution() override;
4347  bool AcceptSolution() override;
4348  virtual std::string Print() const;
4349  std::string DebugString() const override;
4350  void Accept(ModelVisitor* const visitor) const override;
4351 
4352  void ApplyBound();
4353 
4354  protected:
4355  IntVar* const var_;
4356  int64_t step_;
4357  int64_t best_;
4360 
4361  private:
4362  DISALLOW_COPY_AND_ASSIGN(OptimizeVar);
4363 };
4364 
4366 class SearchLimit : public SearchMonitor {
4367  public:
4368  explicit SearchLimit(Solver* const s) : SearchMonitor(s), crossed_(false) {}
4369  ~SearchLimit() override;
4370 
4372  bool crossed() const { return crossed_; }
4373 
4378  bool Check() { return CheckWithOffset(absl::ZeroDuration()); }
4381  virtual bool CheckWithOffset(absl::Duration offset) = 0;
4382 
4384  virtual void Init() = 0;
4385 
4388  virtual void Copy(const SearchLimit* const limit) = 0;
4389 
4391  virtual SearchLimit* MakeClone() const = 0;
4392 
4394  void EnterSearch() override;
4395  void BeginNextDecision(DecisionBuilder* const b) override;
4396  void PeriodicCheck() override;
4397  void RefuteDecision(Decision* const d) override;
4398  std::string DebugString() const override {
4399  return absl::StrFormat("SearchLimit(crossed = %i)", crossed_);
4400  }
4401  void Install() override;
4402 
4403  private:
4404  void TopPeriodicCheck();
4405 
4406  bool crossed_;
4407  DISALLOW_COPY_AND_ASSIGN(SearchLimit);
4408 };
4409 
4412 class RegularLimit : public SearchLimit {
4413  public:
4414  RegularLimit(Solver* const s, absl::Duration time, int64_t branches,
4415  int64_t failures, int64_t solutions, bool smart_time_check,
4416  bool cumulative);
4417  ~RegularLimit() override;
4418  void Copy(const SearchLimit* const limit) override;
4419  SearchLimit* MakeClone() const override;
4421  bool CheckWithOffset(absl::Duration offset) override;
4422  void Init() override;
4423  void ExitSearch() override;
4424  void UpdateLimits(absl::Duration time, int64_t branches, int64_t failures,
4425  int64_t solutions);
4426  absl::Duration duration_limit() const { return duration_limit_; }
4427  int64_t wall_time() const {
4428  return duration_limit_ == absl::InfiniteDuration()
4429  ? kint64max
4430  : absl::ToInt64Milliseconds(duration_limit());
4431  }
4432  int64_t branches() const { return branches_; }
4433  int64_t failures() const { return failures_; }
4434  int64_t solutions() const { return solutions_; }
4436  int ProgressPercent() override;
4437  std::string DebugString() const override;
4438  void Install() override;
4439 
4440  absl::Time AbsoluteSolverDeadline() const {
4441  return solver_time_at_limit_start_ + duration_limit_;
4442  }
4443 
4444  void Accept(ModelVisitor* const visitor) const override;
4445 
4446  private:
4447  bool CheckTime(absl::Duration offset);
4448  absl::Duration TimeElapsed();
4449  static int64_t GetPercent(int64_t value, int64_t offset, int64_t total) {
4450  return (total > 0 && total < kint64max) ? 100 * (value - offset) / total
4451  : -1;
4452  }
4453 
4454  absl::Duration duration_limit_;
4455  absl::Time solver_time_at_limit_start_;
4456  absl::Duration last_time_elapsed_;
4457  int64_t check_count_;
4458  int64_t next_check_;
4459  bool smart_time_check_;
4460  int64_t branches_;
4461  int64_t branches_offset_;
4462  int64_t failures_;
4463  int64_t failures_offset_;
4464  int64_t solutions_;
4465  int64_t solutions_offset_;
4473  bool cumulative_;
4474 };
4475 
4476 // Limit based on the improvement rate of 'objective_var'.
4477 // This limit proceeds in two stages:
4478 // 1) During the phase of the search in which the objective_var is strictly
4479 // improving, a threshold value is computed as the minimum improvement rate of
4480 // the objective, based on the 'improvement_rate_coefficient' and
4481 // 'improvement_rate_solutions_distance' parameters.
4482 // 2) Then, if the search continues beyond this phase of strict improvement, the
4483 // limit stops the search when the improvement rate of the objective gets below
4484 // this threshold value.
4486  public:
4487  ImprovementSearchLimit(Solver* const s, IntVar* objective_var, bool maximize,
4488  double objective_scaling_factor,
4489  double objective_offset,
4490  double improvement_rate_coefficient,
4491  int improvement_rate_solutions_distance);
4493  void Copy(const SearchLimit* const limit) override;
4494  SearchLimit* MakeClone() const override;
4495  bool CheckWithOffset(absl::Duration offset) override;
4496  bool AtSolution() override;
4497  void Init() override;
4498  void Install() override;
4499 
4500  private:
4501  IntVar* objective_var_;
4502  bool maximize_;
4503  double objective_scaling_factor_;
4504  double objective_offset_;
4505  double improvement_rate_coefficient_;
4506  int improvement_rate_solutions_distance_;
4507 
4508  double best_objective_;
4509  // clang-format off
4510  std::deque<std::pair<double, int64_t> > improvements_;
4511  // clang-format on
4512  double threshold_;
4513  bool objective_updated_;
4514  bool gradient_stage_;
4515 };
4516 
4528  public:
4530  static const int64_t kMinValidValue;
4532  static const int64_t kMaxValidValue;
4533  IntervalVar(Solver* const solver, const std::string& name)
4535  set_name(name);
4536  }
4537  ~IntervalVar() override {}
4538 
4541  virtual int64_t StartMin() const = 0;
4542  virtual int64_t StartMax() const = 0;
4543  virtual void SetStartMin(int64_t m) = 0;
4544  virtual void SetStartMax(int64_t m) = 0;
4545  virtual void SetStartRange(int64_t mi, int64_t ma) = 0;
4546  virtual int64_t OldStartMin() const = 0;
4547  virtual int64_t OldStartMax() const = 0;
4548  virtual void WhenStartRange(Demon* const d) = 0;
4550  WhenStartRange(solver()->MakeClosureDemon(std::move(closure)));
4551  }
4552 #if !defined(SWIG)
4554  WhenStartRange(solver()->MakeActionDemon(std::move(action)));
4555  }
4556 #endif // SWIG
4557  virtual void WhenStartBound(Demon* const d) = 0;
4559  WhenStartBound(solver()->MakeClosureDemon(std::move(closure)));
4560  }
4561 #if !defined(SWIG)
4563  WhenStartBound(solver()->MakeActionDemon(std::move(action)));
4564  }
4565 #endif // SWIG
4566 
4568  virtual int64_t DurationMin() const = 0;
4569  virtual int64_t DurationMax() const = 0;
4570  virtual void SetDurationMin(int64_t m) = 0;
4571  virtual void SetDurationMax(int64_t m) = 0;
4572  virtual void SetDurationRange(int64_t mi, int64_t ma) = 0;
4573  virtual int64_t OldDurationMin() const = 0;
4574  virtual int64_t OldDurationMax() const = 0;
4575  virtual void WhenDurationRange(Demon* const d) = 0;
4577  WhenDurationRange(solver()->MakeClosureDemon(std::move(closure)));
4578  }
4579 #if !defined(SWIG)
4581  WhenDurationRange(solver()->MakeActionDemon(std::move(action)));
4582  }
4583 #endif // SWIG
4584  virtual void WhenDurationBound(Demon* const d) = 0;
4586  WhenDurationBound(solver()->MakeClosureDemon(std::move(closure)));
4587  }
4588 #if !defined(SWIG)
4590  WhenDurationBound(solver()->MakeActionDemon(std::move(action)));
4591  }
4592 #endif // SWIG
4593 
4595  virtual int64_t EndMin() const = 0;
4596  virtual int64_t EndMax() const = 0;
4597  virtual void SetEndMin(int64_t m) = 0;
4598  virtual void SetEndMax(int64_t m) = 0;
4599  virtual void SetEndRange(int64_t mi, int64_t ma) = 0;
4600  virtual int64_t OldEndMin() const = 0;
4601  virtual int64_t OldEndMax() const = 0;
4602  virtual void WhenEndRange(Demon* const d) = 0;
4604  WhenEndRange(solver()->MakeClosureDemon(std::move(closure)));
4605  }
4606 #if !defined(SWIG)
4608  WhenEndRange(solver()->MakeActionDemon(std::move(action)));
4609  }
4610 #endif // SWIG
4611  virtual void WhenEndBound(Demon* const d) = 0;
4613  WhenEndBound(solver()->MakeClosureDemon(std::move(closure)));
4614  }
4615 #if !defined(SWIG)
4617  WhenEndBound(solver()->MakeActionDemon(std::move(action)));
4618  }
4619 #endif // SWIG
4620 
4623  virtual bool MustBePerformed() const = 0;
4624  virtual bool MayBePerformed() const = 0;
4625  bool CannotBePerformed() const { return !MayBePerformed(); }
4626  bool IsPerformedBound() const {
4627  return MustBePerformed() || !MayBePerformed();
4628  }
4629  virtual void SetPerformed(bool val) = 0;
4630  virtual bool WasPerformedBound() const = 0;
4631  virtual void WhenPerformedBound(Demon* const d) = 0;
4633  WhenPerformedBound(solver()->MakeClosureDemon(std::move(closure)));
4634  }
4635 #if !defined(SWIG)
4637  WhenPerformedBound(solver()->MakeActionDemon(std::move(action)));
4638  }
4639 #endif // SWIG
4640 
4642  void WhenAnything(Demon* const d);
4645  WhenAnything(solver()->MakeClosureDemon(std::move(closure)));
4646  }
4647 #if !defined(SWIG)
4650  WhenAnything(solver()->MakeActionDemon(std::move(action)));
4651  }
4652 #endif // SWIG
4653 
4657  virtual IntExpr* StartExpr() = 0;
4658  virtual IntExpr* DurationExpr() = 0;
4659  virtual IntExpr* EndExpr() = 0;
4660  virtual IntExpr* PerformedExpr() = 0;
4664  virtual IntExpr* SafeStartExpr(int64_t unperformed_value) = 0;
4665  virtual IntExpr* SafeDurationExpr(int64_t unperformed_value) = 0;
4666  virtual IntExpr* SafeEndExpr(int64_t unperformed_value) = 0;
4667 
4669  virtual void Accept(ModelVisitor* const visitor) const = 0;
4670 
4671  private:
4672  DISALLOW_COPY_AND_ASSIGN(IntervalVar);
4673 };
4674 
4682  public:
4683  SequenceVar(Solver* const s, const std::vector<IntervalVar*>& intervals,
4684  const std::vector<IntVar*>& nexts, const std::string& name);
4685 
4686  ~SequenceVar() override;
4687 
4688  std::string DebugString() const override;
4689 
4690 #if !defined(SWIG)
4693  void DurationRange(int64_t* const dmin, int64_t* const dmax) const;
4694 
4697  void HorizonRange(int64_t* const hmin, int64_t* const hmax) const;
4698 
4701  void ActiveHorizonRange(int64_t* const hmin, int64_t* const hmax) const;
4702 
4704  void ComputeStatistics(int* const ranked, int* const not_ranked,
4705  int* const unperformed) const;
4706 #endif // !defined(SWIG)
4707 
4710  void RankFirst(int index);
4711 
4714  void RankNotFirst(int index);
4715 
4718  void RankLast(int index);
4719 
4722  void RankNotLast(int index);
4723 
4726  void ComputePossibleFirstsAndLasts(std::vector<int>* const possible_firsts,
4727  std::vector<int>* const possible_lasts);
4728 
4734  void RankSequence(const std::vector<int>& rank_first,
4735  const std::vector<int>& rank_last,
4736  const std::vector<int>& unperformed);
4737 
4746  void FillSequence(std::vector<int>* const rank_first,
4747  std::vector<int>* const rank_last,
4748  std::vector<int>* const unperformed) const;
4749 
4751  IntervalVar* Interval(int index) const;
4752 
4754  IntVar* Next(int index) const;
4755 
4757  int64_t size() const { return intervals_.size(); }
4758 
4760  virtual void Accept(ModelVisitor* const visitor) const;
4761 
4762  private:
4763  int ComputeForwardFrontier();
4764  int ComputeBackwardFrontier();
4765  void UpdatePrevious() const;
4766 
4767  const std::vector<IntervalVar*> intervals_;
4768  const std::vector<IntVar*> nexts_;
4769  mutable std::vector<int> previous_;
4770 };
4771 
4773  public:
4774  AssignmentElement() : activated_(true) {}
4775 
4776  void Activate() { activated_ = true; }
4777  void Deactivate() { activated_ = false; }
4778  bool Activated() const { return activated_; }
4779 
4780  private:
4781  bool activated_;
4782 };
4783 
4785  public:
4787  explicit IntVarElement(IntVar* const var);
4788  void Reset(IntVar* const var);
4790  void Copy(const IntVarElement& element);
4791  IntVar* Var() const { return var_; }
4792  void Store() {
4793  min_ = var_->Min();
4794  max_ = var_->Max();
4795  }
4796  void Restore() {
4797  if (var_ != nullptr) {
4798  var_->SetRange(min_, max_);
4799  }
4800  }
4801  void LoadFromProto(const IntVarAssignment& int_var_assignment_proto);
4802  void WriteToProto(IntVarAssignment* int_var_assignment_proto) const;
4803 
4804  int64_t Min() const { return min_; }
4805  void SetMin(int64_t m) { min_ = m; }
4806  int64_t Max() const { return max_; }
4807  void SetMax(int64_t m) { max_ = m; }
4808  int64_t Value() const {
4809  DCHECK_EQ(min_, max_);
4810  // Get the value from an unbound int var assignment element.
4811  return min_;
4812  }
4813  bool Bound() const { return (max_ == min_); }
4814  void SetRange(int64_t l, int64_t u) {
4815  min_ = l;
4816  max_ = u;
4817  }
4818  void SetValue(int64_t v) {
4819  min_ = v;
4820  max_ = v;
4821  }
4822  std::string DebugString() const;
4823 
4824  bool operator==(const IntVarElement& element) const;
4825  bool operator!=(const IntVarElement& element) const {
4826  return !(*this == element);
4827  }
4828 
4829  private:
4830  IntVar* var_;
4831  int64_t min_;
4832  int64_t max_;
4833 };
4834 
4836  public:
4838  explicit IntervalVarElement(IntervalVar* const var);
4839  void Reset(IntervalVar* const var);
4841  void Copy(const IntervalVarElement& element);
4842  IntervalVar* Var() const { return var_; }
4843  void Store();
4844  void Restore();
4846  const IntervalVarAssignment& interval_var_assignment_proto);
4847  void WriteToProto(IntervalVarAssignment* interval_var_assignment_proto) const;
4848 
4849  int64_t StartMin() const { return start_min_; }
4850  int64_t StartMax() const { return start_max_; }
4851  int64_t StartValue() const {
4852  CHECK_EQ(start_max_, start_min_);
4853  return start_max_;
4854  }
4855  int64_t DurationMin() const { return duration_min_; }
4856  int64_t DurationMax() const { return duration_max_; }
4857  int64_t DurationValue() const {
4858  CHECK_EQ(duration_max_, duration_min_);
4859  return duration_max_;
4860  }
4861  int64_t EndMin() const { return end_min_; }
4862  int64_t EndMax() const { return end_max_; }
4863  int64_t EndValue() const {
4864  CHECK_EQ(end_max_, end_min_);
4865  return end_max_;
4866  }
4867  int64_t PerformedMin() const { return performed_min_; }
4868  int64_t PerformedMax() const { return performed_max_; }
4869  int64_t PerformedValue() const {
4870  CHECK_EQ(performed_max_, performed_min_);
4871  return performed_max_;
4872  }
4873  void SetStartMin(int64_t m) { start_min_ = m; }
4874  void SetStartMax(int64_t m) { start_max_ = m; }
4875  void SetStartRange(int64_t mi, int64_t ma) {
4876  start_min_ = mi;
4877  start_max_ = ma;
4878  }
4879  void SetStartValue(int64_t v) {
4880  start_min_ = v;
4881  start_max_ = v;
4882  }
4883  void SetDurationMin(int64_t m) { duration_min_ = m; }
4884  void SetDurationMax(int64_t m) { duration_max_ = m; }
4885  void SetDurationRange(int64_t mi, int64_t ma) {
4886  duration_min_ = mi;
4887  duration_max_ = ma;
4888  }
4889  void SetDurationValue(int64_t v) {
4890  duration_min_ = v;
4891  duration_max_ = v;
4892  }
4893  void SetEndMin(int64_t m) { end_min_ = m; }
4894  void SetEndMax(int64_t m) { end_max_ = m; }
4895  void SetEndRange(int64_t mi, int64_t ma) {
4896  end_min_ = mi;
4897  end_max_ = ma;
4898  }
4899  void SetEndValue(int64_t v) {
4900  end_min_ = v;
4901  end_max_ = v;
4902  }
4903  void SetPerformedMin(int64_t m) { performed_min_ = m; }
4904  void SetPerformedMax(int64_t m) { performed_max_ = m; }
4905  void SetPerformedRange(int64_t mi, int64_t ma) {
4906  performed_min_ = mi;
4907  performed_max_ = ma;
4908  }
4909  void SetPerformedValue(int64_t v) {
4910  performed_min_ = v;
4911  performed_max_ = v;
4912  }
4913  bool Bound() const {
4914  return (start_min_ == start_max_ && duration_min_ == duration_max_ &&
4915  end_min_ == end_max_ && performed_min_ == performed_max_);
4916  }
4917  std::string DebugString() const;
4918  bool operator==(const IntervalVarElement& element) const;
4919  bool operator!=(const IntervalVarElement& element) const {
4920  return !(*this == element);
4921  }
4922 
4923  private:
4924  int64_t start_min_;
4925  int64_t start_max_;
4926  int64_t duration_min_;
4927  int64_t duration_max_;
4928  int64_t end_min_;
4929  int64_t end_max_;
4930  int64_t performed_min_;
4931  int64_t performed_max_;
4932  IntervalVar* var_;
4933 };
4934 
4949  public:
4951  explicit SequenceVarElement(SequenceVar* const var);
4952  void Reset(SequenceVar* const var);
4954  void Copy(const SequenceVarElement& element);
4955  SequenceVar* Var() const { return var_; }
4956  void Store();
4957  void Restore();
4959  const SequenceVarAssignment& sequence_var_assignment_proto);
4960  void WriteToProto(SequenceVarAssignment* sequence_var_assignment_proto) const;
4961 
4962  const std::vector<int>& ForwardSequence() const;
4963  const std::vector<int>& BackwardSequence() const;
4964  const std::vector<int>& Unperformed() const;
4965  void SetSequence(const std::vector<int>& forward_sequence,
4966  const std::vector<int>& backward_sequence,
4967  const std::vector<int>& unperformed);
4968  void SetForwardSequence(const std::vector<int>& forward_sequence);
4969  void SetBackwardSequence(const std::vector<int>& backward_sequence);
4970  void SetUnperformed(const std::vector<int>& unperformed);
4971  bool Bound() const {
4972  return forward_sequence_.size() + unperformed_.size() == var_->size();
4973  }
4974 
4975  std::string DebugString() const;
4976 
4977  bool operator==(const SequenceVarElement& element) const;
4978  bool operator!=(const SequenceVarElement& element) const {
4979  return !(*this == element);
4980  }
4981 
4982  private:
4983  bool CheckClassInvariants();
4984 
4985  SequenceVar* var_;
4986  std::vector<int> forward_sequence_;
4987  std::vector<int> backward_sequence_;
4988  std::vector<int> unperformed_;
4989 };
4990 
4991 template <class V, class E>
4993  public:
4995  E* Add(V* var) {
4996  CHECK(var != nullptr);
4997  int index = -1;
4998  if (!Find(var, &index)) {
4999  return FastAdd(var);
5000  } else {
5001  return &elements_[index];
5002  }
5003  }
5005  E* FastAdd(V* var) {
5006  DCHECK(var != nullptr);
5007  elements_.emplace_back(var);
5008  return &elements_.back();
5009  }
5012  E* AddAtPosition(V* var, int position) {
5013  elements_[position].Reset(var);
5014  return &elements_[position];
5015  }
5016  void Clear() {
5017  elements_.clear();
5018  if (!elements_map_.empty()) {
5019  elements_map_.clear();
5020  }
5021  }
5024  void Resize(size_t size) { elements_.resize(size); }
5025  bool Empty() const { return elements_.empty(); }
5029  for (int i = 0; i < container.elements_.size(); ++i) {
5030  const E& element = container.elements_[i];
5031  const V* const var = element.Var();
5032  int index = -1;
5033  if (i < elements_.size() && elements_[i].Var() == var) {
5034  index = i;
5035  } else if (!Find(var, &index)) {
5036  continue;
5037  }
5038  DCHECK_GE(index, 0);
5039  E* const local_element = &elements_[index];
5040  local_element->Copy(element);
5041  if (element.Activated()) {
5042  local_element->Activate();
5043  } else {
5044  local_element->Deactivate();
5045  }
5046  }
5047  }
5050  void Copy(const AssignmentContainer<V, E>& container) {
5051  Clear();
5052  for (int i = 0; i < container.elements_.size(); ++i) {
5053  const E& element = container.elements_[i];
5054  FastAdd(element.Var())->Copy(element);
5055  }
5056  }
5057  bool Contains(const V* const var) const {
5058  int index;
5059  return Find(var, &index);
5060  }
5061  E* MutableElement(const V* const var) {
5062  E* const element = MutableElementOrNull(var);
5063  DCHECK(element != nullptr)
5064  << "Unknown variable " << var->DebugString() << " in solution";
5065  return element;
5066  }
5067  E* MutableElementOrNull(const V* const var) {
5068  int index = -1;
5069  if (Find(var, &index)) {
5070  return MutableElement(index);
5071  }
5072  return nullptr;
5073  }
5074  const E& Element(const V* const var) const {
5075  const E* const element = ElementPtrOrNull(var);
5076  DCHECK(element != nullptr)
5077  << "Unknown variable " << var->DebugString() << " in solution";
5078  return *element;
5079  }
5080  const E* ElementPtrOrNull(const V* const var) const {
5081  int index = -1;
5082  if (Find(var, &index)) {
5083  return &Element(index);
5084  }
5085  return nullptr;
5086  }
5087  const std::vector<E>& elements() const { return elements_; }
5088  E* MutableElement(int index) { return &elements_[index]; }
5089  const E& Element(int index) const { return elements_[index]; }
5090  int Size() const { return elements_.size(); }
5091  void Store() {
5092  for (E& element : elements_) {
5093  element.Store();
5094  }
5095  }
5096  void Restore() {
5097  for (E& element : elements_) {
5098  if (element.Activated()) {
5099  element.Restore();
5100  }
5101  }
5102  }
5103  bool AreAllElementsBound() const {
5104  for (const E& element : elements_) {
5105  if (!element.Bound()) return false;
5106  }
5107  return true;
5108  }
5109 
5113  bool operator==(const AssignmentContainer<V, E>& container) const {
5115  if (Size() != container.Size()) {
5116  return false;
5117  }
5119  EnsureMapIsUpToDate();
5123  for (const E& element : container.elements_) {
5124  const int position =
5125  gtl::FindWithDefault(elements_map_, element.Var(), -1);
5126  if (position < 0 || elements_[position] != element) {
5127  return false;
5128  }
5129  }
5130  return true;
5131  }
5132  bool operator!=(const AssignmentContainer<V, E>& container) const {
5133  return !(*this == container);
5134  }
5135 
5136  private:
5137  void EnsureMapIsUpToDate() const {
5138  absl::flat_hash_map<const V*, int>* map =
5139  const_cast<absl::flat_hash_map<const V*, int>*>(&elements_map_);
5140  for (int i = map->size(); i < elements_.size(); ++i) {
5141  (*map)[elements_[i].Var()] = i;
5142  }
5143  }
5144  bool Find(const V* const var, int* index) const {
5146  const size_t kMaxSizeForLinearAccess = 11;
5147  if (Size() <= kMaxSizeForLinearAccess) {
5151  for (int i = 0; i < elements_.size(); ++i) {
5152  if (var == elements_[i].Var()) {
5153  *index = i;
5154  return true;
5155  }
5156  }
5157  return false;
5158  } else {
5159  EnsureMapIsUpToDate();
5160  DCHECK_EQ(elements_map_.size(), elements_.size());
5161  return gtl::FindCopy(elements_map_, var, index);
5162  }
5163  }
5164 
5165  std::vector<E> elements_;
5166  absl::flat_hash_map<const V*, int> elements_map_;
5167 };
5168 
5172  public:
5178 
5179  explicit Assignment(Solver* const s);
5180  explicit Assignment(const Assignment* const copy);
5181  ~Assignment() override;
5182 
5183  void Clear();
5184  bool Empty() const {
5185  return int_var_container_.Empty() && interval_var_container_.Empty() &&
5186  sequence_var_container_.Empty();
5187  }
5188  int Size() const {
5189  return NumIntVars() + NumIntervalVars() + NumSequenceVars();
5190  }
5191  int NumIntVars() const { return int_var_container_.Size(); }
5192  int NumIntervalVars() const { return interval_var_container_.Size(); }
5193  int NumSequenceVars() const { return sequence_var_container_.Size(); }
5194  void Store();
5195  void Restore();
5196 
5199  bool Load(const std::string& filename);
5200 #if !defined(SWIG)
5201  bool Load(File* file);
5202 #endif
5203  void Load(const AssignmentProto& assignment_proto);
5205  bool Save(const std::string& filename) const;
5206 #if !defined(SWIG)
5207  bool Save(File* file) const;
5208 #endif // #if !defined(SWIG)
5209  void Save(AssignmentProto* const assignment_proto) const;
5210 
5211  void AddObjective(IntVar* const v) {
5212  // Objective can only set once.
5213  DCHECK(!HasObjective());
5214  objective_element_.Reset(v);
5215  }
5216  void ClearObjective() { objective_element_.Reset(nullptr); }
5217  IntVar* Objective() const { return objective_element_.Var(); }
5218  bool HasObjective() const { return (Objective() != nullptr); }
5219  int64_t ObjectiveMin() const;
5220  int64_t ObjectiveMax() const;
5221  int64_t ObjectiveValue() const;
5222  bool ObjectiveBound() const;
5223  void SetObjectiveMin(int64_t m);
5224  void SetObjectiveMax(int64_t m);
5225  void SetObjectiveValue(int64_t value);
5226  void SetObjectiveRange(int64_t l, int64_t u);
5227 
5228  IntVarElement* Add(IntVar* const var);
5229  void Add(const std::vector<IntVar*>& vars);
5232  int64_t Min(const IntVar* const var) const;
5233  int64_t Max(const IntVar* const var) const;
5234  int64_t Value(const IntVar* const var) const;
5235  bool Bound(const IntVar* const var) const;
5236  void SetMin(const IntVar* const var, int64_t m);
5237  void SetMax(const IntVar* const var, int64_t m);
5238  void SetRange(const IntVar* const var, int64_t l, int64_t u);
5239  void SetValue(const IntVar* const var, int64_t value);
5240 
5242  void Add(const std::vector<IntervalVar*>& vars);
5245  int64_t StartMin(const IntervalVar* const var) const;
5246  int64_t StartMax(const IntervalVar* const var) const;
5247  int64_t StartValue(const IntervalVar* const var) const;
5248  int64_t DurationMin(const IntervalVar* const var) const;
5249  int64_t DurationMax(const IntervalVar* const var) const;
5250  int64_t DurationValue(const IntervalVar* const var) const;
5251  int64_t EndMin(const IntervalVar* const var) const;
5252  int64_t EndMax(const IntervalVar* const var) const;
5253  int64_t EndValue(const IntervalVar* const var) const;
5254  int64_t PerformedMin(const IntervalVar* const var) const;
5255  int64_t PerformedMax(const IntervalVar* const var) const;
5256  int64_t PerformedValue(const IntervalVar* const var) const;
5257  void SetStartMin(const IntervalVar* const var, int64_t m);
5258  void SetStartMax(const IntervalVar* const var, int64_t m);
5259  void SetStartRange(const IntervalVar* const var, int64_t mi, int64_t ma);
5260  void SetStartValue(const IntervalVar* const var, int64_t value);
5261  void SetDurationMin(const IntervalVar* const var, int64_t m);
5262  void SetDurationMax(const IntervalVar* const var, int64_t m);
5263  void SetDurationRange(const IntervalVar* const var, int64_t mi, int64_t ma);
5264  void SetDurationValue(const IntervalVar* const var, int64_t value);
5265  void SetEndMin(const IntervalVar* const var, int64_t m);
5266  void SetEndMax(const IntervalVar* const var, int64_t m);
5267  void SetEndRange(const IntervalVar* const var, int64_t mi, int64_t ma);
5268  void SetEndValue(const IntervalVar* const var, int64_t value);
5269  void SetPerformedMin(const IntervalVar* const var, int64_t m);
5270  void SetPerformedMax(const IntervalVar* const var, int64_t m);
5271  void SetPerformedRange(const IntervalVar* const var, int64_t mi, int64_t ma);
5272  void SetPerformedValue(const IntervalVar* const var, int64_t value);
5273 
5275  void Add(const std::vector<SequenceVar*>& vars);
5278  const std::vector<int>& ForwardSequence(const SequenceVar* const var) const;
5279  const std::vector<int>& BackwardSequence(const SequenceVar* const var) const;
5280  const std::vector<int>& Unperformed(const SequenceVar* const var) const;
5281  void SetSequence(const SequenceVar* const var,
5282  const std::vector<int>& forward_sequence,
5283  const std::vector<int>& backward_sequence,
5284  const std::vector<int>& unperformed);
5285  void SetForwardSequence(const SequenceVar* const var,
5286  const std::vector<int>& forward_sequence);
5287  void SetBackwardSequence(const SequenceVar* const var,
5288  const std::vector<int>& backward_sequence);
5289  void SetUnperformed(const SequenceVar* const var,
5290  const std::vector<int>& unperformed);
5291 
5292  void Activate(const IntVar* const var);
5293  void Deactivate(const IntVar* const var);
5294  bool Activated(const IntVar* const var) const;
5295 
5296  void Activate(const IntervalVar* const var);
5297  void Deactivate(const IntervalVar* const var);
5298  bool Activated(const IntervalVar* const var) const;
5299 
5300  void Activate(const SequenceVar* const var);
5301  void Deactivate(const SequenceVar* const var);
5302  bool Activated(const SequenceVar* const var) const;
5303 
5306  bool ActivatedObjective() const;
5307 
5308  std::string DebugString() const override;
5309 
5310  bool AreAllElementsBound() const {
5311  return int_var_container_.AreAllElementsBound() &&
5312  interval_var_container_.AreAllElementsBound() &&
5313  sequence_var_container_.AreAllElementsBound();
5314  }
5315 
5316  bool Contains(const IntVar* const var) const;
5317  bool Contains(const IntervalVar* const var) const;
5318  bool Contains(const SequenceVar* const var) const;
5320  void CopyIntersection(const Assignment* assignment);
5323  void Copy(const Assignment* assignment);
5324 
5325  // TODO(user): Add element iterators to avoid exposing container class.
5326  const IntContainer& IntVarContainer() const { return int_var_container_; }
5327  IntContainer* MutableIntVarContainer() { return &int_var_container_; }
5329  return interval_var_container_;
5330  }
5332  return &interval_var_container_;
5333  }
5335  return sequence_var_container_;
5336  }
5338  return &sequence_var_container_;
5339  }
5340  bool operator==(const Assignment& assignment) const {
5341  return int_var_container_ == assignment.int_var_container_ &&
5342  interval_var_container_ == assignment.interval_var_container_ &&
5343  sequence_var_container_ == assignment.sequence_var_container_ &&
5344  objective_element_ == assignment.objective_element_;
5345  }
5346  bool operator!=(const Assignment& assignment) const {
5347  return !(*this == assignment);
5348  }
5349 
5350  private:
5351  IntContainer int_var_container_;
5352  IntervalContainer interval_var_container_;
5353  SequenceContainer sequence_var_container_;
5354  IntVarElement objective_element_;
5355  DISALLOW_COPY_AND_ASSIGN(Assignment);
5356 };
5357 
5358 std::ostream& operator<<(std::ostream& out,
5359  const Assignment& assignment);
5360 
5366 void SetAssignmentFromAssignment(Assignment* target_assignment,
5367  const std::vector<IntVar*>& target_vars,
5368  const Assignment* source_assignment,
5369  const std::vector<IntVar*>& source_vars);
5370 
5371 class Pack : public Constraint {
5372  public:
5373  Pack(Solver* const s, const std::vector<IntVar*>& vars, int number_of_bins);
5374 
5375  ~Pack() override;
5376 
5381 
5386  const std::vector<int64_t>& weights, const std::vector<int64_t>& bounds);
5387 
5393  Solver::IndexEvaluator1 weights, const std::vector<int64_t>& bounds);
5394 
5400  Solver::IndexEvaluator2 weights, const std::vector<int64_t>& bounds);
5401 
5404  void AddWeightedSumEqualVarDimension(const std::vector<int64_t>& weights,
5405  const std::vector<IntVar*>& loads);
5406 
5411  const std::vector<IntVar*>& loads);
5412 
5423  const std::vector<IntVar*>& usage, const std::vector<int64_t>& capacity);
5424 
5427  void AddWeightedSumOfAssignedDimension(const std::vector<int64_t>& weights,
5428  IntVar* const cost_var);
5429 
5432  void AddCountUsedBinDimension(IntVar* const count_var);
5433 
5436  void AddCountAssignedItemsDimension(IntVar* const count_var);
5437 
5438  void Post() override;
5439  void ClearAll();
5441  void InitialPropagate() override;
5442  void Propagate();
5443  void OneDomain(int var_index);
5444  std::string DebugString() const override;
5445  bool IsUndecided(int var_index, int bin_index) const;
5446  void SetImpossible(int var_index, int bin_index);
5447  void Assign(int var_index, int bin_index);
5448  bool IsAssignedStatusKnown(int var_index) const;
5449  bool IsPossible(int var_index, int bin_index) const;
5450  IntVar* AssignVar(int var_index, int bin_index) const;
5451  void SetAssigned(int var_index);
5452  void SetUnassigned(int var_index);
5453  void RemoveAllPossibleFromBin(int bin_index);
5454  void AssignAllPossibleToBin(int bin_index);
5455  void AssignFirstPossibleToBin(int bin_index);
5458  void Accept(ModelVisitor* const visitor) const override;
5459 
5460  private:
5461  bool IsInProcess() const;
5462  const std::vector<IntVar*> vars_;
5463  const int bins_;
5464  std::vector<Dimension*> dims_;
5465  std::unique_ptr<RevBitMatrix> unprocessed_;
5466  std::vector<std::vector<int>> forced_;
5467  std::vector<std::vector<int>> removed_;
5468  std::vector<IntVarIterator*> holes_;
5469  uint64_t stamp_;
5470  Demon* demon_;
5471  std::vector<std::pair<int, int>> to_set_;
5472  std::vector<std::pair<int, int>> to_unset_;
5473  bool in_process_;
5474 };
5475 
5477  public:
5479  const std::vector<IntervalVar*>& intervals,
5480  const std::string& name);
5482 
5485 
5491 
5492  int64_t TransitionTime(int before_index, int after_index) {
5493  DCHECK(transition_time_);
5494  return transition_time_(before_index, after_index);
5495  }
5496 
5497 #if !defined(SWIG)
5498  virtual const std::vector<IntVar*>& nexts() const = 0;
5499  virtual const std::vector<IntVar*>& actives() const = 0;
5500  virtual const std::vector<IntVar*>& time_cumuls() const = 0;
5501  virtual const std::vector<IntVar*>& time_slacks() const = 0;
5502 #endif // !defined(SWIG)
5503 
5504  protected:
5505  const std::vector<IntervalVar*> intervals_;
5507 
5508  private:
5509  DISALLOW_COPY_AND_ASSIGN(DisjunctiveConstraint);
5510 };
5511 
5514 class SolutionPool : public BaseObject {
5515  public:
5517  ~SolutionPool() override {}
5518 
5521  virtual void Initialize(Assignment* const assignment) = 0;
5522 
5525  virtual void RegisterNewSolution(Assignment* const assignment) = 0;
5526 
5529  virtual void GetNextSolution(Assignment* const assignment) = 0;
5530 
5533  virtual bool SyncNeeded(Assignment* const local_assignment) = 0;
5534 };
5535 } // namespace operations_research
5536 
5537 #endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
bool operator==(const AssignmentContainer< V, E > &container) const
Returns true if this and 'container' both represent the same V* -> E map.
const E * ElementPtrOrNull(const V *const var) const
const std::vector< E > & elements() const
bool Contains(const V *const var) const
E * AddAtPosition(V *var, int position)
Advanced usage: Adds element at a given position; position has to have been allocated with Assignment...
void Copy(const AssignmentContainer< V, E > &container)
Copies all the elements of 'container' to this container, clearing its previous content.
bool operator!=(const AssignmentContainer< V, E > &container) const
const E & Element(const V *const var) const
void CopyIntersection(const AssignmentContainer< V, E > &container)
Copies the elements of 'container' which are already in the calling container.
void Resize(size_t size)
Advanced usage: Resizes the container, potentially adding elements with null variables.
E * FastAdd(V *var)
Adds element without checking its presence in the container.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
IntVarElement * Add(IntVar *const var)
bool Activated(const IntervalVar *const var) const
void SetForwardSequence(const SequenceVar *const var, const std::vector< int > &forward_sequence)
void SetStartRange(const IntervalVar *const var, int64_t mi, int64_t ma)
void Deactivate(const IntVar *const var)
int64_t EndMin(const IntervalVar *const var) const
bool Save(File *file) const
int64_t PerformedMin(const IntervalVar *const var) const
int64_t EndMax(const IntervalVar *const var) const
void SetBackwardSequence(const SequenceVar *const var, const std::vector< int > &backward_sequence)
int64_t StartMax(const IntervalVar *const var) const
const IntContainer & IntVarContainer() const
void SetStartMin(const IntervalVar *const var, int64_t m)
SequenceVarElement * Add(SequenceVar *const var)
int64_t DurationMin(const IntervalVar *const var) const
int64_t EndValue(const IntervalVar *const var) const
void SetRange(const IntVar *const var, int64_t l, int64_t u)
const SequenceContainer & SequenceVarContainer() const
void Deactivate(const SequenceVar *const var)
AssignmentContainer< SequenceVar, SequenceVarElement > SequenceContainer
bool Activated(const SequenceVar *const var) const
int64_t StartValue(const IntervalVar *const var) const
bool Contains(const SequenceVar *const var) const
const std::vector< int > & Unperformed(const SequenceVar *const var) const
void SetObjectiveValue(int64_t value)
IntervalVarElement * Add(IntervalVar *const var)
void Add(const std::vector< SequenceVar * > &vars)
bool Load(const std::string &filename)
Loads an assignment from a file; does not add variables to the assignment (only the variables contain...
void SetMax(const IntVar *const var, int64_t m)
const std::vector< int > & ForwardSequence(const SequenceVar *const var) const
void SetDurationMin(const IntervalVar *const var, int64_t m)
int64_t PerformedValue(const IntervalVar *const var) const
int64_t DurationMax(const IntervalVar *const var) const
IntervalVarElement * FastAdd(IntervalVar *const var)
Adds without checking if variable has been previously added.
bool Contains(const IntVar *const var) const
void SetEndRange(const IntervalVar *const var, int64_t mi, int64_t ma)
void Add(const std::vector< IntVar * > &vars)
void Activate(const SequenceVar *const var)
bool Contains(const IntervalVar *const var) const
bool Activated(const IntVar *const var) const
bool Save(const std::string &filename) const
Saves the assignment to a file.
void Add(const std::vector< IntervalVar * > &vars)
void SetPerformedRange(const IntervalVar *const var, int64_t mi, int64_t ma)
int64_t DurationValue(const IntervalVar *const var) const
const std::vector< int > & BackwardSequence(const SequenceVar *const var) const
void SetDurationRange(const IntervalVar *const var, int64_t mi, int64_t ma)
void AddObjective(IntVar *const v)
void SetEndMin(const IntervalVar *const var, int64_t m)
void SetValue(const IntVar *const var, int64_t value)
void Activate(const IntVar *const var)
void SetDurationMax(const IntervalVar *const var, int64_t m)
SequenceContainer * MutableSequenceVarContainer()
int64_t Max(const IntVar *const var) const
int64_t Value(const IntVar *const var) const
void SetStartMax(const IntervalVar *const var, int64_t m)
void SetPerformedMax(const IntervalVar *const var, int64_t m)
IntervalContainer * MutableIntervalVarContainer()
void SetUnperformed(const SequenceVar *const var, const std::vector< int > &unperformed)
void SetObjectiveRange(int64_t l, int64_t u)
void SetMin(const IntVar *const var, int64_t m)
int64_t PerformedMax(const IntervalVar *const var) const
void Deactivate(const IntervalVar *const var)
bool operator==(const Assignment &assignment) const
void SetDurationValue(const IntervalVar *const var, int64_t value)
void CopyIntersection(const Assignment *assignment)
Copies the intersection of the two assignments to the current assignment.
void SetEndValue(const IntervalVar *const var, int64_t value)
AssignmentContainer< IntervalVar, IntervalVarElement > IntervalContainer
SequenceVarElement * FastAdd(SequenceVar *const var)
Adds without checking if the variable had been previously added.
void SetStartValue(const IntervalVar *const var, int64_t value)
void Activate(const IntervalVar *const var)
void SetEndMax(const IntervalVar *const var, int64_t m)
void SetPerformedValue(const IntervalVar *const var, int64_t value)
void SetPerformedMin(const IntervalVar *const var, int64_t m)
void Load(const AssignmentProto &assignment_proto)
#if !defined(SWIG)
void Copy(const Assignment *assignment)
Copies 'assignment' to the current assignment, clearing its previous content.
AssignmentContainer< IntVar, IntVarElement > IntContainer
void SetSequence(const SequenceVar *const var, const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
const IntervalContainer & IntervalVarContainer() const
bool Bound(const IntVar *const var) const
std::string DebugString() const override
int64_t Min(const IntVar *const var) const
void Save(AssignmentProto *const assignment_proto) const
Assignment(const Assignment *const copy)
int64_t StartMin(const IntervalVar *const var) const
bool operator!=(const Assignment &assignment) const
A BaseObject is the root of all reversibly allocated objects.
virtual std::string DebugString() const
Cast constraints are special channeling constraints designed to keep a variable in sync with an expre...
CastConstraint(Solver *const solver, IntVar *const target_var)
A constraint is the main modeling object.
void PostAndPropagate()
Calls Post and then Propagate to initialize the constraints.
bool IsCastConstraint() const
Is the constraint created by a cast from expression to integer variable?
virtual void InitialPropagate()=0
This method performs the initial propagation of the constraint.
virtual IntVar * Var()
Creates a Boolean variable representing the status of the constraint (false = constraint is violated,...
std::string DebugString() const override
virtual void Post()=0
This method is called when the constraint is processed by the solver.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
A DecisionBuilder is responsible for creating the search tree.
virtual Decision * Next(Solver *const s)=0
This is the main method of the decision builder class.
virtual void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras)
This method will be called at the start of the search.
void set_name(const std::string &name)
std::string DebugString() const override
virtual void Accept(ModelVisitor *const visitor) const
A Decision represents a choice point in the search tree.
virtual void Apply(Solver *const s)=0
Apply will be called first when the decision is executed.
virtual void Accept(DecisionVisitor *const visitor) const
Accepts the given visitor.
virtual void Refute(Solver *const s)=0
Refute will be called after a backtrack.
std::string DebugString() const override
A DecisionVisitor is used to inspect a decision.
virtual void VisitScheduleOrExpedite(IntervalVar *const var, int64_t est)
virtual void VisitSetVariableValue(IntVar *const var, int64_t value)
virtual void VisitSplitVariableDomain(IntVar *const var, int64_t value, bool start_with_lower_half)
virtual void VisitRankLastInterval(SequenceVar *const sequence, int index)
virtual void VisitRankFirstInterval(SequenceVar *const sequence, int index)
virtual void VisitScheduleOrPostpone(IntervalVar *const var, int64_t est)
A Demon is the base element of a propagation queue.
void inhibit(Solver *const s)
This method inhibits the demon in the search tree below the current position.
Demon()
This indicates the priority of a demon.
void desinhibit(Solver *const s)
This method un-inhibits the demon that was previously inhibited.
virtual Solver::DemonPriority priority() const
This method returns the priority of the demon.
std::string DebugString() const override
virtual void Run(Solver *const s)=0
This is the main callback of the demon.
const std::vector< IntervalVar * > intervals_
virtual const std::vector< IntVar * > & time_cumuls() const =0
int64_t TransitionTime(int before_index, int after_index)
virtual const std::vector< IntVar * > & actives() const =0
virtual SequenceVar * MakeSequenceVar()=0
Creates a sequence variable from the constraint.
virtual const std::vector< IntVar * > & nexts() const =0
DisjunctiveConstraint(Solver *const s, const std::vector< IntervalVar * > &intervals, const std::string &name)
void SetTransitionTime(Solver::IndexEvaluator2 transition_time)
Add a transition time between intervals.
virtual const std::vector< IntVar * > & time_slacks() const =0
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void Init() override
This method is called when the search limit is initialized.
void Copy(const SearchLimit *const limit) override
Copy a limit.
bool AtSolution() override
This method is called when a valid solution is found.
bool CheckWithOffset(absl::Duration offset) override
Same as Check() but adds the 'offset' value to the current time when time is considered in the limit.
SearchLimit * MakeClone() const override
Allocates a clone of the limit.
ImprovementSearchLimit(Solver *const s, IntVar *objective_var, bool maximize, double objective_scaling_factor, double objective_offset, double improvement_rate_coefficient, int improvement_rate_solutions_distance)
Utility class to encapsulate an IntVarIterator and use it in a range-based loop.
The class IntExpr is the base of all integer expressions in constraint programming.
virtual IntVar * Var()=0
Creates a variable from the expression.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
void WhenRange(Solver::Closure closure)
Attach a demon that will watch the min or the max of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
IntVar * VarWithName(const std::string &name)
Creates a variable from the expression and set the name of the resulting var.
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
virtual int64_t Min() const =0
virtual void SetMax(int64_t m)=0
virtual void SetMin(int64_t m)=0
virtual int64_t Max() const =0
virtual void Range(int64_t *l, int64_t *u)
By default calls Min() and Max(), but can be redefined when Min and Max code can be factorized.
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
void WhenRange(Solver::Action action)
Attach a demon that will watch the min or the max of the expression.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
void Copy(const IntVarElement &element)
bool operator!=(const IntVarElement &element) const
void Reset(IntVar *const var)
bool operator==(const IntVarElement &element) const
void WriteToProto(IntVarAssignment *int_var_assignment_proto) const
void LoadFromProto(const IntVarAssignment &int_var_assignment_proto)
void SetRange(int64_t l, int64_t u)
The class IntVar is a subset of IntExpr.
virtual bool Contains(int64_t v) const =0
This method returns whether the value 'v' is in the domain of the variable.
virtual IntVar * IsDifferent(int64_t constant)=0
virtual int64_t OldMax() const =0
Returns the previous max.
IntVar * Var() override
Creates a variable from the expression.
virtual IntVar * IsGreaterOrEqual(int64_t constant)=0
virtual void RemoveValue(int64_t v)=0
This method removes the value 'v' from the domain of the variable.
void WhenBound(Solver::Closure closure)
This method attaches a closure that will be awakened when the variable is bound.
virtual void WhenBound(Demon *d)=0
This method attaches a demon that will be awakened when the variable is bound.
void WhenDomain(Solver::Closure closure)
This method attaches a closure that will watch any domain modification of the domain of the variable.
virtual IntVarIterator * MakeHoleIterator(bool reversible) const =0
Creates a hole iterator.
virtual void RemoveValues(const std::vector< int64_t > &values)
This method remove the values from the domain of the variable.
virtual IntVar * IsLessOrEqual(int64_t constant)=0
void WhenDomain(Solver::Action action)
This method attaches an action that will watch any domain modification of the domain of the variable.
virtual void SetValues(const std::vector< int64_t > &values)
This method intersects the current domain with the values in the array.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
virtual IntVarIterator * MakeDomainIterator(bool reversible) const =0
Creates a domain iterator.
virtual void RemoveInterval(int64_t l, int64_t u)=0
This method removes the interval 'l' .
virtual IntVar * IsEqual(int64_t constant)=0
IsEqual.
virtual void WhenDomain(Demon *d)=0
This method attaches a demon that will watch any domain modification of the domain of the variable.
IntVar(Solver *const s, const std::string &name)
virtual int64_t Value() const =0
This method returns the value of the variable.
int index() const
Returns the index of the variable.
void WhenBound(Solver::Action action)
This method attaches an action that will be awakened when the variable is bound.
virtual int VarType() const
virtual int64_t OldMin() const =0
Returns the previous min.
bool IsVar() const override
Returns true if the expression is indeed a variable.
virtual uint64_t Size() const =0
This method returns the number of values in the domain of the variable.
The class Iterator has two direct subclasses.
virtual void Init()=0
This method must be called before each loop.
virtual void Next()=0
This method moves the iterator to the next value.
virtual int64_t Value() const =0
This method returns the current value of the iterator.
std::string DebugString() const override
Pretty Print.
virtual bool Ok() const =0
This method indicates if we can call Value() or not.
void LoadFromProto(const IntervalVarAssignment &interval_var_assignment_proto)
void SetDurationRange(int64_t mi, int64_t ma)
bool operator!=(const IntervalVarElement &element) const
void Reset(IntervalVar *const var)
void SetPerformedRange(int64_t mi, int64_t ma)
void SetEndRange(int64_t mi, int64_t ma)
void SetStartRange(int64_t mi, int64_t ma)
IntervalVarElement(IntervalVar *const var)
bool operator==(const IntervalVarElement &element) const
void Copy(const IntervalVarElement &element)
void WriteToProto(IntervalVarAssignment *interval_var_assignment_proto) const
Interval variables are often used in scheduling.
virtual void SetDurationMin(int64_t m)=0
void WhenDurationRange(Solver::Closure closure)
virtual IntExpr * SafeStartExpr(int64_t unperformed_value)=0
These methods create expressions encapsulating the start, end and duration of the interval var.
void WhenAnything(Solver::Closure closure)
Attaches a closure awakened when anything about this interval changes.
void WhenStartBound(Solver::Closure closure)
virtual int64_t DurationMax() const =0
virtual void WhenStartBound(Demon *const d)=0
virtual void SetEndMax(int64_t m)=0
void WhenEndRange(Solver::Closure closure)
void WhenAnything(Demon *const d)
Attaches a demon awakened when anything about this interval changes.
virtual int64_t DurationMin() const =0
These methods query, set, and watch the duration of the interval var.
virtual void SetPerformed(bool val)=0
virtual void SetDurationMax(int64_t m)=0
void WhenEndBound(Solver::Action action)
virtual void WhenEndRange(Demon *const d)=0
virtual int64_t OldEndMax() const =0
virtual void WhenDurationBound(Demon *const d)=0
virtual bool WasPerformedBound() const =0
virtual void SetStartMax(int64_t m)=0
void WhenStartRange(Solver::Action action)
static const int64_t kMinValidValue
The smallest acceptable value to be returned by StartMin()
virtual void SetStartRange(int64_t mi, int64_t ma)=0
virtual void WhenDurationRange(Demon *const d)=0
virtual IntExpr * SafeEndExpr(int64_t unperformed_value)=0
virtual int64_t OldStartMax() const =0
virtual int64_t OldDurationMin() const =0
static const int64_t kMaxValidValue
The largest acceptable value to be returned by EndMax()
virtual int64_t OldEndMin() const =0
virtual void WhenEndBound(Demon *const d)=0
virtual int64_t OldDurationMax() const =0
virtual void Accept(ModelVisitor *const visitor) const =0
Accepts the given visitor.
void WhenDurationBound(Solver::Action action)
virtual bool MustBePerformed() const =0
These methods query, set, and watch the performed status of the interval var.
IntervalVar(Solver *const solver, const std::string &name)
virtual void WhenPerformedBound(Demon *const d)=0
virtual IntExpr * EndExpr()=0
void WhenStartBound(Solver::Action action)
virtual void SetEndMin(int64_t m)=0
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
void WhenAnything(Solver::Action action)
Attaches an action awakened when anything about this interval changes.
virtual IntExpr * PerformedExpr()=0
virtual int64_t StartMin() const =0
These methods query, set, and watch the start position of the interval var.
virtual IntExpr * DurationExpr()=0
void WhenEndRange(Solver::Action action)
void WhenStartRange(Solver::Closure closure)
virtual void WhenStartRange(Demon *const d)=0
virtual IntExpr * StartExpr()=0
These methods create expressions encapsulating the start, end and duration of the interval var.
virtual void SetDurationRange(int64_t mi, int64_t ma)=0
void WhenPerformedBound(Solver::Action action)
virtual int64_t EndMax() const =0
void WhenPerformedBound(Solver::Closure closure)
void WhenEndBound(Solver::Closure closure)
virtual void SetStartMin(int64_t m)=0
virtual bool MayBePerformed() const =0
void WhenDurationRange(Solver::Action action)
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t OldStartMin() const =0
virtual int64_t StartMax() const =0
virtual IntExpr * SafeDurationExpr(int64_t unperformed_value)=0
void WhenDurationBound(Solver::Closure closure)
Local Search Filters are used for fast neighbor pruning.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
The base class for all local search operators.
Implements a complete cache for model elements: expressions and constraints.
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
virtual void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate)
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kUsageEqualVariableExtension[]
static const char kCountUsedBinsExtension[]
virtual void BeginVisitExtension(const std::string &type)
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
virtual void VisitIntegerVariable(const IntVar *const variable, const std::string &operation, int64_t value, IntVar *const delegate)
static const char kVariableGroupExtension[]
void VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1 &eval, const std::string &arg_name, int64_t index_max)
Expands function as array when index min is 0.
static const char kIntervalUnaryRelation[]
static const char kIntervalBinaryRelation[]
static const char kInt64ToInt64Extension[]
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
static const char kUsageLessConstantExtension[]
virtual void VisitSequenceVariable(const SequenceVar *const variable)
void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, int64_t index_max)
Using SWIG on callbacks is troublesome, so we hide these methods during the wrapping.
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint)
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint)
virtual void EndVisitExtension(const std::string &type)
static const char kSmartTimeCheckArgument[]
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
static const char kCountAssignedItemsExtension[]
Extension names:
static const char kSolutionLimitArgument[]
virtual void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate)
static const char kMirrorOperation[]
Operations.
virtual void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments)
static const char kActiveArgument[]
argument names:
static const char kFailuresLimitArgument[]
static const char kBranchesLimitArgument[]
static const char kStartSyncOnStartOperation[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument)
Visit integer expression argument.
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
virtual void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument)
Visit interval argument.
static const char kScalProdGreaterOrEqual[]
static const char kWeightedSumOfAssignedEqualVariableExtension[]
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument)
Visit sequence argument.
static const char kAbs[]
Constraint and Expression types.
static const char kVariableUsageLessConstantExtension[]
static const char kStartSyncOnEndOperation[]
virtual void EndVisitModel(const std::string &type_name)
Subclass of RevArray<T> which adds numerical operations.
void Decr(Solver *const s, int index)
void Add(Solver *const s, int index, const T &to_add)
void Incr(Solver *const s, int index)
Subclass of Rev<T> which adds numerical operations.
void Add(Solver *const s, const T &to_add)
This class encapsulates an objective.
void EnterSearch() override
Beginning of the search.
void BeginNextDecision(DecisionBuilder *const db) override
Before calling DecisionBuilder::Next.
OptimizeVar(Solver *const s, bool maximize, IntVar *const a, int64_t step)
int64_t best() const
Returns the best value found during search.
IntVar * Var() const
Returns the variable that is optimized.
void Accept(ModelVisitor *const visitor) const override
Accepts the given model visitor.
bool AcceptSolution() override
This method is called when a solution is found.
bool AtSolution() override
This method is called when a valid solution is found.
virtual std::string Print() const
void RefuteDecision(Decision *const d) override
Before refuting the decision.
bool AcceptDelta(Assignment *delta, Assignment *deltadelta) override
Internal methods.
std::string DebugString() const override
bool IsAssignedStatusKnown(int var_index) const
void AddWeightedSumEqualVarDimension(const std::vector< int64_t > &weights, const std::vector< IntVar * > &loads)
This dimension imposes that for all bins b, the weighted sum (weights[i]) of all objects i assigned t...
void Post() override
This method is called when the constraint is processed by the solver.
void AddCountAssignedItemsDimension(IntVar *const count_var)
This dimension links 'count_var' to the actual number of items assigned to a bin in the pack.
void AddSumVariableWeightsLessOrEqualConstantDimension(const std::vector< IntVar * > &usage, const std::vector< int64_t > &capacity)
This dimension imposes: forall b in bins, sum (i in items: usage[i] * is_assigned(i,...
void AddWeightedSumLessOrEqualConstantDimension(const std::vector< int64_t > &weights, const std::vector< int64_t > &bounds)
Dimensions are additional constraints than can restrict what is possible with the pack constraint.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
void AddWeightedSumEqualVarDimension(Solver::IndexEvaluator2 weights, const std::vector< IntVar * > &loads)
This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b)) of all objects i as...
Pack(Solver *const s, const std::vector< IntVar * > &vars, int number_of_bins)
void SetImpossible(int var_index, int bin_index)
void SetAssigned(int var_index)
bool IsUndecided(int var_index, int bin_index) const
void AddWeightedSumOfAssignedDimension(const std::vector< int64_t > &weights, IntVar *const cost_var)
This dimension enforces that cost_var == sum of weights[i] for all objects 'i' assigned to a bin.
bool IsPossible(int var_index, int bin_index) const
void AssignFirstPossibleToBin(int bin_index)
void AddCountUsedBinDimension(IntVar *const count_var)
This dimension links 'count_var' to the actual number of bins used in the pack.
void AddWeightedSumLessOrEqualConstantDimension(Solver::IndexEvaluator1 weights, const std::vector< int64_t > &bounds)
This dimension imposes that for all bins b, the weighted sum (weights->Run(i)) of all objects i assig...
IntVar * AssignVar(int var_index, int bin_index) const
void AddWeightedSumLessOrEqualConstantDimension(Solver::IndexEvaluator2 weights, const std::vector< int64_t > &bounds)
This dimension imposes that for all bins b, the weighted sum (weights->Run(i, b) of all objects i ass...
void OneDomain(int var_index)
void SetUnassigned(int var_index)
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
void AssignAllPossibleToBin(int bin_index)
void Assign(int var_index, int bin_index)
std::string DebugString() const override
void RemoveAllPossibleFromBin(int bin_index)
Decision * Next(Solver *const solver) override
This is the main method of the decision builder class.
void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras) override
This method will be called at the start of the search.
void Accept(ModelVisitor *const visitor) const override
std::string DebugString() const override
virtual std::string BaseName() const
Returns a base name for automatic naming.
void EnqueueDelayedDemon(Demon *const d)
This method pushes the demon onto the propagation queue.
void reset_action_on_fail()
This method clears the failure callback.
bool HasName() const
Returns whether the object has been named or not.
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void FreezeQueue()
This method freezes the propagation queue.
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string name() const
Object naming.
void set_variable_to_clean_on_fail(IntVar *v)
Shortcut for variable cleaner.
void set_name(const std::string &name)
void UnfreezeQueue()
This method unfreezes the propagation queue.
Usual limit based on wall_time, number of explored branches and number of failures in the search tree...
absl::Duration duration_limit() const
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
bool IsUncheckedSolutionLimitReached() override
Returns true if the limit of solutions has been reached including unchecked solutions.
void UpdateLimits(absl::Duration time, int64_t branches, int64_t failures, int64_t solutions)
void Init() override
This method is called when the search limit is initialized.
void ExitSearch() override
End of the search.
int ProgressPercent() override
Returns a percentage representing the propress of the search before reaching limits.
RegularLimit * MakeIdenticalClone() const
void Accept(ModelVisitor *const visitor) const override
Accepts the given model visitor.
void Copy(const SearchLimit *const limit) override
Copy a limit.
bool CheckWithOffset(absl::Duration offset) override
Same as Check() but adds the 'offset' value to the current time when time is considered in the limit.
SearchLimit * MakeClone() const override
Allocates a clone of the limit.
RegularLimit(Solver *const s, absl::Duration time, int64_t branches, int64_t failures, int64_t solutions, bool smart_time_check, bool cumulative)
std::string DebugString() const override
Reversible array of POD types.
const T & Value(int index) const
RevArray(int size, const T &val)
void SetValue(Solver *const s, int index, const T &val)
const T & operator[](int index) const
Matrix version of the RevBitSet class.
This class adds reversibility to a POD type.
void SetValue(Solver *const s, const T &val)
Reversible Immutable MultiMap class.
Base class of all search limits.
virtual bool CheckWithOffset(absl::Duration offset)=0
Same as Check() but adds the 'offset' value to the current time when time is considered in the limit.
void EnterSearch() override
Internal methods.
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void PeriodicCheck() override
Periodic call to check limits in long running methods.
virtual void Init()=0
This method is called when the search limit is initialized.
void BeginNextDecision(DecisionBuilder *const b) override
Before calling DecisionBuilder::Next.
virtual void Copy(const SearchLimit *const limit)=0
Copy a limit.
virtual SearchLimit * MakeClone() const =0
Allocates a clone of the limit.
void RefuteDecision(Decision *const d) override
Before refuting the decision.
bool Check()
This method is called to check the status of the limit.
bool crossed() const
Returns true if the limit has been crossed.
std::string DebugString() const override
A search monitor is a simple set of callbacks to monitor all search events.
virtual void RefuteDecision(Decision *const d)
Before refuting the decision.
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
virtual bool IsUncheckedSolutionLimitReached()
Returns true if the limit of solutions has been reached including unchecked solutions.
virtual void ExitSearch()
End of the search.
virtual void EndInitialPropagation()
After the initial propagation.
virtual void PeriodicCheck()
Periodic call to check limits in long running methods.
virtual void BeginFail()
Just when the failure occurs.
virtual void RestartSearch()
Restart the search.
virtual void EnterSearch()
Beginning of the search.
virtual bool AcceptSolution()
This method is called when a solution is found.
virtual int ProgressPercent()
Returns a percentage representing the propress of the search before reaching limits.
virtual void EndFail()
After completing the backtrack.
virtual void AcceptNeighbor()
After accepting a neighbor during local search.
void ListenToEvent(Solver::MonitorEvent event)
virtual void NoMoreSolutions()
When the search tree is finished.
virtual bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
virtual void AfterDecision(Decision *const d, bool apply)
Just after refuting or applying the decision, apply is true after Apply.
virtual bool AtSolution()
This method is called when a valid solution is found.
virtual void EndNextDecision(DecisionBuilder *const b, Decision *const d)
After calling DecisionBuilder::Next, along with the returned decision.
virtual bool LocalOptimum()
When a local optimum is reached.
virtual void BeginNextDecision(DecisionBuilder *const b)
Before calling DecisionBuilder::Next.
virtual void BeginInitialPropagation()
Before the initial propagation.
virtual void AcceptUncheckedNeighbor()
After accepting an unchecked neighbor during local search.
virtual void ApplyDecision(Decision *const d)
Before applying the decision.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
The SequenceVarElement stores a partial representation of ranked interval variables in the underlying...
void SetSequence(const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
void Reset(SequenceVar *const var)
bool operator==(const SequenceVarElement &element) const
bool operator!=(const SequenceVarElement &element) const
void SetBackwardSequence(const std::vector< int > &backward_sequence)
void SetUnperformed(const std::vector< int > &unperformed)
const std::vector< int > & BackwardSequence() const
void Copy(const SequenceVarElement &element)
SequenceVarElement(SequenceVar *const var)
void LoadFromProto(const SequenceVarAssignment &sequence_var_assignment_proto)
void WriteToProto(SequenceVarAssignment *sequence_var_assignment_proto) const
void SetForwardSequence(const std::vector< int > &forward_sequence)
const std::vector< int > & ForwardSequence() const
const std::vector< int > & Unperformed() const
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
void ComputePossibleFirstsAndLasts(std::vector< int > *const possible_firsts, std::vector< int > *const possible_lasts)
Computes the set of indices of interval variables that can be ranked first in the set of unranked act...
void HorizonRange(int64_t *const hmin, int64_t *const hmax) const
Returns the minimum start min and the maximum end max of all interval vars in the sequence.
void FillSequence(std::vector< int > *const rank_first, std::vector< int > *const rank_last, std::vector< int > *const unperformed) const
Clears 'rank_first' and 'rank_last', and fills them with the intervals in the order of the ranks.
void RankSequence(const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)
Applies the following sequence of ranks, ranks first, then rank last.
void ComputeStatistics(int *const ranked, int *const not_ranked, int *const unperformed) const
Compute statistics on the sequence.
void DurationRange(int64_t *const dmin, int64_t *const dmax) const
Returns the minimum and maximum duration of combined interval vars in the sequence.
IntVar * Next(int index) const
Returns the next of the index_th interval of the sequence.
IntervalVar * Interval(int index) const
Returns the index_th interval of the sequence.
void ActiveHorizonRange(int64_t *const hmin, int64_t *const hmax) const
Returns the minimum start min and the maximum end max of all unranked interval vars in the sequence.
int64_t size() const
Returns the number of interval vars in the sequence.
void RankLast(int index)
Ranks the index_th interval var first of all unranked interval vars.
void RankFirst(int index)
Ranks the index_th interval var first of all unranked interval vars.
void RankNotLast(int index)
Indicates that the index_th interval var will not be ranked first of all currently unranked interval ...
void RankNotFirst(int index)
Indicates that the index_th interval var will not be ranked first of all currently unranked interval ...
SequenceVar(Solver *const s, const std::vector< IntervalVar * > &intervals, const std::vector< IntVar * > &nexts, const std::string &name)
std::string DebugString() const override
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
This class represent a reversible FIFO structure.
This class is the root class of all solution collectors.
void EnterSearch() override
Beginning of the search.
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
Assignment * solution(int n) const
Returns the nth solution.
void Push(const SolutionData &data)
void PushSolution()
Push the current state as a new solution.
void AddObjective(IntVar *const objective)
std::vector< Assignment * > recycle_solutions_
const std::vector< int > & ForwardSequence(int n, SequenceVar *const var) const
This is a shortcut to get the ForwardSequence of 'var' in the nth solution.
const std::vector< int > & Unperformed(int n, SequenceVar *const var) const
This is a shortcut to get the list of unperformed of 'var' in the nth solution.
void Add(const std::vector< SequenceVar * > &vars)
std::vector< SolutionData > solution_data_
SolutionCollector(Solver *const solver)
void Add(IntVar *const var)
Add API.
int solution_count() const
Returns how many solutions were stored during the search.
void Add(const std::vector< IntVar * > &vars)
void Add(IntervalVar *const var)
const std::vector< int > & BackwardSequence(int n, SequenceVar *const var) const
This is a shortcut to get the BackwardSequence of 'var' in the nth solution.
void Add(const std::vector< IntervalVar * > &vars)
int64_t Value(int n, IntVar *const var) const
This is a shortcut to get the Value of 'var' in the nth solution.
int64_t DurationValue(int n, IntervalVar *const var) const
This is a shortcut to get the DurationValue of 'var' in the nth solution.
int64_t StartValue(int n, IntervalVar *const var) const
This is a shortcut to get the StartValue of 'var' in the nth solution.
int64_t EndValue(int n, IntervalVar *const var) const
This is a shortcut to get the EndValue of 'var' in the nth solution.
int64_t objective_value(int n) const
Returns the objective value of the nth solution.
int64_t wall_time(int n) const
Returns the wall time in ms for the nth solution.
int64_t branches(int n) const
Returns the number of branches when the nth solution was found.
int64_t PerformedValue(int n, IntervalVar *const var) const
This is a shortcut to get the PerformedValue of 'var' in the nth solution.
void FreeSolution(Assignment *solution)
int64_t failures(int n) const
Returns the number of failures encountered at the time of the nth solution.
std::unique_ptr< Assignment > prototype_
SolutionCollector(Solver *const solver, const Assignment *assignment)
void PopSolution()
Remove and delete the last popped solution.
std::string DebugString() const override
void Add(SequenceVar *const var)
This class is used to manage a pool of solutions.
virtual bool SyncNeeded(Assignment *const local_assignment)=0
This method checks if the local solution needs to be updated with an external one.
virtual void RegisterNewSolution(Assignment *const assignment)=0
This method is called when a new solution has been accepted by the local search.
virtual void GetNextSolution(Assignment *const assignment)=0
This method is called when the local search starts a new neighborhood to initialize the default assig...
virtual void Initialize(Assignment *const assignment)=0
This method is called to initialize the solution pool with the assignment from the local search.
SolverState state() const
State of the solver.
Constraint * MakePathConnected(std::vector< IntVar * > nexts, std::vector< int64_t > sources, std::vector< int64_t > sinks, std::vector< IntVar * > status)
Constraint enforcing that status[i] is true iff there's a path defined on next variables from sources...
Constraint * MakeEquality(IntervalVar *const var1, IntervalVar *const var2)
This constraints states that the two interval variables are equal.
int64_t neighbors() const
The number of neighbors created.
Decision * MakeAssignVariableValue(IntVar *const var, int64_t val)
Decisions.
DecisionBuilder * MakeProfiledDecisionBuilderWrapper(DecisionBuilder *db)
Activates profiling on a decision builder.
Constraint * MakeScalProdEquality(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefficients, IntVar *const target)
Constraint * MakeLightElement(F values, IntVar *const var, IntVar *const index, std::function< bool()> deep_serialize=nullptr)
Light versions of function-based elements, in constraint version only, well-suited for use within Loc...
IntVar * MakeIsGreaterVar(IntExpr *const left, IntExpr *const right)
status var of (left > right)
void SaveValue(T *o)
reversibility
DecisionModification
The Solver is responsible for creating the search tree.
@ NO_CHANGE
Keeps the default behavior, i.e.
@ SWITCH_BRANCHES
Applies right branch first.
@ KEEP_RIGHT
Left branches are ignored.
@ KEEP_LEFT
Right branches are ignored.
@ KILL_BOTH
Backtracks to the previous decisions, i.e.
bool IsBooleanVar(IntExpr *const expr, IntVar **inner_var, bool *is_negated) const
Returns true if expr represents either boolean_var or 1 - boolean_var.
Constraint * MakeIndexOfFirstMaxValueConstraint(IntVar *index, const std::vector< IntVar * > &vars)
Creates a constraint that binds the index variable to the index of the first variable with the maximu...
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IndexEvaluator2 eval, EvaluatorStrategy str)
Returns a decision builder which assigns values to variables which minimize the values returned by th...
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step, const std::vector< SearchMonitor * > &monitors)
Constraint * MakeScalProdGreaterOrEqual(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coeffs, int64_t cst)
Constraint * MakeNonOverlappingNonStrictBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< IntVar * > &x_size, const std::vector< IntVar * > &y_size)
This constraint states that all the boxes must not overlap.
Decision * MakeScheduleOrPostpone(IntervalVar *const var, int64_t est, int64_t *const marker)
Returns a decision that tries to schedule a task at a given time.
Constraint * MakeCount(const std::vector< IntVar * > &vars, int64_t value, IntVar *const max_count)
|{i | vars[i] == value}| == max_count
Constraint * MakeIsMemberCt(IntExpr *const expr, const std::vector< int64_t > &values, IntVar *const boolvar)
boolvar == (expr in set)
bool SolveAndCommit(DecisionBuilder *const db)
IntVar * MakeIsGreaterOrEqualVar(IntExpr *const left, IntExpr *const right)
status var of (left >= right)
void MakeBoolVarArray(int var_count, const std::string &name, std::vector< IntVar * > *vars)
This method will append the vector vars with 'var_count' boolean variables having name "name<i>" wher...
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *const t1, BinaryIntervalRelation r, IntervalVar *const t2, int64_t delay)
This method creates a relation between two interval vars.
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
Constraint * MakeIsGreaterCt(IntExpr *const left, IntExpr *const right, IntVar *const b)
b == (left > right)
SearchMonitor * MakeSearchLog(int branch_period, OptimizeVar *const opt_var, std::function< std::string()> display_callback)
Creates a search monitor that will also print the result of the display callback.
IntExpr * MakeSemiContinuousExpr(IntExpr *const expr, int64_t fixed_charge, int64_t step)
Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) a >= 0 and b >= 0.
Decision * MakeAssignVariablesValues(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
void ClearLocalSearchState()
Clears the local search state.
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< IntVar * > &demands, IntVar *const capacity, const std::string &name)
This constraint enforces that, for any integer t, the sum of demands corresponding to an interval con...
DecisionBuilder * MakeConstraintAdder(Constraint *const ct)
Returns a decision builder that will add the given constraint to the model.
DemonProfiler * demon_profiler() const
Access to demon profiler.
DisjunctiveConstraint * MakeStrictDisjunctiveConstraint(const std::vector< IntervalVar * > &intervals, const std::string &name)
This constraint forces all interval vars into an non-overlapping sequence.
IntExpr * MakeMin(IntExpr *const expr, int value)
std::min(expr, value)
Constraint * MakeAllowedAssignments(const std::vector< IntVar * > &vars, const IntTupleSet &tuples)
This method creates a constraint where the graph of the relation between the variables is given in ex...
LocalSearchOperator * MakeRandomLnsOperator(const std::vector< IntVar * > &vars, int number_of_variables, int32_t seed)
SolutionCollector * MakeFirstSolutionCollector(const Assignment *const assignment)
Collect the first solution of the search.
int64_t branches() const
The number of branches explored since the creation of the solver.
const ConstraintSolverParameters & const_parameters() const
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int > &card_min, const std::vector< int > &card_max)
Aggregated version of count with bounded cardinalities: forall j in 0 .
IntVar * MakeIntVar(const std::vector< int64_t > &values, const std::string &name)
MakeIntVar will create a variable with the given sparse domain.
bool SolveAndCommit(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
SolveAndCommit using a decision builder and up to three search monitors, usually one for the objectiv...
bool SolveAndCommit(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2, SearchMonitor *const m3)
friend void InternalSaveBooleanVarValue(Solver *const, IntVar *const)
IntervalVar * MakeFixedDurationStartSyncedOnStartIntervalVar(IntervalVar *const interval_var, int64_t duration, int64_t offset)
Creates an interval var with a fixed duration whose start is synchronized with the start of another i...
IntVarLocalSearchFilter * MakeSumObjectiveFilter(const std::vector< IntVar * > &vars, IndexEvaluator2 values, Solver::LocalSearchFilterBound filter_enum)
IntervalVar * MakeFixedDurationEndSyncedOnEndIntervalVar(IntervalVar *const interval_var, int64_t duration, int64_t offset)
Creates an interval var with a fixed duration whose end is synchronized with the end of another inter...
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values, const std::vector< IntVar * > &cards)
Aggregated version of count: |{i | v[i] == values[j]}| == cards[j].
Constraint * MakeFalseConstraint(const std::string &explanation)
SearchMonitor * MakeSymmetryManager(SymmetryBreaker *const v1)
IntVar * MakeBoolVar()
MakeBoolVar will create a variable with a {0, 1} domain.
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int64_t > &card_min, const std::vector< int64_t > &card_max)
Aggregated version of count with bounded cardinalities: forall j in 0 .
SearchMonitor * MakeSymmetryManager(SymmetryBreaker *const v1, SymmetryBreaker *const v2, SymmetryBreaker *const v3, SymmetryBreaker *const v4)
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IntVarStrategy var_str, IndexEvaluator2 value_evaluator)
void NewSearch(DecisionBuilder *const db)
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, SolutionPool *const pool, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder, RegularLimit *const limit, LocalSearchFilterManager *filter_manager)
Constraint * MakeNotMemberCt(IntExpr *const expr, const std::vector< int64_t > &values)
expr not in set.
void MakeFixedDurationIntervalVarArray(const std::vector< IntVar * > &start_variables, const std::vector< int64_t > &durations, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with interval variables built with the corresponding start variables.
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, SolutionPool *const pool, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder, RegularLimit *const limit)
IntVar * MakeIsLessOrEqualCstVar(IntExpr *const var, int64_t value)
status var of (var <= value)
SearchMonitor * MakeSymmetryManager(const std::vector< SymmetryBreaker * > &visitors)
Symmetry Breaking.
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
IntVar ** MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string &name)
Same but allocates an array and returns it.
ModelVisitor * MakePrintModelVisitor()
Prints the model.
SearchMonitor * MakeSearchLog(SearchLogParameters parameters)
LocalSearchStatistics GetLocalSearchStatistics() const
Returns detailed local search statistics.
Constraint * MakeMemberCt(IntExpr *const expr, const std::vector< int64_t > &values)
expr in set.
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step, SearchMonitor *const monitor1, SearchMonitor *const monitor2, SearchMonitor *const monitor3, SearchMonitor *const monitor4)
IntVar * MakeIsGreaterOrEqualCstVar(IntExpr *const var, int64_t value)
status var of (var >= value)
Constraint * MakeLess(IntExpr *const expr, int64_t value)
expr < value
static constexpr int kNumPriorities
Number of priorities for demons.
Constraint * MakeScalProdLessOrEqual(const std::vector< IntVar * > &vars, const std::vector< int > &coefficients, int64_t cst)
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
@ NORMAL_PRIORITY
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
Demon * MakeConstraintInitialPropagateCallback(Constraint *const ct)
This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of ...
Constraint * MakeGreater(IntExpr *const expr, int64_t value)
expr > value
ConstraintSolverParameters parameters() const
Stored Parameters.
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder)
Local Search Phase Parameters.
SolutionCollector * MakeBestValueSolutionCollector(bool maximize)
Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignm...
DecisionBuilder * Compose(DecisionBuilder *const db1, DecisionBuilder *const db2, DecisionBuilder *const db3, DecisionBuilder *const db4)
IntVar * MakeIsLessVar(IntExpr *const left, IntExpr *const right)
status var of (left < right)
IntervalVar * MakeFixedDurationEndSyncedOnStartIntervalVar(IntervalVar *const interval_var, int64_t duration, int64_t offset)
Creates an interval var with a fixed duration whose end is synchronized with the start of another int...
Constraint * MakeGreaterOrEqual(IntExpr *const expr, int value)
expr >= value
LocalSearchFilter * MakeVariableDomainFilter()
int64_t filtered_neighbors() const
The number of filtered neighbors (neighbors accepted by filters).
Assignment * MakeAssignment()
This method creates an empty assignment.
SolverState
This enum represents the state of the solver w.r.t. the search.
@ AT_SOLUTION
After successful NextSolution and before EndSearch.
@ PROBLEM_INFEASIBLE
After search, the model is infeasible.
@ OUTSIDE_SEARCH
Before search, after search.
@ IN_ROOT_NODE
Executing the root node.
@ NO_MORE_SOLUTIONS
After failed NextSolution and before EndSearch.
@ IN_SEARCH
Executing the search code.
Constraint * MakeNullIntersectExcept(const std::vector< IntVar * > &first_vars, const std::vector< IntVar * > &second_vars, int64_t escape_value)
Creates a constraint that states that all variables in the first vector are different from all variab...
Decision * MakeAssignVariableValueOrFail(IntVar *const var, int64_t value)
IntExpr * MakeDifference(IntExpr *const left, IntExpr *const right)
left - right
std::string SearchContext() const
Constraint * MakeAtMost(std::vector< IntVar * > vars, int64_t value, int64_t max_count)
|{i | vars[i] == value}| <= max_count
bool CheckAssignment(Assignment *const solution)
Checks whether the given assignment satisfies all relevant constraints.
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< int > &demands, int64_t capacity, const std::string &name)
This constraint forces that, for any integer t, the sum of the demands corresponding to an interval c...
bool IsProduct(IntExpr *const expr, IntExpr **inner_expr, int64_t *coefficient)
Returns true if expr represents a product of a expr and a constant.
ABSL_MUST_USE_RESULT SearchLimit * MakeCustomLimit(std::function< bool()> limiter)
Callback-based search limit.
Decision * MakeScheduleOrExpedite(IntervalVar *const var, int64_t est, int64_t *const marker)
Returns a decision that tries to schedule a task at a given time.
LocalSearchOperator * RandomConcatenateOperators(const std::vector< LocalSearchOperator * > &ops, int32_t seed)
Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeig...
IntVar * MakeIntVar(const std::vector< int > &values)
MakeIntVar will create a variable with the given sparse domain.
IntVar * MakeBoolVar(const std::string &name)
MakeBoolVar will create a variable with a {0, 1} domain.
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
absl::Time Now() const
The 'absolute time' as seen by the solver.
DecisionBuilder * MakeLocalSearchPhase(const std::vector< IntVar * > &vars, DecisionBuilder *const first_solution, DecisionBuilder *const first_solution_sub_decision_builder, LocalSearchPhaseParameters *const parameters)
Variant with a sub_decison_builder specific to the first solution.
SearchMonitor * MakeSimulatedAnnealing(bool maximize, IntVar *const v, int64_t step, int64_t initial_temperature)
Creates a Simulated Annealing monitor.
LocalSearchFilter * MakeRejectFilter()
OptimizationDirection
Optimization directions.
DecisionBuilder * MakePhase(IntVar *const v0, IntVar *const v1, IntVar *const v2, IntVarStrategy var_str, IntValueStrategy val_str)
static int64_t MemoryUsage()
Current memory usage in bytes.
IntervalStrategy
This enum describes the straregy used to select the next interval variable and its value to be fixed.
@ INTERVAL_SET_TIMES_FORWARD
Selects the variable with the lowest starting time of all variables, and fixes its starting time to t...
@ INTERVAL_SIMPLE
The simple is INTERVAL_SET_TIMES_FORWARD.
@ INTERVAL_SET_TIMES_BACKWARD
Selects the variable with the highest ending time of all variables, and fixes the ending time to this...
@ INTERVAL_DEFAULT
The default is INTERVAL_SET_TIMES_FORWARD.
Constraint * MakeFalseConstraint()
This constraint always fails.
DisjunctiveConstraint * MakeDisjunctiveConstraint(const std::vector< IntervalVar * > &intervals, const std::string &name)
This constraint forces all interval vars into an non-overlapping sequence.
LocalSearchOperator * RandomConcatenateOperators(const std::vector< LocalSearchOperator * > &ops)
Randomized version of local search concatenator; calls a random operator at each call to MakeNextNeig...
std::function< int64_t(int64_t, int64_t, int64_t)> IndexEvaluator3
IntervalVar * MakeIntervalRelaxedMin(IntervalVar *const interval_var)
Creates and returns an interval variable that wraps around the given one, relaxing the min start and ...
Constraint * MakeBetweenCt(IntExpr *const expr, int64_t l, int64_t u)
(l <= expr <= u)
IntVar * MakeIntVar(const std::vector< int64_t > &values)
MakeIntVar will create a variable with the given sparse domain.
LocalSearchOperator * MakeNeighborhoodLimit(LocalSearchOperator *const op, int64_t limit)
Creates a local search operator that wraps another local search operator and limits the number of nei...
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
IntExpr * MakeElement(IndexEvaluator1 values, IntVar *const index)
Function-based element.
SearchMonitor * MakeGenericTabuSearch(bool maximize, IntVar *const v, int64_t step, const std::vector< IntVar * > &tabu_vars, int64_t forbid_tenure)
Creates a Tabu Search based on the vars |vars|.
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder, RegularLimit *const limit)
IntExpr * MakeOpposite(IntExpr *const expr)
-expr
SearchMonitor * MakeAtSolutionCallback(std::function< void()> callback)
SearchMonitor * MakeEnterSearchCallback(std::function< void()> callback)
--— Callback-based search monitors --—
int64_t demon_runs(DemonPriority p) const
The number of demons executed during search for a given priority.
void AddPropagationMonitor(PropagationMonitor *const monitor)
Adds the propagation monitor to the solver.
Constraint * MakeNonEquality(IntExpr *const expr, int64_t value)
expr != value
DecisionBuilder * MakeDecisionBuilderFromAssignment(Assignment *const assignment, DecisionBuilder *const db, const std::vector< IntVar * > &vars)
Returns a decision builder for which the left-most leaf corresponds to assignment,...
Constraint * MakeNonOverlappingBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< int > &x_size, const std::vector< int > &y_size)
IntExpr * MakeDiv(IntExpr *const expr, int64_t value)
expr / value (integer division)
IntExpr * MakeSum(const std::vector< IntVar * > &vars)
sum of all vars.
IntValueStrategy
This enum describes the strategy used to select the next variable value to set.
@ INT_VALUE_SIMPLE
The simple selection is ASSIGN_MIN_VALUE.
@ ASSIGN_CENTER_VALUE
Selects the first possible value which is the closest to the center of the domain of the selected var...
@ SPLIT_UPPER_HALF
Split the domain in two around the center, and choose the lower part first.
@ ASSIGN_MIN_VALUE
Selects the min value of the selected variable.
@ ASSIGN_RANDOM_VALUE
Selects randomly one of the possible values of the selected variable.
@ INT_VALUE_DEFAULT
The default behavior is ASSIGN_MIN_VALUE.
@ ASSIGN_MAX_VALUE
Selects the max value of the selected variable.
@ SPLIT_LOWER_HALF
Split the domain in two around the center, and choose the lower part first.
Constraint * MakeScalProdGreaterOrEqual(const std::vector< IntVar * > &vars, const std::vector< int > &coeffs, int64_t cst)
SearchMonitor * MakeTabuSearch(bool maximize, IntVar *const v, int64_t step, const std::vector< IntVar * > &vars, int64_t keep_tenure, int64_t forbid_tenure, double tabu_factor)
MetaHeuristics which try to get the search out of local optima.
UnaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between an inte...
@ ENDS_BEFORE
t ends before d, i.e. End(t) <= d.
@ AVOID_DATE
STARTS_AFTER or ENDS_BEFORE, i.e.
@ ENDS_AFTER
t ends after d, i.e. End(t) >= d.
@ STARTS_BEFORE
t starts before d, i.e. Start(t) <= d.
@ STARTS_AT
t starts at d, i.e. Start(t) == d.
@ ENDS_AT
t ends at d, i.e. End(t) == d.
@ STARTS_AFTER
t starts after d, i.e. Start(t) >= d.
@ CROSS_DATE
STARTS_BEFORE and ENDS_AFTER at the same time, i.e.
bool CheckConstraint(Constraint *const ct)
Checks whether adding this constraint will lead to an immediate failure.
SolutionCollector * MakeLastSolutionCollector(const Assignment *const assignment)
Collect the last solution of the search.
Pack * MakePack(const std::vector< IntVar * > &vars, int number_of_bins)
This constraint packs all variables onto 'number_of_bins' variables.
void SetSearchContext(Search *search, const std::string &search_context)
bool SolveAndCommit(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2)
IntExpr * MakeDifference(int64_t value, IntExpr *const expr)
value - expr
Constraint * MakeTrueConstraint()
This constraint always succeeds.
IntExpr * MakeModulo(IntExpr *const x, IntExpr *const mod)
Modulo expression x % mod (with the python convention for modulo).
Constraint * MakeTemporalDisjunction(IntervalVar *const t1, IntervalVar *const t2, IntVar *const alt)
This constraint implements a temporal disjunction between two interval vars t1 and t2.
ABSL_MUST_USE_RESULT RegularLimit * MakeTimeLimit(int64_t time_in_ms)
bool Solve(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2)
Constraint * MakeLexicalLessOrEqual(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
Creates a constraint that enforces that left is lexicographically less than or equal to right.
std::function< int64_t(Solver *solver, const std::vector< IntVar * > &vars, int64_t first_unbound, int64_t last_unbound)> VariableIndexSelector
void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string &name, std::vector< IntVar * > *vars)
This method will append the vector vars with 'var_count' variables having bounds vmin and vmax and ha...
ModelCache * Cache() const
Returns the cache of the model.
ABSL_MUST_USE_RESULT SearchLimit * MakeLimit(SearchLimit *const limit_1, SearchLimit *const limit_2)
Creates a search limit that is reached when either of the underlying limit is reached.
void TopPeriodicCheck()
Performs PeriodicCheck on the top-level search; for instance, can be called from a nested solve to ch...
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IndexEvaluator1 var_evaluator, IndexEvaluator2 value_evaluator)
void MakeFixedDurationIntervalVarArray(const std::vector< IntVar * > &start_variables, const std::vector< int > &durations, const std::vector< IntVar * > &performed_variables, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with interval variables built with the corresponding start and performed...
IntervalVar * RegisterIntervalVar(IntervalVar *const var)
Registers a new IntervalVar and wraps it inside a TraceIntervalVar if necessary.
IntVar ** MakeBoolVarArray(int var_count, const std::string &name)
Same but allocates an array and returns it.
int64_t Rand64(int64_t size)
Returns a random value between 0 and 'size' - 1;.
Constraint * MakePathCumul(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, const std::vector< IntVar * > &cumuls, const std::vector< IntVar * > &slacks, IndexEvaluator2 transit_evaluator)
Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + t...
SearchMonitor * MakeExitSearchCallback(std::function< void()> callback)
IntVar * MakeIntVar(const std::vector< int > &values, const std::string &name)
MakeIntVar will create a variable with the given sparse domain.
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step, SearchMonitor *const monitor1, SearchMonitor *const monitor2, SearchMonitor *const monitor3)
Constraint * MakeNotMemberCt(IntExpr *expr, SortedDisjointIntervalList intervals)
expr should not be in the list of forbidden intervals.
SearchMonitor * MakeSearchTrace(const std::string &prefix)
Creates a search monitor that will trace precisely the behavior of the search.
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
LocalSearchOperator * MakeOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, IndexEvaluator3 evaluator, EvaluatorLocalSearchOperators op)
Constraint * MakeGreater(IntExpr *const expr, int value)
expr > value
void SetUseFastLocalSearch(bool use_fast_local_search)
enabled for metaheuristics.
Constraint * MakeNotMemberCt(IntExpr *const expr, std::vector< int64_t > starts, std::vector< int64_t > ends)
expr should not be in the list of forbidden intervals [start[i]..end[i]].
ABSL_MUST_USE_RESULT RegularLimit * MakeLimit(int64_t time, int64_t branches, int64_t failures, int64_t solutions, bool smart_time_check=false, bool cumulative=false)
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IntVarStrategy var_str, VariableValueComparator var_val1_val2_comparator)
var_val1_val2_comparator(var, val1, val2) is true iff assigning value "val1" to variable "var" is bet...
Constraint * MakeGreaterOrEqual(IntExpr *const left, IntExpr *const right)
left >= right
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db, SearchMonitor *const monitor1, SearchMonitor *const monitor2, SearchMonitor *const monitor3, SearchMonitor *const monitor4)
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
void NewSearch(DecisionBuilder *const db, SearchMonitor *const m1)
Constraint * MakeIsLessCt(IntExpr *const left, IntExpr *const right, IntVar *const b)
b == (left < right)
DecisionBuilder * Try(DecisionBuilder *const db1, DecisionBuilder *const db2)
Creates a decision builder which will create a search tree where each decision builder is called from...
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< int > &demands, IntVar *const capacity, const std::string &name)
This constraint enforces that, for any integer t, the sum of the demands corresponding to an interval...
Constraint * MakePathCumul(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, const std::vector< IntVar * > &cumuls, const std::vector< IntVar * > &transits)
Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + t...
bool Solve(DecisionBuilder *const db)
LocalSearchOperator * MakeMoveTowardTargetOperator(const std::vector< IntVar * > &variables, const std::vector< int64_t > &target_values)
Creates a local search operator that tries to move the assignment of some variables toward a target.
bool Solve(DecisionBuilder *const db, SearchMonitor *const m1)
Constraint * MakeNullIntersect(const std::vector< IntVar * > &first_vars, const std::vector< IntVar * > &second_vars)
Creates a constraint that states that all variables in the first vector are different from all variab...
int64_t wall_time() const
DEPRECATED: Use Now() instead.
OptimizeVar * MakeOptimize(bool maximize, IntVar *const v, int64_t step)
Creates a objective with a given sense (true = maximization).
std::function< bool(int64_t)> IndexFilter1
Decision * MakeRankFirstInterval(SequenceVar *const sequence, int index)
Returns a decision that tries to rank first the ith interval var in the sequence variable.
SolutionCollector * MakeNBestValueSolutionCollector(int solution_count, bool maximize)
OptimizeVar * MakeWeightedMaximize(const std::vector< IntVar * > &sub_objectives, const std::vector< int64_t > &weights, int64_t step)
Creates a maximization weigthed objective.
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IndexEvaluator2 eval, IndexEvaluator1 tie_breaker, EvaluatorStrategy str)
Returns a decision builder which assigns values to variables which minimize the values returned by th...
Constraint * MakeElementEquality(const std::vector< int64_t > &vals, IntVar *const index, IntVar *const target)
void ShouldFail()
These methods are only useful for the SWIG wrappers, which need a way to externally cause the Solver ...
int SearchDepth() const
Gets the search depth of the current active search.
Constraint * MakeIndexOfConstraint(const std::vector< IntVar * > &vars, IntVar *const index, int64_t target)
This constraint is a special case of the element constraint with an array of integer variables,...
IntVar * MakeIsEqualCstVar(IntExpr *const var, int64_t value)
status var of (var == value)
IntExpr * MakePiecewiseLinearExpr(IntExpr *expr, const PiecewiseLinearFunction &f)
General piecewise-linear function expression, built from f(x) where f is piecewise-linear.
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
Demon * MakeActionDemon(Action action)
Creates a demon from a callback.
DecisionBuilder * Compose(DecisionBuilder *const db1, DecisionBuilder *const db2)
Creates a decision builder which sequentially composes decision builders.
ABSL_MUST_USE_RESULT ImprovementSearchLimit * MakeImprovementLimit(IntVar *objective_var, bool maximize, double objective_scaling_factor, double objective_offset, double improvement_rate_coefficient, int improvement_rate_solutions_distance)
Limits the search based on the improvements of 'objective_var'.
ABSL_MUST_USE_RESULT RegularLimit * MakeLimit(const RegularLimitParameters &proto)
Creates a search limit from its protobuf description.
Constraint * MakeCircuit(const std::vector< IntVar * > &nexts)
Force the "nexts" variable to create a complete Hamiltonian path.
Constraint * MakeNonEquality(IntExpr *const left, IntExpr *const right)
left != right
Constraint * MakeIsBetweenCt(IntExpr *const expr, int64_t l, int64_t u, IntVar *const b)
b == (l <= expr <= u)
Constraint * MakeIsMemberCt(IntExpr *const expr, const std::vector< int > &values, IntVar *const boolvar)
OptimizeVar * MakeMinimize(IntVar *const v, int64_t step)
Creates a minimization objective.
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
Adds the local search monitor to the solver.
Constraint * MakeIfThenElseCt(IntVar *const condition, IntExpr *const then_expr, IntExpr *const else_expr, IntVar *const target_var)
Special cases with arrays of size two.
OptimizeVar * MakeWeightedMinimize(const std::vector< IntVar * > &sub_objectives, const std::vector< int64_t > &weights, int64_t step)
Creates a minimization weighted objective.
Constraint * MakeScalProdLessOrEqual(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefficients, int64_t cst)
DecisionBuilder * Try(const std::vector< DecisionBuilder * > &dbs)
BinaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between the two...
@ ENDS_AFTER_END
t1 ends after t2 end, i.e. End(t1) >= End(t2) + delay.
@ ENDS_AFTER_START
t1 ends after t2 start, i.e. End(t1) >= Start(t2) + delay.
@ STAYS_IN_SYNC
STARTS_AT_START and ENDS_AT_END at the same time.
@ ENDS_AT_END
t1 ends at t2 end, i.e. End(t1) == End(t2) + delay.
@ STARTS_AT_END
t1 starts at t2 end, i.e. Start(t1) == End(t2) + delay.
@ ENDS_AT_START
t1 ends at t2 start, i.e. End(t1) == Start(t2) + delay.
@ STARTS_AFTER_END
t1 starts after t2 end, i.e. Start(t1) >= End(t2) + delay.
@ STARTS_AFTER_START
t1 starts after t2 start, i.e. Start(t1) >= Start(t2) + delay.
@ STARTS_AT_START
t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay.
Constraint * MakeCover(const std::vector< IntervalVar * > &vars, IntervalVar *const target_var)
This constraint states that the target_var is the convex hull of the intervals.
LocalSearchOperators
This enum is used in Solver::MakeOperator to specify the neighborhood to create.
@ EXCHANGE
Operator which exchanges the positions of two nodes.
@ MAKEINACTIVE
Operator which makes path nodes inactive.
@ RELOCATE
Relocate neighborhood with length of 1 (see OROPT comment).
@ SWAPACTIVE
Operator which replaces an active node by an inactive one.
@ SIMPLELNS
Operator which defines one neighbor per variable.
@ INCREMENT
Operator which defines one neighbor per variable.
@ MAKECHAININACTIVE
Operator which makes a "chain" of path nodes inactive.
@ TWOOPT
Operator which reverses a sub-chain of a path.
@ FULLPATHLNS
Operator which relaxes one entire path and all inactive nodes, thus defining num_paths neighbors.
@ EXTENDEDSWAPACTIVE
Operator which makes an inactive node active and an active one inactive.
@ OROPT
Relocate: OROPT and RELOCATE.
@ PATHLNS
Operator which relaxes two sub-chains of three consecutive arcs each.
@ UNACTIVELNS
Operator which relaxes all inactive nodes and one sub-chain of six consecutive arcs.
@ MAKEACTIVE
Operator which inserts an inactive node into a path.
@ DECREMENT
Operator which defines a neighborhood to decrement values.
@ CROSS
Operator which cross exchanges the starting chains of 2 paths, including exchanging the whole paths.
IntervalVar * MakeFixedInterval(int64_t start, int64_t duration, const std::string &name)
Creates a fixed and performed interval.
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db, SearchMonitor *const monitor1)
SearchMonitor * MakeSymmetryManager(SymmetryBreaker *const v1, SymmetryBreaker *const v2, SymmetryBreaker *const v3)
Constraint * MakeSumEquality(const std::vector< IntVar * > &vars, int64_t cst)
void PushState()
The PushState and PopState methods manipulates the states of the reversible objects.
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db, SearchMonitor *const monitor1, SearchMonitor *const monitor2)
Demon * MakeDelayedConstraintInitialPropagateCallback(Constraint *const ct)
This method is a specialized case of the MakeConstraintDemon method to call the InitiatePropagate of ...
SolutionCollector * MakeLastSolutionCollector()
Collect the last solution of the search.
IntExpr * MakeMax(IntExpr *const expr, int64_t value)
std::max(expr, value)
void ReSeed(int32_t seed)
Reseed the solver random generator.
Constraint * MakeIndexOfFirstMinValueConstraint(IntVar *index, const std::vector< IntVar * > &vars)
Creates a constraint that binds the index variable to the index of the first variable with the minimu...
std::string DebugString() const
!defined(SWIG)
Constraint * MakeNonOverlappingBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< int64_t > &x_size, const std::vector< int64_t > &y_size)
IntVar * MakeIsLessCstVar(IntExpr *const var, int64_t value)
status var of (var < value)
LocalSearchOperator * MakeOperator(const std::vector< IntVar * > &vars, IndexEvaluator3 evaluator, EvaluatorLocalSearchOperators op)
Constraint * MakeSumEquality(const std::vector< IntVar * > &vars, IntVar *const var)
Constraint * MakeNoCycle(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, IndexFilter1 sink_handler=nullptr)
Prevent cycles.
bool Solve(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2, SearchMonitor *const m3, SearchMonitor *const m4)
IntExpr * MakeMin(IntExpr *const expr, int64_t value)
std::min(expr, value)
Decision * MakeVariableGreaterOrEqualValue(IntVar *const var, int64_t value)
int64_t failures() const
The number of failures encountered since the creation of the solver.
SearchMonitor * MakeSymmetryManager(SymmetryBreaker *const v1, SymmetryBreaker *const v2)
DecisionBuilder * MakePhase(const std::vector< SequenceVar * > &sequences, SequenceStrategy str)
IntExpr * MakeSum(IntExpr *const left, IntExpr *const right)
left + right.
IntExpr * MakeConditionalExpression(IntVar *const condition, IntExpr *const expr, int64_t unperformed_value)
Conditional Expr condition ? expr : unperformed_value.
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
Decision * MakeVariableLessOrEqualValue(IntVar *const var, int64_t value)
DecisionBuilder * MakePhase(const std::vector< IntervalVar * > &intervals, IntervalStrategy str)
Scheduling phases.
Constraint * MakeIsEqualCt(IntExpr *const v1, IntExpr *v2, IntVar *const b)
b == (v1 == v2)
Constraint * MakeEquality(IntExpr *const expr, int64_t value)
expr == value
int constraints() const
Counts the number of constraints that have been added to the solver before the search.
DecisionBuilder * Compose(DecisionBuilder *const db1, DecisionBuilder *const db2, DecisionBuilder *const db3)
SolutionCollector * MakeBestValueSolutionCollector(const Assignment *const assignment, bool maximize)
Collect the solution corresponding to the optimal value of the objective of 'assignment'; if 'assignm...
std::string SearchContext(const Search *search) const
Constraint * MakeIsLessOrEqualCt(IntExpr *const left, IntExpr *const right, IntVar *const b)
b == (left <= right)
Constraint * MakePathPrecedenceConstraint(std::vector< IntVar * > nexts, const std::vector< std::pair< int, int >> &precedences, const std::vector< int > &lifo_path_starts, const std::vector< int > &fifo_path_starts)
Same as MakePathPrecedenceConstraint but ensures precedence pairs on some paths follow a LIFO or FIFO...
void MakeBoolVarArray(int var_count, std::vector< IntVar * > *vars)
This method will append the vector vars with 'var_count' boolean variables having no names.
DecisionBuilder * MakeLocalSearchPhase(const std::vector< IntVar * > &vars, DecisionBuilder *const first_solution, LocalSearchPhaseParameters *const parameters)
IntExpr * MakeElement(Int64ToIntVar vars, int64_t range_start, int64_t range_end, IntVar *argument)
vars(argument)
DecisionBuilder * MakeStoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which stores an Assignment (calls void Assignment::Store())
Constraint * MakeSumLessOrEqual(const std::vector< IntVar * > &vars, int64_t cst)
Variation on arrays.
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, SolutionPool *const pool, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder)
SearchMonitor * MakeSearchLog(int branch_period, std::function< std::string()> display_callback)
At each solution, this monitor will also display result of display_callback.
Constraint * MakeNotMemberCt(IntExpr *const expr, std::vector< int > starts, std::vector< int > ends)
expr should not be in the list of forbidden intervals [start[i]..end[i]].
OptimizeVar * MakeWeightedMinimize(const std::vector< IntVar * > &sub_objectives, const std::vector< int > &weights, int64_t step)
Creates a minimization weighted objective.
Constraint * MakeLessOrEqual(IntExpr *const expr, int value)
expr <= value
EvaluatorStrategy
This enum is used by Solver::MakePhase to specify how to select variables and values during the searc...
@ CHOOSE_STATIC_GLOBAL_BEST
Pairs are compared at the first call of the selector, and results are cached.
@ CHOOSE_DYNAMIC_GLOBAL_BEST
Pairs are compared each time a variable is selected.
void set_optimization_direction(OptimizationDirection direction)
LocalSearchOperator * ConcatenateOperators(const std::vector< LocalSearchOperator * > &ops, bool restart)
Decision * MakeAssignVariablesValuesOrFail(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
SearchMonitor * MakeSearchLog(int branch_period)
The SearchMonitors below will display a periodic search log on LOG(INFO) every branch_period branches...
int SolveDepth() const
Gets the number of nested searches.
IntExpr * MakeMin(IntExpr *const left, IntExpr *const right)
std::min (left, right)
Constraint * MakeIsDifferentCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var != value)
DecisionBuilder * Try(DecisionBuilder *const db1, DecisionBuilder *const db2, DecisionBuilder *const db3, DecisionBuilder *const db4)
IntExpr * MakeMin(const std::vector< IntVar * > &vars)
std::min(vars)
IntVar * MakeIntVar(int64_t min, int64_t max)
MakeIntVar will create the best range based int var for the bounds given.
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, int64_t card_min, int64_t card_max, int64_t card_size)
Aggregated version of count with bounded cardinalities: forall j in 0 .
SearchMonitor * MakeGuidedLocalSearch(bool maximize, IntVar *objective, IndexEvaluator2 objective_function, int64_t step, const std::vector< IntVar * > &vars, double penalty_factor, bool reset_penalties_on_new_best_solution=false)
Creates a Guided Local Search monitor.
void MakeFixedDurationIntervalVarArray(int count, int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with 'count' interval variables built with the corresponding parameters.
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IndexEvaluator1 var_evaluator, IntValueStrategy val_str)
OptimizeVar * MakeWeightedOptimize(bool maximize, const std::vector< IntVar * > &sub_objectives, const std::vector< int64_t > &weights, int64_t step)
Creates a weighted objective with a given sense (true = maximization).
bool Solve(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
Constraint * MakeAllDifferent(const std::vector< IntVar * > &vars)
All variables are pairwise different.
IntExpr * MakeIndexExpression(const std::vector< IntVar * > &vars, int64_t value)
Returns the expression expr such that vars[expr] == value.
Constraint * MakeNotBetweenCt(IntExpr *const expr, int64_t l, int64_t u)
(expr < l || expr > u) This constraint is lazy as it will not make holes in the domain of variables.
IntExpr * MakeMax(IntExpr *const expr, int value)
std::max(expr, value)
SearchMonitor * MakeGuidedLocalSearch(bool maximize, IntVar *objective, IndexEvaluator3 objective_function, int64_t step, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, double penalty_factor, bool reset_penalties_on_new_best_solution=false)
Demon * MakeClosureDemon(Closure closure)
!defined(SWIG)
void MakeFixedDurationIntervalVarArray(const std::vector< IntVar * > &start_variables, const std::vector< int64_t > &durations, const std::vector< IntVar * > &performed_variables, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with interval variables built with the corresponding start and performed...
void NewSearch(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2, SearchMonitor *const m3, SearchMonitor *const m4)
std::string model_name() const
Returns the name of the model.
DecisionBuilder * MakeLocalSearchPhase(Assignment *const assignment, LocalSearchPhaseParameters *const parameters)
Local Search decision builders factories.
OptimizeVar * MakeWeightedOptimize(bool maximize, const std::vector< IntVar * > &sub_objectives, const std::vector< int > &weights, int64_t step)
Creates a weighted objective with a given sense (true = maximization).
DecisionBuilder * MakeDefaultPhase(const std::vector< IntVar * > &vars, const DefaultPhaseParameters &parameters)
RegularLimitParameters MakeDefaultRegularLimitParameters() const
Creates a regular limit proto containing default values.
IntVar * MakeIntVar(int64_t min, int64_t max, const std::string &name)
MakeIntVar will create the best range based int var for the bounds given.
IntVar * MakeIsDifferentVar(IntExpr *const v1, IntExpr *const v2)
status var of (v1 != v2)
IntExpr * MakeElement(const std::vector< IntVar * > &vars, IntVar *const index)
vars[expr]
void MakeFixedDurationIntervalVarArray(const std::vector< IntVar * > &start_variables, int64_t duration, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with 'count' interval var built with the corresponding start variables.
void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, std::vector< IntVar * > *vars)
This method will append the vector vars with 'var_count' variables having bounds vmin and vmax and ha...
IntervalVar * MakeIntervalVar(int64_t start_min, int64_t start_max, int64_t duration_min, int64_t duration_max, int64_t end_min, int64_t end_max, bool optional, const std::string &name)
Creates an interval var by specifying the bounds on start, duration, and end.
Constraint * MakeNotMemberCt(IntExpr *const expr, const std::vector< int > &values)
IntVar * MakeIsMemberVar(IntExpr *const expr, const std::vector< int64_t > &values)
bool UseFastLocalSearch() const
Returns true if fast local search is enabled.
IntExpr * MakeScalProd(const std::vector< IntVar * > &vars, const std::vector< int > &coefs)
scalar product
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int > &values, const std::vector< IntVar * > &cards)
Aggregated version of count: |{i | v[i] == values[j]}| == cards[j].
bool InstrumentsVariables() const
Returns whether we are tracing variables.
IntExpr * MakeProd(IntExpr *const left, IntExpr *const right)
left * right
MonitorEvent
Search monitor events.
IntervalVar * MakeMirrorInterval(IntervalVar *const interval_var)
Creates an interval var that is the mirror image of the given one, that is, the interval var obtained...
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step, SearchMonitor *const monitor1, SearchMonitor *const monitor2)
IntVar * MakeIsMemberVar(IntExpr *const expr, const std::vector< int > &values)
LocalSearchFilter * MakeAcceptFilter()
Local Search Filters.
Constraint * MakeMaxEquality(const std::vector< IntVar * > &vars, IntVar *const max_var)
ModelVisitor * MakeVariableDegreeVisitor(absl::flat_hash_map< const IntVar *, int > *const map)
Compute the number of constraints a variable is attached to.
LocalSearchOperator * MakeOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, LocalSearchOperators op)
Constraint * MakeSubCircuit(const std::vector< IntVar * > &nexts)
Force the "nexts" variable to create a complete Hamiltonian path for those that do not loop upon them...
int64_t accepted_neighbors() const
The number of accepted neighbors.
IntervalVar * MakeFixedDurationStartSyncedOnEndIntervalVar(IntervalVar *const interval_var, int64_t duration, int64_t offset)
Creates an interval var with a fixed duration whose start is synchronized with the end of another int...
Decision * MakeAssignVariablesValuesOrDoNothing(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IntVarStrategy var_str, IndexEvaluator2 value_evaluator, IndexEvaluator1 tie_breaker)
Constraint * MakeSumGreaterOrEqual(const std::vector< IntVar * > &vars, int64_t cst)
SearchMonitor * MakeSearchLog(int branch_period, IntVar *var, std::function< std::string()> display_callback)
At each solution, this monitor will display the 'var' value and the result of display_callback.
Constraint * MakeNonOverlappingNonStrictBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< int64_t > &x_size, const std::vector< int64_t > &y_size)
IntVar * MakeIntConst(int64_t val)
IntConst will create a constant expression.
LocalSearchOperator * MakeMoveTowardTargetOperator(const Assignment &target)
Creates a local search operator that tries to move the assignment of some variables toward a target.
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int > &values, const std::vector< int > &card_min, const std::vector< int > &card_max)
Aggregated version of count with bounded cardinalities: forall j in 0 .
std::string LocalSearchProfile() const
Returns local search profiling information in a human readable format.
void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
SolutionPool * MakeDefaultSolutionPool()
Solution Pool.
IntExpr * MakeModulo(IntExpr *const x, int64_t mod)
Modulo expression x % mod (with the python convention for modulo).
Constraint * MakeIsGreaterOrEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var >= value)
int SearchLeftDepth() const
Gets the search left depth of the current active search.
Constraint * MakeInversePermutationConstraint(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
Creates a constraint that enforces that 'left' and 'right' both represent permutations of [0....
IntExpr * CastExpression(const IntVar *const var) const
!defined(SWIG)
IntExpr * MakeMonotonicElement(IndexEvaluator1 values, bool increasing, IntVar *const index)
Function based element.
Constraint * MakeDeviation(const std::vector< IntVar * > &vars, IntVar *const deviation_var, int64_t total_sum)
Deviation constraint: sum_i |n * vars[i] - total_sum| <= deviation_var and sum_i vars[i] == total_sum...
void AddBacktrackAction(Action a, bool fast)
When SaveValue() is not the best way to go, one can create a reversible action that will be called up...
Constraint * MakeAllDifferent(const std::vector< IntVar * > &vars, bool stronger_propagation)
All variables are pairwise different.
int TopProgressPercent()
Returns a percentage representing the propress of the search before reaching the limits of the top-le...
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values, const std::vector< int64_t > &card_min, const std::vector< int64_t > &card_max)
Aggregated version of count with bounded cardinalities: forall j in 0 .
Constraint * MakeElementEquality(const std::vector< IntVar * > &vars, IntVar *const index, IntVar *const target)
const std::string & context() const
Gets the current context of the search.
bool CurrentlyInSolve() const
Returns true whether the current search has been created using a Solve() call instead of a NewSearch ...
Constraint * MakeNoCycle(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, IndexFilter1 sink_handler, bool assume_paths)
Constraint * MakeLess(IntExpr *const expr, int value)
expr < value
DecisionBuilder * MakeDefaultPhase(const std::vector< IntVar * > &vars)
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< IntVar * > &demands, int64_t capacity, const std::string &name)
This constraint enforces that, for any integer t, the sum of demands corresponding to an interval con...
IntExpr * MakeSum(IntExpr *const expr, int64_t value)
expr + value.
T * RevAlloc(T *object)
Registers the given object as being reversible.
IntVarStrategy
This enum describes the strategy used to select the next branching variable at each node during the s...
@ CHOOSE_RANDOM
Randomly select one of the remaining unbound variables.
@ CHOOSE_MIN_SIZE
Among unbound variables, select the variable with the smallest size.
@ CHOOSE_FIRST_UNBOUND
Select the first unbound variable.
@ CHOOSE_PATH
Selects the next unbound variable on a path, the path being defined by the variables: var[i] correspo...
@ CHOOSE_HIGHEST_MAX
Among unbound variables, select the variable with the highest maximal value.
@ CHOOSE_MIN_SIZE_LOWEST_MIN
Among unbound variables, select the variable with the smallest size, i.e., the smallest number of pos...
@ INT_VAR_DEFAULT
The default behavior is CHOOSE_FIRST_UNBOUND.
@ CHOOSE_MIN_SIZE_HIGHEST_MAX
Among unbound variables, select the variable with the smallest size, i.e., the smallest number of pos...
@ CHOOSE_MAX_REGRET_ON_MIN
Among unbound variables, select the variable with the largest gap between the first and the second va...
@ CHOOSE_MIN_SIZE_HIGHEST_MIN
Among unbound variables, select the variable with the smallest size, i.e., the smallest number of pos...
@ CHOOSE_MAX_SIZE
Among unbound variables, select the variable with the highest size.
@ INT_VAR_SIMPLE
The simple selection is CHOOSE_FIRST_UNBOUND.
@ CHOOSE_MIN_SIZE_LOWEST_MAX
Among unbound variables, select the variable with the smallest size, i.e., the smallest number of pos...
@ CHOOSE_LOWEST_MIN
Among unbound variables, select the variable with the smallest minimal value.
Constraint * MakePathTransitPrecedenceConstraint(std::vector< IntVar * > nexts, std::vector< IntVar * > transits, const std::vector< std::pair< int, int >> &precedences)
Same as MakePathPrecedenceConstraint but will force i to be before j if the sum of transits on the pa...
IntExpr * MakeProd(IntExpr *const expr, int64_t value)
expr * value
IntExpr * MakeMax(IntExpr *const left, IntExpr *const right)
std::max(left, right)
Constraint * MakeGreaterOrEqual(IntExpr *const expr, int64_t value)
expr >= value
Constraint * MakeIsEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var == value)
SequenceStrategy
Used for scheduling. Not yet implemented.
DecisionBuilder * MakePhase(IntVar *const v0, IntVar *const v1, IntVar *const v2, IntVar *const v3, IntVarStrategy var_str, IntValueStrategy val_str)
void MakeIntervalVarArray(int count, int64_t start_min, int64_t start_max, int64_t duration_min, int64_t duration_max, int64_t end_min, int64_t end_max, bool optional, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with 'count' interval var built with the corresponding parameters.
Solver(const std::string &name)
Solver API.
Constraint * MakePathPrecedenceConstraint(std::vector< IntVar * > nexts, const std::vector< std::pair< int, int >> &precedences)
Constraint enforcing, for each pair (i,j) in precedences, i to be before j in paths defined by next v...
Constraint * MakeTemporalDisjunction(IntervalVar *const t1, IntervalVar *const t2)
This constraint implements a temporal disjunction between two interval vars.
void NewSearch(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2, SearchMonitor *const m3)
uint64_t stamp() const
The stamp indicates how many moves in the search tree we have performed.
bool Solve(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2, SearchMonitor *const m3)
SolutionCollector * MakeAllSolutionCollector(const Assignment *const assignment)
Collect all solutions of the search.
Constraint * MakeDistribute(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &cards)
Aggregated version of count: |{i | v[i] == j}| == cards[j].
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step)
NestedOptimize will collapse a search tree described by a decision builder 'db' and a set of monitors...
Constraint * MakeCount(const std::vector< IntVar * > &vars, int64_t value, int64_t max_count)
|{i | vars[i] == value}| == max_count
Constraint * MakeEquality(IntExpr *const expr, int value)
expr == value
Decision * MakeSplitVariableDomain(IntVar *const var, int64_t val, bool start_with_lower_half)
LocalSearchOperator * MakeOperator(const std::vector< IntVar * > &vars, LocalSearchOperators op)
Local Search Operators.
Constraint * MakeLessOrEqual(IntExpr *const left, IntExpr *const right)
left <= right
LocalSearchOperator * MultiArmedBanditConcatenateOperators(const std::vector< LocalSearchOperator * > &ops, double memory_coefficient, double exploration_coefficient, bool maximize)
Creates a local search operator which concatenates a vector of operators.
Constraint * MakeIsLessCstCt(IntExpr *const v, int64_t c, IntVar *const b)
b == (v < c)
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db, SearchMonitor *const monitor1, SearchMonitor *const monitor2, SearchMonitor *const monitor3)
ABSL_MUST_USE_RESULT RegularLimit * MakeTimeLimit(absl::Duration time)
Creates a search limit that constrains the running time.
ABSL_MUST_USE_RESULT RegularLimit * MakeFailuresLimit(int64_t failures)
Creates a search limit that constrains the number of failures that can happen when exploring the sear...
std::function< int64_t(const IntVar *v, int64_t id)> VariableValueSelector
IntExpr * MakeDiv(IntExpr *const numerator, IntExpr *const denominator)
numerator / denominator (integer division). Terms need to be positive.
Decision * MakeRankLastInterval(SequenceVar *const sequence, int index)
Returns a decision that tries to rank last the ith interval var in the sequence variable.
SearchMonitor * MakeLubyRestart(int scale_factor)
This search monitor will restart the search periodically.
IntervalVar * MakeFixedDurationIntervalVar(IntVar *const start_variable, int64_t duration, IntVar *const performed_variable, const std::string &name)
Creates an interval var with a fixed duration, and performed_variable.
LocalSearchOperator * ConcatenateOperators(const std::vector< LocalSearchOperator * > &ops, std::function< int64_t(int, int)> evaluator)
Constraint * MakeTransitionConstraint(const std::vector< IntVar * > &vars, const IntTupleSet &transition_table, int64_t initial_state, const std::vector< int > &final_states)
This constraint create a finite automaton that will check the sequence of variables vars.
IntExpr * MakeElement(const std::vector< int > &values, IntVar *const index)
values[index]
bool NameAllVariables() const
Returns whether all variables should be named.
OptimizeVar * MakeWeightedMaximize(const std::vector< IntVar * > &sub_objectives, const std::vector< int > &weights, int64_t step)
Creates a maximization weigthed objective.
Constraint * MakeGreater(IntExpr *const left, IntExpr *const right)
left > right
Constraint * MakeTransitionConstraint(const std::vector< IntVar * > &vars, const IntTupleSet &transition_table, int64_t initial_state, const std::vector< int64_t > &final_states)
This constraint create a finite automaton that will check the sequence of variables vars.
IntExpr * MakeConvexPiecewiseExpr(IntExpr *expr, int64_t early_cost, int64_t early_date, int64_t late_date, int64_t late_cost)
Convex piecewise function.
T * RevAllocArray(T *object)
Like RevAlloc() above, but for an array of objects: the array must have been allocated with the new[]...
Constraint * MakeEquality(IntExpr *const left, IntExpr *const right)
left == right
Constraint * MakeIsGreaterCstCt(IntExpr *const v, int64_t c, IntVar *const b)
b == (v > c)
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
SolutionCollector * MakeFirstSolutionCollector()
Collect the first solution of the search.
IntVar * MakeIsGreaterCstVar(IntExpr *const var, int64_t value)
status var of (var > value)
Constraint * MakeIsGreaterOrEqualCt(IntExpr *const left, IntExpr *const right, IntVar *const b)
b == (left >= right)
LocalSearchOperator * MakeRandomLnsOperator(const std::vector< IntVar * > &vars, int number_of_variables)
Creates a large neighborhood search operator which creates fragments (set of relaxed variables) with ...
IntVarLocalSearchFilter * MakeSumObjectiveFilter(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, IndexEvaluator3 values, Solver::LocalSearchFilterBound filter_enum)
IntExpr * MakeElement(const std::vector< int64_t > &values, IntVar *const index)
values[index]
Constraint * MakeIntervalVarRelation(IntervalVar *const t, UnaryIntervalRelation r, int64_t d)
This method creates a relation between an interval var and a date.
IntExpr * RegisterIntExpr(IntExpr *const expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
DecisionBuilder * MakePhase(IntVar *const v0, IntVarStrategy var_str, IntValueStrategy val_str)
Shortcuts for small arrays.
DecisionBuilder * Compose(const std::vector< DecisionBuilder * > &dbs)
Constraint * MakeIsLessOrEqualCstCt(IntExpr *const var, int64_t value, IntVar *const boolvar)
boolvar == (var <= value)
IntervalVar * MakeFixedDurationIntervalVar(IntVar *const start_variable, int64_t duration, const std::string &name)
Creates a performed interval var with a fixed duration.
std::vector< int64_t > tmp_vector_
Unsafe temporary vector.
Constraint * MakeScalProdEquality(const std::vector< IntVar * > &vars, const std::vector< int > &coefficients, IntVar *const target)
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< int64_t > &demands, int64_t capacity, const std::string &name)
This constraint forces that, for any integer t, the sum of the demands corresponding to an interval c...
std::function< void()> Closure
IntExpr * MakeMax(const std::vector< IntVar * > &vars)
std::max(vars)
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< int64_t > &demands, IntVar *const capacity, const std::string &name)
This constraint forces that, for any integer t, the sum of the demands corresponding to an interval c...
std::function< void(Solver *)> Action
ABSL_MUST_USE_RESULT RegularLimit * MakeLimit(absl::Duration time, int64_t branches, int64_t failures, int64_t solutions, bool smart_time_check=false, bool cumulative=false)
Limits the search with the 'time', 'branches', 'failures' and 'solutions' limits.
DecisionBuilder * Try(DecisionBuilder *const db1, DecisionBuilder *const db2, DecisionBuilder *const db3)
Constraint * MakeMinEquality(const std::vector< IntVar * > &vars, IntVar *const min_var)
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *const db, Assignment *const solution, bool maximize, int64_t step, SearchMonitor *const monitor1)
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, LocalSearchOperator *const ls_operator, DecisionBuilder *const sub_decision_builder, RegularLimit *const limit, LocalSearchFilterManager *filter_manager)
DecisionBuilder * MakePhase(IntVar *const v0, IntVar *const v1, IntVarStrategy var_str, IntValueStrategy val_str)
void set_context(const std::string &context)
Sets the current context of the search.
Constraint * MakeIsDifferentCt(IntExpr *const v1, IntExpr *const v2, IntVar *const b)
b == (v1 != v2)
Constraint * MakeMemberCt(IntExpr *const expr, const std::vector< int > &values)
Constraint * MakeLightElement(F values, IntVar *const var, IntVar *const index1, IntVar *const index2, std::function< bool()> deep_serialize=nullptr)
Light two-dimension function-based element constraint ensuring var == values(index1,...
IntVar * MakeIsEqualVar(IntExpr *const v1, IntExpr *v2)
status var of (v1 == v2)
Assignment * MakeAssignment(const Assignment *const a)
This method creates an assignment which is a copy of 'a'.
Demon * RegisterDemon(Demon *const demon)
Adds a new demon and wraps it inside a DemonProfiler if necessary.
void ExportProfilingOverview(const std::string &filename)
Exports the profiling information in a human readable overview.
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IndexEvaluator1 var_evaluator, IndexEvaluator2 value_evaluator, IndexEvaluator1 tie_breaker)
SearchMonitor * MakeSearchLog(int branch_period, IntVar *const var)
At each solution, this monitor also display the var value.
Decision * MakeDecision(Action apply, Action refute)
IntExpr * MakeAbs(IntExpr *const expr)
|expr|
Solver(const std::string &name, const ConstraintSolverParameters &parameters)
MarkerType
This enum is used internally in private methods Solver::PushState and Solver::PopState to tag states ...
void MakeFixedDurationIntervalVarArray(const std::vector< IntVar * > &start_variables, const std::vector< int > &durations, const std::string &name, std::vector< IntervalVar * > *const array)
This method fills the vector with interval variables built with the corresponding start variables.
Constraint * MakeNonOverlappingBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< IntVar * > &x_size, const std::vector< IntVar * > &y_size)
This constraint states that all the boxes must not overlap.
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IntVarStrategy var_str, IntValueStrategy val_str)
Phases on IntVar arrays.
Constraint * MakeElementEquality(const std::vector< int > &vals, IntVar *const index, IntVar *const target)
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
void AddCastConstraint(CastConstraint *const constraint, IntVar *const target_var, IntExpr *const expr)
Adds 'constraint' to the solver and marks it as a cast constraint, that is, a constraint created call...
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
Constraint * MakeSortingConstraint(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &sorted)
Creates a constraint binding the arrays of variables "vars" and "sorted_vars": sorted_vars[0] must be...
int32_t Rand32(int32_t size)
Returns a random value between 0 and 'size' - 1;.
IntVar * MakeIntConst(int64_t val, const std::string &name)
IntConst will create a constant expression.
std::function< DecisionModification()> BranchSelector
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
OptimizeVar * MakeMaximize(IntVar *const v, int64_t step)
Creates a maximization objective.
bool SolveAndCommit(DecisionBuilder *const db, SearchMonitor *const m1)
Constraint * MakeAbsEquality(IntVar *const var, IntVar *const abs_var)
Creates the constraint abs(var) == abs_var.
Constraint * MakeScalProdEquality(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefficients, int64_t cst)
void set_fail_intercept(std::function< void()> fail_intercept)
Internal.
ABSL_MUST_USE_RESULT RegularLimit * MakeBranchesLimit(int64_t branches)
Creates a search limit that constrains the number of branches explored in the search tree.
Constraint * MakeLessOrEqual(IntExpr *const expr, int64_t value)
expr <= value
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
Constraint * MakePathCumul(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, const std::vector< IntVar * > &cumuls, IndexEvaluator2 transit_evaluator)
Creates a constraint which accumulates values along a path such that: cumuls[next[i]] = cumuls[i] + t...
SearchMonitor * MakeSearchLog(int branch_period, OptimizeVar *const opt_var)
OptimizeVar Search Logs At each solution, this monitor will also display the 'opt_var' value.
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
IntervalVar * MakeIntervalRelaxedMax(IntervalVar *const interval_var)
Creates and returns an interval variable that wraps around the given one, relaxing the max start and ...
Assignment * GetOrCreateLocalSearchState()
Returns (or creates) an assignment representing the state of local search.
IntVar * MakeIsLessOrEqualVar(IntExpr *const left, IntExpr *const right)
status var of (left <= right)
IntExpr * MakeElement(IndexEvaluator2 values, IntVar *const index1, IntVar *const index2)
2D version of function-based element expression, values(expr1, expr2).
IntExpr * MakeSquare(IntExpr *const expr)
expr * expr
void NewSearch(DecisionBuilder *const db, SearchMonitor *const m1, SearchMonitor *const m2)
int64_t solutions() const
The number of solutions found since the start of the search.
IntVar * MakeIsDifferentCstVar(IntExpr *const var, int64_t value)
status var of (var != value)
IntervalVar * MakeFixedDurationIntervalVar(int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string &name)
Creates an interval var with a fixed duration.
Constraint * MakeDelayedPathCumul(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, const std::vector< IntVar * > &cumuls, const std::vector< IntVar * > &transits)
Delayed version of the same constraint: propagation on the nexts variables is delayed until all const...
SolutionCollector * MakeAllSolutionCollector()
Collect all solutions of the search.
ABSL_MUST_USE_RESULT RegularLimit * MakeSolutionsLimit(int64_t solutions)
Creates a search limit that constrains the number of solutions found during the search.
Constraint * MakeElementEquality(const std::vector< IntVar * > &vars, IntVar *const index, int64_t target)
Constraint * MakeNonEquality(IntExpr *const expr, int value)
expr != value
std::function< IntVar *(int64_t)> Int64ToIntVar
SolutionCollector * MakeNBestValueSolutionCollector(const Assignment *const assignment, int solution_count, bool maximize)
Same as MakeBestValueSolutionCollector but collects the best solution_count solutions.
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
void NewSearch(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
Constraint * MakeNonOverlappingNonStrictBoxesConstraint(const std::vector< IntVar * > &x_vars, const std::vector< IntVar * > &y_vars, const std::vector< int > &x_size, const std::vector< int > &y_size)
Constraint * MakeAllDifferentExcept(const std::vector< IntVar * > &vars, int64_t escape_value)
All variables are pairwise different, unless they are assigned to the escape value.
Constraint * MakeScalProdEquality(const std::vector< IntVar * > &vars, const std::vector< int > &coefficients, int64_t cst)
Constraint * MakeIntervalVarRelation(IntervalVar *const t1, BinaryIntervalRelation r, IntervalVar *const t2)
This method creates a relation between two interval vars.
Constraint * MakeLexicalLess(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
Creates a constraint that enforces that left is lexicographically less than right.
Decision * balancing_decision() const
LocalSearchOperator * ConcatenateOperators(const std::vector< LocalSearchOperator * > &ops)
Creates a local search operator which concatenates a vector of operators.
IntVar * MakeIsBetweenVar(IntExpr *const v, int64_t l, int64_t u)
IntVar * RegisterIntVar(IntVar *const var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
IntExpr * MakePower(IntExpr *const expr, int64_t n)
expr ^ n (n > 0)
IntExpr * MakeScalProd(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefs)
scalar product
EvaluatorLocalSearchOperators
This enum is used in Solver::MakeOperator associated with an evaluator to specify the neighborhood to...
@ TSPOPT
Sliding TSP operator.
@ LK
Lin-Kernighan local search.
LocalSearchFilterBound
This enum is used in Solver::MakeLocalSearchObjectiveFilter.
@ GE
Move is accepted when the current objective value >= objective.Min.
@ LE
Move is accepted when the current objective value <= objective.Max.
@ EQ
Move is accepted when the current objective value is in the interval objective.Min .
SearchMonitor * MakeConstantRestart(int frequency)
This search monitor will restart the search periodically after 'frequency' failures.
Decision * MakeAssignVariableValueOrDoNothing(IntVar *const var, int64_t value)
Constraint * MakeLess(IntExpr *const left, IntExpr *const right)
left < right
DecisionBuilder * MakeLocalSearchPhase(const std::vector< SequenceVar * > &vars, DecisionBuilder *const first_solution, LocalSearchPhaseParameters *const parameters)
OptimizationDirection optimization_direction() const
The direction of optimization, getter and setter.
DecisionBuilder * MakeSolveOnce(DecisionBuilder *const db)
SolveOnce will collapse a search tree described by a decision builder 'db' and a set of monitors and ...
void SaveAndAdd(T *adr, T val)
All-in-one SaveAndAdd_value.
A symmetry breaker is an object that will visit a decision and create the 'symmetrical' decision in r...
ABSL_DECLARE_FLAG(int64_t, cp_random_seed)
Declaration of the core objects for the constraint solver.
Collection of objects used to extend the Constraint Solver library.
std::ostream & operator<<(std::ostream &out, const Solver *const s)
int64_t Zero()
NOLINT.
int64_t One()
This method returns 1.
void SetAssignmentFromAssignment(Assignment *target_assignment, const std::vector< IntVar * > &target_vars, const Assignment *source_assignment, const std::vector< IntVar * > &source_vars)
NOLINT.
This struct holds all parameters for the default search.
int heuristic_num_failures_limit
The failure limit for each heuristic that we run.
int initialization_splits
Maximum number of intervals that the initialization of impacts will scan per variable.
DecisionBuilder * decision_builder
When defined, this overrides the default impact based decision builder.
DisplayLevel display_level
This represents the amount of information displayed by the default search.
ValueSelection value_selection_schema
This parameter describes which value to select for a given var.
VariableSelection var_selection_schema
This parameter describes how the next variable to instantiate will be chosen.
bool persistent_impact
Whether to keep the impact from the first search for other searches, or to recompute the impact for e...
bool use_last_conflict
Should we use last conflict method. The default is false.
int heuristic_period
The distance in nodes between each run of the heuristics.
int random_seed
Seed used to initialize the random part in some heuristics.
bool run_all_heuristics
The default phase will run heuristics periodically.
static Iterator Begin(IntVarIterator *it)
These are the only way to construct an Iterator.
bool operator!=(const Iterator &other) const
static Iterator End(IntVarIterator *it)
bool operator<(const SolutionData &other) const
Holds semantic information stating that the 'expression' has been cast into 'variable' using the Var(...
IntegerCastInfo(IntVar *const v, IntExpr *const e, Constraint *const c)
Creates a search monitor from logging parameters.
int branch_period
SearchMonitors will display a periodic search log every branch_period branches explored.
OptimizeVar * objective
SearchMonitors will display values of objective or variable (both cannot be used together).
std::function< std::string()> display_callback
SearchMonitors will display the result of display_callback at each new solution found and when the se...
double scaling_factor
When displayed, objective or var values will be scaled and offset by the given values in the followin...
bool display_on_new_solutions_only
To be used to protect from cases where display_callback assumes variables are instantiated,...