Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
constraint_solver.h
Go to the documentation of this file.
1// Copyright 2010-2025 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 <ostream>
78#include <random>
79#include <string>
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/log/check.h"
90#include "absl/random/random.h"
91#include "absl/strings/str_format.h"
92#include "absl/strings/string_view.h"
93#include "absl/time/time.h"
94#include "absl/types/span.h"
98#include "ortools/base/timer.h"
99#include "ortools/base/types.h"
106
107#if !defined(SWIG)
108OR_DLL ABSL_DECLARE_FLAG(int64_t, cp_random_seed);
109OR_DLL ABSL_DECLARE_FLAG(bool, cp_disable_solve);
110#endif // !defined(SWIG)
111
112class File;
113
114namespace operations_research {
115
116class Assignment;
117class AssignmentProto;
118class BaseObject;
119class CastConstraint;
120class Constraint;
121class Decision;
122class DecisionBuilder;
123class DecisionVisitor;
124class Demon;
125class DemonProfiler;
126class Dimension;
127class DisjunctiveConstraint;
128class ImprovementSearchLimit;
129class IntExpr;
130class IntVar;
131class IntVarAssignment;
132class IntVarLocalSearchFilter;
133class IntervalVar;
134class IntervalVarAssignment;
135class LocalSearch;
136class LocalSearchFilter;
137class LocalSearchFilterManager;
138class LocalSearchMonitor;
139class LocalSearchOperator;
140class LocalSearchPhaseParameters;
141class LocalSearchProfiler;
142class ModelCache;
143class ModelVisitor;
144class ObjectiveMonitor;
145class BaseObjectiveMonitor;
146class OptimizeVar;
147class Pack;
148class ProfiledDecisionBuilder;
149class PropagationBaseObject;
150class PropagationMonitor;
151class Queue;
152class RegularLimit;
153class RegularLimitParameters;
154class RevBitMatrix;
155class Search;
156class SearchLimit;
157class SearchMonitor;
158class SequenceVar;
159class SequenceVarAssignment;
160class SolutionCollector;
161class SolutionPool;
162class SymmetryBreaker;
163struct StateInfo;
164struct Trail;
165template <class T>
166class SimpleRevFIFO;
167template <typename F>
168class LightIntFunctionElementCt;
169template <typename F>
170class LightIntIntFunctionElementCt;
171template <typename F>
172class LightIntIntIntFunctionElementCt;
173
174inline int64_t CpRandomSeed() {
175 return absl::GetFlag(FLAGS_cp_random_seed) == -1
176 ? absl::Uniform<int64_t>(absl::BitGen(), 0, kint64max)
177 : absl::GetFlag(FLAGS_cp_random_seed);
178}
179
189 };
190
191 enum ValueSelection {
250
259class Solver {
260 public:
265 struct IntegerCastInfo {
267 : variable(nullptr), expression(nullptr), maintainer(nullptr) {}
268 IntegerCastInfo(IntVar* const v, IntExpr* const e, Constraint* const c)
269 : variable(v), expression(e), maintainer(c) {}
273 };
274
276 static constexpr int kNumPriorities = 3;
278 /// This enum describes the strategy used to select the next branching
279 /// variable at each node during the search.
286
291
292 /// Randomly select one of the remaining unbound variables.
310
318
326
332
338
348
352
356 };
357 // TODO(user): add HIGHEST_MIN and LOWEST_MAX.
358
361 enum IntValueStrategy {
364
370
402
407
426
428 /// The simple is INTERVAL_SET_TIMES_FORWARD.
434
436 };
449
450 TWOOPT,
451
452 /// Relocate: OROPT and RELOCATE.
453 /// Operator which moves a sub-chain of a path to another position; the
454 /// specified chain length is the fixed length of the chains being moved.
455 /// When this length is 1, the operator simply moves a node to another
456 /// position.
457 /// Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain
458 /// length of 2 (where (1, 5) are first and last nodes of the path and can
459 /// therefore not be moved):
460 /// 1 -> 4 -> [2 -> 3] -> 5
461 /// 1 -> [3 -> 4] -> 2 -> 5
462 ///
463 /// Using Relocate with chain lengths of 1, 2 and 3 together is equivalent
464 /// to the OrOpt operator on a path. The OrOpt operator is a limited
465 /// version of 3Opt (breaks 3 arcs on a path).
466 OROPT,
467
469 RELOCATE,
470
478 EXCHANGE,
489 CROSS,
490
498
505
513
520
528
548 PATHLNS,
549
553
558
567 INCREMENT,
568
572 DECREMENT,
573
582 };
583
591 LK,
592
596
600
607 TSPLNS
608 };
609
616 GE,
618 LE,
621 EQ
622 };
623
636 NORMAL_PRIORITY = 2,
637 };
638
640 /// temporal relation between the two intervals t1 and t2.
644
647
650
651
653
654 /// t1 starts after t2 end, i.e. Start(t1) >= End(t2) + delay.
670 };
679 ENDS_AT,
680
683
684
686
687 /// t starts at d, i.e. Start(t) == d.
688 STARTS_AT,
697
702 };
703
712 NO_CHANGE,
713
716
717 KEEP_LEFT,
718
745
768 kEndFail,
782 // Dummy event whose underlying int is the number of MonitorEvent enums.
784 };
785#endif // SWIG
788 typedef std::function<int64_t(int64_t)> IndexEvaluator1;
789 typedef std::function<int64_t(int64_t, int64_t)> IndexEvaluator2;
790 typedef std::function<int64_t(int64_t, int64_t, int64_t)> IndexEvaluator3;
792 typedef std::function<bool(int64_t)> IndexFilter1;
794 typedef std::function<IntVar*(int64_t)> Int64ToIntVar;
795
796 typedef std::function<int64_t(Solver* solver,
797 const std::vector<IntVar*>& vars,
798 int64_t first_unbound, int64_t last_unbound)>
800
801 typedef std::function<int64_t(const IntVar* v, int64_t id)>
803 typedef std::function<bool(int64_t, int64_t, int64_t)>
805 typedef std::function<DecisionModification()> BranchSelector;
806 // TODO(user): wrap in swig.
807 typedef std::function<void(Solver*)> Action;
808 typedef std::function<void()> Closure;
809
811 explicit Solver(const std::string& name);
812 Solver(const std::string& name, const ConstraintSolverParameters& parameters);
813
814#ifndef SWIG
815 // This type is neither copyable nor movable.
816 Solver(const Solver&) = delete;
817 Solver& operator=(const Solver&) = delete;
818#endif
819
823 ConstraintSolverParameters parameters() const { return parameters_; }
824 // Read-only.
826 return parameters_;
827 }
829 // TODO(user): Move to constraint_solver_parameters.h.
831
833
837 template <class T>
838 void SaveValue(T* o) {
839 InternalSaveValue(o);
840 }
841
851 /// BaseObject: for all subclasses predefined in the library, the
852 /// corresponding factory methods (e.g., MakeIntVar(...),
853 /// MakeAllDifferent(...) already take care of the registration.
854 template <typename T>
855 T* RevAlloc(T* object) {
856 return reinterpret_cast<T*>(SafeRevAlloc(object));
857 }
858
865 template <typename T>
866 T* RevAllocArray(T* object) {
867 return reinterpret_cast<T*>(SafeRevAllocArray(object));
868 }
869
870 /// Adds the constraint 'c' to the model.
871 ///
872 /// After calling this method, and until there is a backtrack that undoes the
873 /// addition, any assignment of variables to values must satisfy the given
874 /// constraint in order to be considered feasible. There are two fairly
875 /// different use cases:
876 ///
877 /// - the most common use case is modeling: the given constraint is really
878 /// part of the problem that the user is trying to solve. In this use case,
879 /// AddConstraint is called outside of search (i.e., with <tt>state() ==
880 /// OUTSIDE_SEARCH</tt>). Most users should only use AddConstraint in this
881 /// way. In this case, the constraint will belong to the model forever: it
882 /// cannot be removed by backtracking.
883 ///
884 /// - a rarer use case is that 'c' is not a real constraint of the model. It
885 /// may be a constraint generated by a branching decision (a constraint whose
886 /// goal is to restrict the search space), a symmetry breaking constraint (a
887 /// constraint that does restrict the search space, but in a way that cannot
888 /// have an impact on the quality of the solutions in the subtree), or an
889 /// inferred constraint that, while having no semantic value to the model (it
890 /// does not restrict the set of solutions), is worth having because we
891 /// believe it may strengthen the propagation. In these cases, it happens
892 /// that the constraint is added during the search (i.e., with state() ==
893 /// IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is
894 /// added during a search, it applies only to the subtree of the search tree
895 /// rooted at the current node, and will be automatically removed by
896 /// backtracking.
897 ///
898 /// This method does not take ownership of the constraint. If the constraint
899 /// has been created by any factory method (Solver::MakeXXX), it will
900 /// automatically be deleted. However, power users who implement their own
901 /// constraints should do: solver.AddConstraint(solver.RevAlloc(new
902 /// MyConstraint(...));
903 void AddConstraint(Constraint* c);
907 void AddCastConstraint(CastConstraint* constraint, IntVar* target_var,
908 IntExpr* expr);
909
951 bool Solve(DecisionBuilder* db, const std::vector<SearchMonitor*>& monitors);
952 bool Solve(DecisionBuilder* db);
953 bool Solve(DecisionBuilder* db, SearchMonitor* m1);
956 SearchMonitor* m3);
960
969
970 void NewSearch(DecisionBuilder* db,
971 const std::vector<SearchMonitor*>& monitors);
972 void NewSearch(DecisionBuilder* db);
976 SearchMonitor* m3);
979
980 bool NextSolution();
981 void RestartSearch();
982 void EndSearch();
984
994 const std::vector<SearchMonitor*>& monitors);
998 SearchMonitor* m2);
1000 SearchMonitor* m3);
1001
1004
1008 bool CheckConstraint(Constraint* ct);
1009
1011 SolverState state() const { return state_; }
1012
1014 void Fail();
1015
1016#if !defined(SWIG)
1021 void AddBacktrackAction(Action a, bool fast);
1022#endif
1023
1025 std::string DebugString() const;
1026
1028 static int64_t MemoryUsage();
1029
1034 absl::Time Now() const;
1035
1038 int64_t wall_time() const;
1039
1041 int64_t branches() const { return branches_; }
1042
1044 int64_t solutions() const;
1045
1047 int64_t unchecked_solutions() const;
1048
1050 int64_t demon_runs(DemonPriority p) const { return demon_runs_[p]; }
1051
1053 int64_t failures() const { return fails_; }
1054
1056 int64_t neighbors() const { return neighbors_; }
1057
1060 void ClearNeighbors() { neighbors_ = 0; }
1061 void IncrementNeighbors() { ++neighbors_; }
1062
1064 int64_t filtered_neighbors() const { return filtered_neighbors_; }
1065
1067 int64_t accepted_neighbors() const { return accepted_neighbors_; }
1071 uint64_t stamp() const;
1072
1074 uint64_t fail_stamp() const;
1075
1077 void set_context(absl::string_view context) { context_ = context; }
1078
1080 const std::string& context() const { return context_; }
1081
1084 return optimization_direction_;
1085 }
1087 optimization_direction_ = direction;
1089
1090 // An internal method called by Guided Local Search to share current
1091 // penalties with the solver.
1093 std::function<int64_t(int64_t, int64_t, int64_t)> penalty_callback) {
1094 penalty_callback_ = std::move(penalty_callback);
1095 }
1096 // Returns the current (Guided Local Search)penalty of the given arc tuple.
1097 int64_t GetGuidedLocalSearchPenalty(int64_t i, int64_t j, int64_t k) const {
1098 return (penalty_callback_ == nullptr) ? 0 : penalty_callback_(i, j, k);
1099 }
1100
1101 // All factories (MakeXXX methods) encapsulate creation of objects
1102 // through RevAlloc(). Hence, the Solver used for allocating the
1103 // returned object will retain ownership of the allocated memory.
1104 // Destructors are called upon backtrack, or when the Solver is
1105 // itself destructed.
1106
1107 // ----- Int Variables and Constants -----
1108
1110 IntVar* MakeIntVar(int64_t min, int64_t max, const std::string& name);
1111
1113 IntVar* MakeIntVar(const std::vector<int64_t>& values,
1114 const std::string& name);
1115
1116
1117 IntVar* MakeIntVar(const std::vector<int>& values, const std::string& name);
1118
1119 /// MakeIntVar will create the best range based int var for the bounds given.
1120 IntVar* MakeIntVar(int64_t min, int64_t max);
1121
1123 IntVar* MakeIntVar(const std::vector<int64_t>& values);
1126 IntVar* MakeIntVar(const std::vector<int>& values);
1127
1129 IntVar* MakeBoolVar(const std::string& name);
1130
1133
1135 IntVar* MakeIntConst(int64_t val, const std::string& name);
1136
1138 IntVar* MakeIntConst(int64_t val);
1139
1143 void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1144 const std::string& name, std::vector<IntVar*>* vars);
1147 void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1148 std::vector<IntVar*>* vars);
1150 IntVar** MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax,
1151 const std::string& name);
1152
1156 void MakeBoolVarArray(int var_count, const std::string& name,
1157 std::vector<IntVar*>* vars);
1160 void MakeBoolVarArray(int var_count, std::vector<IntVar*>* vars);
1162 IntVar** MakeBoolVarArray(int var_count, const std::string& name);
1163
1164 // ----- Integer Expressions -----
1165
1167 IntExpr* MakeSum(IntExpr* left, IntExpr* right);
1169 IntExpr* MakeSum(IntExpr* expr, int64_t value);
1171 IntExpr* MakeSum(const std::vector<IntVar*>& vars);
1172
1174 IntExpr* MakeScalProd(const std::vector<IntVar*>& vars,
1175 const std::vector<int64_t>& coefs);
1177 IntExpr* MakeScalProd(const std::vector<IntVar*>& vars,
1178 const std::vector<int>& coefs);
1179
1181 IntExpr* MakeDifference(IntExpr* left, IntExpr* right);
1183 IntExpr* MakeDifference(int64_t value, IntExpr* expr);
1186
1188 IntExpr* MakeProd(IntExpr* left, IntExpr* right);
1190 IntExpr* MakeProd(IntExpr* expr, int64_t value);
1191
1193 IntExpr* MakeDiv(IntExpr* expr, int64_t value);
1195 IntExpr* MakeDiv(IntExpr* numerator, IntExpr* denominator);
1196
1198 IntExpr* MakeAbs(IntExpr* expr);
1200 IntExpr* MakeSquare(IntExpr* expr);
1202 IntExpr* MakePower(IntExpr* expr, int64_t n);
1203
1205 IntExpr* MakeElement(const std::vector<int64_t>& values, IntVar* index);
1207 IntExpr* MakeElement(const std::vector<int>& values, IntVar* index);
1208
1212 IntExpr* MakeElement(IndexEvaluator1 values, IntVar* index);
1219 IntExpr* MakeMonotonicElement(IndexEvaluator1 values, bool increasing,
1220 IntVar* index);
1222 IntExpr* MakeElement(IndexEvaluator2 values, IntVar* index1, IntVar* index2);
1223
1225 IntExpr* MakeElement(const std::vector<IntVar*>& vars, IntVar* index);
1226
1227#if !defined(SWIG)
1229 IntExpr* MakeElement(Int64ToIntVar vars, int64_t range_start,
1230 int64_t range_end, IntVar* argument);
1231#endif // SWIG
1232
1237
1244 template <typename F>
1245 Constraint* MakeLightElement(F values, IntVar* const var, IntVar* const index,
1246 std::function<bool()> deep_serialize = nullptr) {
1248 this, var, index, std::move(values), std::move(deep_serialize)));
1249 }
1250
1257 template <typename F>
1258 Constraint* MakeLightElement(F values, IntVar* const var,
1259 IntVar* const index1, IntVar* const index2,
1260 std::function<bool()> deep_serialize = nullptr) {
1262 this, var, index1, index2, std::move(values),
1263 std::move(deep_serialize)));
1264 }
1265
1270 template <typename F>
1271 Constraint* MakeLightElement(F values, IntVar* const var,
1272 IntVar* const index1, IntVar* const index2,
1273 IntVar* const index3) {
1275 this, var, index1, index2, index3, std::move(values)));
1276 }
1277
1280 IntExpr* MakeIndexExpression(const std::vector<IntVar*>& vars, int64_t value);
1281
1283 Constraint* MakeIfThenElseCt(IntVar* condition, IntExpr* then_expr,
1284 IntExpr* else_expr, IntVar* target_var);
1287 IntExpr* MakeMin(const std::vector<IntVar*>& vars);
1289 IntExpr* MakeMin(IntExpr* left, IntExpr* right);
1291 IntExpr* MakeMin(IntExpr* expr, int64_t value);
1292
1293 IntExpr* MakeMin(IntExpr* expr, int value);
1294
1296 IntExpr* MakeMax(const std::vector<IntVar*>& vars);
1300 IntExpr* MakeMax(IntExpr* expr, int64_t value);
1302 IntExpr* MakeMax(IntExpr* expr, int value);
1303
1304
1305 IntExpr* MakeConvexPiecewiseExpr(IntExpr* expr, int64_t early_cost,
1306 int64_t early_date, int64_t late_date,
1307 int64_t late_cost);
1308
1311 IntExpr* MakeSemiContinuousExpr(IntExpr* expr, int64_t fixed_charge,
1312 int64_t step);
1313
1316 // TODO(user): Investigate if we can merge all three piecewise linear
1318#ifndef SWIG
1320 const PiecewiseLinearFunction& f);
1321#endif
1322
1324 IntExpr* MakeModulo(IntExpr* x, int64_t mod);
1325
1327 IntExpr* MakeModulo(IntExpr* x, IntExpr* mod);
1328
1331 int64_t unperformed_value);
1332
1337 Constraint* MakeFalseConstraint(const std::string& explanation);
1338
1340 Constraint* MakeIsEqualCstCt(IntExpr* var, int64_t value, IntVar* boolvar);
1342 IntVar* MakeIsEqualCstVar(IntExpr* var, int64_t value);
1348 Constraint* MakeEquality(IntExpr* left, IntExpr* right);
1350 Constraint* MakeEquality(IntExpr* expr, int64_t value);
1352 Constraint* MakeEquality(IntExpr* expr, int value);
1353
1355 Constraint* MakeIsDifferentCstCt(IntExpr* var, int64_t value,
1356 IntVar* boolvar);
1358 IntVar* MakeIsDifferentCstVar(IntExpr* var, int64_t value);
1364 Constraint* MakeNonEquality(IntExpr* left, IntExpr* right);
1366 Constraint* MakeNonEquality(IntExpr* expr, int64_t value);
1368 Constraint* MakeNonEquality(IntExpr* expr, int value);
1369
1371 Constraint* MakeIsLessOrEqualCstCt(IntExpr* var, int64_t value,
1372 IntVar* boolvar);
1374 IntVar* MakeIsLessOrEqualCstVar(IntExpr* var, int64_t value);
1380 Constraint* MakeLessOrEqual(IntExpr* left, IntExpr* right);
1382 Constraint* MakeLessOrEqual(IntExpr* expr, int64_t value);
1384 Constraint* MakeLessOrEqual(IntExpr* expr, int value);
1385
1387 Constraint* MakeIsGreaterOrEqualCstCt(IntExpr* var, int64_t value,
1388 IntVar* boolvar);
1390 IntVar* MakeIsGreaterOrEqualCstVar(IntExpr* var, int64_t value);
1398 Constraint* MakeGreaterOrEqual(IntExpr* expr, int64_t value);
1400 Constraint* MakeGreaterOrEqual(IntExpr* expr, int value);
1401
1403 Constraint* MakeIsGreaterCstCt(IntExpr* v, int64_t c, IntVar* b);
1405 IntVar* MakeIsGreaterCstVar(IntExpr* var, int64_t value);
1407 IntVar* MakeIsGreaterVar(IntExpr* left, IntExpr* right);
1409 Constraint* MakeIsGreaterCt(IntExpr* left, IntExpr* right, IntVar* b);
1411 Constraint* MakeGreater(IntExpr* left, IntExpr* right);
1413 Constraint* MakeGreater(IntExpr* expr, int64_t value);
1415 Constraint* MakeGreater(IntExpr* expr, int value);
1416
1418 Constraint* MakeIsLessCstCt(IntExpr* v, int64_t c, IntVar* b);
1420 IntVar* MakeIsLessCstVar(IntExpr* var, int64_t value);
1422 IntVar* MakeIsLessVar(IntExpr* left, IntExpr* right);
1424 Constraint* MakeIsLessCt(IntExpr* left, IntExpr* right, IntVar* b);
1426 Constraint* MakeLess(IntExpr* left, IntExpr* right);
1428 Constraint* MakeLess(IntExpr* expr, int64_t value);
1430 Constraint* MakeLess(IntExpr* expr, int value);
1431
1433 Constraint* MakeSumLessOrEqual(const std::vector<IntVar*>& vars, int64_t cst);
1434 Constraint* MakeSumGreaterOrEqual(const std::vector<IntVar*>& vars,
1435 int64_t cst);
1436 Constraint* MakeSumEquality(const std::vector<IntVar*>& vars, int64_t cst);
1437 Constraint* MakeSumEquality(const std::vector<IntVar*>& vars, IntVar* var);
1438 Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1439 const std::vector<int64_t>& coefficients,
1440 int64_t cst);
1441 Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1442 const std::vector<int>& coefficients,
1443 int64_t cst);
1444 Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1445 const std::vector<int64_t>& coefficients,
1446 IntVar* target);
1447 Constraint* MakeScalProdEquality(const std::vector<IntVar*>& vars,
1448 const std::vector<int>& coefficients,
1449 IntVar* target);
1450 Constraint* MakeScalProdGreaterOrEqual(const std::vector<IntVar*>& vars,
1451 const std::vector<int64_t>& coeffs,
1452 int64_t cst);
1453 Constraint* MakeScalProdGreaterOrEqual(const std::vector<IntVar*>& vars,
1454 const std::vector<int>& coeffs,
1455 int64_t cst);
1456 Constraint* MakeScalProdLessOrEqual(const std::vector<IntVar*>& vars,
1457 const std::vector<int64_t>& coefficients,
1458 int64_t cst);
1459 Constraint* MakeScalProdLessOrEqual(const std::vector<IntVar*>& vars,
1460 const std::vector<int>& coefficients,
1461 int64_t cst);
1462
1463 Constraint* MakeMinEquality(const std::vector<IntVar*>& vars,
1464 IntVar* min_var);
1465 Constraint* MakeMaxEquality(const std::vector<IntVar*>& vars,
1466 IntVar* max_var);
1467
1468 Constraint* MakeElementEquality(const std::vector<int64_t>& vals,
1469 IntVar* index, IntVar* target);
1470 Constraint* MakeElementEquality(const std::vector<int>& vals, IntVar* index,
1471 IntVar* target);
1472 Constraint* MakeElementEquality(const std::vector<IntVar*>& vars,
1473 IntVar* index, IntVar* target);
1474 Constraint* MakeElementEquality(const std::vector<IntVar*>& vars,
1475 IntVar* index, int64_t target);
1477 Constraint* MakeAbsEquality(IntVar* var, IntVar* abs_var);
1482 Constraint* MakeIndexOfConstraint(const std::vector<IntVar*>& vars,
1483 IntVar* index, int64_t target);
1484
1492#if !defined(SWIG)
1494 Demon* MakeActionDemon(Action action);
1495#endif
1497 Demon* MakeClosureDemon(Closure closure);
1498
1499 // ----- Between and related constraints -----
1500
1502 Constraint* MakeBetweenCt(IntExpr* expr, int64_t l, int64_t u);
1503
1508 Constraint* MakeNotBetweenCt(IntExpr* expr, int64_t l, int64_t u);
1509
1511 Constraint* MakeIsBetweenCt(IntExpr* expr, int64_t l, int64_t u, IntVar* b);
1512 IntVar* MakeIsBetweenVar(IntExpr* v, int64_t l, int64_t u);
1513
1514 // ----- Member and related constraints -----
1515
1518 Constraint* MakeMemberCt(IntExpr* expr, const std::vector<int64_t>& values);
1519 Constraint* MakeMemberCt(IntExpr* expr, const std::vector<int>& values);
1520
1523 const std::vector<int64_t>& values);
1524 Constraint* MakeNotMemberCt(IntExpr* expr, const std::vector<int>& values);
1525
1527 Constraint* MakeNotMemberCt(IntExpr* expr, std::vector<int64_t> starts,
1528 std::vector<int64_t> ends);
1530 Constraint* MakeNotMemberCt(IntExpr* expr, std::vector<int> starts,
1531 std::vector<int> ends);
1532#if !defined(SWIG)
1535 SortedDisjointIntervalList intervals);
1536#endif // !defined(SWIG)
1537
1539 Constraint* MakeIsMemberCt(IntExpr* expr, const std::vector<int64_t>& values,
1540 IntVar* boolvar);
1541 Constraint* MakeIsMemberCt(IntExpr* expr, const std::vector<int>& values,
1542 IntVar* boolvar);
1543 IntVar* MakeIsMemberVar(IntExpr* expr, const std::vector<int64_t>& values);
1544 IntVar* MakeIsMemberVar(IntExpr* expr, const std::vector<int>& values);
1545
1547 Constraint* MakeAtMost(std::vector<IntVar*> vars, int64_t value,
1548 int64_t max_count);
1550 Constraint* MakeCount(const std::vector<IntVar*>& vars, int64_t value,
1551 int64_t max_count);
1553 Constraint* MakeCount(const std::vector<IntVar*>& vars, int64_t value,
1554 IntVar* max_count);
1555
1557 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1558 const std::vector<int64_t>& values,
1559 const std::vector<IntVar*>& cards);
1561 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1562 const std::vector<int>& values,
1563 const std::vector<IntVar*>& cards);
1565 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1566 const std::vector<IntVar*>& cards);
1569 Constraint* MakeDistribute(const std::vector<IntVar*>& vars, int64_t card_min,
1570 int64_t card_max, int64_t card_size);
1574 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1575 const std::vector<int64_t>& card_min,
1576 const std::vector<int64_t>& card_max);
1580 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1581 const std::vector<int>& card_min,
1582 const std::vector<int>& card_max);
1586 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1587 const std::vector<int64_t>& values,
1588 const std::vector<int64_t>& card_min,
1589 const std::vector<int64_t>& card_max);
1593 Constraint* MakeDistribute(const std::vector<IntVar*>& vars,
1594 const std::vector<int>& values,
1595 const std::vector<int>& card_min,
1596 const std::vector<int>& card_max);
1597
1602 Constraint* MakeDeviation(const std::vector<IntVar*>& vars,
1603 IntVar* deviation_var, int64_t total_sum);
1604
1607 Constraint* MakeAllDifferent(const std::vector<IntVar*>& vars);
1608
1612 Constraint* MakeAllDifferent(const std::vector<IntVar*>& vars,
1613 bool stronger_propagation);
1614
1617 Constraint* MakeAllDifferentExcept(const std::vector<IntVar*>& vars,
1618 int64_t escape_value);
1619 // TODO(user): Do we need a version with an array of escape values.
1620
1636 Constraint* MakeSortingConstraint(const std::vector<IntVar*>& vars,
1637 const std::vector<IntVar*>& sorted);
1638 // TODO(user): Add void MakeSortedArray(
1639 // const std::vector<IntVar*>& vars,
1640 // std::vector<IntVar*>* const sorted);
1641
1644 Constraint* MakeLexicalLess(const std::vector<IntVar*>& left,
1645 const std::vector<IntVar*>& right);
1646
1649 Constraint* MakeLexicalLessOrEqual(const std::vector<IntVar*>& left,
1650 const std::vector<IntVar*>& right);
1651
1656 Constraint* MakeLexicalLessOrEqualWithOffsets(std::vector<IntVar*> left,
1657 std::vector<IntVar*> right,
1658 std::vector<int64_t> offsets);
1659
1660 // Semi-reified version of the above: boolvar -> LexLE(left, right, offsets).
1662 std::vector<IntVar*> left, std::vector<IntVar*> right,
1663 std::vector<int64_t> offsets, IntVar* boolvar);
1664
1670 const std::vector<IntVar*>& left, const std::vector<IntVar*>& right);
1671
1675 IntVar* index, const std::vector<IntVar*>& vars);
1676
1680 IntVar* index, const std::vector<IntVar*>& vars);
1681
1686 Constraint* MakeNullIntersect(const std::vector<IntVar*>& first_vars,
1687 const std::vector<IntVar*>& second_vars);
1688
1694 Constraint* MakeNullIntersectExcept(const std::vector<IntVar*>& first_vars,
1695 const std::vector<IntVar*>& second_vars,
1696 int64_t escape_value);
1697
1698 // TODO(user): Implement MakeAllNullIntersect taking an array of
1699 // variable vectors.
1700
1710 Constraint* MakeNoCycle(const std::vector<IntVar*>& nexts,
1711 const std::vector<IntVar*>& active,
1712 IndexFilter1 sink_handler = nullptr);
1713 Constraint* MakeNoCycle(const std::vector<IntVar*>& nexts,
1714 const std::vector<IntVar*>& active,
1715 IndexFilter1 sink_handler, bool assume_paths);
1716
1718 Constraint* MakeCircuit(const std::vector<IntVar*>& nexts);
1719
1722 Constraint* MakeSubCircuit(const std::vector<IntVar*>& nexts);
1723
1728 Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1729 const std::vector<IntVar*>& active,
1730 const std::vector<IntVar*>& cumuls,
1731 const std::vector<IntVar*>& transits);
1734 // TODO(user): Merge with other path-cumuls constraints.
1735 Constraint* MakeDelayedPathCumul(const std::vector<IntVar*>& nexts,
1736 const std::vector<IntVar*>& active,
1737 const std::vector<IntVar*>& cumuls,
1738 const std::vector<IntVar*>& transits);
1745 Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1746 const std::vector<IntVar*>& active,
1747 const std::vector<IntVar*>& cumuls,
1748 IndexEvaluator2 transit_evaluator);
1749
1756 Constraint* MakePathCumul(const std::vector<IntVar*>& nexts,
1757 const std::vector<IntVar*>& active,
1758 const std::vector<IntVar*>& cumuls,
1759 const std::vector<IntVar*>& slacks,
1760 IndexEvaluator2 transit_evaluator);
1763 // TODO(user): Only does checking on WhenBound events on next variables.
1765 Constraint* MakePathConnected(std::vector<IntVar*> nexts,
1766 std::vector<int64_t> sources,
1767 std::vector<int64_t> sinks,
1768 std::vector<IntVar*> status);
1769#ifndef SWIG
1772 // TODO(user): This constraint does not make holes in variable domains;
1776 std::vector<IntVar*> nexts,
1777 const std::vector<std::pair<int, int>>& precedences);
1787 std::vector<IntVar*> nexts,
1788 const std::vector<std::pair<int, int>>& precedences,
1789 absl::Span<const int> lifo_path_starts,
1790 absl::Span<const int> fifo_path_starts);
1794 std::vector<IntVar*> nexts, std::vector<IntVar*> transits,
1795 const std::vector<std::pair<int, int>>& precedences);
1814 struct EnergyCost {
1815 int64_t threshold;
1818 bool IsNull() const {
1819 return (cost_per_unit_below_threshold == 0 || threshold == 0) &&
1821 }
1822 };
1823 std::vector<IntVar*> nexts;
1824 std::vector<IntVar*> paths;
1825 std::vector<IntVar*> forces;
1826 std::vector<IntVar*> distances;
1827 std::vector<EnergyCost> path_energy_costs;
1828 std::vector<bool> path_used_when_empty;
1829 std::vector<int64_t> path_starts;
1830 std::vector<int64_t> path_ends;
1831 std::vector<IntVar*> costs;
1832 };
1835#endif // !SWIG
1839 Constraint* MakeMapDomain(IntVar* var, const std::vector<IntVar*>& actives);
1840
1843 /// variables involved in the relation and the graph is given by a
1844 /// integer tuple set.
1845 Constraint* MakeAllowedAssignments(const std::vector<IntVar*>& vars,
1846 const IntTupleSet& tuples);
1848 /// This constraint create a finite automaton that will check the
1849 /// sequence of variables vars. It uses a transition table called
1850 /// 'transition_table'. Each transition is a triple
1851 /// (current_state, variable_value, new_state).
1852 /// The initial state is given, and the set of accepted states is decribed
1853 /// by 'final_states'. These states are hidden inside the constraint.
1854 /// Only the transitions (i.e. the variables) are visible.
1856 const std::vector<IntVar*>& vars, const IntTupleSet& transition_table,
1857 int64_t initial_state, const std::vector<int64_t>& final_states);
1863
1866 Constraint* MakeTransitionConstraint(const std::vector<IntVar*>& vars,
1867 const IntTupleSet& transition_table,
1868 int64_t initial_state,
1869 const std::vector<int>& final_states);
1870
1871#if defined(SWIGPYTHON)
1874 const std::vector<IntVar*>& vars,
1875 const std::vector<std::vector<int64_t> /*keep for swig*/>& raw_tuples) {
1876 IntTupleSet tuples(vars.size());
1877 tuples.InsertAll(raw_tuples);
1878 return MakeAllowedAssignments(vars, tuples);
1879 }
1880
1882 const std::vector<IntVar*>& vars,
1883 const std::vector<std::vector<int64_t> /*keep for swig*/>&
1884 raw_transitions,
1885 int64_t initial_state, const std::vector<int>& final_states) {
1886 IntTupleSet transitions(3);
1887 transitions.InsertAll(raw_transitions);
1888 return MakeTransitionConstraint(vars, transitions, initial_state,
1889 final_states);
1890 }
1891#endif
1892
1902 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1903 const std::vector<IntVar*>& x_size, const std::vector<IntVar*>& y_size);
1905 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1906 absl::Span<const int64_t> x_size, absl::Span<const int64_t> y_size);
1908 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1909 absl::Span<const int> x_size, absl::Span<const int> y_size);
1910
1920 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1921 const std::vector<IntVar*>& x_size, const std::vector<IntVar*>& y_size);
1923 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1924 absl::Span<const int64_t> x_size, absl::Span<const int64_t> y_size);
1926 const std::vector<IntVar*>& x_vars, const std::vector<IntVar*>& y_vars,
1927 absl::Span<const int> x_size, absl::Span<const int> y_size);
1928
1934 Pack* MakePack(const std::vector<IntVar*>& vars, int number_of_bins);
1935
1940 IntervalVar* MakeFixedDurationIntervalVar(int64_t start_min,
1941 int64_t start_max, int64_t duration,
1942 bool optional,
1943 const std::string& name);
1944
1947 void MakeFixedDurationIntervalVarArray(int count, int64_t start_min,
1948 int64_t start_max, int64_t duration,
1949 bool optional, absl::string_view name,
1950 std::vector<IntervalVar*>* array);
1951
1955 int64_t duration,
1956 const std::string& name);
1957
1961 int64_t duration,
1962 IntVar* performed_variable,
1963 const std::string& name);
1964
1968 const std::vector<IntVar*>& start_variables, int64_t duration,
1969 absl::string_view name, std::vector<IntervalVar*>* array);
1970
1974 const std::vector<IntVar*>& start_variables,
1975 absl::Span<const int64_t> durations, absl::string_view name,
1976 std::vector<IntervalVar*>* array);
1980 const std::vector<IntVar*>& start_variables,
1981 absl::Span<const int> durations, absl::string_view name,
1982 std::vector<IntervalVar*>* array);
1983
1987 const std::vector<IntVar*>& start_variables,
1988 absl::Span<const int64_t> durations,
1989 const std::vector<IntVar*>& performed_variables, absl::string_view name,
1990 std::vector<IntervalVar*>* array);
1991
1995 const std::vector<IntVar*>& start_variables,
1996 absl::Span<const int> durations,
1997 const std::vector<IntVar*>& performed_variables, absl::string_view name,
1998 std::vector<IntervalVar*>* array);
1999
2001 IntervalVar* MakeFixedInterval(int64_t start, int64_t duration,
2002 const std::string& name);
2003
2006 IntervalVar* MakeIntervalVar(int64_t start_min, int64_t start_max,
2007 int64_t duration_min, int64_t duration_max,
2008 int64_t end_min, int64_t end_max, bool optional,
2009 const std::string& name);
2010
2013 void MakeIntervalVarArray(int count, int64_t start_min, int64_t start_max,
2014 int64_t duration_min, int64_t duration_max,
2015 int64_t end_min, int64_t end_max, bool optional,
2016 absl::string_view name,
2017 std::vector<IntervalVar*>* array);
2018
2022
2028 IntervalVar* interval_var, int64_t duration, int64_t offset);
2029
2035 IntervalVar* interval_var, int64_t duration, int64_t offset);
2036
2042 IntervalVar* interval_var, int64_t duration, int64_t offset);
2043
2049 IntervalVar* interval_var, int64_t duration, int64_t offset);
2050
2069
2088
2092 int64_t d);
2093
2096 IntervalVar* t2);
2097
2104 IntervalVar* t2, int64_t delay);
2105
2110 IntVar* alt);
2111
2115
2119 const std::vector<IntervalVar*>& intervals, const std::string& name);
2120
2125 const std::vector<IntervalVar*>& intervals, const std::string& name);
2126
2136 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2137 const std::vector<int64_t>& demands,
2138 int64_t capacity, const std::string& name);
2139
2149 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2150 const std::vector<int>& demands, int64_t capacity,
2151 const std::string& name);
2152
2162 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2163 const std::vector<int64_t>& demands,
2164 IntVar* capacity, absl::string_view name);
2165
2175 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2176 const std::vector<int>& demands, IntVar* capacity,
2177 const std::string& name);
2178
2186 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2187 const std::vector<IntVar*>& demands,
2188 int64_t capacity, const std::string& name);
2189
2197 Constraint* MakeCumulative(const std::vector<IntervalVar*>& intervals,
2198 const std::vector<IntVar*>& demands,
2199 IntVar* capacity, const std::string& name);
2200
2206 Constraint* MakeCover(const std::vector<IntervalVar*>& vars,
2207 IntervalVar* target_var);
2208
2211
2214
2217
2223
2229
2235 const Assignment* assignment, bool maximize);
2239 const Assignment* assignment, std::vector<bool> maximize);
2249 std::vector<bool> maximize);
2250
2255 const Assignment* assignment, int solution_count, bool maximize);
2257 bool maximize);
2261 const Assignment* assignment, int solution_count,
2262 std::vector<bool> maximize);
2264 int solution_count, std::vector<bool> maximize);
2265
2271
2273 OptimizeVar* MakeMinimize(IntVar* v, int64_t step);
2274
2276 OptimizeVar* MakeMaximize(IntVar* v, int64_t step);
2277
2279 OptimizeVar* MakeOptimize(bool maximize, IntVar* v, int64_t step);
2280
2283 OptimizeVar* MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
2284 const std::vector<int64_t>& weights,
2285 int64_t step);
2286
2289 OptimizeVar* MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
2290 const std::vector<int>& weights,
2291 int64_t step);
2292
2294 OptimizeVar* MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
2295 const std::vector<int64_t>& weights,
2296 int64_t step);
2297
2299 OptimizeVar* MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
2300 const std::vector<int>& weights,
2301 int64_t step);
2302
2304 OptimizeVar* MakeWeightedOptimize(bool maximize,
2305 const std::vector<IntVar*>& sub_objectives,
2306 const std::vector<int64_t>& weights,
2307 int64_t step);
2308
2310 OptimizeVar* MakeWeightedOptimize(bool maximize,
2311 const std::vector<IntVar*>& sub_objectives,
2312 const std::vector<int>& weights,
2313 int64_t step);
2314
2317 OptimizeVar* MakeLexicographicOptimize(std::vector<bool> maximize,
2318 std::vector<IntVar*> variables,
2319 std::vector<int64_t> steps);
2320
2322
2338
2339 ObjectiveMonitor* MakeTabuSearch(bool maximize, IntVar* objective,
2340 int64_t step,
2341 const std::vector<IntVar*>& vars,
2342 int64_t keep_tenure, int64_t forbid_tenure,
2343 double tabu_factor);
2344
2346 const std::vector<bool>& maximize, std::vector<IntVar*> objectives,
2347 std::vector<int64_t> steps, const std::vector<IntVar*>& vars,
2348 int64_t keep_tenure, int64_t forbid_tenure, double tabu_factor);
2349
2353 int64_t step,
2354 const std::vector<IntVar*>& tabu_vars,
2355 int64_t forbid_tenure);
2356
2358 // TODO(user): document behavior
2360 int64_t step,
2361 int64_t initial_temperature);
2363 const std::vector<bool>& maximize, std::vector<IntVar*> vars,
2364 std::vector<int64_t> steps, std::vector<int64_t> initial_temperatures);
2365
2368#ifndef SWIG
2370 bool maximize, IntVar* objective, IndexEvaluator2 objective_function,
2371 int64_t step, const std::vector<IntVar*>& vars, double penalty_factor,
2372 std::function<std::vector<std::pair<int64_t, int64_t>>(int64_t, int64_t)>
2373 get_equivalent_pairs = nullptr,
2374 bool reset_penalties_on_new_best_solution = false);
2376 bool maximize, IntVar* objective, IndexEvaluator3 objective_function,
2377 int64_t step, const std::vector<IntVar*>& vars,
2378 const std::vector<IntVar*>& secondary_vars, double penalty_factor,
2379 std::function<std::vector<std::pair<int64_t, int64_t>>(int64_t, int64_t)>
2380 get_equivalent_pairs = nullptr,
2381 bool reset_penalties_on_new_best_solution = false);
2382#endif
2383
2384 // Creates a composite objective monitor which alternates between objective
2385 // monitors every time the search reaches a local optimum local optimium
2386 // reached. This will stop if all monitors return false when LocalOptimium is
2387 // called.
2389 std::vector<BaseObjectiveMonitor*> monitors,
2390 int num_max_local_optima_before_metaheuristic_switch);
2391
2395 SearchMonitor* MakeLubyRestart(int scale_factor);
2396
2399 SearchMonitor* MakeConstantRestart(int frequency);
2400
2402 ABSL_MUST_USE_RESULT RegularLimit* MakeTimeLimit(absl::Duration time);
2403#if !defined(SWIG)
2404 ABSL_DEPRECATED("Use the version taking absl::Duration() as argument")
2405#endif // !defined(SWIG)
2406 ABSL_MUST_USE_RESULT RegularLimit* MakeTimeLimit(int64_t time_in_ms) {
2407 return MakeTimeLimit(time_in_ms == kint64max
2408 ? absl::InfiniteDuration()
2409 : absl::Milliseconds(time_in_ms));
2410 }
2411
2414 ABSL_MUST_USE_RESULT RegularLimit* MakeBranchesLimit(int64_t branches);
2415
2418 ABSL_MUST_USE_RESULT RegularLimit* MakeFailuresLimit(int64_t failures);
2419
2422 ABSL_MUST_USE_RESULT RegularLimit* MakeSolutionsLimit(int64_t solutions);
2423
2426 // timer by estimating the number of remaining calls, and 'cumulative' means
2427 // that the limit applies cumulatively, instead of search-by-search.
2428 ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(absl::Duration time,
2429 int64_t branches,
2430 int64_t failures,
2431 int64_t solutions,
2432 bool smart_time_check = false,
2433 bool cumulative = false);
2435 ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(
2436 const RegularLimitParameters& proto);
2437
2438#if !defined(SWIG)
2439 ABSL_DEPRECATED("Use other MakeLimit() versions")
2440#endif // !defined(SWIG)
2441 ABSL_MUST_USE_RESULT RegularLimit* MakeLimit(int64_t time, int64_t branches,
2442 int64_t failures,
2443 int64_t solutions,
2444 bool smart_time_check = false,
2445 bool cumulative = false);
2446
2448 RegularLimitParameters MakeDefaultRegularLimitParameters() const;
2449
2452 /// argument limits.
2453 ABSL_MUST_USE_RESULT SearchLimit* MakeLimit(SearchLimit* limit_1,
2454 SearchLimit* limit_2);
2455
2457
2460 ABSL_MUST_USE_RESULT ImprovementSearchLimit* MakeImprovementLimit(
2461 IntVar* objective_var, bool maximize, double objective_scaling_factor,
2462 double objective_offset, double improvement_rate_coefficient,
2463 int improvement_rate_solutions_distance);
2466 ABSL_MUST_USE_RESULT ImprovementSearchLimit*
2468 std::vector<IntVar*> objective_vars, std::vector<bool> maximize,
2469 std::vector<double> objective_scaling_factors,
2470 std::vector<double> objective_offsets,
2471 double improvement_rate_coefficient,
2472 int improvement_rate_solutions_distance);
2473
2476 ABSL_MUST_USE_RESULT SearchLimit* MakeCustomLimit(
2477 std::function<bool()> limiter);
2478
2479 // TODO(user): DEPRECATE API of MakeSearchLog(.., IntVar* var,..).
2480
2483 SearchMonitor* MakeSearchLog(int branch_period);
2484
2486 SearchMonitor* MakeSearchLog(int branch_period, IntVar* var);
2487
2490 SearchMonitor* MakeSearchLog(int branch_period,
2491 std::function<std::string()> display_callback);
2492
2495 SearchMonitor* MakeSearchLog(int branch_period, IntVar* var,
2496 std::function<std::string()> display_callback);
2497
2500 SearchMonitor* MakeSearchLog(int branch_period, std::vector<IntVar*> vars,
2501 std::function<std::string()> display_callback);
2502
2505 SearchMonitor* MakeSearchLog(int branch_period, OptimizeVar* opt_var);
2506
2509 SearchMonitor* MakeSearchLog(int branch_period, OptimizeVar* opt_var,
2510 std::function<std::string()> display_callback);
2511
2513 struct SearchLogParameters {
2516 int branch_period = 1;
2519 OptimizeVar* objective = nullptr;
2520 std::vector<IntVar*> variables;
2524 std::vector<double> scaling_factors;
2525 std::vector<double> offsets;
2529 std::function<std::string()> display_callback;
2533 };
2534 SearchMonitor* MakeSearchLog(SearchLogParameters parameters);
2535
2538 SearchMonitor* MakeSearchTrace(const std::string& prefix);
2539
2541 SearchMonitor* MakeEnterSearchCallback(std::function<void()> callback);
2542 SearchMonitor* MakeExitSearchCallback(std::function<void()> callback);
2543 SearchMonitor* MakeAtSolutionCallback(std::function<void()> callback);
2544
2549#if !defined(SWIG)
2552 absl::flat_hash_map<const IntVar*, int>* map);
2553#endif // !defined(SWIG)
2554
2557 const std::vector<SymmetryBreaker*>& visitors);
2561 SymmetryBreaker* v3);
2564
2567 Decision* MakeVariableLessOrEqualValue(IntVar* var, int64_t value);
2568 Decision* MakeVariableGreaterOrEqualValue(IntVar* var, int64_t value);
2569 Decision* MakeSplitVariableDomain(IntVar* var, int64_t val,
2570 bool start_with_lower_half);
2573 Decision* MakeAssignVariablesValues(const std::vector<IntVar*>& vars,
2574 const std::vector<int64_t>& values);
2576 const std::vector<IntVar*>& vars, const std::vector<int64_t>& values);
2577 Decision* MakeAssignVariablesValuesOrFail(const std::vector<IntVar*>& vars,
2578 const std::vector<int64_t>& values);
2580 Decision* MakeDecision(Action apply, Action refute);
2581
2592 DecisionBuilder* db3);
2594 DecisionBuilder* db3, DecisionBuilder* db4);
2595 DecisionBuilder* Compose(const std::vector<DecisionBuilder*>& dbs);
2596
2608 // TODO(user): The search tree can be balanced by using binary
2615 DecisionBuilder* db3);
2617 DecisionBuilder* db3, DecisionBuilder* db4);
2618 DecisionBuilder* Try(const std::vector<DecisionBuilder*>& dbs);
2619
2621 // TODO(user): name each of them differently, and document them (and do that
2623 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2624 IntVarStrategy var_str, IntValueStrategy val_str);
2625 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2626 IndexEvaluator1 var_evaluator,
2627 IntValueStrategy val_str);
2628
2629 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2630 IntVarStrategy var_str,
2631 IndexEvaluator2 value_evaluator);
2632
2635 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2636 IntVarStrategy var_str,
2637 VariableValueComparator var_val1_val2_comparator);
2638
2639 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2640 IndexEvaluator1 var_evaluator,
2641 IndexEvaluator2 value_evaluator);
2642
2643 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2644 IntVarStrategy var_str,
2645 IndexEvaluator2 value_evaluator,
2646 IndexEvaluator1 tie_breaker);
2647
2648 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2649 IndexEvaluator1 var_evaluator,
2650 IndexEvaluator2 value_evaluator,
2651 IndexEvaluator1 tie_breaker);
2652
2653 DecisionBuilder* MakeDefaultPhase(const std::vector<IntVar*>& vars);
2654 DecisionBuilder* MakeDefaultPhase(const std::vector<IntVar*>& vars,
2656
2659 IntValueStrategy val_str);
2661 IntValueStrategy val_str);
2663 IntVarStrategy var_str, IntValueStrategy val_str);
2664 DecisionBuilder* MakePhase(IntVar* v0, IntVar* v1, IntVar* v2, IntVar* v3,
2665 IntVarStrategy var_str, IntValueStrategy val_str);
2666
2672 Decision* MakeScheduleOrPostpone(IntervalVar* var, int64_t est,
2673 int64_t* marker);
2674
2680 Decision* MakeScheduleOrExpedite(IntervalVar* var, int64_t est,
2681 int64_t* marker);
2682
2685 Decision* MakeRankFirstInterval(SequenceVar* sequence, int index);
2686
2689 Decision* MakeRankLastInterval(SequenceVar* sequence, int index);
2690
2696 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2698
2706 DecisionBuilder* MakePhase(const std::vector<IntVar*>& vars,
2707 IndexEvaluator2 eval, IndexEvaluator1 tie_breaker,
2708 EvaluatorStrategy str);
2709
2711 DecisionBuilder* MakePhase(const std::vector<IntervalVar*>& intervals,
2712 IntervalStrategy str);
2713
2714 DecisionBuilder* MakePhase(const std::vector<SequenceVar*>& sequences,
2715 SequenceStrategy str);
2716
2720 Assignment* assignment, DecisionBuilder* db,
2721 const std::vector<IntVar*>& vars);
2722
2726
2734 SearchMonitor* monitor2);
2736 SearchMonitor* monitor2,
2737 SearchMonitor* monitor3);
2739 SearchMonitor* monitor2,
2740 SearchMonitor* monitor3,
2741 SearchMonitor* monitor4);
2743 const std::vector<SearchMonitor*>& monitors);
2744
2753 bool maximize, int64_t step);
2755 bool maximize, int64_t step,
2756 SearchMonitor* monitor1);
2758 bool maximize, int64_t step,
2759 SearchMonitor* monitor1,
2760 SearchMonitor* monitor2);
2762 bool maximize, int64_t step,
2763 SearchMonitor* monitor1,
2764 SearchMonitor* monitor2,
2765 SearchMonitor* monitor3);
2767 bool maximize, int64_t step,
2768 SearchMonitor* monitor1,
2769 SearchMonitor* monitor2,
2770 SearchMonitor* monitor3,
2771 SearchMonitor* monitor4);
2773 DecisionBuilder* db, Assignment* solution, bool maximize, int64_t step,
2774 const std::vector<SearchMonitor*>& monitors);
2775
2779
2783
2786 const std::vector<IntVar*>& vars, LocalSearchOperators op,
2787 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2788 nullptr,
2789 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2790 nullptr);
2792 const std::vector<IntVar*>& vars,
2793 const std::vector<IntVar*>& secondary_vars, LocalSearchOperators op,
2794 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2795 nullptr,
2796 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2797 nullptr);
2798 // TODO(user): Make the callback an IndexEvaluator2 when there are no
2799 // secondary variables.
2800 LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2801 IndexEvaluator3 evaluator,
2803 LocalSearchOperator* MakeOperator(const std::vector<IntVar*>& vars,
2804 const std::vector<IntVar*>& secondary_vars,
2805 IndexEvaluator3 evaluator,
2807
2815 LocalSearchOperator* MakeRandomLnsOperator(const std::vector<IntVar*>& vars,
2816 int number_of_variables);
2817 LocalSearchOperator* MakeRandomLnsOperator(const std::vector<IntVar*>& vars,
2818 int number_of_variables,
2819 int32_t seed);
2820
2827
2835 const std::vector<IntVar*>& variables,
2836 const std::vector<int64_t>& target_values);
2837
2869 const std::vector<LocalSearchOperator*>& ops);
2871 const std::vector<LocalSearchOperator*>& ops, bool restart);
2873 const std::vector<LocalSearchOperator*>& ops,
2874 std::function<int64_t(int, int)> evaluator);
2878 const std::vector<LocalSearchOperator*>& ops);
2879
2884 const std::vector<LocalSearchOperator*>& ops, int32_t seed);
2885
2894 const std::vector<LocalSearchOperator*>& ops, double memory_coefficient,
2895 double exploration_coefficient, bool maximize);
2896
2903 int64_t limit);
2904
2929 // TODO(user): Make a variant which runs a local search after each
2930 // solution found in a DFS.
2931
2934 DecisionBuilder* MakeLocalSearchPhase(const std::vector<IntVar*>& vars,
2935 DecisionBuilder* first_solution,
2939 const std::vector<IntVar*>& vars, DecisionBuilder* first_solution,
2940 DecisionBuilder* first_solution_sub_decision_builder,
2942 DecisionBuilder* MakeLocalSearchPhase(const std::vector<SequenceVar*>& vars,
2943 DecisionBuilder* first_solution,
2945
2951 const Assignment* initial_solution,
2952 LocalSearchFilterManager* filter_manager,
2953 LocalSearchOperator* ls_operator,
2954 const std::vector<SearchMonitor*>& monitors, RegularLimit* limit,
2955 absl::flat_hash_set<IntVar*>* touched = nullptr);
2956
2959
2962 IntVar* objective, LocalSearchOperator* ls_operator,
2963 DecisionBuilder* sub_decision_builder);
2965 IntVar* objective, LocalSearchOperator* ls_operator,
2966 DecisionBuilder* sub_decision_builder, RegularLimit* limit);
2968 IntVar* objective, LocalSearchOperator* ls_operator,
2969 DecisionBuilder* sub_decision_builder, RegularLimit* limit,
2970 LocalSearchFilterManager* filter_manager);
2971
2973 IntVar* objective, SolutionPool* pool, LocalSearchOperator* ls_operator,
2974 DecisionBuilder* sub_decision_builder);
2976 IntVar* objective, SolutionPool* pool, LocalSearchOperator* ls_operator,
2977 DecisionBuilder* sub_decision_builder, RegularLimit* limit);
2979 IntVar* objective, SolutionPool* pool, LocalSearchOperator* ls_operator,
2980 DecisionBuilder* sub_decision_builder, RegularLimit* limit,
2981 LocalSearchFilterManager* filter_manager);
2982
2988 const std::vector<IntVar*>& vars, IndexEvaluator2 values,
2989 Solver::LocalSearchFilterBound filter_enum);
2991 const std::vector<IntVar*>& vars,
2992 const std::vector<IntVar*>& secondary_vars, IndexEvaluator3 values,
2993 Solver::LocalSearchFilterBound filter_enum);
2994
2997 void TopPeriodicCheck();
3001 int TopProgressPercent();
3002
3006 void PushState();
3007 void PopState();
3008
3011 int SearchDepth() const;
3012
3015 int SearchLeftDepth() const;
3016
3019 int SolveDepth() const;
3020
3023
3026
3028 template <class T>
3029 void SaveAndSetValue(T* adr, T val) {
3030 if (*adr != val) {
3031 InternalSaveValue(adr);
3032 *adr = val;
3033 }
3034 }
3035
3037 template <class T>
3038 void SaveAndAdd(T* adr, T val) {
3039 if (val != 0) {
3040 InternalSaveValue(adr);
3041 (*adr) += val;
3042 }
3043 }
3044
3046 int64_t Rand64(int64_t size) {
3047 DCHECK_GT(size, 0);
3048 return absl::Uniform<int64_t>(random_, 0, size);
3049 }
3050
3052 int32_t Rand32(int32_t size) {
3053 DCHECK_GT(size, 0);
3054 return absl::Uniform<int32_t>(random_, 0, size);
3055 }
3056
3058 void ReSeed(int32_t seed) { random_.seed(seed); }
3059
3063 void ExportProfilingOverview(const std::string& filename);
3064
3066 // TODO(user): Merge demon and local search profiles.
3067 std::string LocalSearchProfile() const;
3068
3069#if !defined(SWIG)
3071 ConstraintSolverStatistics GetConstraintSolverStatistics() const;
3073 LocalSearchStatistics GetLocalSearchStatistics() const;
3074#endif // !defined(SWIG)
3075
3079 bool CurrentlyInSolve() const;
3080
3083 int constraints() const { return constraints_list_.size(); }
3084
3085 /// Accepts the given model visitor.
3086 void Accept(ModelVisitor* visitor) const;
3087
3088 Decision* balancing_decision() const { return balancing_decision_.get(); }
3089
3091#if !defined(SWIG)
3092 void set_fail_intercept(std::function<void()> fail_intercept) {
3093 fail_intercept_ = std::move(fail_intercept);
3095#endif // !defined(SWIG)
3096 void clear_fail_intercept() { fail_intercept_ = nullptr; }
3098 DemonProfiler* demon_profiler() const { return demon_profiler_; }
3099 // TODO(user): Get rid of the following methods once fast local search is
3100
3102 void SetUseFastLocalSearch(bool use_fast_local_search) {
3103 use_fast_local_search_ = use_fast_local_search;
3104 }
3106 bool UseFastLocalSearch() const { return use_fast_local_search_; }
3108 bool HasName(const PropagationBaseObject* object) const;
3110 Demon* RegisterDemon(Demon* demon);
3118
3120 Search* ActiveSearch() const;
3122 ModelCache* Cache() const;
3124 bool InstrumentsDemons() const;
3126 bool IsProfilingEnabled() const;
3128 bool IsLocalSearchProfilingEnabled() const;
3130 bool InstrumentsVariables() const;
3132 bool NameAllVariables() const;
3134 std::string model_name() const;
3145 void SetSearchContext(Search* search, absl::string_view search_context);
3146 std::string SearchContext() const;
3147 std::string SearchContext(const Search* search) const;
3148 /// Returns (or creates) an assignment representing the state of local search.
3149 // TODO(user): Investigate if this should be moved to Search.
3151
3152 void ClearLocalSearchState() { local_search_state_.reset(nullptr); }
3153
3158 std::vector<int64_t> tmp_vector_;
3159
3160 friend class BaseIntExpr;
3161 friend class Constraint;
3162 friend class DemonProfiler;
3163 friend class FindOneNeighbor;
3164 friend class IntVar;
3165 friend class PropagationBaseObject;
3166 friend class Queue;
3167 friend class SearchMonitor;
3168 friend class SearchLimit;
3169 friend class RoutingModel;
3170 friend class LocalSearch;
3171 friend class LocalSearchProfiler;
3172
3173#if !defined(SWIG)
3175 template <class>
3176 friend class SimpleRevFIFO;
3177 template <class K, class V>
3178 friend class RevImmutableMultiMap;
3179
3184 bool IsBooleanVar(IntExpr* expr, IntVar** inner_var, bool* is_negated) const;
3185
3190 bool IsProduct(IntExpr* expr, IntExpr** inner_expr, int64_t* coefficient);
3191#endif
3192
3195 IntExpr* CastExpression(const IntVar* var) const;
3196
3198 void FinishCurrentSearch();
3199 void RestartCurrentSearch();
3200
3203 void ShouldFail() { should_fail_ = true; }
3204 void CheckFail() {
3205 if (!should_fail_) return;
3206 should_fail_ = false;
3207 Fail();
3209
3212
3213 private:
3214 void Init();
3215 void PushState(MarkerType t, const StateInfo& info);
3217 void PushSentinel(int magic_code);
3218 void BacktrackToSentinel(int magic_code);
3219 void ProcessConstraints();
3220 bool BacktrackOneLevel(Decision** fail_decision);
3221 void JumpToSentinelWhenNested();
3222 void JumpToSentinel();
3223 void check_alloc_state();
3224 void FreezeQueue();
3225 void EnqueueVar(Demon* d);
3226 void EnqueueDelayedDemon(Demon* d);
3227 void ExecuteAll(const SimpleRevFIFO<Demon*>& demons);
3228 void EnqueueAll(const SimpleRevFIFO<Demon*>& demons);
3229 void UnfreezeQueue();
3230 void reset_action_on_fail();
3231 void set_action_on_fail(Action a);
3232 void set_variable_to_clean_on_fail(IntVar* v);
3233 void IncrementUncheckedSolutionCounter();
3234 bool IsUncheckedSolutionLimitReached();
3235
3236 void InternalSaveValue(int* valptr);
3237 void InternalSaveValue(int64_t* valptr);
3238 void InternalSaveValue(uint64_t* valptr);
3239 void InternalSaveValue(double* valptr);
3240 void InternalSaveValue(bool* valptr);
3241 void InternalSaveValue(void** valptr);
3242 void InternalSaveValue(int64_t** valptr) {
3243 InternalSaveValue(reinterpret_cast<void**>(valptr));
3244 }
3245
3246 BaseObject* SafeRevAlloc(BaseObject* ptr);
3247
3248 int* SafeRevAllocArray(int* ptr);
3249 int64_t* SafeRevAllocArray(int64_t* ptr);
3250 uint64_t* SafeRevAllocArray(uint64_t* ptr);
3251 double* SafeRevAllocArray(double* ptr);
3252 BaseObject** SafeRevAllocArray(BaseObject** ptr);
3253 IntVar** SafeRevAllocArray(IntVar** ptr);
3254 IntExpr** SafeRevAllocArray(IntExpr** ptr);
3255 Constraint** SafeRevAllocArray(Constraint** ptr);
3258 void* UnsafeRevAllocAux(void* ptr);
3259 template <class T>
3260 T* UnsafeRevAlloc(T* ptr) {
3261 return reinterpret_cast<T*>(
3262 UnsafeRevAllocAux(reinterpret_cast<void*>(ptr)));
3263 }
3264 void** UnsafeRevAllocArrayAux(void** ptr);
3265 template <class T>
3266 T** UnsafeRevAllocArray(T** ptr) {
3267 return reinterpret_cast<T**>(
3268 UnsafeRevAllocArrayAux(reinterpret_cast<void**>(ptr)));
3269 }
3270
3271 void InitCachedIntConstants();
3272 void InitCachedConstraint();
3273
3277 Search* TopLevelSearch() const { return searches_.at(1); }
3281 Search* ParentSearch() const {
3282 const size_t search_size = searches_.size();
3283 DCHECK_GT(search_size, 1);
3284 return searches_[search_size - 2];
3285 }
3286
3287 template <bool is_profile_active>
3288 Assignment* RunUncheckedLocalSearchInternal(
3289 const Assignment* initial_solution,
3290 LocalSearchFilterManager* filter_manager,
3291 LocalSearchOperator* ls_operator,
3292 const std::vector<SearchMonitor*>& monitors, RegularLimit* limit,
3293 absl::flat_hash_set<IntVar*>* touched);
3294
3296 std::string GetName(const PropagationBaseObject* object);
3297 void SetName(const PropagationBaseObject* object, absl::string_view name);
3298
3301 int GetNewIntVarIndex() { return num_int_vars_++; }
3302
3304 bool IsADifference(IntExpr* expr, IntExpr** left, IntExpr** right);
3305
3306 const std::string name_;
3307 const ConstraintSolverParameters parameters_;
3308 absl::flat_hash_map<const PropagationBaseObject*, std::string>
3309 propagation_object_names_;
3310 absl::flat_hash_map<const PropagationBaseObject*, IntegerCastInfo>
3311 cast_information_;
3312 absl::flat_hash_set<const Constraint*> cast_constraints_;
3313 const std::string empty_name_;
3314 std::unique_ptr<Queue> queue_;
3315 std::unique_ptr<Trail> trail_;
3316 std::vector<Constraint*> constraints_list_;
3317 std::vector<Constraint*> additional_constraints_list_;
3318 std::vector<int> additional_constraints_parent_list_;
3319 SolverState state_;
3320 int64_t branches_;
3321 int64_t fails_;
3322 int64_t decisions_;
3323 int64_t demon_runs_[kNumPriorities];
3324 int64_t neighbors_;
3325 int64_t filtered_neighbors_;
3326 int64_t accepted_neighbors_;
3327 std::string context_;
3328 OptimizationDirection optimization_direction_;
3329 std::unique_ptr<ClockTimer> timer_;
3330 std::vector<Search*> searches_;
3331 std::mt19937 random_;
3332 uint64_t fail_stamp_;
3333 std::unique_ptr<Decision> balancing_decision_;
3335 std::function<void()> fail_intercept_;
3337 DemonProfiler* const demon_profiler_;
3339 bool use_fast_local_search_;
3341 LocalSearchProfiler* const local_search_profiler_;
3343 std::unique_ptr<Assignment> local_search_state_;
3344
3346 enum { MIN_CACHED_INT_CONST = -8, MAX_CACHED_INT_CONST = 8 };
3347 IntVar* cached_constants_[MAX_CACHED_INT_CONST + 1 - MIN_CACHED_INT_CONST];
3348
3350 Constraint* true_constraint_;
3351 Constraint* false_constraint_;
3352
3353 std::unique_ptr<Decision> fail_decision_;
3354 int constraint_index_;
3355 int additional_constraint_index_;
3356 int num_int_vars_;
3357
3358 std::unique_ptr<ModelCache> model_cache_;
3359 std::unique_ptr<PropagationMonitor> propagation_monitor_;
3360 PropagationMonitor* print_trace_;
3361 std::unique_ptr<LocalSearchMonitor> local_search_monitor_;
3362 int anonymous_variable_index_;
3363 bool should_fail_;
3364
3365 std::function<int64_t(int64_t, int64_t, int64_t)> penalty_callback_;
3366};
3367
3368std::ostream& operator<<(std::ostream& out, const Solver* const s);
3369
3373inline int64_t Zero() { return 0; }
3374
3376inline int64_t One() { return 1; }
3377
3381class BaseObject {
3382 public:
3383 BaseObject() {}
3384
3385#ifndef SWIG
3386 // This type is neither copyable nor movable.
3387 BaseObject(const BaseObject&) = delete;
3388 BaseObject& operator=(const BaseObject&) = delete;
3389#endif
3390 virtual ~BaseObject() = default;
3391 virtual std::string DebugString() const { return "BaseObject"; }
3392};
3393
3394std::ostream& operator<<(std::ostream& out, const BaseObject* o);
3395
3399class PropagationBaseObject : public BaseObject {
3400 public:
3401 explicit PropagationBaseObject(Solver* const s) : solver_(s) {}
3402
3403#ifndef SWIG
3404 // This type is neither copyable nor movable.
3407#endif
3408 ~PropagationBaseObject() override {};
3409
3410 std::string DebugString() const override {
3411 if (name().empty()) {
3412 return "PropagationBaseObject";
3413 } else {
3414 return absl::StrFormat("PropagationBaseObject: %s", name());
3415 }
3416 }
3417 Solver* solver() const { return solver_; }
3418
3421 void FreezeQueue() { solver_->FreezeQueue(); }
3422
3423
3425 void UnfreezeQueue() { solver_->UnfreezeQueue(); }
3426
3430 void EnqueueDelayedDemon(Demon* const d) { solver_->EnqueueDelayedDemon(d); }
3431 void EnqueueVar(Demon* const d) { solver_->EnqueueVar(d); }
3433 void EnqueueAll(const SimpleRevFIFO<Demon*>& demons);
3434
3435#if !defined(SWIG)
3436 // This method sets a callback that will be called if a failure
3437 // happens during the propagation of the queue.
3439 solver_->set_action_on_fail(std::move(a));
3440 }
3441#endif // !defined(SWIG)
3442
3444 void reset_action_on_fail() { solver_->reset_action_on_fail(); }
3445
3448 solver_->set_variable_to_clean_on_fail(v);
3449 }
3450
3452 virtual std::string name() const;
3453 void set_name(absl::string_view name);
3455 bool HasName() const;
3457 virtual std::string BaseName() const;
3458
3459 private:
3460 Solver* const solver_;
3465class Decision : public BaseObject {
3466 public:
3467 Decision() {}
3468
3469#ifndef SWIG
3470 // This type is neither copyable nor movable.
3471 Decision(const Decision&) = delete;
3472 Decision& operator=(const Decision&) = delete;
3473#endif
3474 ~Decision() override {}
3475
3477 virtual void Apply(Solver* s) = 0;
3478
3480 virtual void Refute(Solver* s) = 0;
3482 std::string DebugString() const override { return "Decision"; }
3484 virtual void Accept(DecisionVisitor* visitor) const;
3485};
3489class DecisionVisitor : public BaseObject {
3490 public:
3491 DecisionVisitor() {}
3492
3493#ifndef SWIG
3494 // This type is neither copyable nor movable.
3495 DecisionVisitor(const DecisionVisitor&) = delete;
3496 DecisionVisitor& operator=(const DecisionVisitor&) = delete;
3497#endif
3498 ~DecisionVisitor() override {}
3499 virtual void VisitSetVariableValue(IntVar* var, int64_t value);
3500 virtual void VisitSplitVariableDomain(IntVar* var, int64_t value,
3501 bool start_with_lower_half);
3502 virtual void VisitScheduleOrPostpone(IntervalVar* var, int64_t est);
3503 virtual void VisitScheduleOrExpedite(IntervalVar* var, int64_t est);
3504 virtual void VisitRankFirstInterval(SequenceVar* sequence, int index);
3505 virtual void VisitRankLastInterval(SequenceVar* sequence, int index);
3506 virtual void VisitUnknownDecision();
3507};
3508
3511class DecisionBuilder : public BaseObject {
3512 public:
3513 DecisionBuilder() {}
3514
3515#ifndef SWIG
3516 // This type is neither copyable nor movable.
3517 DecisionBuilder(const DecisionBuilder&) = delete;
3518 DecisionBuilder& operator=(const DecisionBuilder&) = delete;
3519#endif
3520 ~DecisionBuilder() override {}
3521 /// This is the main method of the decision builder class. It must
3522 /// return a decision (an instance of the class Decision). If it
3523 /// returns nullptr, this means that the decision builder has finished
3524 /// its work.
3525 virtual Decision* Next(Solver* s) = 0;
3526 std::string DebugString() const override;
3527#if !defined(SWIG)
3532 virtual void AppendMonitors(Solver* solver,
3533 std::vector<SearchMonitor*>* extras);
3534 virtual void Accept(ModelVisitor* visitor) const;
3535#endif
3536 void set_name(absl::string_view name) { name_ = name; }
3537 std::string GetName() const;
3539 private:
3540 std::string name_;
3541};
3542
3543#if !defined(SWIG)
3545 public:
3548 const std::string& name() const { return name_; }
3549 double seconds() const { return seconds_; }
3550 Decision* Next(Solver* solver) override;
3551 std::string DebugString() const override;
3553 std::vector<SearchMonitor*>* extras) override;
3554 void Accept(ModelVisitor* visitor) const override;
3555
3556 private:
3557 DecisionBuilder* const db_;
3558 const std::string name_;
3559 SimpleCycleTimer timer_;
3560 double seconds_;
3561};
3562#endif
3563
3564
3567/// of the variables. The main concept is that demons are listeners that are
3568/// attached to the variables and listen to their modifications.
3569/// There are two methods:
3570/// - Run() is the actual method called when the demon is processed.
3571/// - priority() returns its priority. Standard priorities are slow, normal
3572/// or fast. "immediate" is reserved for variables and is treated separately.
3573class Demon : public BaseObject {
3574 public:
3577 Demon() : stamp_(uint64_t{0}) {}
3578
3579#ifndef SWIG
3580 // This type is neither copyable nor movable.
3581 Demon(const Demon&) = delete;
3582 Demon& operator=(const Demon&) = delete;
3583#endif
3584 ~Demon() override {}
3585
3587 virtual void Run(Solver* s) = 0;
3588
3593
3594 std::string DebugString() const override;
3595
3598 void inhibit(Solver* s);
3599
3600 /// This method un-inhibits the demon that was previously inhibited.
3601 void desinhibit(Solver* s);
3602
3603 private:
3604 friend class Queue;
3605 void set_stamp(int64_t stamp) { stamp_ = stamp; }
3606 uint64_t stamp() const { return stamp_; }
3607 uint64_t stamp_;
3608};
3609
3611class OR_DLL ModelVisitor : public BaseObject {
3612 public:
3614 static const char kAbs[];
3615 static const char kAbsEqual[];
3616 static const char kAllDifferent[];
3617 static const char kAllowedAssignments[];
3618 static const char kAtMost[];
3619 static const char kIndexOf[];
3620 static const char kBetween[];
3621 static const char kConditionalExpr[];
3622 static const char kCircuit[];
3623 static const char kConvexPiecewise[];
3624 static const char kCountEqual[];
3625 static const char kCover[];
3626 static const char kCumulative[];
3627 static const char kDeviation[];
3628 static const char kDifference[];
3629 static const char kDisjunctive[];
3630 static const char kDistribute[];
3631 static const char kDivide[];
3632 static const char kDurationExpr[];
3633 static const char kElement[];
3634 static const char kLightElementEqual[];
3635 static const char kElementEqual[];
3636 static const char kEndExpr[];
3637 static const char kEquality[];
3638 static const char kFalseConstraint[];
3639 static const char kGlobalCardinality[];
3640 static const char kGreater[];
3641 static const char kGreaterOrEqual[];
3642 static const char kIntegerVariable[];
3643 static const char kIntervalBinaryRelation[];
3644 static const char kIntervalDisjunction[];
3645 static const char kIntervalUnaryRelation[];
3646 static const char kIntervalVariable[];
3647 static const char kInversePermutation[];
3648 static const char kIsBetween[];
3649 static const char kIsDifferent[];
3650 static const char kIsEqual[];
3651 static const char kIsGreater[];
3652 static const char kIsGreaterOrEqual[];
3653 static const char kIsLess[];
3654 static const char kIsLessOrEqual[];
3655 static const char kIsMember[];
3656 static const char kLess[];
3657 static const char kLessOrEqual[];
3658 static const char kLexLess[];
3659 static const char kLinkExprVar[];
3660 static const char kMapDomain[];
3661 static const char kMax[];
3662 static const char kMaxEqual[];
3663 static const char kMember[];
3664 static const char kMin[];
3665 static const char kMinEqual[];
3666 static const char kModulo[];
3667 static const char kNoCycle[];
3668 static const char kNonEqual[];
3669 static const char kNotBetween[];
3670 static const char kNotMember[];
3671 static const char kNullIntersect[];
3672 static const char kOpposite[];
3673 static const char kPack[];
3674 static const char kPathCumul[];
3675 static const char kDelayedPathCumul[];
3676 static const char kPerformedExpr[];
3677 static const char kPower[];
3678 static const char kProduct[];
3679 static const char kScalProd[];
3680 static const char kScalProdEqual[];
3681 static const char kScalProdGreaterOrEqual[];
3682 static const char kScalProdLessOrEqual[];
3683 static const char kSemiContinuous[];
3684 static const char kSequenceVariable[];
3685 static const char kSortingConstraint[];
3686 static const char kSquare[];
3687 static const char kStartExpr[];
3688 static const char kSum[];
3689 static const char kSumEqual[];
3690 static const char kSumGreaterOrEqual[];
3691 static const char kSumLessOrEqual[];
3692 static const char kTrace[];
3693 static const char kTransition[];
3694 static const char kTrueConstraint[];
3695 static const char kVarBoundWatcher[];
3696 static const char kVarValueWatcher[];
3699 static const char kCountAssignedItemsExtension[];
3700 static const char kCountUsedBinsExtension[];
3701 static const char kInt64ToBoolExtension[];
3702 static const char kInt64ToInt64Extension[];
3703 static const char kObjectiveExtension[];
3704 static const char kSearchLimitExtension[];
3705 static const char kUsageEqualVariableExtension[];
3707 static const char kUsageLessConstantExtension[];
3708 static const char kVariableGroupExtension[];
3713 static const char kActiveArgument[];
3714 static const char kAssumePathsArgument[];
3715 static const char kBranchesLimitArgument[];
3716 static const char kCapacityArgument[];
3717 static const char kCardsArgument[];
3718 static const char kCoefficientsArgument[];
3719 static const char kCountArgument[];
3720 static const char kCumulativeArgument[];
3721 static const char kCumulsArgument[];
3722 static const char kDemandsArgument[];
3723 static const char kDurationMaxArgument[];
3724 static const char kDurationMinArgument[];
3725 static const char kEarlyCostArgument[];
3726 static const char kEarlyDateArgument[];
3727 static const char kEndMaxArgument[];
3728 static const char kEndMinArgument[];
3729 static const char kEndsArgument[];
3730 static const char kExpressionArgument[];
3731 static const char kFailuresLimitArgument[];
3732 static const char kFinalStatesArgument[];
3733 static const char kFixedChargeArgument[];
3734 static const char kIndex2Argument[];
3735 static const char kIndex3Argument[];
3736 static const char kIndexArgument[];
3737 static const char kInitialState[];
3738 static const char kIntervalArgument[];
3739 static const char kIntervalsArgument[];
3740 static const char kLateCostArgument[];
3741 static const char kLateDateArgument[];
3742 static const char kLeftArgument[];
3743 static const char kMaxArgument[];
3744 static const char kMaximizeArgument[];
3745 static const char kMinArgument[];
3746 static const char kModuloArgument[];
3747 static const char kNextsArgument[];
3748 static const char kOptionalArgument[];
3749 static const char kPartialArgument[];
3750 static const char kPositionXArgument[];
3751 static const char kPositionYArgument[];
3752 static const char kRangeArgument[];
3753 static const char kRelationArgument[];
3754 static const char kRightArgument[];
3755 static const char kSequenceArgument[];
3756 static const char kSequencesArgument[];
3757 static const char kSizeArgument[];
3758 static const char kSizeXArgument[];
3759 static const char kSizeYArgument[];
3760 static const char kSmartTimeCheckArgument[];
3761 static const char kSolutionLimitArgument[];
3762 static const char kStartMaxArgument[];
3763 static const char kStartMinArgument[];
3764 static const char kStartsArgument[];
3765 static const char kStepArgument[];
3766 static const char kTargetArgument[];
3767 static const char kTimeLimitArgument[];
3768 static const char kTransitsArgument[];
3769 static const char kTuplesArgument[];
3770 static const char kValueArgument[];
3771 static const char kValuesArgument[];
3772 static const char kVariableArgument[];
3773 static const char kVarsArgument[];
3774 static const char kEvaluatorArgument[];
3777 static const char kMirrorOperation[];
3778 static const char kRelaxedMaxOperation[];
3779 static const char kRelaxedMinOperation[];
3780 static const char kSumOperation[];
3781 static const char kDifferenceOperation[];
3782 static const char kProductOperation[];
3783 static const char kStartSyncOnStartOperation[];
3784 static const char kStartSyncOnEndOperation[];
3785 static const char kTraceOperation[];
3787 ~ModelVisitor() override;
3792 virtual void BeginVisitModel(const std::string& type_name);
3793 virtual void EndVisitModel(const std::string& type_name);
3794 virtual void BeginVisitConstraint(const std::string& type_name,
3795 const Constraint* constraint);
3796 virtual void EndVisitConstraint(const std::string& type_name,
3797 const Constraint* constraint);
3798 virtual void BeginVisitExtension(const std::string& type);
3799 virtual void EndVisitExtension(const std::string& type);
3800 virtual void BeginVisitIntegerExpression(const std::string& type_name,
3801 const IntExpr* expr);
3802 virtual void EndVisitIntegerExpression(const std::string& type_name,
3803 const IntExpr* expr);
3804 virtual void VisitIntegerVariable(const IntVar* variable, IntExpr* delegate);
3805 virtual void VisitIntegerVariable(const IntVar* variable,
3806 const std::string& operation, int64_t value,
3807 IntVar* delegate);
3808 virtual void VisitIntervalVariable(const IntervalVar* variable,
3809 const std::string& operation,
3810 int64_t value, IntervalVar* delegate);
3811 virtual void VisitSequenceVariable(const SequenceVar* variable);
3814 virtual void VisitIntegerArgument(const std::string& arg_name, int64_t value);
3815 virtual void VisitIntegerArrayArgument(const std::string& arg_name,
3816 const std::vector<int64_t>& values);
3817 virtual void VisitIntegerMatrixArgument(const std::string& arg_name,
3818 const IntTupleSet& tuples);
3821 virtual void VisitIntegerExpressionArgument(const std::string& arg_name,
3822 IntExpr* argument);
3825 const std::string& arg_name, const std::vector<IntVar*>& arguments);
3828 virtual void VisitIntervalArgument(const std::string& arg_name,
3829 IntervalVar* argument);
3831 virtual void VisitIntervalArrayArgument(
3832 const std::string& arg_name, const std::vector<IntervalVar*>& arguments);
3834 virtual void VisitSequenceArgument(const std::string& arg_name,
3835 SequenceVar* argument);
3838 const std::string& arg_name, const std::vector<SequenceVar*>& arguments);
3839#if !defined(SWIG)
3842 const std::string& arg_name, const Solver::Int64ToIntVar& arguments);
3843
3846 void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min,
3847 int64_t index_max);
3849 int64_t index_min, int64_t index_max);
3852 const std::string& arg_name, int64_t index_max);
3853#endif // #if !defined(SWIG)
3854};
3855
3862class Constraint : public PropagationBaseObject {
3863 public:
3864 explicit Constraint(Solver* const solver) : PropagationBaseObject(solver) {}
3865
3866#ifndef SWIG
3867 // This type is neither copyable nor movable.
3868 Constraint(const Constraint&) = delete;
3869 Constraint& operator=(const Constraint&) = delete;
3870#endif
3871 ~Constraint() override {}
3872
3875 virtual void Post() = 0;
3876
3879 virtual void InitialPropagate() = 0;
3880 std::string DebugString() const override;
3881
3884 void PostAndPropagate();
3885
3887 virtual void Accept(ModelVisitor* visitor) const;
3888
3890 bool IsCastConstraint() const;
3891
3895 virtual IntVar* Var();
3896};
3897
3901class CastConstraint : public Constraint {
3902 public:
3903 CastConstraint(Solver* const solver, IntVar* const target_var)
3905 CHECK(target_var != nullptr);
3906 }
3907 ~CastConstraint() override {}
3908
3909 IntVar* target_var() const { return target_var_; }
3910
3911 protected:
3912 IntVar* const target_var_;
3913};
3914
3916class SearchMonitor : public BaseObject {
3917 public:
3918 static constexpr int kNoProgress = -1;
3919
3920 explicit SearchMonitor(Solver* const s) : solver_(s) {}
3921
3922#ifndef SWIG
3923 // This type is neither copyable nor movable.
3926#endif
3927 ~SearchMonitor() override {}
3929 virtual void EnterSearch();
3930
3932 virtual void RestartSearch();
3933
3935 virtual void ExitSearch();
3936
3938 virtual void BeginNextDecision(DecisionBuilder* b);
3939
3941 virtual void EndNextDecision(DecisionBuilder* b, Decision* d);
3942
3944 virtual void ApplyDecision(Decision* d);
3945
3947 virtual void RefuteDecision(Decision* d);
3948
3951 virtual void AfterDecision(Decision* d, bool apply);
3952
3953
3954 virtual void BeginFail();
3955
3957 virtual void EndFail();
3958
3959 /// Before the initial propagation.
3960 virtual void BeginInitialPropagation();
3961
3964
3968 virtual bool AcceptSolution();
3969
3970
3972 /// is false, then search will stop there.
3973 virtual bool AtSolution();
3976 virtual void NoMoreSolutions();
3977
3980 virtual bool LocalOptimum();
3983 virtual bool AcceptDelta(Assignment* delta, Assignment* deltadelta);
3984
3986 virtual void AcceptNeighbor();
3987
3989 virtual void AcceptUncheckedNeighbor();
3990
3993 virtual bool IsUncheckedSolutionLimitReached() { return false; }
3994
3996 virtual void PeriodicCheck();
3997
4000 virtual int ProgressPercent() { return kNoProgress; }
4001
4003 virtual void Accept(ModelVisitor* visitor) const;
4004
4008 virtual void Install();
4009
4010 Solver* solver() const { return solver_; }
4011
4012 protected:
4014
4015 private:
4016 Solver* const solver_;
4017};
4018
4024template <class T>
4025class Rev {
4026 public:
4027 explicit Rev(const T& val) : stamp_(0), value_(val) {}
4028
4029 const T& Value() const { return value_; }
4030
4031 void SetValue(Solver* const s, const T& val) {
4032 if (val != value_) {
4033 if (stamp_ < s->stamp()) {
4034 s->SaveValue(&value_);
4035 stamp_ = s->stamp();
4036 }
4037 value_ = val;
4038 }
4039 }
4040
4041 private:
4042 uint64_t stamp_;
4043 T value_;
4044};
4045
4047template <class T>
4048class NumericalRev : public Rev<T> {
4049 public:
4050 explicit NumericalRev(const T& val) : Rev<T>(val) {}
4051
4052 void Add(Solver* const s, const T& to_add) {
4053 this->SetValue(s, this->Value() + to_add);
4054 }
4055
4056 void Incr(Solver* const s) { Add(s, 1); }
4058 void Decr(Solver* const s) { Add(s, -1); }
4059};
4060
4066template <class T>
4068 public:
4069 RevArray(int size, const T& val)
4070 : stamps_(new uint64_t[size]), values_(new T[size]), size_(size) {
4071 for (int i = 0; i < size; ++i) {
4072 stamps_[i] = 0;
4073 values_[i] = val;
4074 }
4075 }
4076
4077 ~RevArray() {}
4078
4079 int64_t size() const { return size_; }
4080
4081 const T& Value(int index) const { return values_[index]; }
4083#if !defined(SWIG)
4084 const T& operator[](int index) const { return values_[index]; }
4085#endif
4087 void SetValue(Solver* const s, int index, const T& val) {
4088 DCHECK_LT(index, size_);
4089 if (val != values_[index]) {
4090 if (stamps_[index] < s->stamp()) {
4091 s->SaveValue(&values_[index]);
4092 stamps_[index] = s->stamp();
4093 }
4094 values_[index] = val;
4095 }
4096 }
4097
4098 private:
4099 std::unique_ptr<uint64_t[]> stamps_;
4100 std::unique_ptr<T[]> values_;
4101 const int size_;
4102};
4103
4105template <class T>
4106class NumericalRevArray : public RevArray<T> {
4107 public:
4108 NumericalRevArray(int size, const T& val) : RevArray<T>(size, val) {}
4110 void Add(Solver* const s, int index, const T& to_add) {
4111 this->SetValue(s, index, this->Value(index) + to_add);
4112 }
4114 void Incr(Solver* const s, int index) { Add(s, index, 1); }
4116 void Decr(Solver* const s, int index) { Add(s, index, -1); }
4117};
4118
4124/// - listening to events modifying its bounds
4125/// - casting it into a variable (instance of IntVar)
4127 public:
4128 explicit IntExpr(Solver* const s) : PropagationBaseObject(s) {}
4129
4130#ifndef SWIG
4131 // This type is neither copyable nor movable.
4132 IntExpr(const IntExpr&) = delete;
4133 IntExpr& operator=(const IntExpr&) = delete;
4134#endif
4135 ~IntExpr() override {}
4137 virtual int64_t Min() const = 0;
4138 virtual void SetMin(int64_t m) = 0;
4139 virtual int64_t Max() const = 0;
4140 virtual void SetMax(int64_t m) = 0;
4144 virtual void Range(int64_t* l, int64_t* u) {
4145 *l = Min();
4146 *u = Max();
4147 }
4149 virtual void SetRange(int64_t l, int64_t u) {
4150 SetMin(l);
4151 SetMax(u);
4152 }
4153
4154
4155 virtual void SetValue(int64_t v) { SetRange(v, v); }
4156
4158 virtual bool Bound() const { return (Min() == Max()); }
4159
4160
4161 virtual bool IsVar() const { return false; }
4162
4163 /// Creates a variable from the expression.
4164 virtual IntVar* Var() = 0;
4167 /// resulting var. If the expression is already a variable, then it
4168 /// will set the name of the expression, possibly overwriting it.
4169 /// This is just a shortcut to Var() followed by set_name().
4170 IntVar* VarWithName(const std::string& name);
4173 virtual void WhenRange(Demon* d) = 0;
4175 void WhenRange(Solver::Closure closure) {
4176 WhenRange(solver()->MakeClosureDemon(std::move(closure)));
4177 }
4178
4179#if !defined(SWIG)
4181 void WhenRange(Solver::Action action) {
4182 WhenRange(solver()->MakeActionDemon(std::move(action)));
4184#endif // SWIG
4187 virtual void Accept(ModelVisitor* visitor) const;
4188};
4200
4201/// IntVar* current_var;
4202/// std::unique_ptr<IntVarIterator> it(current_var->MakeHoleIterator(false));
4203/// for (const int64_t hole : InitAndGetValues(it)) {
4204/// /// use the hole
4205/// }
4207class IntVarIterator : public BaseObject {
4208 public:
4209 ~IntVarIterator() override {}
4210
4212 virtual void Init() = 0;
4213
4215 virtual bool Ok() const = 0;
4216
4218 virtual int64_t Value() const = 0;
4219
4221 virtual void Next() = 0;
4222
4224 std::string DebugString() const override { return "IntVar::Iterator"; }
4225};
4226
4227#ifndef SWIG
4232/// same iterator instance isn't being iterated on in multiple places
4233/// simultaneously.
4234class InitAndGetValues {
4235 public:
4236 explicit InitAndGetValues(IntVarIterator* it)
4237 : it_(it), begin_was_called_(false) {
4238 it_->Init();
4239 }
4240 struct Iterator;
4241
4242 Iterator begin() {
4243 if (DEBUG_MODE) {
4244 DCHECK(!begin_was_called_);
4245 begin_was_called_ = true;
4246 }
4247 return Iterator::Begin(it_);
4248 }
4249 Iterator end() { return Iterator::End(it_); }
4250
4251 struct Iterator {
4253 static Iterator Begin(IntVarIterator* it) {
4254 return Iterator(it, /*is_end=*/false);
4255 }
4256 static Iterator End(IntVarIterator* it) {
4257 return Iterator(it, /*is_end=*/true);
4258 }
4259
4260 int64_t operator*() const {
4261 DCHECK(it->Ok());
4262 return it->Value();
4263 }
4264 Iterator& operator++() {
4265 DCHECK(it->Ok());
4266 it->Next();
4267 return *this;
4268 }
4269 bool operator!=(const Iterator& other) const {
4270 DCHECK(other.it == it);
4271 DCHECK(other.is_end);
4272 return it->Ok();
4273 }
4274
4275 private:
4276 Iterator(IntVarIterator* it, bool is_end) : it(it), is_end(is_end) {}
4277
4279 const bool is_end;
4280 };
4282 private:
4283 IntVarIterator* const it_;
4284 bool begin_was_called_;
4285};
4286#endif // SWIG
4287
4291class IntVar : public IntExpr {
4292 public:
4293 explicit IntVar(Solver* s);
4294 IntVar(Solver* s, const std::string& name);
4295
4296#ifndef SWIG
4297 // This type is neither copyable nor movable.
4298 IntVar(const IntVar&) = delete;
4299 IntVar& operator=(const IntVar&) = delete;
4300#endif
4301
4302 ~IntVar() override {};
4303
4304 bool IsVar() const override { return true; }
4305 IntVar* Var() override { return this; }
4306
4307
4309 virtual int64_t Value() const = 0;
4310
4311 /// This method removes the value 'v' from the domain of the variable.
4312 virtual void RemoveValue(int64_t v) = 0;
4313
4314
4314 /// This method removes the interval 'l' .. 'u' from the domain of
4315 /// the variable. It assumes that 'l' <= 'u'.
4316 virtual void RemoveInterval(int64_t l, int64_t u) = 0;
4317
4318 /// This method remove the values from the domain of the variable.
4319 virtual void RemoveValues(const std::vector<int64_t>& values);
4320
4322 virtual void SetValues(const std::vector<int64_t>& values);
4323
4326 virtual void WhenBound(Demon* d) = 0;
4327
4327 /// This method attaches a closure that will be awakened when the
4328 /// variable is bound.
4329 void WhenBound(Solver::Closure closure) {
4330 WhenBound(solver()->MakeClosureDemon(std::move(closure)));
4331 }
4332
4333#if !defined(SWIG)
4336 void WhenBound(Solver::Action action) {
4337 WhenBound(solver()->MakeActionDemon(std::move(action)));
4338 }
4339#endif // SWIG
4340
4343 virtual void WhenDomain(Demon* d) = 0;
4344
4346 void WhenDomain(Solver::Closure closure) {
4347 WhenDomain(solver()->MakeClosureDemon(std::move(closure)));
4348 }
4349#if !defined(SWIG)
4352 void WhenDomain(Solver::Action action) {
4353 WhenDomain(solver()->MakeActionDemon(std::move(action)));
4354 }
4355#endif // SWIG
4358 virtual uint64_t Size() const = 0;
4359
4362 virtual bool Contains(int64_t v) const = 0;
4367 virtual IntVarIterator* MakeHoleIterator(bool reversible) const = 0;
4368
4372 virtual IntVarIterator* MakeDomainIterator(bool reversible) const = 0;
4373
4375 virtual int64_t OldMin() const = 0;
4376
4378 virtual int64_t OldMax() const = 0;
4379
4380 virtual int VarType() const;
4381
4383 void Accept(ModelVisitor* visitor) const override;
4386 virtual IntVar* IsEqual(int64_t constant) = 0;
4387 virtual IntVar* IsDifferent(int64_t constant) = 0;
4388 virtual IntVar* IsGreaterOrEqual(int64_t constant) = 0;
4389 virtual IntVar* IsLessOrEqual(int64_t constant) = 0;
4390
4392 int index() const { return index_; }
4393
4394 private:
4395 const int index_;
4396};
4397
4402 public:
4403 SolutionCollector(Solver* solver, const Assignment* assignment);
4405
4406#ifndef SWIG
4407 // This type is neither copyable nor movable.
4408 SolutionCollector(const SolutionCollector&) = delete;
4410#endif
4411
4412 ~SolutionCollector() override;
4413 void Install() override;
4414 std::string DebugString() const override { return "SolutionCollector"; }
4415
4417 void Add(IntVar* var);
4418 void Add(const std::vector<IntVar*>& vars);
4419 void Add(IntervalVar* var);
4420 void Add(const std::vector<IntervalVar*>& vars);
4421 void Add(SequenceVar* var);
4422 void Add(const std::vector<SequenceVar*>& vars);
4423 void AddObjective(IntVar* objective);
4424 void AddObjectives(const std::vector<IntVar*>& objectives);
4427 void EnterSearch() override;
4428
4430 int solution_count() const;
4431
4433 bool has_solution() const;
4434
4436 Assignment* solution(int n) const;
4437
4440
4442 int64_t wall_time(int n) const;
4443
4445 int64_t branches(int n) const;
4449 int64_t failures(int n) const;
4452 int64_t objective_value(int n) const;
4453
4455 int64_t ObjectiveValueFromIndex(int n, int index) const;
4456
4458 int64_t Value(int n, IntVar* var) const;
4461 int64_t StartValue(int n, IntervalVar* var) const;
4462
4464 int64_t EndValue(int n, IntervalVar* var) const;
4465
4467 int64_t DurationValue(int n, IntervalVar* var) const;
4468
4470 int64_t PerformedValue(int n, IntervalVar* var) const;
4471
4475 const std::vector<int>& ForwardSequence(int n, SequenceVar* var) const;
4479 const std::vector<int>& BackwardSequence(int n, SequenceVar* var) const;
4482 const std::vector<int>& Unperformed(int n, SequenceVar* var) const;
4483
4484 protected:
4485 struct SolutionData {
4487 int64_t time;
4488 int64_t branches;
4489 int64_t failures;
4490 int64_t ObjectiveValue() const;
4491 int64_t ObjectiveValueFromIndex(int index) const;
4492 bool operator<(const SolutionData& other) const;
4493 };
4494
4496 void PushSolution();
4497 void Push(const SolutionData& data) { solution_data_.push_back(data); }
4499 void PopSolution();
4500 SolutionData BuildSolutionDataForCurrentState();
4501 void FreeSolution(Assignment* solution);
4502 void check_index(int n) const;
4503
4504 std::unique_ptr<Assignment> prototype_;
4505 std::vector<SolutionData> solution_data_;
4506 std::vector<Assignment*> recycle_solutions_;
4507#if !defined(SWIG)
4508 std::vector<std::unique_ptr<Assignment>> solution_pool_;
4509#endif // SWIG
4510};
4511
4512// Base objective monitor class. All metaheuristics and metaheuristic combiners
4513// derive from this.
4514class BaseObjectiveMonitor : public SearchMonitor {
4515 public:
4516 explicit BaseObjectiveMonitor(Solver* solver) : SearchMonitor(solver) {}
4517 ~BaseObjectiveMonitor() override {}
4518#ifndef SWIG
4521#endif // SWIG
4522 virtual IntVar* ObjectiveVar(int index) const = 0;
4523 virtual IntVar* MinimizationVar(int index) const = 0;
4524 virtual int64_t Step(int index) const = 0;
4525 virtual bool Maximize(int index) const = 0;
4526 virtual int64_t BestValue(int index) const = 0;
4527 virtual int Size() const = 0;
4528 bool is_active() const { return is_active_; }
4529 void set_active(bool is_active) { is_active_ = is_active; }
4530
4531 private:
4532 bool is_active_ = true;
4533};
4534
4535// Base atomic objective monitor class. All non-composite metaheuristics derive
4536// from this.
4538 public:
4539 ObjectiveMonitor(Solver* solver, const std::vector<bool>& maximize,
4540 std::vector<IntVar*> vars, std::vector<int64_t> steps);
4541 ~ObjectiveMonitor() override {}
4542#ifndef SWIG
4545#endif // SWIG
4546 IntVar* ObjectiveVar(int index) const override {
4547 return objective_vars_[index];
4548 }
4549 IntVar* MinimizationVar(int index) const override {
4550 return minimization_vars_[index];
4551 }
4552 int64_t Step(int index) const override { return steps_[index]; }
4553 bool Maximize(int index) const override {
4554 return ObjectiveVar(index) != MinimizationVar(index);
4556 int64_t BestValue(int index) const override {
4557 return Maximize(index) ? CapOpp(BestInternalValue(index))
4558 : BestInternalValue(index);
4559 }
4560 int Size() const override { return objective_vars_.size(); }
4561 void EnterSearch() override;
4562 bool AtSolution() override;
4563 bool AcceptDelta(Assignment* delta, Assignment* deltadelta) override;
4564 void Accept(ModelVisitor* visitor) const override;
4565
4566 protected:
4567 const std::vector<IntVar*>& objective_vars() const { return objective_vars_; }
4568 const std::vector<IntVar*>& minimization_vars() const {
4569 return minimization_vars_;
4570 }
4571 int64_t BestInternalValue(int index) const { return best_values_[index]; }
4572 int64_t CurrentInternalValue(int index) const {
4573 return current_values_[index];
4575 void SetCurrentInternalValue(int index, int64_t value) {
4576 current_values_[index] = value;
4578 template <typename T>
4579 void MakeMinimizationVarsLessOrEqualWithSteps(const T& upper_bounds) {
4580 if (Size() == 1) {
4581 MinimizationVar(0)->SetMax(CapSub(upper_bounds(0), Step(0)));
4582 } else {
4583 Solver* const solver = this->solver();
4584 for (int i = 0; i < Size(); ++i) {
4585 upper_bounds_[i] = solver->MakeIntConst(upper_bounds(i));
4587 solver->AddConstraint(solver->MakeLexicalLessOrEqualWithOffsets(
4588 minimization_vars_, upper_bounds_, steps_));
4589 }
4590 }
4591 template <typename T>
4593 const T& upper_bounds) {
4594 Solver* const solver = this->solver();
4595 IntVar* status = solver->MakeBoolVar();
4596 if (Size() == 1) {
4597 solver->AddConstraint(solver->MakeIsLessOrEqualCstCt(
4598 MinimizationVar(0), CapSub(upper_bounds(0), Step(0)), status));
4599 } else {
4600 for (int i = 0; i < Size(); ++i) {
4601 upper_bounds_[i] = solver->MakeIntConst(upper_bounds(i));
4604 minimization_vars_, upper_bounds_, steps_, status));
4605 }
4606 return status;
4609
4612 private:
4613 friend class Solver;
4614 const std::vector<IntVar*> objective_vars_;
4615 std::vector<IntVar*> minimization_vars_;
4616 std::vector<IntVar*> upper_bounds_;
4617 std::vector<int64_t> steps_;
4618 std::vector<int64_t> best_values_;
4619 std::vector<int64_t> current_values_;
4620};
4621
4626 public:
4627 OptimizeVar(Solver* solver, bool maximize, IntVar* var, int64_t step);
4628 // Specifies a lexicographic objective. Each objective is specified in
4629 // decreasing order with the corresponding direction and step.
4630 OptimizeVar(Solver* solver, const std::vector<bool>& maximize,
4631 std::vector<IntVar*> vars, std::vector<int64_t> steps);
4632#ifndef SWIG
4633 ~OptimizeVar() override {}
4634#endif // SIWG
4635
4636
4637 int64_t best() const { return BestValue(0); }
4638
4640 IntVar* var() const { return Size() == 0 ? nullptr : ObjectiveVar(0); }
4641
4643 void BeginNextDecision(DecisionBuilder* db) override;
4644 void RefuteDecision(Decision* d) override;
4645 bool AtSolution() override;
4646 bool AcceptSolution() override;
4647 virtual std::string Name() const;
4648 std::string DebugString() const override;
4649
4651};
4652
4654class SearchLimit : public SearchMonitor {
4655 public:
4656 explicit SearchLimit(Solver* const s) : SearchMonitor(s), crossed_(false) {}
4657
4658#ifndef SWIG
4659 // This type is neither copyable nor movable.
4660 SearchLimit(const SearchLimit&) = delete;
4661 SearchLimit& operator=(const SearchLimit&) = delete;
4662#endif
4663 ~SearchLimit() override;
4664
4666 bool crossed() const { return crossed_; }
4667
4672 bool Check() { return CheckWithOffset(absl::ZeroDuration()); }
4675 virtual bool CheckWithOffset(absl::Duration offset) = 0;
4676
4678 virtual void Init() = 0;
4679
4682 virtual void Copy(const SearchLimit* limit) = 0;
4685 virtual SearchLimit* MakeClone() const = 0;
4686
4688 void EnterSearch() override;
4689 void BeginNextDecision(DecisionBuilder* b) override;
4690 void PeriodicCheck() override;
4691 void RefuteDecision(Decision* d) override;
4692 std::string DebugString() const override {
4693 return absl::StrFormat("SearchLimit(crossed = %i)", crossed_);
4694 }
4695 void Install() override;
4696
4697 private:
4698 void TopPeriodicCheck();
4699
4700 bool crossed_;
4701};
4702
4705class RegularLimit : public SearchLimit {
4706 public:
4707 RegularLimit(Solver* s, absl::Duration time, int64_t branches,
4708 int64_t failures, int64_t solutions, bool smart_time_check,
4709 bool cumulative);
4710 ~RegularLimit() override;
4711 void Copy(const SearchLimit* limit) override;
4712 SearchLimit* MakeClone() const override;
4714 bool CheckWithOffset(absl::Duration offset) override;
4715 void Init() override;
4716 void ExitSearch() override;
4717 void UpdateLimits(absl::Duration time, int64_t branches, int64_t failures,
4718 int64_t solutions);
4719 absl::Duration duration_limit() const { return duration_limit_; }
4720 int64_t wall_time() const {
4721 return duration_limit_ == absl::InfiniteDuration()
4722 ? kint64max
4723 : absl::ToInt64Milliseconds(duration_limit());
4725 int64_t branches() const { return branches_; }
4726 int64_t failures() const { return failures_; }
4727 int64_t solutions() const { return solutions_; }
4728 bool IsUncheckedSolutionLimitReached() override;
4729 int ProgressPercent() override;
4730 std::string DebugString() const override;
4731 void Install() override;
4732
4733 absl::Time AbsoluteSolverDeadline() const {
4734 return solver_time_at_limit_start_ + duration_limit_;
4735 }
4737 void Accept(ModelVisitor* visitor) const override;
4738
4739 private:
4740 bool CheckTime(absl::Duration offset);
4741 absl::Duration TimeElapsed();
4742 static int64_t GetPercent(int64_t value, int64_t offset, int64_t total) {
4743 return (total > 0 && total < kint64max) ? 100 * (value - offset) / total
4744 : -1;
4745 }
4746
4747 absl::Duration duration_limit_;
4748 absl::Time solver_time_at_limit_start_;
4749 absl::Duration last_time_elapsed_;
4750 int64_t check_count_;
4751 int64_t next_check_;
4752 bool smart_time_check_;
4753 int64_t branches_;
4754 int64_t branches_offset_;
4755 int64_t failures_;
4756 int64_t failures_offset_;
4757 int64_t solutions_;
4758 int64_t solutions_offset_;
4760
4763 /// depending on context:
4764 /// - within a search, it's an offset to be subtracted from the current value
4765 /// - outside of search, it's the amount consumed in previous searches
4766 bool cumulative_;
4767};
4768
4769// Limit based on the improvement rate of 'objective_var' or a lexicographic
4770// objective composed of 'objective_vars'.
4771// This limit proceeds in two stages:
4772// 1) During the phase of the search in which the objective is strictly
4773// improving, a threshold value is computed as the minimum improvement rate of
4774// the objective, based on the 'improvement_rate_coefficient' and
4775// 'improvement_rate_solutions_distance' parameters.
4776// 2) Then, if the search continues beyond this phase of strict improvement, the
4777// limit stops the search when the improvement rate of the objective gets below
4778// this threshold value.
4779class ImprovementSearchLimit : public SearchLimit {
4780 public:
4781 ImprovementSearchLimit(Solver* solver, IntVar* objective_var, bool maximize,
4782 double objective_scaling_factor,
4783 double objective_offset,
4784 double improvement_rate_coefficient,
4785 int improvement_rate_solutions_distance);
4786 ImprovementSearchLimit(Solver* solver, std::vector<IntVar*> objective_vars,
4787 std::vector<bool> maximize,
4788 std::vector<double> objective_scaling_factors,
4789 std::vector<double> objective_offsets,
4790 double improvement_rate_coefficient,
4791 int improvement_rate_solutions_distance);
4792 ~ImprovementSearchLimit() override;
4793 void Copy(const SearchLimit* limit) override;
4794 SearchLimit* MakeClone() const override;
4795 bool CheckWithOffset(absl::Duration offset) override;
4796 bool AtSolution() override;
4797 void Init() override;
4798 void Install() override;
4799
4800 private:
4801 std::vector<IntVar*> objective_vars_;
4802 std::vector<bool> maximize_;
4803 std::vector<double> objective_scaling_factors_;
4804 std::vector<double> objective_offsets_;
4805 double improvement_rate_coefficient_;
4806 int improvement_rate_solutions_distance_;
4807
4808 std::vector<double> best_objectives_;
4809 // clang-format off
4810 std::vector<std::deque<std::pair<double, int64_t> > > improvements_;
4811 // clang-format on
4812 std::vector<double> thresholds_;
4813 bool objective_updated_;
4814 bool gradient_stage_;
4815};
4816
4826
4828 public:
4830 static const int64_t kMinValidValue;
4832 static const int64_t kMaxValidValue;
4833 IntervalVar(Solver* const solver, const std::string& name)
4834 : PropagationBaseObject(solver) {
4835 set_name(name);
4836 }
4838#ifndef SWIG
4839 // This type is neither copyable nor movable.
4840 IntervalVar(const IntervalVar&) = delete;
4841 IntervalVar& operator=(const IntervalVar&) = delete;
4842#endif
4843 ~IntervalVar() override {}
4844
4847 virtual int64_t StartMin() const = 0;
4848 virtual int64_t StartMax() const = 0;
4849 virtual void SetStartMin(int64_t m) = 0;
4850 virtual void SetStartMax(int64_t m) = 0;
4851 virtual void SetStartRange(int64_t mi, int64_t ma) = 0;
4852 virtual int64_t OldStartMin() const = 0;
4853 virtual int64_t OldStartMax() const = 0;
4854 virtual void WhenStartRange(Demon* d) = 0;
4855 void WhenStartRange(Solver::Closure closure) {
4856 WhenStartRange(solver()->MakeClosureDemon(std::move(closure)));
4857 }
4858#if !defined(SWIG)
4859 void WhenStartRange(Solver::Action action) {
4860 WhenStartRange(solver()->MakeActionDemon(std::move(action)));
4861 }
4862#endif // SWIG
4863 virtual void WhenStartBound(Demon* d) = 0;
4864 void WhenStartBound(Solver::Closure closure) {
4865 WhenStartBound(solver()->MakeClosureDemon(std::move(closure)));
4866 }
4867#if !defined(SWIG)
4868 void WhenStartBound(Solver::Action action) {
4869 WhenStartBound(solver()->MakeActionDemon(std::move(action)));
4870 }
4871#endif // SWIG
4872
4874 virtual int64_t DurationMin() const = 0;
4875 virtual int64_t DurationMax() const = 0;
4876 virtual void SetDurationMin(int64_t m) = 0;
4877 virtual void SetDurationMax(int64_t m) = 0;
4878 virtual void SetDurationRange(int64_t mi, int64_t ma) = 0;
4879 virtual int64_t OldDurationMin() const = 0;
4880 virtual int64_t OldDurationMax() const = 0;
4881 virtual void WhenDurationRange(Demon* d) = 0;
4882 void WhenDurationRange(Solver::Closure closure) {
4883 WhenDurationRange(solver()->MakeClosureDemon(std::move(closure)));
4884 }
4885#if !defined(SWIG)
4887 WhenDurationRange(solver()->MakeActionDemon(std::move(action)));
4888 }
4889#endif // SWIG
4890 virtual void WhenDurationBound(Demon* d) = 0;
4892 WhenDurationBound(solver()->MakeClosureDemon(std::move(closure)));
4893 }
4894#if !defined(SWIG)
4895 void WhenDurationBound(Solver::Action action) {
4896 WhenDurationBound(solver()->MakeActionDemon(std::move(action)));
4897 }
4898#endif // SWIG
4901 virtual int64_t EndMin() const = 0;
4902 virtual int64_t EndMax() const = 0;
4903 virtual void SetEndMin(int64_t m) = 0;
4904 virtual void SetEndMax(int64_t m) = 0;
4905 virtual void SetEndRange(int64_t mi, int64_t ma) = 0;
4906 virtual int64_t OldEndMin() const = 0;
4907 virtual int64_t OldEndMax() const = 0;
4908 virtual void WhenEndRange(Demon* d) = 0;
4910 WhenEndRange(solver()->MakeClosureDemon(std::move(closure)));
4912#if !defined(SWIG)
4914 WhenEndRange(solver()->MakeActionDemon(std::move(action)));
4915 }
4916#endif // SWIG
4917 virtual void WhenEndBound(Demon* d) = 0;
4919 WhenEndBound(solver()->MakeClosureDemon(std::move(closure)));
4920 }
4921#if !defined(SWIG)
4923 WhenEndBound(solver()->MakeActionDemon(std::move(action)));
4924 }
4925#endif // SWIG
4926
4927 /// These methods query, set, and watch the performed status of the
4928 /// interval var.
4929 virtual bool MustBePerformed() const = 0;
4930 virtual bool MayBePerformed() const = 0;
4931 bool CannotBePerformed() const { return !MayBePerformed(); }
4932 bool IsPerformedBound() const {
4935 virtual void SetPerformed(bool val) = 0;
4936 virtual bool WasPerformedBound() const = 0;
4937 virtual void WhenPerformedBound(Demon* d) = 0;
4939 WhenPerformedBound(solver()->MakeClosureDemon(std::move(closure)));
4941#if !defined(SWIG)
4942 void WhenPerformedBound(Solver::Action action) {
4943 WhenPerformedBound(solver()->MakeActionDemon(std::move(action)));
4944 }
4945#endif // SWIG
4946
4948 void WhenAnything(Demon* d);
4951 WhenAnything(solver()->MakeClosureDemon(std::move(closure)));
4952 }
4953#if !defined(SWIG)
4954 /// Attaches an action awakened when anything about this interval changes.
4955 void WhenAnything(Solver::Action action) {
4956 WhenAnything(solver()->MakeActionDemon(std::move(action)));
4957 }
4958#endif // SWIG
4959
4963 virtual IntExpr* StartExpr() = 0;
4964 virtual IntExpr* DurationExpr() = 0;
4965 virtual IntExpr* EndExpr() = 0;
4966 virtual IntExpr* PerformedExpr() = 0;
4968 /// and duration of the interval var. If the interval var is
4969 /// unperformed, they will return the unperformed_value.
4970 virtual IntExpr* SafeStartExpr(int64_t unperformed_value) = 0;
4971 virtual IntExpr* SafeDurationExpr(int64_t unperformed_value) = 0;
4972 virtual IntExpr* SafeEndExpr(int64_t unperformed_value) = 0;
4973
4975 virtual void Accept(ModelVisitor* visitor) const = 0;
4980
4981/// returns the list of interval variables that can be ranked first or
4982/// last; and RankFirst/RankNotFirst/RankLast/RankNotLast, which can be
4983/// used to create the search decision.
4984class SequenceVar : public PropagationBaseObject {
4985 public:
4986 SequenceVar(Solver* s, const std::vector<IntervalVar*>& intervals,
4987 const std::vector<IntVar*>& nexts, const std::string& name);
4989 ~SequenceVar() override;
4991 std::string DebugString() const override;
4992
4993#if !defined(SWIG)
4994
4996 void DurationRange(int64_t* dmin, int64_t* dmax) const;
5000 void HorizonRange(int64_t* hmin, int64_t* hmax) const;
5004 void ActiveHorizonRange(int64_t* hmin, int64_t* hmax) const;
5005
5007 void ComputeStatistics(int* ranked, int* not_ranked, int* unperformed) const;
5008#endif // !defined(SWIG)
5012 void RankFirst(int index);
5013
5014 /// Indicates that the index_th interval var will not be ranked first
5015 /// of all currently unranked interval vars.
5016 void RankNotFirst(int index);
5017
5020 void RankLast(int index);
5021
5024 void RankNotLast(int index);
5028 void ComputePossibleFirstsAndLasts(std::vector<int>* possible_firsts,
5029 std::vector<int>* possible_lasts);
5036 void RankSequence(const std::vector<int>& rank_first,
5037 const std::vector<int>& rank_last,
5038 const std::vector<int>& unperformed);
5039
5043 /// contain none.
5044 /// 'unperformed' will contains all such interval variables.
5045 /// rank_first and rank_last represents different directions.
5046 /// rank_first[0] corresponds to the first interval of the sequence.
5047 /// rank_last[0] corresponds to the last interval of the sequence.
5048 void FillSequence(std::vector<int>* rank_first, std::vector<int>* rank_last,
5049 std::vector<int>* unperformed) const;
5050
5052 IntervalVar* Interval(int index) const;
5053
5055 IntVar* Next(int index) const;
5056
5058 int64_t size() const { return intervals_.size(); }
5059
5061 virtual void Accept(ModelVisitor* visitor) const;
5062
5063 private:
5064 int ComputeForwardFrontier();
5065 int ComputeBackwardFrontier();
5066 void UpdatePrevious() const;
5067
5068 const std::vector<IntervalVar*> intervals_;
5069 const std::vector<IntVar*> nexts_;
5070 mutable std::vector<int> previous_;
5071};
5072
5073class AssignmentElement {
5074 public:
5075 AssignmentElement() : activated_(true) {}
5076
5077 void Activate() { activated_ = true; }
5078 void Deactivate() { activated_ = false; }
5079 bool Activated() const { return activated_; }
5080
5081 private:
5082 bool activated_;
5083};
5084
5085class IntVarElement : public AssignmentElement {
5086 public:
5087 IntVarElement();
5088 explicit IntVarElement(IntVar* var);
5089 void Reset(IntVar* var);
5091 void Copy(const IntVarElement& element);
5092 IntVar* Var() const { return var_; }
5093 void Store() {
5094 min_ = var_->Min();
5095 max_ = var_->Max();
5096 }
5097 void Restore() {
5098 if (var_ != nullptr) {
5099 var_->SetRange(min_, max_);
5100 }
5101 }
5102 void LoadFromProto(const IntVarAssignment& int_var_assignment_proto);
5103 void WriteToProto(IntVarAssignment* int_var_assignment_proto) const;
5104
5105 int64_t Min() const { return min_; }
5106 void SetMin(int64_t m) { min_ = m; }
5107 int64_t Max() const { return max_; }
5108 void SetMax(int64_t m) { max_ = m; }
5109 int64_t Value() const {
5110 DCHECK_EQ(min_, max_);
5111 // Get the value from an unbound int var assignment element.
5112 return min_;
5113 }
5114 bool Bound() const { return (max_ == min_); }
5115 void SetRange(int64_t l, int64_t u) {
5116 min_ = l;
5117 max_ = u;
5118 }
5119 void SetValue(int64_t v) {
5120 min_ = v;
5121 max_ = v;
5122 }
5123 std::string DebugString() const;
5124
5125 bool operator==(const IntVarElement& element) const;
5126 bool operator!=(const IntVarElement& element) const {
5127 return !(*this == element);
5128 }
5129
5130 private:
5131 IntVar* var_;
5132 int64_t min_;
5133 int64_t max_;
5135
5137 public:
5139 explicit IntervalVarElement(IntervalVar* var);
5140 void Reset(IntervalVar* var);
5142 void Copy(const IntervalVarElement& element);
5143 IntervalVar* Var() const { return var_; }
5144 void Store();
5145 void Restore();
5146 void LoadFromProto(
5147 const IntervalVarAssignment& interval_var_assignment_proto);
5148 void WriteToProto(IntervalVarAssignment* interval_var_assignment_proto) const;
5149
5150 int64_t StartMin() const { return start_min_; }
5151 int64_t StartMax() const { return start_max_; }
5152 int64_t StartValue() const {
5153 CHECK_EQ(start_max_, start_min_);
5154 return start_max_;
5155 }
5156 int64_t DurationMin() const { return duration_min_; }
5157 int64_t DurationMax() const { return duration_max_; }
5158 int64_t DurationValue() const {
5159 CHECK_EQ(duration_max_, duration_min_);
5160 return duration_max_;
5161 }
5162 int64_t EndMin() const { return end_min_; }
5163 int64_t EndMax() const { return end_max_; }
5164 int64_t EndValue() const {
5165 CHECK_EQ(end_max_, end_min_);
5166 return end_max_;
5168 int64_t PerformedMin() const { return performed_min_; }
5169 int64_t PerformedMax() const { return performed_max_; }
5170 int64_t PerformedValue() const {
5171 CHECK_EQ(performed_max_, performed_min_);
5172 return performed_max_;
5174 void SetStartMin(int64_t m) { start_min_ = m; }
5175 void SetStartMax(int64_t m) { start_max_ = m; }
5176 void SetStartRange(int64_t mi, int64_t ma) {
5177 start_min_ = mi;
5178 start_max_ = ma;
5179 }
5180 void SetStartValue(int64_t v) {
5181 start_min_ = v;
5182 start_max_ = v;
5183 }
5184 void SetDurationMin(int64_t m) { duration_min_ = m; }
5185 void SetDurationMax(int64_t m) { duration_max_ = m; }
5186 void SetDurationRange(int64_t mi, int64_t ma) {
5187 duration_min_ = mi;
5188 duration_max_ = ma;
5189 }
5190 void SetDurationValue(int64_t v) {
5191 duration_min_ = v;
5192 duration_max_ = v;
5193 }
5194 void SetEndMin(int64_t m) { end_min_ = m; }
5195 void SetEndMax(int64_t m) { end_max_ = m; }
5196 void SetEndRange(int64_t mi, int64_t ma) {
5197 end_min_ = mi;
5198 end_max_ = ma;
5199 }
5200 void SetEndValue(int64_t v) {
5201 end_min_ = v;
5202 end_max_ = v;
5203 }
5204 void SetPerformedMin(int64_t m) { performed_min_ = m; }
5205 void SetPerformedMax(int64_t m) { performed_max_ = m; }
5206 void SetPerformedRange(int64_t mi, int64_t ma) {
5207 performed_min_ = mi;
5208 performed_max_ = ma;
5210 void SetPerformedValue(int64_t v) {
5211 performed_min_ = v;
5212 performed_max_ = v;
5213 }
5214 bool Bound() const {
5215 return (start_min_ == start_max_ && duration_min_ == duration_max_ &&
5216 end_min_ == end_max_ && performed_min_ == performed_max_);
5218 std::string DebugString() const;
5219 bool operator==(const IntervalVarElement& element) const;
5220 bool operator!=(const IntervalVarElement& element) const {
5221 return !(*this == element);
5224 private:
5225 int64_t start_min_;
5226 int64_t start_max_;
5227 int64_t duration_min_;
5228 int64_t duration_max_;
5229 int64_t end_min_;
5230 int64_t end_max_;
5231 int64_t performed_min_;
5232 int64_t performed_max_;
5239
5239/// - the forward sequence. That is the list of interval variables
5240/// ranked first in the sequence. The first element of the backward
5241/// sequence is the first interval in the sequence variable.
5242/// - the backward sequence. That is the list of interval variables
5243/// ranked last in the sequence. The first element of the backward
5244/// sequence is the last interval in the sequence variable.
5245/// - The list of unperformed interval variables.
5246/// Furthermore, if all performed variables are ranked, then by
5247/// convention, the forward_sequence will contain all such variables
5248/// and the backward_sequence will be empty.
5250 public:
5252 explicit SequenceVarElement(SequenceVar* var);
5253 void Reset(SequenceVar* var);
5255 void Copy(const SequenceVarElement& element);
5256 SequenceVar* Var() const { return var_; }
5257 void Store();
5258 void Restore();
5260 const SequenceVarAssignment& sequence_var_assignment_proto);
5261 void WriteToProto(SequenceVarAssignment* sequence_var_assignment_proto) const;
5262
5263 const std::vector<int>& ForwardSequence() const;
5264 const std::vector<int>& BackwardSequence() const;
5265 const std::vector<int>& Unperformed() const;
5266 void SetSequence(const std::vector<int>& forward_sequence,
5267 const std::vector<int>& backward_sequence,
5268 const std::vector<int>& unperformed);
5269 void SetForwardSequence(const std::vector<int>& forward_sequence);
5270 void SetBackwardSequence(const std::vector<int>& backward_sequence);
5271 void SetUnperformed(const std::vector<int>& unperformed);
5272 bool Bound() const {
5273 return forward_sequence_.size() + unperformed_.size() == var_->size();
5274 }
5275
5276 std::string DebugString() const;
5277
5278 bool operator==(const SequenceVarElement& element) const;
5279 bool operator!=(const SequenceVarElement& element) const {
5280 return !(*this == element);
5281 }
5282
5283 private:
5284 bool CheckClassInvariants();
5285
5286 SequenceVar* var_;
5287 std::vector<int> forward_sequence_;
5288 std::vector<int> backward_sequence_;
5289 std::vector<int> unperformed_;
5290};
5291
5292template <class V, class E>
5293class AssignmentContainer {
5294 public:
5296 E* Add(V* var) {
5297 CHECK(var != nullptr);
5298 int index = -1;
5299 if (!Find(var, &index)) {
5300 return FastAdd(var);
5301 } else {
5302 return &elements_[index];
5303 }
5304 }
5306 E* FastAdd(V* var) {
5307 DCHECK(var != nullptr);
5308 elements_.emplace_back(var);
5309 return &elements_.back();
5310 }
5313 E* AddAtPosition(V* var, int position) {
5314 elements_[position].Reset(var);
5315 return &elements_[position];
5316 }
5317 void Clear() {
5318 elements_.clear();
5319 if (!elements_map_.empty()) {
5320 elements_map_.clear();
5321 }
5322 }
5325 void Resize(size_t size) { elements_.resize(size); }
5326 bool Empty() const { return elements_.empty(); }
5329 void CopyIntersection(const AssignmentContainer<V, E>& container) {
5330 for (int i = 0; i < container.elements_.size(); ++i) {
5331 const E& element = container.elements_[i];
5332 const V* const var = element.Var();
5333 int index = -1;
5334 if (i < elements_.size() && elements_[i].Var() == var) {
5335 index = i;
5336 } else if (!Find(var, &index)) {
5337 continue;
5339 DCHECK_GE(index, 0);
5340 E* const local_element = &elements_[index];
5341 local_element->Copy(element);
5342 if (element.Activated()) {
5343 local_element->Activate();
5344 } else {
5345 local_element->Deactivate();
5346 }
5347 }
5348 }
5350
5351 void Copy(const AssignmentContainer<V, E>& container) {
5353 for (int i = 0; i < container.elements_.size(); ++i) {
5354 const E& element = container.elements_[i];
5355 FastAdd(element.Var())->Copy(element);
5356 }
5357 }
5358 bool Contains(const V* const var) const {
5359 int index;
5360 return Find(var, &index);
5361 }
5362 E* MutableElement(const V* const var) {
5363 E* const element = MutableElementOrNull(var);
5364 DCHECK(element != nullptr)
5365 << "Unknown variable " << var->DebugString() << " in solution";
5366 return element;
5367 }
5368 E* MutableElementOrNull(const V* const var) {
5369 int index = -1;
5370 if (Find(var, &index)) {
5371 return MutableElement(index);
5373 return nullptr;
5374 }
5375 const E& Element(const V* const var) const {
5376 const E* const element = ElementPtrOrNull(var);
5377 DCHECK(element != nullptr)
5378 << "Unknown variable " << var->DebugString() << " in solution";
5379 return *element;
5380 }
5381 const E* ElementPtrOrNull(const V* const var) const {
5382 int index = -1;
5383 if (Find(var, &index)) {
5384 return &Element(index);
5386 return nullptr;
5387 }
5388 const std::vector<E>& elements() const { return elements_; }
5389 E* MutableElement(int index) { return &elements_[index]; }
5390 const E& Element(int index) const { return elements_[index]; }
5391 int Size() const { return elements_.size(); }
5392 void Store() {
5393 for (E& element : elements_) {
5394 element.Store();
5395 }
5396 }
5397 void Restore() {
5398 for (E& element : elements_) {
5399 if (element.Activated()) {
5400 element.Restore();
5401 }
5402 }
5403 }
5404 bool AreAllElementsBound() const {
5405 for (const E& element : elements_) {
5406 if (!element.Bound()) return false;
5407 }
5408 return true;
5409 }
5414 bool operator==(const AssignmentContainer<V, E>& container) const {
5416 if (Size() != container.Size()) {
5417 return false;
5418 }
5420 EnsureMapIsUpToDate();
5421
5421 /// Do not use the hash_map::== operator! It
5422 /// compares both content and how the map is hashed (e.g., number of
5423 /// buckets). This is not what we want.
5424 for (const E& element : container.elements_) {
5425 const int position =
5426 gtl::FindWithDefault(elements_map_, element.Var(), -1);
5427 if (position < 0 || elements_[position] != element) {
5428 return false;
5429 }
5430 }
5431 return true;
5432 }
5433 bool operator!=(const AssignmentContainer<V, E>& container) const {
5434 return !(*this == container);
5435 }
5436
5437 private:
5438 void EnsureMapIsUpToDate() const {
5439 absl::flat_hash_map<const V*, int>* map =
5440 const_cast<absl::flat_hash_map<const V*, int>*>(&elements_map_);
5441 for (int i = map->size(); i < elements_.size(); ++i) {
5442 (*map)[elements_[i].Var()] = i;
5443 }
5444 }
5445 bool Find(const V* const var, int* index) const {
5447 const size_t kMaxSizeForLinearAccess = 11;
5448 if (Size() <= kMaxSizeForLinearAccess) {
5451 /// hash table.
5452 for (int i = 0; i < elements_.size(); ++i) {
5453 if (var == elements_[i].Var()) {
5454 *index = i;
5455 return true;
5457 }
5458 return false;
5459 } else {
5460 EnsureMapIsUpToDate();
5461 DCHECK_EQ(elements_map_.size(), elements_.size());
5462 return gtl::FindCopy(elements_map_, var, index);
5464 }
5465
5466 std::vector<E> elements_;
5467 absl::flat_hash_map<const V*, int> elements_map_;
5468};
5469
5472class Assignment : public PropagationBaseObject {
5473 public:
5479
5480 explicit Assignment(Solver* solver);
5481 explicit Assignment(const Assignment* copy);
5482
5483#ifndef SWIG
5484 // This type is neither copyable nor movable.
5485 Assignment(const Assignment&) = delete;
5486 Assignment& operator=(const Assignment&) = delete;
5487#endif
5488
5489 ~Assignment() override;
5490
5491 void Clear();
5492 bool Empty() const {
5493 return int_var_container_.Empty() && interval_var_container_.Empty() &&
5494 sequence_var_container_.Empty();
5495 }
5496 int Size() const {
5498 }
5499 int NumIntVars() const { return int_var_container_.Size(); }
5500 int NumIntervalVars() const { return interval_var_container_.Size(); }
5501 int NumSequenceVars() const { return sequence_var_container_.Size(); }
5502 void Store();
5503 void Restore();
5504
5507 bool Load(const std::string& filename);
5508#if !defined(SWIG)
5509 bool Load(File* file);
5510#endif
5511 void Load(const AssignmentProto& assignment_proto);
5513 bool Save(const std::string& filename) const;
5514#if !defined(SWIG)
5515 bool Save(File* file) const;
5516#endif // #if !defined(SWIG)
5517 void Save(AssignmentProto* assignment_proto) const;
5518
5519 void AddObjective(IntVar* const v) { AddObjectives({v}); }
5520 void AddObjectives(const std::vector<IntVar*>& vars) {
5521 // Objective can only set once.
5522 DCHECK(!HasObjective());
5523 objective_elements_.reserve(vars.size());
5524 for (IntVar* const var : vars) {
5525 if (var != nullptr) {
5526 objective_elements_.emplace_back(var);
5527 }
5528 }
5529 }
5530 void ClearObjective() { objective_elements_.clear(); }
5531 int NumObjectives() const { return objective_elements_.size(); }
5532 IntVar* Objective() const { return ObjectiveFromIndex(0); }
5533 IntVar* ObjectiveFromIndex(int index) const {
5534 return HasObjectiveFromIndex(index) ? objective_elements_[index].Var()
5535 : nullptr;
5536 }
5537 bool HasObjective() const { return !objective_elements_.empty(); }
5538 bool HasObjectiveFromIndex(int index) const {
5539 return index < objective_elements_.size();
5540 }
5541 int64_t ObjectiveMin() const { return ObjectiveMinFromIndex(0); }
5542 int64_t ObjectiveMax() const { return ObjectiveMaxFromIndex(0); }
5543 int64_t ObjectiveValue() const { return ObjectiveValueFromIndex(0); }
5544 bool ObjectiveBound() const { return ObjectiveBoundFromIndex(0); }
5546 void SetObjectiveMax(int64_t m) { SetObjectiveMaxFromIndex(0, m); }
5547 void SetObjectiveValue(int64_t value) {
5549 }
5550 void SetObjectiveRange(int64_t l, int64_t u) {
5552 }
5553 int64_t ObjectiveMinFromIndex(int index) const {
5554 return HasObjectiveFromIndex(index) ? objective_elements_[index].Min() : 0;
5556 int64_t ObjectiveMaxFromIndex(int index) const {
5557 return HasObjectiveFromIndex(index) ? objective_elements_[index].Max() : 0;
5559 int64_t ObjectiveValueFromIndex(int index) const {
5560 return HasObjectiveFromIndex(index) ? objective_elements_[index].Value()
5561 : 0;
5562 }
5563 bool ObjectiveBoundFromIndex(int index) const {
5564 return HasObjectiveFromIndex(index) ? objective_elements_[index].Bound()
5565 : true;
5566 }
5567 void SetObjectiveMinFromIndex(int index, int64_t m) {
5568 if (HasObjectiveFromIndex(index)) {
5569 objective_elements_[index].SetMin(m);
5570 }
5571 }
5572 void SetObjectiveMaxFromIndex(int index, int64_t m) {
5573 if (HasObjectiveFromIndex(index)) {
5574 objective_elements_[index].SetMax(m);
5575 }
5576 }
5577 void SetObjectiveValueFromIndex(int index, int64_t value) {
5579 objective_elements_[index].SetValue(value);
5580 }
5581 }
5582 void SetObjectiveRangeFromIndex(int index, int64_t l, int64_t u) {
5583 if (HasObjectiveFromIndex(index)) {
5584 objective_elements_[index].SetRange(l, u);
5585 }
5586 }
5587
5588 IntVarElement* Add(IntVar* var);
5589 void Add(const std::vector<IntVar*>& vars);
5592 int64_t Min(const IntVar* var) const;
5593 int64_t Max(const IntVar* var) const;
5594 int64_t Value(const IntVar* var) const;
5595 bool Bound(const IntVar* var) const;
5596 void SetMin(const IntVar* var, int64_t m);
5597 void SetMax(const IntVar* var, int64_t m);
5598 void SetRange(const IntVar* var, int64_t l, int64_t u);
5599 void SetValue(const IntVar* var, int64_t value);
5602 void Add(const std::vector<IntervalVar*>& vars);
5605 int64_t StartMin(const IntervalVar* var) const;
5606 int64_t StartMax(const IntervalVar* var) const;
5607 int64_t StartValue(const IntervalVar* var) const;
5608 int64_t DurationMin(const IntervalVar* var) const;
5609 int64_t DurationMax(const IntervalVar* var) const;
5610 int64_t DurationValue(const IntervalVar* var) const;
5611 int64_t EndMin(const IntervalVar* var) const;
5612 int64_t EndMax(const IntervalVar* var) const;
5613 int64_t EndValue(const IntervalVar* var) const;
5614 int64_t PerformedMin(const IntervalVar* var) const;
5615 int64_t PerformedMax(const IntervalVar* var) const;
5616 int64_t PerformedValue(const IntervalVar* var) const;
5617 void SetStartMin(const IntervalVar* var, int64_t m);
5618 void SetStartMax(const IntervalVar* var, int64_t m);
5619 void SetStartRange(const IntervalVar* var, int64_t mi, int64_t ma);
5620 void SetStartValue(const IntervalVar* var, int64_t value);
5621 void SetDurationMin(const IntervalVar* var, int64_t m);
5622 void SetDurationMax(const IntervalVar* var, int64_t m);
5623 void SetDurationRange(const IntervalVar* var, int64_t mi, int64_t ma);
5624 void SetDurationValue(const IntervalVar* var, int64_t value);
5625 void SetEndMin(const IntervalVar* var, int64_t m);
5626 void SetEndMax(const IntervalVar* var, int64_t m);
5627 void SetEndRange(const IntervalVar* var, int64_t mi, int64_t ma);
5628 void SetEndValue(const IntervalVar* var, int64_t value);
5629 void SetPerformedMin(const IntervalVar* var, int64_t m);
5630 void SetPerformedMax(const IntervalVar* var, int64_t m);
5631 void SetPerformedRange(const IntervalVar* var, int64_t mi, int64_t ma);
5632 void SetPerformedValue(const IntervalVar* var, int64_t value);
5633
5635 void Add(const std::vector<SequenceVar*>& vars);
5636
5636 /// Adds without checking if the variable had been previously added.
5638 const std::vector<int>& ForwardSequence(const SequenceVar* var) const;
5639 const std::vector<int>& BackwardSequence(const SequenceVar* var) const;
5640 const std::vector<int>& Unperformed(const SequenceVar* var) const;
5641 void SetSequence(const SequenceVar* var,
5642 const std::vector<int>& forward_sequence,
5643 const std::vector<int>& backward_sequence,
5644 const std::vector<int>& unperformed);
5645 void SetForwardSequence(const SequenceVar* var,
5646 const std::vector<int>& forward_sequence);
5647 void SetBackwardSequence(const SequenceVar* var,
5648 const std::vector<int>& backward_sequence);
5649 void SetUnperformed(const SequenceVar* var,
5650 const std::vector<int>& unperformed);
5651
5652 void Activate(const IntVar* var);
5653 void Deactivate(const IntVar* var);
5654 bool Activated(const IntVar* var) const;
5655
5656 void Activate(const IntervalVar* var);
5657 void Deactivate(const IntervalVar* var);
5658 bool Activated(const IntervalVar* var) const;
5659
5660 void Activate(const SequenceVar* var);
5661 void Deactivate(const SequenceVar* var);
5662 bool Activated(const SequenceVar* var) const;
5663
5666 bool ActivatedObjective() const { return ActivatedObjectiveFromIndex(0); }
5667 void ActivateObjectiveFromIndex(int index) {
5668 if (HasObjectiveFromIndex(index)) {
5669 objective_elements_[index].Activate();
5670 }
5671 }
5672 void DeactivateObjectiveFromIndex(int index) {
5673 if (HasObjectiveFromIndex(index)) {
5674 objective_elements_[index].Deactivate();
5675 }
5676 }
5677 bool ActivatedObjectiveFromIndex(int index) const {
5678 return HasObjectiveFromIndex(index) ? objective_elements_[index].Activated()
5679 : true;
5680 }
5681
5682 std::string DebugString() const override;
5683
5684 bool AreAllElementsBound() const {
5685 return int_var_container_.AreAllElementsBound() &&
5686 interval_var_container_.AreAllElementsBound() &&
5687 sequence_var_container_.AreAllElementsBound();
5688 }
5689
5690 bool Contains(const IntVar* var) const;
5691 bool Contains(const IntervalVar* var) const;
5692 bool Contains(const SequenceVar* var) const;
5695 void CopyIntersection(const Assignment* assignment);
5698 void Copy(const Assignment* assignment);
5699
5700 // TODO(user): Add element iterators to avoid exposing container class.
5701 const IntContainer& IntVarContainer() const { return int_var_container_; }
5702 IntContainer* MutableIntVarContainer() { return &int_var_container_; }
5704 return interval_var_container_;
5705 }
5707 return &interval_var_container_;
5708 }
5710 return sequence_var_container_;
5711 }
5713 return &sequence_var_container_;
5714 }
5715 bool operator==(const Assignment& assignment) const {
5716 return int_var_container_ == assignment.int_var_container_ &&
5717 interval_var_container_ == assignment.interval_var_container_ &&
5718 sequence_var_container_ == assignment.sequence_var_container_ &&
5719 objective_elements_ == assignment.objective_elements_;
5720 }
5721 bool operator!=(const Assignment& assignment) const {
5722 return !(*this == assignment);
5725 private:
5726 IntContainer int_var_container_;
5727 IntervalContainer interval_var_container_;
5728 SequenceContainer sequence_var_container_;
5729 std::vector<IntVarElement> objective_elements_;
5730};
5732std::ostream& operator<<(std::ostream& out,
5733 const Assignment& assignment);
5734
5736
5736/// all IntVars in "target_vars", with the values of the variables set according
5737/// to the corresponding values of "source_vars" in "source_assignment".
5738/// source_vars and target_vars must have the same number of elements.
5739/// The source and target assignments can belong to different Solvers.
5740void SetAssignmentFromAssignment(Assignment* target_assignment,
5741 const std::vector<IntVar*>& target_vars,
5742 const Assignment* source_assignment,
5743 const std::vector<IntVar*>& source_vars);
5744
5745class Pack : public Constraint {
5746 public:
5747 Pack(Solver* s, const std::vector<IntVar*>& vars, int number_of_bins);
5748
5749 ~Pack() override;
5750
5755
5760 const std::vector<int64_t>& weights, const std::vector<int64_t>& bounds);
5762 /// This dimension imposes that for all bins b, the weighted sum
5763 /// (weights->Run(i)) of all objects i assigned to 'b' is less or
5764 /// equal to 'bounds[b]'. Ownership of the callback is transferred to
5765 /// the pack constraint.
5767 Solver::IndexEvaluator1 weights, const std::vector<int64_t>& bounds);
5771
5771 /// equal to 'bounds[b]'. Ownership of the callback is transferred to
5772 /// the pack constraint.
5774 Solver::IndexEvaluator2 weights, const std::vector<int64_t>& bounds);
5775
5778 void AddWeightedSumEqualVarDimension(const std::vector<int64_t>& weights,
5779 const std::vector<IntVar*>& loads);
5783
5785 const std::vector<IntVar*>& loads);
5786
5790
5797 const std::vector<IntVar*>& usage, const std::vector<int64_t>& capacity);
5798
5801 void AddWeightedSumOfAssignedDimension(const std::vector<int64_t>& weights,
5802 IntVar* cost_var);
5803
5804 /// This dimension links 'count_var' to the actual number of bins used in the
5805 /// pack.
5806 void AddCountUsedBinDimension(IntVar* count_var);
5807
5810 void AddCountAssignedItemsDimension(IntVar* count_var);
5811
5812 void Post() override;
5813 void ClearAll();
5814 void PropagateDelayed();
5815 void InitialPropagate() override;
5816 void Propagate();
5817 void OneDomain(int var_index);
5818 std::string DebugString() const override;
5819 bool IsUndecided(int var_index, int bin_index) const;
5820 void SetImpossible(int var_index, int bin_index);
5821 void Assign(int var_index, int bin_index);
5822 bool IsAssignedStatusKnown(int var_index) const;
5823 bool IsPossible(int var_index, int bin_index) const;
5824 IntVar* AssignVar(int var_index, int bin_index) const;
5825 void SetAssigned(int var_index);
5826 void SetUnassigned(int var_index);
5827 void RemoveAllPossibleFromBin(int bin_index);
5828 void AssignAllPossibleToBin(int bin_index);
5829 void AssignFirstPossibleToBin(int bin_index);
5832 void Accept(ModelVisitor* visitor) const override;
5833
5834 private:
5835 bool IsInProcess() const;
5836 const std::vector<IntVar*> vars_;
5837 const int bins_;
5838 std::vector<Dimension*> dims_;
5839 std::unique_ptr<RevBitMatrix> unprocessed_;
5840 std::vector<std::vector<int>> forced_;
5841 std::vector<std::vector<int>> removed_;
5842 std::vector<IntVarIterator*> holes_;
5843 uint64_t stamp_;
5844 Demon* demon_;
5845 std::vector<std::pair<int, int>> to_set_;
5846 std::vector<std::pair<int, int>> to_unset_;
5847 bool in_process_;
5848};
5849
5850class DisjunctiveConstraint : public Constraint {
5851 public:
5852 DisjunctiveConstraint(Solver* s, const std::vector<IntervalVar*>& intervals,
5853 const std::string& name);
5854
5855#ifndef SWIG
5856 // This type is neither copyable nor movable.
5859#endif
5860
5861 ~DisjunctiveConstraint() override;
5862
5864 virtual SequenceVar* MakeSequenceVar() = 0;
5865
5870 void SetTransitionTime(Solver::IndexEvaluator2 transition_time);
5871
5872 int64_t TransitionTime(int before_index, int after_index) {
5873 DCHECK(transition_time_);
5874 return transition_time_(before_index, after_index);
5875 }
5876
5877#if !defined(SWIG)
5878 virtual const std::vector<IntVar*>& nexts() const = 0;
5879 virtual const std::vector<IntVar*>& actives() const = 0;
5880 virtual const std::vector<IntVar*>& time_cumuls() const = 0;
5881 virtual const std::vector<IntVar*>& time_slacks() const = 0;
5882#endif // !defined(SWIG)
5883
5884 protected:
5885 const std::vector<IntervalVar*> intervals_;
5887};
5888
5891class SolutionPool : public BaseObject {
5892 public:
5893 SolutionPool() {}
5894 ~SolutionPool() override {}
5895
5898 virtual void Initialize(Assignment* assignment) = 0;
5899
5902 virtual void RegisterNewSolution(Assignment* assignment) = 0;
5903
5906 virtual void GetNextSolution(Assignment* assignment) = 0;
5907
5909
5910 virtual bool SyncNeeded(Assignment* local_assignment) = 0;
5911};
5912} // namespace operations_research
5913
5914#endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
#define OR_DLL
Definition base_export.h:27
Definition file.h:29
const E & Element(const V *const var) const
E * FastAdd(V *var)
Adds element without checking its presence in the container.
void Copy(const AssignmentContainer< V, E > &container)
bool operator!=(const AssignmentContainer< V, E > &container) const
bool operator==(const AssignmentContainer< V, E > &container) const
void CopyIntersection(const AssignmentContainer< V, E > &container)
const std::vector< E > & elements() const
bool Contains(const V *const var) const
const E * ElementPtrOrNull(const V *const var) const
void Activate(const IntVar *var)
void SetPerformedRange(const IntervalVar *var, int64_t mi, int64_t ma)
AssignmentContainer< SequenceVar, SequenceVarElement > SequenceContainer
int64_t Value(const IntVar *var) const
void SetStartMax(const IntervalVar *var, int64_t m)
void SetMax(const IntVar *var, int64_t m)
void SetForwardSequence(const SequenceVar *var, const std::vector< int > &forward_sequence)
int64_t EndMin(const IntervalVar *var) const
bool Activated(const IntVar *var) const
int64_t ObjectiveValueFromIndex(int index) const
int64_t DurationMax(const IntervalVar *var) const
int64_t PerformedMin(const IntervalVar *var) const
int64_t Max(const IntVar *var) const
void SetBackwardSequence(const SequenceVar *var, const std::vector< int > &backward_sequence)
int64_t Min(const IntVar *var) const
void SetEndValue(const IntervalVar *var, int64_t value)
bool Contains(const IntVar *var) const
void SetValue(const IntVar *var, int64_t value)
bool ObjectiveBoundFromIndex(int index) const
void SetEndMin(const IntervalVar *var, int64_t m)
void AddObjectives(const std::vector< IntVar * > &vars)
bool Load(const std::string &filename)
int64_t EndValue(const IntervalVar *var) const
void SetMin(const IntVar *var, int64_t m)
bool operator==(const Assignment &assignment) const
const std::vector< int > & Unperformed(const SequenceVar *var) const
void SetPerformedValue(const IntervalVar *var, int64_t value)
int64_t PerformedValue(const IntervalVar *var) const
IntervalContainer * MutableIntervalVarContainer()
int64_t StartValue(const IntervalVar *var) const
void SetObjectiveRange(int64_t l, int64_t u)
IntVarElement * Add(IntVar *var)
const IntervalContainer & IntervalVarContainer() const
const SequenceContainer & SequenceVarContainer() const
void SetPerformedMax(const IntervalVar *var, int64_t m)
int64_t ObjectiveMinFromIndex(int index) const
void SetObjectiveMinFromIndex(int index, int64_t m)
std::string DebugString() const override
int64_t EndMax(const IntervalVar *var) const
int64_t StartMin(const IntervalVar *var) const
IntVarElement * FastAdd(IntVar *var)
Adds without checking if variable has been previously added.
void Deactivate(const IntVar *var)
void Copy(const Assignment *assignment)
const std::vector< int > & ForwardSequence(const SequenceVar *var) const
AssignmentContainer< IntVar, IntVarElement > IntContainer
void SetRange(const IntVar *var, int64_t l, int64_t u)
int64_t ObjectiveMaxFromIndex(int index) const
bool ActivatedObjectiveFromIndex(int index) const
int64_t DurationMin(const IntervalVar *var) const
const IntContainer & IntVarContainer() const
void SetObjectiveMaxFromIndex(int index, int64_t m)
bool Bound(const IntVar *var) const
int64_t DurationValue(const IntervalVar *var) const
AssignmentContainer< IntervalVar, IntervalVarElement > IntervalContainer
void SetSequence(const SequenceVar *var, const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
void SetStartMin(const IntervalVar *var, int64_t m)
void SetDurationMin(const IntervalVar *var, int64_t m)
void SetStartValue(const IntervalVar *var, int64_t value)
void SetDurationMax(const IntervalVar *var, int64_t m)
Assignment & operator=(const Assignment &)=delete
void SetEndMax(const IntervalVar *var, int64_t m)
void SetStartRange(const IntervalVar *var, int64_t mi, int64_t ma)
void SetDurationValue(const IntervalVar *var, int64_t value)
void CopyIntersection(const Assignment *assignment)
void SetEndRange(const IntervalVar *var, int64_t mi, int64_t ma)
void SetDurationRange(const IntervalVar *var, int64_t mi, int64_t ma)
bool operator!=(const Assignment &assignment) const
SequenceContainer * MutableSequenceVarContainer()
bool HasObjectiveFromIndex(int index) const
int64_t StartMax(const IntervalVar *var) const
IntVar * ObjectiveFromIndex(int index) const
void SetObjectiveValueFromIndex(int index, int64_t value)
bool Save(const std::string &filename) const
Saves the assignment to a file.
const std::vector< int > & BackwardSequence(const SequenceVar *var) const
void SetPerformedMin(const IntervalVar *var, int64_t m)
void SetObjectiveRangeFromIndex(int index, int64_t l, int64_t u)
void SetUnperformed(const SequenceVar *var, const std::vector< int > &unperformed)
int64_t PerformedMax(const IntervalVar *var) const
BaseObject & operator=(const BaseObject &)=delete
virtual std::string DebugString() const
virtual IntVar * ObjectiveVar(int index) const =0
virtual bool Maximize(int index) const =0
virtual IntVar * MinimizationVar(int index) const =0
virtual int64_t BestValue(int index) const =0
BaseObjectiveMonitor & operator=(const BaseObjectiveMonitor &)=delete
virtual int64_t Step(int index) const =0
CastConstraint(Solver *const solver, IntVar *const target_var)
Constraint & operator=(const Constraint &)=delete
std::string DebugString() const override
--------------— Constraint class ----------------—
virtual void InitialPropagate()=0
bool IsCastConstraint() const
Is the constraint created by a cast from expression to integer variable?
virtual void Accept(ModelVisitor *visitor) const
Accepts the given visitor.
DecisionBuilder & operator=(const DecisionBuilder &)=delete
void set_name(absl::string_view name)
virtual void Accept(ModelVisitor *visitor) const
virtual void AppendMonitors(Solver *solver, std::vector< SearchMonitor * > *extras)
std::string DebugString() const override
-------— Decision Builder -------—
virtual void VisitRankFirstInterval(SequenceVar *sequence, int index)
virtual void VisitSetVariableValue(IntVar *var, int64_t value)
virtual void VisitScheduleOrPostpone(IntervalVar *var, int64_t est)
virtual void VisitRankLastInterval(SequenceVar *sequence, int index)
virtual void VisitScheduleOrExpedite(IntervalVar *var, int64_t est)
DecisionVisitor & operator=(const DecisionVisitor &)=delete
virtual void VisitSplitVariableDomain(IntVar *var, int64_t value, bool start_with_lower_half)
virtual void Refute(Solver *s)=0
Refute will be called after a backtrack.
std::string DebugString() const override
virtual void Apply(Solver *s)=0
Apply will be called first when the decision is executed.
Decision & operator=(const Decision &)=delete
virtual void Accept(DecisionVisitor *visitor) const
Accepts the given visitor.
Demon & operator=(const Demon &)=delete
virtual Solver::DemonPriority priority() const
---------------— Demon class -------------—
std::string DebugString() const override
void desinhibit(Solver *s)
This method un-inhibits the demon that was previously inhibited.
virtual const std::vector< IntVar * > & time_slacks() const =0
virtual SequenceVar * MakeSequenceVar()=0
Creates a sequence variable from the constraint.
DisjunctiveConstraint(Solver *s, const std::vector< IntervalVar * > &intervals, const std::string &name)
Sequence Constraint.
Definition resource.cc:2585
virtual const std::vector< IntVar * > & time_cumuls() const =0
virtual const std::vector< IntVar * > & actives() const =0
int64_t TransitionTime(int before_index, int after_index)
DisjunctiveConstraint & operator=(const DisjunctiveConstraint &)=delete
const std::vector< IntervalVar * > intervals_
virtual const std::vector< IntVar * > & nexts() const =0
void SetTransitionTime(Solver::IndexEvaluator2 transition_time)
Definition resource.cc:2597
bool CheckWithOffset(absl::Duration offset) override
Definition search.cc:4810
ImprovementSearchLimit(Solver *solver, IntVar *objective_var, bool maximize, double objective_scaling_factor, double objective_offset, double improvement_rate_coefficient, int improvement_rate_solutions_distance)
--— Improvement Search Limit --—
Definition search.cc:4738
void Init() override
This method is called when the search limit is initialized.
Definition search.cc:4776
void Install() override
A search monitors adds itself on the active search.
Definition search.cc:4771
void Copy(const SearchLimit *limit) override
Definition search.cc:4786
SearchLimit * MakeClone() const override
Allocates a clone of the limit.
Definition search.cc:4803
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetMax(int64_t m)=0
virtual bool IsVar() const
Returns true if the expression is indeed a variable.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
virtual int64_t Min() const =0
IntExpr & operator=(const IntExpr &)=delete
virtual void SetMin(int64_t m)=0
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
virtual void Range(int64_t *l, int64_t *u)
IntVar * VarWithName(const std::string &name)
-------— IntExpr -------—
virtual IntVar * Var()=0
Creates a variable from the expression.
virtual int64_t Max() const =0
virtual void Accept(ModelVisitor *visitor) const
Accepts the given visitor.
--— Main IntTupleSet class --—
Definition tuple_set.h:47
bool operator==(const IntVarElement &element) const
Definition assignment.cc:76
void SetRange(int64_t l, int64_t u)
bool operator!=(const IntVarElement &element) const
IntVarElement()
--------------— Solutions ---------------------—
Definition assignment.cc:39
std::string DebugString() const
Definition assignment.cc:99
void Copy(const IntVarElement &element)
Definition assignment.cc:55
void WriteToProto(IntVarAssignment *int_var_assignment_proto) const
Definition assignment.cc:91
void LoadFromProto(const IntVarAssignment &int_var_assignment_proto)
Definition assignment.cc:65
virtual bool Ok() const =0
This method indicates if we can call Value() or not.
virtual int64_t Value() const =0
This method returns the current value of the iterator.
virtual void Next()=0
This method moves the iterator to the next value.
virtual void Init()=0
This method must be called before each loop.
std::string DebugString() const override
Pretty Print.
virtual void WhenBound(Demon *d)=0
virtual void WhenDomain(Demon *d)=0
bool IsVar() const override
Returns true if the expression is indeed a 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 *visitor) const override
Accepts the given visitor.
virtual IntVar * IsDifferent(int64_t constant)=0
int index() const
Returns the index of the variable.
IntVar(Solver *s)
-------— IntVar -------—
virtual IntVarIterator * MakeDomainIterator(bool reversible) const =0
virtual int64_t OldMax() const =0
Returns the previous max.
IntVar * Var() override
Creates a variable from the expression.
virtual IntVar * IsLessOrEqual(int64_t constant)=0
IntVar & operator=(const IntVar &)=delete
virtual bool Contains(int64_t v) const =0
virtual int64_t Value() const =0
virtual int VarType() const
------— IntVar ------—
virtual void RemoveValue(int64_t v)=0
This method removes the value 'v' from the domain of the variable.
virtual uint64_t Size() const =0
This method returns the number of values in the domain of the variable.
virtual IntVarIterator * MakeHoleIterator(bool reversible) const =0
virtual IntVar * IsGreaterOrEqual(int64_t constant)=0
virtual IntVar * IsEqual(int64_t constant)=0
IsEqual.
virtual void RemoveInterval(int64_t l, int64_t u)=0
virtual int64_t OldMin() const =0
Returns the previous min.
virtual void RemoveValues(const std::vector< int64_t > &values)
This method remove the values from the domain of the variable.
void SetDurationRange(int64_t mi, int64_t ma)
void WriteToProto(IntervalVarAssignment *interval_var_assignment_proto) const
bool operator!=(const IntervalVarElement &element) const
void Copy(const IntervalVarElement &element)
void SetEndRange(int64_t mi, int64_t ma)
IntervalVarElement()
--— IntervalVarElement --—
bool operator==(const IntervalVarElement &element) const
void SetStartRange(int64_t mi, int64_t ma)
void SetPerformedRange(int64_t mi, int64_t ma)
void LoadFromProto(const IntervalVarAssignment &interval_var_assignment_proto)
virtual IntExpr * PerformedExpr()=0
virtual bool WasPerformedBound() const =0
virtual void WhenEndRange(Demon *d)=0
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t OldEndMax() const =0
virtual int64_t EndMax() const =0
virtual IntExpr * StartExpr()=0
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
virtual void SetEndMax(int64_t m)=0
virtual void SetPerformed(bool val)=0
void WhenAnything(Demon *d)
Attaches a demon awakened when anything about this interval changes.
Definition interval.cc:2272
virtual int64_t OldEndMin() const =0
virtual bool MayBePerformed() const =0
virtual void WhenDurationBound(Demon *d)=0
virtual IntExpr * SafeStartExpr(int64_t unperformed_value)=0
virtual IntExpr * SafeDurationExpr(int64_t unperformed_value)=0
virtual IntExpr * SafeEndExpr(int64_t unperformed_value)=0
virtual IntExpr * DurationExpr()=0
virtual void WhenDurationRange(Demon *d)=0
virtual void WhenEndBound(Demon *d)=0
virtual void SetEndMin(int64_t m)=0
virtual IntExpr * EndExpr()=0
virtual void Accept(ModelVisitor *visitor) const =0
Accepts the given visitor.
virtual void WhenPerformedBound(Demon *d)=0
virtual bool MustBePerformed() const =0
--— LightIntFunctionElementCt --—
--— LightIntIntFunctionElementCt --—
--— LightIntIntIntFunctionElementCt --—
-------— Local Search Phase Parameters -------—
virtual void VisitSequenceVariable(const SequenceVar *variable)
virtual void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments)
virtual void VisitIntervalArgument(const std::string &arg_name, IntervalVar *argument)
Visit interval argument.
static const char kVariableUsageLessConstantExtension[]
void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, int64_t index_max)
--— Helpers --—
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 kMirrorOperation[]
Operations.
static const char kActiveArgument[]
argument names:
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *expr)
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
virtual void VisitIntegerVariable(const IntVar *variable, IntExpr *delegate)
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kStartSyncOnStartOperation[]
virtual void EndVisitModel(const std::string &type_name)
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *argument)
Visit integer expression argument.
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
static const char kUsageLessConstantExtension[]
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *constraint)
virtual void EndVisitExtension(const std::string &type)
static const char kUsageEqualVariableExtension[]
static const char kCountAssignedItemsExtension[]
Extension names:
virtual void VisitIntervalVariable(const IntervalVar *variable, const std::string &operation, int64_t value, IntervalVar *delegate)
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
virtual void BeginVisitExtension(const std::string &type)
static const char kWeightedSumOfAssignedEqualVariableExtension[]
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *argument)
Visit sequence argument.
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *expr)
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *constraint)
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)
bool CurrentInternalValuesAreConstraining() const
Definition search.cc:3185
const std::vector< IntVar * > & minimization_vars() const
const std::vector< IntVar * > & objective_vars() const
int64_t Step(int index) const override
void SetCurrentInternalValue(int index, int64_t value)
void MakeMinimizationVarsLessOrEqualWithSteps(const T &upper_bounds)
int64_t CurrentInternalValue(int index) const
bool Maximize(int index) const override
bool AcceptDelta(Assignment *delta, Assignment *deltadelta) override
Definition search.cc:3135
void Accept(ModelVisitor *visitor) const override
Accepts the given model visitor.
Definition search.cc:3175
int64_t BestValue(int index) const override
ObjectiveMonitor(Solver *solver, const std::vector< bool > &maximize, std::vector< IntVar * > vars, std::vector< int64_t > steps)
Definition search.cc:3077
IntVar * MakeMinimizationVarsLessOrEqualWithStepsStatus(const T &upper_bounds)
void EnterSearch() override
Beginning of the search.
Definition search.cc:3111
ObjectiveMonitor & operator=(const ObjectiveMonitor &)=delete
IntVar * ObjectiveVar(int index) const override
IntVar * MinimizationVar(int index) const override
void BeginNextDecision(DecisionBuilder *db) override
Internal methods.
Definition search.cc:3207
int64_t best() const
Returns the best value found during search.
void RefuteDecision(Decision *d) override
Before refuting the decision.
Definition search.cc:3220
IntVar * var() const
Returns the variable that is optimized.
OptimizeVar(Solver *solver, bool maximize, IntVar *var, int64_t step)
Definition search.cc:3198
std::string DebugString() const override
Definition search.cc:3249
virtual std::string Name() const
Definition search.cc:3247
void SetUnassigned(int var_index)
Definition pack.cc:445
void SetAssigned(int var_index)
Definition pack.cc:437
void Assign(int var_index, int bin_index)
Definition pack.cc:417
bool IsPossible(int var_index, int bin_index) const
Definition pack.cc:429
void Post() override
Definition pack.cc:128
void AddCountUsedBinDimension(IntVar *count_var)
Definition pack.cc:1599
Pack(Solver *s, const std::vector< IntVar * > &vars, int number_of_bins)
--— Pack --—
Definition pack.cc:109
void AddWeightedSumLessOrEqualConstantDimension(const std::vector< int64_t > &weights, const std::vector< int64_t > &bounds)
-------— API -------—
Definition pack.cc:1530
void AddSumVariableWeightsLessOrEqualConstantDimension(const std::vector< IntVar * > &usage, const std::vector< int64_t > &capacity)
Definition pack.cc:1589
void AddCountAssignedItemsDimension(IntVar *count_var)
Definition pack.cc:1606
void UnassignAllRemainingItems()
Definition pack.cc:494
void AssignAllRemainingItems()
Definition pack.cc:484
std::string DebugString() const override
--------------— Constraint class ----------------—
Definition pack.cc:381
void AssignAllPossibleToBin(int bin_index)
Definition pack.cc:467
void Accept(ModelVisitor *visitor) const override
Accepts the given visitor.
Definition pack.cc:394
IntVar * AssignVar(int var_index, int bin_index) const
Definition pack.cc:433
bool IsAssignedStatusKnown(int var_index) const
Definition pack.cc:425
void AssignFirstPossibleToBin(int bin_index)
Definition pack.cc:477
void AddWeightedSumEqualVarDimension(const std::vector< int64_t > &weights, const std::vector< IntVar * > &loads)
Definition pack.cc:1560
void RemoveAllPossibleFromBin(int bin_index)
Definition pack.cc:457
void AddWeightedSumOfAssignedDimension(const std::vector< int64_t > &weights, IntVar *cost_var)
Definition pack.cc:1580
void InitialPropagate() override
Definition pack.cc:191
void SetImpossible(int var_index, int bin_index)
Definition pack.cc:409
void OneDomain(int var_index)
Definition pack.cc:335
bool IsUndecided(int var_index, int bin_index) const
Definition pack.cc:405
ProfiledDecisionBuilder(DecisionBuilder *db)
--------------— ProfiledDecisionBuilder ---------—
std::string DebugString() const override
-------— Decision Builder -------—
void Accept(ModelVisitor *visitor) const override
void AppendMonitors(Solver *solver, std::vector< SearchMonitor * > *extras) override
PropagationBaseObject & operator=(const PropagationBaseObject &)=delete
void ExecuteAll(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 EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string BaseName() const
Returns a base name for automatic naming.
void reset_action_on_fail()
This method clears the failure callback.
bool HasName() const
Returns whether the object has been named or not.
SearchLimit * MakeClone() const override
Allocates a clone of the limit.
Definition search.cc:4562
bool IsUncheckedSolutionLimitReached() override
Definition search.cc:4622
void Install() override
A search monitors adds itself on the active search.
Definition search.cc:4543
bool CheckWithOffset(absl::Duration offset) override
Definition search.cc:4570
void Init() override
This method is called when the search limit is initialized.
Definition search.cc:4591
std::string DebugString() const override
Definition search.cc:4628
void Accept(ModelVisitor *visitor) const override
Accepts the given model visitor.
Definition search.cc:4636
void ExitSearch() override
End of the search.
Definition search.cc:4602
RegularLimit(Solver *s, absl::Duration time, int64_t branches, int64_t failures, int64_t solutions, bool smart_time_check, bool cumulative)
--— Regular Limit --—
Definition search.cc:4522
void Copy(const SearchLimit *limit) override
Definition search.cc:4551
void UpdateLimits(absl::Duration time, int64_t branches, int64_t failures, int64_t solutions)
Definition search.cc:4613
RegularLimit * MakeIdenticalClone() const
Definition search.cc:4564
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
void SetValue(Solver *const s, const T &val)
Base class of all search limits.
~SearchLimit() override
-------— Search Limits -------—
Definition search.cc:4483
std::string DebugString() const override
void BeginNextDecision(DecisionBuilder *b) override
Before calling DecisionBuilder::Next.
Definition search.cc:4497
void PeriodicCheck() override
Periodic call to check limits in long running methods.
Definition search.cc:4507
bool crossed() const
Returns true if the limit has been crossed.
virtual void Copy(const SearchLimit *limit)=0
void EnterSearch() override
Internal methods.
Definition search.cc:4492
virtual void Init()=0
This method is called when the search limit is initialized.
void Install() override
A search monitors adds itself on the active search.
Definition search.cc:4485
SearchLimit & operator=(const SearchLimit &)=delete
virtual bool CheckWithOffset(absl::Duration offset)=0
void RefuteDecision(Decision *d) override
Before refuting the decision.
Definition search.cc:4502
virtual SearchLimit * MakeClone() const =0
Allocates a clone of the limit.
A search monitor is a simple set of callbacks to monitor all search events.
virtual void Install()
A search monitors adds itself on the active search.
virtual void BeginInitialPropagation()
Before the initial propagation.
virtual void EndFail()
After completing the backtrack.
virtual void RestartSearch()
Restart the search.
virtual void EndInitialPropagation()
After the initial propagation.
virtual bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
virtual void BeginNextDecision(DecisionBuilder *b)
Before calling DecisionBuilder::Next.
virtual void RefuteDecision(Decision *d)
Before refuting the decision.
virtual void EndNextDecision(DecisionBuilder *b, Decision *d)
After calling DecisionBuilder::Next, along with the returned decision.
virtual void ApplyDecision(Decision *d)
Before applying the decision.
virtual void Accept(ModelVisitor *visitor) const
Accepts the given model visitor.
virtual void ExitSearch()
End of the search.
virtual void PeriodicCheck()
Periodic call to check limits in long running methods.
virtual void NoMoreSolutions()
When the search tree is finished.
void ListenToEvent(Solver::MonitorEvent event)
virtual void BeginFail()
Just when the failure occurs.
virtual void EnterSearch()
Beginning of the search.
virtual void AfterDecision(Decision *d, bool apply)
virtual void AcceptNeighbor()
After accepting a neighbor during local search.
virtual void AcceptUncheckedNeighbor()
After accepting an unchecked neighbor during local search.
---------------— Search class --------------—
void WriteToProto(SequenceVarAssignment *sequence_var_assignment_proto) const
bool operator==(const SequenceVarElement &element) const
SequenceVarElement()
--— SequenceVarElement --—
void SetUnperformed(const std::vector< int > &unperformed)
const std::vector< int > & ForwardSequence() const
void Copy(const SequenceVarElement &element)
void SetBackwardSequence(const std::vector< int > &backward_sequence)
const std::vector< int > & BackwardSequence() const
void SetSequence(const std::vector< int > &forward_sequence, const std::vector< int > &backward_sequence, const std::vector< int > &unperformed)
void SetForwardSequence(const std::vector< int > &forward_sequence)
void LoadFromProto(const SequenceVarAssignment &sequence_var_assignment_proto)
const std::vector< int > & Unperformed() const
void HorizonRange(int64_t *hmin, int64_t *hmax) const
virtual void Accept(ModelVisitor *visitor) const
Accepts the given visitor.
void RankSequence(const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)
IntervalVar * Interval(int index) const
Returns the index_th interval of the sequence.
void ComputePossibleFirstsAndLasts(std::vector< int > *possible_firsts, std::vector< int > *possible_lasts)
int64_t size() const
Returns the number of interval vars in the sequence.
SequenceVar(Solver *s, const std::vector< IntervalVar * > &intervals, const std::vector< IntVar * > &nexts, const std::string &name)
--— SequenceVar --—
void ComputeStatistics(int *ranked, int *not_ranked, int *unperformed) const
Compute statistics on the sequence.
void FillSequence(std::vector< int > *rank_first, std::vector< int > *rank_last, std::vector< int > *unperformed) const
std::string DebugString() const override
void ActiveHorizonRange(int64_t *hmin, int64_t *hmax) const
void DurationRange(int64_t *dmin, int64_t *dmax) const
std::string DebugString() const override
int64_t branches(int n) const
Returns the number of branches when the nth solution was found.
Definition search.cc:2494
SolutionData BuildSolutionDataForCurrentState()
Definition search.cc:2444
void AddObjectives(const std::vector< IntVar * > &objectives)
Definition search.cc:2421
const std::vector< int > & ForwardSequence(int n, SequenceVar *var) const
Definition search.cc:2534
int64_t objective_value(int n) const
Returns the objective value of the nth solution.
Definition search.cc:2504
void Add(IntVar *var)
Add API.
Definition search.cc:2379
SolutionCollector & operator=(const SolutionCollector &)=delete
std::vector< std::unique_ptr< Assignment > > solution_pool_
int64_t PerformedValue(int n, IntervalVar *var) const
This is a shortcut to get the PerformedValue of 'var' in the nth solution.
Definition search.cc:2530
void EnterSearch() override
Beginning of the search.
Definition search.cc:2427
void FreeSolution(Assignment *solution)
Definition search.cc:2465
void Push(const SolutionData &data)
void PopSolution()
Remove and delete the last popped solution.
Definition search.cc:2436
const std::vector< int > & Unperformed(int n, SequenceVar *var) const
Definition search.cc:2544
void AddObjective(IntVar *objective)
Definition search.cc:2415
bool has_solution() const
Returns whether any solutions were stored during the search.
Definition search.cc:2487
int solution_count() const
Returns how many solutions were stored during the search.
Definition search.cc:2485
void Install() override
A search monitors adds itself on the active search.
Definition search.cc:2375
int64_t wall_time(int n) const
Returns the wall time in ms for the nth solution.
Definition search.cc:2489
void PushSolution()
Push the current state as a new solution.
Definition search.cc:2432
int64_t DurationValue(int n, IntervalVar *var) const
This is a shortcut to get the DurationValue of 'var' in the nth solution.
Definition search.cc:2522
int64_t ObjectiveValueFromIndex(int n, int index) const
Returns the value of the index-th objective of the nth solution.
Definition search.cc:2509
const std::vector< int > & BackwardSequence(int n, SequenceVar *var) const
Definition search.cc:2539
int64_t StartValue(int n, IntervalVar *var) const
This is a shortcut to get the StartValue of 'var' in the nth solution.
Definition search.cc:2518
SolutionCollector(Solver *solver, const Assignment *assignment)
-------— Solution Collectors --------—
Definition search.cc:2337
Assignment * solution(int n) const
Returns the nth solution.
Definition search.cc:2476
int64_t Value(int n, IntVar *var) const
This is a shortcut to get the Value of 'var' in the nth solution.
Definition search.cc:2514
std::vector< Assignment * > recycle_solutions_
std::vector< SolutionData > solution_data_
std::unique_ptr< Assignment > prototype_
Assignment * last_solution_or_null() const
Returns the last solution if there are any, nullptr otherwise.
Definition search.cc:2481
int64_t EndValue(int n, IntervalVar *var) const
This is a shortcut to get the EndValue of 'var' in the nth solution.
Definition search.cc:2526
virtual bool SyncNeeded(Assignment *local_assignment)=0
virtual void Initialize(Assignment *assignment)=0
virtual void RegisterNewSolution(Assignment *assignment)=0
virtual void GetNextSolution(Assignment *assignment)=0
For the time being, Solver is neither MT_SAFE nor MT_HOT.
Constraint * MakeIsLexicalLessOrEqualWithOffsetsCt(std::vector< IntVar * > left, std::vector< IntVar * > right, std::vector< int64_t > offsets, IntVar *boolvar)
Semi-reified version of the above: boolvar -> LexLE(left, right, offsets).
static ConstraintSolverParameters DefaultSolverParameters()
--— ConstraintSolverParameters --—
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].
Definition count_cst.cc:966
std::function< int64_t(Solver *solver, const std::vector< IntVar * > &vars, int64_t first_unbound, int64_t last_unbound)> VariableIndexSelector
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
IntervalVar * MakeMirrorInterval(IntervalVar *interval_var)
--— API --—
Definition interval.cc:2249
IntExpr * MakeElement(const std::vector< int64_t > &values, IntVar *index)
values[index]
Definition element.cc:658
OptimizationDirection optimization_direction() const
The direction of optimization, getter and setter.
Constraint * MakePathConnected(std::vector< IntVar * > nexts, std::vector< int64_t > sources, std::vector< int64_t > sinks, std::vector< IntVar * > status)
Constraint * MakeIsLessOrEqualCt(IntExpr *left, IntExpr *right, IntVar *b)
b == (left <= right)
Definition range_cst.cc:736
Decision * MakeAssignVariablesValuesOrDoNothing(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
Definition search.cc:1880
Demon * RegisterDemon(Demon *demon)
Adds a new demon and wraps it inside a DemonProfiler if necessary.
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
Constraint * MakeScalProdLessOrEqual(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefficients, int64_t cst)
Constraint * MakeIsEqualCstCt(IntExpr *var, int64_t value, IntVar *boolvar)
boolvar == (var == value)
Definition expr_cst.cc:493
Demon * MakeClosureDemon(Closure closure)
Creates a demon from a closure.
IntExpr * MakeScalProd(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefs)
scalar product
IntVar * MakeIsGreaterOrEqualVar(IntExpr *left, IntExpr *right)
status var of (left >= right)
Definition range_cst.cc:791
IntExpr * MakeDiv(IntExpr *expr, int64_t value)
expr / value (integer division)
Constraint * MakeSortingConstraint(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &sorted)
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
void ExportProfilingOverview(const std::string &filename)
Constraint * MakeLexicalLess(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
bool NextSolution()
Search for the next solution in the search tree.
Constraint * MakeSumEquality(const std::vector< IntVar * > &vars, int64_t cst)
DecisionBuilder * MakeSolveOnce(DecisionBuilder *db)
Definition search.cc:5061
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
int64_t accepted_neighbors() const
The number of accepted neighbors.
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
Constraint * MakeNotMemberCt(IntExpr *expr, const std::vector< int64_t > &values)
expr not in set.
Definition expr_cst.cc:1239
void set_fail_intercept(std::function< void()> fail_intercept)
Internal.
Constraint * MakeIsGreaterCt(IntExpr *left, IntExpr *right, IntVar *b)
b == (left > right)
Definition range_cst.cc:806
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Constraint * MakeIsGreaterOrEqualCt(IntExpr *left, IntExpr *right, IntVar *b)
b == (left >= right)
Definition range_cst.cc:796
SearchMonitor * MakeEnterSearchCallback(std::function< void()> callback)
--— Callback-based search monitors --—
Definition search.cc:516
LocalSearchOperator * MakeMoveTowardTargetOperator(const Assignment &target)
Constraint * MakeIsEqualCt(IntExpr *v1, IntExpr *v2, IntVar *b)
b == (v1 == v2)
Definition range_cst.cc:628
IntVar * MakeIsMemberVar(IntExpr *expr, const std::vector< int64_t > &values)
Definition expr_cst.cc:1501
Decision * MakeAssignVariableValueOrFail(IntVar *var, int64_t value)
Definition search.cc:1680
Constraint * MakeNonEquality(IntExpr *left, IntExpr *right)
left != right
Definition range_cst.cc:570
IntVar * MakeIsEqualCstVar(IntExpr *var, int64_t value)
status var of (var == value)
Definition expr_cst.cc:468
Constraint * MakeSubCircuit(const std::vector< IntVar * > &nexts)
Decision * MakeVariableLessOrEqualValue(IntVar *var, int64_t value)
Definition search.cc:1768
IntExpr * MakeMax(const std::vector< IntVar * > &vars)
std::max(vars)
SearchMonitor * MakeLubyRestart(int scale_factor)
Definition search.cc:5293
int64_t branches() const
The number of branches explored since the creation of the solver.
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).
Definition search.cc:3304
IntervalVar * MakeFixedDurationStartSyncedOnEndIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)
Definition interval.cc:2450
LocalSearchOperator * ConcatenateOperators(const std::vector< LocalSearchOperator * > &ops)
IntExpr * MakeDifference(IntExpr *left, IntExpr *right)
left - right
SearchMonitor * MakeConstantRestart(int frequency)
Definition search.cc:5328
int64_t solutions() const
The number of solutions found since the start of the search.
LocalSearchFilter * MakeVariableDomainFilter()
bool NameAllVariables() const
Returns whether all variables should be named.
DecisionBuilder * MakeNestedOptimize(DecisionBuilder *db, Assignment *solution, bool maximize, int64_t step)
Definition search.cc:5180
Constraint * MakeMemberCt(IntExpr *expr, const std::vector< int64_t > &values)
--— Member and related constraints --—
Definition expr_cst.cc:1169
ABSL_MUST_USE_RESULT RegularLimit * MakeSolutionsLimit(int64_t solutions)
Definition search.cc:4696
Constraint * MakeGreaterOrEqual(IntExpr *left, IntExpr *right)
left >= right
Definition range_cst.cc:548
void AddPropagationMonitor(PropagationMonitor *monitor)
Decision * MakeRankLastInterval(SequenceVar *sequence, int index)
IntVar * MakeBoolVar()
MakeBoolVar will create a variable with a {0, 1} domain.
LocalSearchPhaseParameters * MakeLocalSearchPhaseParameters(IntVar *objective, LocalSearchOperator *ls_operator, DecisionBuilder *sub_decision_builder)
Local Search Phase Parameters.
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, absl::string_view name, std::vector< IntervalVar * > *array)
Definition interval.cc:2425
SolutionCollector * MakeBestValueSolutionCollector(const Assignment *assignment, bool maximize)
Definition search.cc:2756
IntVar * MakeIsLessOrEqualCstVar(IntExpr *var, int64_t value)
status var of (var <= value)
Definition expr_cst.cc:785
Constraint * MakeIfThenElseCt(IntVar *condition, IntExpr *then_expr, IntExpr *else_expr, IntVar *target_var)
Special cases with arrays of size two.
Definition element.cc:1607
Solver & operator=(const Solver &)=delete
IntExpr * MakeSum(IntExpr *left, IntExpr *right)
--— Integer Expressions --—
Constraint * MakeCumulative(const std::vector< IntervalVar * > &intervals, const std::vector< int64_t > &demands, int64_t capacity, const std::string &name)
Demands are constant.
Definition resource.cc:2620
ABSL_MUST_USE_RESULT SearchLimit * MakeCustomLimit(std::function< bool()> limiter)
Definition search.cc:5018
Constraint * MakeScalProdEquality(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coefficients, int64_t cst)
Constraint * MakeIsMemberCt(IntExpr *expr, const std::vector< int64_t > &values, IntVar *boolvar)
boolvar == (expr in set)
Definition expr_cst.cc:1489
static constexpr int kNumPriorities
Number of priorities for demons.
IntExpr * MakeMin(const std::vector< IntVar * > &vars)
std::min(vars)
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, const std::vector< IntVar * > &transits)
const ConstraintSolverParameters & const_parameters() const
Read-only.
IntVar * MakeIsDifferentVar(IntExpr *v1, IntExpr *v2)
status var of (v1 != v2)
Definition range_cst.cc:647
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)
Variable Duration Interval Var.
Definition interval.cc:2416
ABSL_MUST_USE_RESULT RegularLimit * MakeFailuresLimit(int64_t failures)
Definition search.cc:4689
Decision * balancing_decision() const
int64_t demon_runs(DemonPriority p) const
The number of demons executed during search for a given priority.
@ NORMAL_PRIORITY
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
OptimizeVar * MakeWeightedMinimize(const std::vector< IntVar * > &sub_objectives, const std::vector< int64_t > &weights, int64_t step)
Definition search.cc:3311
void NewSearch(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
Opens a new top level search.
IntVarLocalSearchFilter * MakeSumObjectiveFilter(const std::vector< IntVar * > &vars, IndexEvaluator2 values, Solver::LocalSearchFilterBound filter_enum)
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)
Definition diffn.cc:330
DecisionBuilder * MakeProfiledDecisionBuilderWrapper(DecisionBuilder *db)
Activates profiling on a decision builder.
bool UseFastLocalSearch() const
Returns true if fast local search is enabled.
IntVar * MakeIsGreaterVar(IntExpr *left, IntExpr *right)
status var of (left > right)
Definition range_cst.cc:802
Decision * MakeVariableGreaterOrEqualValue(IntVar *var, int64_t value)
Definition search.cc:1773
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
Assignment * RunUncheckedLocalSearch(const Assignment *initial_solution, LocalSearchFilterManager *filter_manager, LocalSearchOperator *ls_operator, const std::vector< SearchMonitor * > &monitors, RegularLimit *limit, absl::flat_hash_set< IntVar * > *touched=nullptr)
IntVar * MakeIsLessVar(IntExpr *left, IntExpr *right)
status var of (left < right)
Definition range_cst.cc:748
ABSL_MUST_USE_RESULT RegularLimit * MakeTimeLimit(absl::Duration time)
Creates a search limit that constrains the running time.
Definition search.cc:4675
const std::string & context() const
Gets the current context of the search.
Constraint * MakeCircuit(const std::vector< IntVar * > &nexts)
Force the "nexts" variable to create a complete Hamiltonian path.
Constraint * MakeDeviation(const std::vector< IntVar * > &vars, IntVar *deviation_var, int64_t total_sum)
Definition deviation.cc:414
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
SolverState
This enum represents the state of the solver w.r.t. the search.
@ IN_SEARCH
Executing the search code.
@ IN_ROOT_NODE
Executing the root node.
@ PROBLEM_INFEASIBLE
After search, the model is infeasible.
@ NO_MORE_SOLUTIONS
After failed NextSolution and before EndSearch.
@ OUTSIDE_SEARCH
Before search, after search.
@ AT_SOLUTION
After successful NextSolution and before EndSearch.
std::function< int64_t(int64_t, int64_t, int64_t)> IndexEvaluator3
void set_context(absl::string_view context)
Sets the current context of the search.
DisjunctiveConstraint * MakeDisjunctiveConstraint(const std::vector< IntervalVar * > &intervals, const std::string &name)
-------— Factory methods -------—
Definition resource.cc:2608
LocalSearchStatistics GetLocalSearchStatistics() const
Returns detailed local search statistics.
void SaveAndAdd(T *adr, T val)
All-in-one SaveAndAdd_value.
IntVar * RegisterIntVar(IntVar *var)
Registers a new IntVar and wraps it inside a TraceIntVar if necessary.
Definition trace.cc:860
Constraint * MakeIsGreaterCstCt(IntExpr *v, int64_t c, IntVar *b)
b == (v > c)
Definition expr_cst.cc:722
DecisionBuilder * Compose(DecisionBuilder *db1, DecisionBuilder *db2)
Definition search.cc:635
ObjectiveMonitor * MakeTabuSearch(bool maximize, IntVar *objective, 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.
Definition search.cc:3663
std::string LocalSearchProfile() const
IntervalVar * MakeFixedDurationEndSyncedOnStartIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)
Definition interval.cc:2457
Constraint * MakeAllDifferentExcept(const std::vector< IntVar * > &vars, int64_t escape_value)
DecisionBuilder * MakePhase(const std::vector< IntVar * > &vars, IntVarStrategy var_str, IntValueStrategy val_str)
Definition search.cc:2142
IntVar * MakeIsGreaterCstVar(IntExpr *var, int64_t value)
status var of (var > value)
Definition expr_cst.cc:702
bool CheckAssignment(Assignment *solution)
Checks whether the given assignment satisfies all relevant constraints.
LocalSearchOperator * RandomConcatenateOperators(const std::vector< LocalSearchOperator * > &ops)
bool IsBooleanVar(IntExpr *expr, IntVar **inner_var, bool *is_negated) const
void AddBacktrackAction(Action a, bool fast)
void MakeFixedDurationIntervalVarArray(int count, int64_t start_min, int64_t start_max, int64_t duration, bool optional, absl::string_view name, std::vector< IntervalVar * > *array)
Definition interval.cc:2299
Decision * MakeAssignVariableValue(IntVar *var, int64_t val)
Decisions.
Definition search.cc:1642
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
std::string model_name() const
Returns the name of the model.
LocalSearchFilter * MakeAcceptFilter()
Local Search Filters.
IntExpr * MakeMonotonicElement(IndexEvaluator1 values, bool increasing, IntVar *index)
Definition element.cc:869
Decision * MakeAssignVariablesValuesOrFail(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
Definition search.cc:1887
Decision * MakeScheduleOrExpedite(IntervalVar *var, int64_t est, int64_t *marker)
Constraint * MakeSumLessOrEqual(const std::vector< IntVar * > &vars, int64_t cst)
Variation on arrays.
Constraint * MakeIsLessCstCt(IntExpr *v, int64_t c, IntVar *b)
b == (v < c)
Definition expr_cst.cc:822
std::function< DecisionModification()> BranchSelector
SolutionPool * MakeDefaultSolutionPool()
Solution Pool.
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)
Definition diffn.cc:300
LocalSearchOperator * MakeNeighborhoodLimit(LocalSearchOperator *op, int64_t limit)
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
void SetGuidedLocalSearchPenaltyCallback(std::function< int64_t(int64_t, int64_t, int64_t)> penalty_callback)
Constraint * MakePathEnergyCostConstraint(PathEnergyCostConstraintSpecification specification)
Decision * MakeSplitVariableDomain(IntVar *var, int64_t val, bool start_with_lower_half)
Definition search.cc:1763
Constraint * MakeSumGreaterOrEqual(const std::vector< IntVar * > &vars, int64_t cst)
Constraint * MakeTemporalDisjunction(IntervalVar *t1, IntervalVar *t2, IntVar *alt)
Constraint * MakeAllowedAssignments(const std::vector< IntVar * > &vars, const IntTupleSet &tuples)
------— API -------—
Definition table.cc:1259
Constraint * MakePathPrecedenceConstraint(std::vector< IntVar * > nexts, const std::vector< std::pair< int, int > > &precedences)
IntervalVar * MakeFixedDurationIntervalVar(int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string &name)
Definition interval.cc:2284
DecisionBuilder * MakeLocalSearchPhase(Assignment *assignment, LocalSearchPhaseParameters *parameters)
Constraint * MakeLightElement(F values, IntVar *const var, IntVar *const index, std::function< bool()> deep_serialize=nullptr)
Constraint * MakeLess(IntExpr *left, IntExpr *right)
left < right
Definition range_cst.cc:552
IntExpr * CastExpression(const IntVar *var) const
!defined(SWIG)
ModelCache * Cache() const
Returns the cache of the model.
IntExpr * MakeOpposite(IntExpr *expr)
-expr
Constraint * MakeAtMost(std::vector< IntVar * > vars, int64_t value, int64_t max_count)
|{i | vars[i] == value}| <= max_count
Definition count_cst.cc:957
ABSL_MUST_USE_RESULT ImprovementSearchLimit * MakeLexicographicImprovementLimit(std::vector< IntVar * > objective_vars, std::vector< bool > maximize, std::vector< double > objective_scaling_factors, std::vector< double > objective_offsets, double improvement_rate_coefficient, int improvement_rate_solutions_distance)
Definition search.cc:4904
Constraint * MakeAbsEquality(IntVar *var, IntVar *abs_var)
Creates the constraint abs(var) == abs_var.
OptimizeVar * MakeOptimize(bool maximize, IntVar *v, int64_t step)
Creates a objective with a given sense (true = maximization).
Definition search.cc:3268
void MakeBoolVarArray(int var_count, const std::string &name, std::vector< IntVar * > *vars)
DecisionBuilder * MakeConstraintAdder(Constraint *ct)
@ STARTS_BEFORE
t starts before 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.
@ ENDS_BEFORE
t ends before d, i.e. End(t) <= d.
@ STARTS_AT
t starts at d, i.e. Start(t) == d.
@ ENDS_AFTER
t ends after d, i.e. End(t) >= d.
IntExpr * MakePiecewiseLinearExpr(IntExpr *expr, const PiecewiseLinearFunction &f)
IntExpr * RegisterIntExpr(IntExpr *expr)
Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary.
Definition trace.cc:848
int64_t neighbors() const
The number of neighbors created.
Constraint * MakeIsDifferentCt(IntExpr *v1, IntExpr *v2, IntVar *b)
b == (v1 != v2)
Definition range_cst.cc:692
Constraint * MakeNullIntersectExcept(const std::vector< IntVar * > &first_vars, const std::vector< IntVar * > &second_vars, int64_t escape_value)
IntExpr * MakeModulo(IntExpr *x, int64_t mod)
Modulo expression x % mod (with the python convention for modulo).
std::function< void(Solver *)> Action
Constraint * MakeGreater(IntExpr *left, IntExpr *right)
left > right
Definition range_cst.cc:566
DisjunctiveConstraint * MakeStrictDisjunctiveConstraint(const std::vector< IntervalVar * > &intervals, const std::string &name)
Definition resource.cc:2613
Constraint * MakeLexicalLessOrEqual(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
OptimizationDirection
Optimization directions.
IntVar * MakeIsEqualVar(IntExpr *v1, IntExpr *v2)
status var of (v1 == v2)
Definition range_cst.cc:583
IntVar * MakeIsDifferentCstVar(IntExpr *var, int64_t value)
status var of (var != value)
Definition expr_cst.cc:586
LocalSearchOperator * MakeOperator(const std::vector< IntVar * > &vars, LocalSearchOperators op, std::function< const std::vector< int > &(int, int)> get_incoming_neighbors=nullptr, std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors=nullptr)
Local Search Operators.
SearchMonitor * MakeAtSolutionCallback(std::function< void()> callback)
Definition search.cc:491
Constraint * MakeCount(const std::vector< IntVar * > &vars, int64_t value, int64_t max_count)
|{i | vars[i] == value}| == max_count
Definition count_cst.cc:33
@ CHOOSE_RANDOM
Randomly select one of the remaining unbound variables.
@ INT_VAR_DEFAULT
The default behavior is CHOOSE_FIRST_UNBOUND.
@ INT_VAR_SIMPLE
The simple selection is CHOOSE_FIRST_UNBOUND.
IntVar * MakeIsBetweenVar(IntExpr *v, int64_t l, int64_t u)
Definition expr_cst.cc:1093
Constraint * MakeElementEquality(const std::vector< int64_t > &vals, IntVar *index, IntVar *target)
Definition element.cc:1679
IntervalVar * MakeFixedInterval(int64_t start, int64_t duration, const std::string &name)
Creates a fixed and performed interval.
Definition interval.cc:2279
Pack * MakePack(const std::vector< IntVar * > &vars, int number_of_bins)
Definition pack.cc:1613
@ LE
Move is accepted when the current objective value <= objective.Max.
@ GE
Move is accepted when the current objective value >= objective.Min.
DecisionBuilder * Try(DecisionBuilder *db1, DecisionBuilder *db2)
Definition search.cc:783
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
SolutionCollector * MakeAllSolutionCollector()
Definition search.cc:2966
DecisionBuilder * MakeDefaultPhase(const std::vector< IntVar * > &vars)
SequenceStrategy
Used for scheduling. Not yet implemented.
LocalSearchFilter * MakeRejectFilter()
IntervalVar * RegisterIntervalVar(IntervalVar *var)
Definition trace.cc:869
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
IntVar * MakeIsGreaterOrEqualCstVar(IntExpr *var, int64_t value)
status var of (var >= value)
Definition expr_cst.cc:685
Constraint * MakeMinEquality(const std::vector< IntVar * > &vars, IntVar *min_var)
Decision * MakeDecision(Action apply, Action refute)
Definition search.cc:693
Constraint * MakeIsLessCt(IntExpr *left, IntExpr *right, IntVar *b)
b == (left < right)
Definition range_cst.cc:779
ObjectiveMonitor * MakeLexicographicSimulatedAnnealing(const std::vector< bool > &maximize, std::vector< IntVar * > vars, std::vector< int64_t > steps, std::vector< int64_t > initial_temperatures)
Definition search.cc:3785
SolutionCollector * MakeFirstSolutionCollector()
Definition search.cc:2608
Constraint * MakeIndexOfConstraint(const std::vector< IntVar * > &vars, IntVar *index, int64_t target)
Definition element.cc:1742
int32_t Rand32(int32_t size)
Returns a random value between 0 and 'size' - 1;.
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
Constraint * MakeDelayedPathCumul(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, const std::vector< IntVar * > &cumuls, const std::vector< IntVar * > &transits)
std::function< bool(int64_t)> IndexFilter1
void Accept(ModelVisitor *visitor) const
Accepts the given model visitor.
Constraint * MakeIndexOfFirstMinValueConstraint(IntVar *index, const std::vector< IntVar * > &vars)
IntExpr * MakeAbs(IntExpr *expr)
expr
Decision * MakeRankFirstInterval(SequenceVar *sequence, int index)
IntExpr * MakeSquare(IntExpr *expr)
expr * expr
std::vector< int64_t > tmp_vector_
SolutionCollector * MakeLastSolutionCollector()
Definition search.cc:2660
ModelVisitor * MakeVariableDegreeVisitor(absl::flat_hash_map< const IntVar *, int > *map)
Compute the number of constraints a variable is attached to.
Definition utilities.cc:822
Constraint * MakeNoCycle(const std::vector< IntVar * > &nexts, const std::vector< IntVar * > &active, IndexFilter1 sink_handler=nullptr)
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
MonitorEvent
Search monitor events.
@ kLast
Dummy event whose underlying int is the number of MonitorEvent enums.
std::function< void()> Closure
Constraint * MakeIndexOfFirstMaxValueConstraint(IntVar *index, const std::vector< IntVar * > &vars)
DecisionBuilder * MakeStoreAssignment(Assignment *assignment)
Constraint * MakeScalProdGreaterOrEqual(const std::vector< IntVar * > &vars, const std::vector< int64_t > &coeffs, int64_t cst)
IntExpr * MakeIndexExpression(const std::vector< IntVar * > &vars, int64_t value)
Definition element.cc:1757
@ STARTS_AT_START
t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay.
@ 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.
@ ENDS_AT_END
t1 ends at t2 end, i.e. End(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_END
t1 starts at t2 end, i.e. Start(t1) == End(t2) + delay.
SolutionCollector * MakeBestLexicographicValueSolutionCollector(const Assignment *assignment, std::vector< bool > maximize)
Definition search.cc:2761
SearchMonitor * MakeExitSearchCallback(std::function< void()> callback)
Definition search.cc:541
LocalSearchOperator * MultiArmedBanditConcatenateOperators(const std::vector< LocalSearchOperator * > &ops, double memory_coefficient, double exploration_coefficient, bool maximize)
SearchMonitor * MakeSearchTrace(const std::string &prefix)
Definition search.cc:462
Decision * MakeAssignVariablesValues(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values)
Definition search.cc:1872
SolutionCollector * MakeNBestValueSolutionCollector(const Assignment *assignment, int solution_count, bool maximize)
Definition search.cc:2882
Constraint * MakeMaxEquality(const std::vector< IntVar * > &vars, IntVar *max_var)
void ClearLocalSearchState()
Clears the local search state.
std::function< IntVar *(int64_t)> Int64ToIntVar
Constraint * MakeEquality(IntExpr *left, IntExpr *right)
left == right
Definition range_cst.cc:518
IntervalVar * MakeIntervalRelaxedMax(IntervalVar *interval_var)
Definition interval.cc:2254
IntVar * MakeIsLessOrEqualVar(IntExpr *left, IntExpr *right)
status var of (left <= right)
Definition range_cst.cc:704
ObjectiveMonitor * MakeLexicographicTabuSearch(const std::vector< bool > &maximize, std::vector< IntVar * > objectives, std::vector< int64_t > steps, const std::vector< IntVar * > &vars, int64_t keep_tenure, int64_t forbid_tenure, double tabu_factor)
Definition search.cc:3673
Assignment * MakeAssignment()
This method creates an empty assignment.
DecisionBuilder * MakeDecisionBuilderFromAssignment(Assignment *assignment, DecisionBuilder *db, const std::vector< IntVar * > &vars)
Definition search.cc:2327
ABSL_MUST_USE_RESULT RegularLimit * MakeBranchesLimit(int64_t branches)
Definition search.cc:4682
@ RELOCATE
Relocate neighborhood with length of 1 (see OROPT comment).
Constraint * MakeTrueConstraint()
This constraint always succeeds.
Decision * MakeScheduleOrPostpone(IntervalVar *var, int64_t est, int64_t *marker)
Demon * MakeDelayedConstraintInitialPropagateCallback(Constraint *ct)
SearchMonitor * MakeSearchLog(int branch_period)
Definition search.cc:334
ObjectiveMonitor * MakeSimulatedAnnealing(bool maximize, IntVar *v, int64_t step, int64_t initial_temperature)
Definition search.cc:3778
Constraint * MakeLessOrEqual(IntExpr *left, IntExpr *right)
left <= right
Definition range_cst.cc:532
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
Constraint * MakeIsGreaterOrEqualCstCt(IntExpr *var, int64_t value, IntVar *boolvar)
boolvar == (var >= value)
Definition expr_cst.cc:706
int64_t GetGuidedLocalSearchPenalty(int64_t i, int64_t j, int64_t k) const
Returns the current (Guided Local Search)penalty of the given arc tuple.
OptimizeVar * MakeMinimize(IntVar *v, int64_t step)
Creates a minimization objective.
Definition search.cc:3260
void SetSearchContext(Search *search, absl::string_view search_context)
ObjectiveMonitor * MakeGuidedLocalSearch(bool maximize, IntVar *objective, IndexEvaluator2 objective_function, int64_t step, const std::vector< IntVar * > &vars, double penalty_factor, std::function< std::vector< std::pair< int64_t, int64_t > >(int64_t, int64_t)> get_equivalent_pairs=nullptr, bool reset_penalties_on_new_best_solution=false)
Definition search.cc:4435
IntervalVar * MakeFixedDurationEndSyncedOnEndIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)
Definition interval.cc:2464
Constraint * MakeLexicalLessOrEqualWithOffsets(std::vector< IntVar * > left, std::vector< IntVar * > right, std::vector< int64_t > offsets)
std::string DebugString() const
!defined(SWIG)
Constraint * MakeBetweenCt(IntExpr *expr, int64_t l, int64_t u)
--— Between and related constraints --—
Definition expr_cst.cc:929
DemonProfiler * demon_profiler() const
Access to demon profiler.
Demon * MakeConstraintInitialPropagateCallback(Constraint *ct)
void MakeIntVarArray(int var_count, int64_t vmin, int64_t vmax, const std::string &name, std::vector< IntVar * > *vars)
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)
Definition search.cc:4710
OptimizeVar * MakeWeightedMaximize(const std::vector< IntVar * > &sub_objectives, const std::vector< int64_t > &weights, int64_t step)
Creates a maximization weigthed objective.
Definition search.cc:3318
int64_t filtered_neighbors() const
The number of filtered neighbors (neighbors accepted by filters).
Decision * MakeAssignVariableValueOrDoNothing(IntVar *var, int64_t value)
Definition search.cc:1709
SolverState state() const
State of the solver.
SolutionCollector * MakeNBestLexicographicValueSolutionCollector(const Assignment *assignment, int solution_count, std::vector< bool > maximize)
Definition search.cc:2900
int64_t Rand64(int64_t size)
Returns a random value between 0 and 'size' - 1;.
IntVar * MakeIntVar(int64_t min, int64_t max, const std::string &name)
--— Int Variables and Constants --—
ConstraintSolverParameters parameters() const
Stored Parameters.
Constraint * MakeAllDifferent(const std::vector< IntVar * > &vars)
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *t1, BinaryIntervalRelation r, IntervalVar *t2, int64_t delay)
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
bool Solve(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
ModelVisitor * MakePrintModelVisitor()
Prints the model.
Definition utilities.cc:814
void SaveValue(T *o)
reversibility
Constraint * MakeFalseConstraint()
This constraint always fails.
friend void InternalSaveBooleanVarValue(Solver *, IntVar *)
ObjectiveMonitor * MakeGenericTabuSearch(bool maximize, IntVar *v, int64_t step, const std::vector< IntVar * > &tabu_vars, int64_t forbid_tenure)
Definition search.cc:3682
void ReSeed(int32_t seed)
Reseed the solver random generator.
@ INTERVAL_DEFAULT
The default is INTERVAL_SET_TIMES_FORWARD.
@ INTERVAL_SIMPLE
The simple is INTERVAL_SET_TIMES_FORWARD.
bool IsProduct(IntExpr *expr, IntExpr **inner_expr, int64_t *coefficient)
IntExpr * MakeConvexPiecewiseExpr(IntExpr *expr, int64_t early_cost, int64_t early_date, int64_t late_date, int64_t late_cost)
Convex piecewise function.
IntervalVar * MakeFixedDurationStartSyncedOnStartIntervalVar(IntervalVar *interval_var, int64_t duration, int64_t offset)
Synced Interval Vars.
Definition interval.cc:2443
void set_optimization_direction(OptimizationDirection direction)
IntExpr * MakePower(IntExpr *expr, int64_t n)
expr ^ n (n > 0)
IntExpr * MakeConditionalExpression(IntVar *condition, IntExpr *expr, int64_t unperformed_value)
Conditional Expr condition ? expr : unperformed_value.
@ ASSIGN_MAX_VALUE
Selects the max value of the selected variable.
@ INT_VALUE_DEFAULT
The default behavior is ASSIGN_MIN_VALUE.
@ INT_VALUE_SIMPLE
The simple selection is ASSIGN_MIN_VALUE.
@ 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.
OptimizeVar * MakeLexicographicOptimize(std::vector< bool > maximize, std::vector< IntVar * > variables, std::vector< int64_t > steps)
Definition search.cc:3273
SearchMonitor * MakeSymmetryManager(const std::vector< SymmetryBreaker * > &visitors)
Symmetry Breaking.
Definition search.cc:5467
IntVar * MakeIsLessCstVar(IntExpr *var, int64_t value)
status var of (var < value)
Definition expr_cst.cc:802
IntervalVar * MakeIntervalRelaxedMin(IntervalVar *interval_var)
Definition interval.cc:2263
int64_t failures() const
The number of failures encountered since the creation of the solver.
bool CheckConstraint(Constraint *ct)
RegularLimitParameters MakeDefaultRegularLimitParameters() const
Creates a regular limit proto containing default values.
Definition search.cc:4725
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
Constraint * MakeIsBetweenCt(IntExpr *expr, int64_t l, int64_t u, IntVar *b)
b == (l <= expr <= u)
Definition expr_cst.cc:1057
Constraint * MakeIsLessOrEqualCstCt(IntExpr *var, int64_t value, IntVar *boolvar)
boolvar == (var <= value)
Definition expr_cst.cc:806
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
Constraint * MakeTransitionConstraint(const std::vector< IntVar * > &vars, const IntTupleSet &transition_table, int64_t initial_state, const std::vector< int64_t > &final_states)
Definition table.cc:1272
IntExpr * MakeProd(IntExpr *left, IntExpr *right)
left * right
IntVar * MakeIntConst(int64_t val, const std::string &name)
IntConst will create a constant expression.
Constraint * MakeIntervalVarRelation(IntervalVar *t, UnaryIntervalRelation r, int64_t d)
Demon * MakeActionDemon(Action action)
Creates a demon from a callback.
Constraint * MakeNullIntersect(const std::vector< IntVar * > &first_vars, const std::vector< IntVar * > &second_vars)
Solver(const std::string &name)
Solver API.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
Constraint * MakeNotBetweenCt(IntExpr *expr, int64_t l, int64_t u)
Definition expr_cst.cc:962
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
BaseObjectiveMonitor * MakeRoundRobinCompoundObjectiveMonitor(std::vector< BaseObjectiveMonitor * > monitors, int num_max_local_optima_before_metaheuristic_switch)
Definition search.cc:3070
Constraint * MakePathTransitPrecedenceConstraint(std::vector< IntVar * > nexts, std::vector< IntVar * > transits, const std::vector< std::pair< int, int > > &precedences)
static int64_t MemoryUsage()
Current memory usage in bytes.
Constraint * MakeCover(const std::vector< IntervalVar * > &vars, IntervalVar *target_var)
LocalSearchOperator * MakeRandomLnsOperator(const std::vector< IntVar * > &vars, int number_of_variables)
Constraint * MakeInversePermutationConstraint(const std::vector< IntVar * > &left, const std::vector< IntVar * > &right)
void SetUseFastLocalSearch(bool use_fast_local_search)
OptimizeVar * MakeMaximize(IntVar *v, int64_t step)
Creates a maximization objective.
Definition search.cc:3264
Constraint * MakeIsDifferentCstCt(IntExpr *var, int64_t value, IntVar *boolvar)
boolvar == (var != value)
Definition expr_cst.cc:595
IntExpr * MakeSemiContinuousExpr(IntExpr *expr, int64_t fixed_charge, int64_t step)
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)
Definition search.cc:4895
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
Definition utilities.cc:818
std::function< int64_t(const IntVar *v, int64_t id)> VariableValueSelector
bool SolveAndCommit(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
void AddCastConstraint(CastConstraint *constraint, IntVar *target_var, IntExpr *expr)
OR_DLL ABSL_DECLARE_FLAG(int64_t, cp_random_seed)
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition map_util.h:190
const MapUtilMappedT< Collection > & FindWithDefault(const Collection &collection, const KeyType &key, const MapUtilMappedT< Collection > &value)
Definition map_util.h:36
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
In SWIG mode, we don't want anything besides these top-level includes.
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
int64_t CapSub(int64_t x, int64_t y)
const bool DEBUG_MODE
Definition radix_sort.h:266
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
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.
int64_t CapOpp(int64_t v)
Note(user): -kint64min != kint64max, but kint64max == ~kint64min.
bool Next()
bool use_last_conflict
Should we use last conflict method. The default is false.
DecisionBuilder * decision_builder
When defined, this overrides the default impact based decision builder.
int heuristic_num_failures_limit
The failure limit for each heuristic that we run.
ValueSelection value_selection_schema
This parameter describes which value to select for a given var.
int random_seed
Seed used to initialize the random part in some heuristics.
static Iterator Begin(IntVarIterator *it)
These are the only way to construct an Iterator.
bool operator<(const SolutionData &other) const
Definition search.cc:2357
Creates a search monitor from logging parameters.
---------------— StateMarker / StateInfo struct --------—
CycleTimer SimpleCycleTimer
Definition timer.h:79
static const int64_t kint64max
Definition types.h:32