29 #include <type_traits>
33 #include "absl/memory/memory.h"
34 #include "absl/time/clock.h"
35 #include "absl/time/time.h"
52 "Trace propagation events (constraint and demon executions,"
53 " variable modifications).");
54 ABSL_FLAG(
bool, cp_trace_search,
false,
"Trace search events");
56 "show all constraints added to the solver.");
58 "use PrintModelVisitor on model before solving.");
60 "use StatisticsModelVisitor on model before solving.");
62 "Force failure at the beginning of a search.");
64 "Export profiling overview to file.");
65 ABSL_FLAG(
bool, cp_print_local_search_profile,
false,
66 "Print local search profiling data after solving.");
67 ABSL_FLAG(
bool, cp_name_variables,
false,
"Force all variables to have names.");
69 "Name variables casted from expressions");
71 "Use small compact table constraint when possible.");
72 ABSL_FLAG(
bool, cp_use_cumulative_edge_finder,
true,
73 "Use the O(n log n) cumulative edge finding algorithm described "
74 "in 'Edge Finding Filtering Algorithm for Discrete Cumulative "
75 "Resources in O(kn log n)' by Petr Vilim, CP 2009.");
77 "Use a O(n^2) cumulative time table propagation algorithm.");
78 ABSL_FLAG(
bool, cp_use_cumulative_time_table_sync,
false,
79 "Use a synchronized O(n^2 log n) cumulative time table propagation "
81 ABSL_FLAG(
bool, cp_use_sequence_high_demand_tasks,
true,
82 "Use a sequence constraints for cumulative tasks that have a "
83 "demand greater than half of the capacity of the resource.");
84 ABSL_FLAG(
bool, cp_use_all_possible_disjunctions,
true,
85 "Post temporal disjunctions for all pairs of tasks sharing a "
86 "cumulative resource and that cannot overlap because the sum of "
87 "their demand exceeds the capacity.");
89 "Do not post the edge finder in the cumulative constraints if "
90 "it contains more than this number of tasks");
92 "Diffn constraint adds redundant cumulative constraint");
94 "If true, rmq's will be used in element expressions.");
96 "Number of solutions explored between two solution checks during "
99 "Random seed used in several (but not all) random number "
100 "generators used by the CP solver. Use -1 to auto-generate an"
101 "undeterministic random seed.");
105 #if defined(_MSC_VER)
106 #pragma warning(disable : 4351 4355)
114 template <
typename T,
typename MethodPointer,
typename... Args>
115 void ForAll(
const std::vector<T*>& objects, MethodPointer method,
116 const Args&... args) {
117 for (T*
const object : objects) {
118 DCHECK(
object !=
nullptr);
119 (
object->*method)(args...);
124 template <
typename E>
125 constexpr
typename std::underlying_type<E>::type to_underlying(E e) {
126 return static_cast<typename std::underlying_type<E>::type
>(e);
134 ConstraintSolverParameters params;
135 params.set_compress_trail(ConstraintSolverParameters::NO_COMPRESSION);
136 params.set_trail_block_size(8000);
137 params.set_array_split_size(16);
138 params.set_store_names(
true);
139 params.set_profile_propagation(!absl::GetFlag(FLAGS_cp_profile_file).empty());
140 params.set_trace_propagation(absl::GetFlag(FLAGS_cp_trace_propagation));
141 params.set_trace_search(absl::GetFlag(FLAGS_cp_trace_search));
142 params.set_name_all_variables(absl::GetFlag(FLAGS_cp_name_variables));
143 params.set_profile_file(absl::GetFlag(FLAGS_cp_profile_file));
144 params.set_profile_local_search(
145 absl::GetFlag(FLAGS_cp_print_local_search_profile));
146 params.set_print_local_search_profile(
147 absl::GetFlag(FLAGS_cp_print_local_search_profile));
148 params.set_print_model(absl::GetFlag(FLAGS_cp_print_model));
149 params.set_print_model_stats(absl::GetFlag(FLAGS_cp_model_stats));
150 params.set_disable_solve(absl::GetFlag(FLAGS_cp_disable_solve));
151 params.set_name_cast_variables(absl::GetFlag(FLAGS_cp_name_cast_variables));
152 params.set_print_added_constraints(
153 absl::GetFlag(FLAGS_cp_print_added_constraints));
154 params.set_use_small_table(absl::GetFlag(FLAGS_cp_use_small_table));
155 params.set_use_cumulative_edge_finder(
156 absl::GetFlag(FLAGS_cp_use_cumulative_edge_finder));
157 params.set_use_cumulative_time_table(
158 absl::GetFlag(FLAGS_cp_use_cumulative_time_table));
159 params.set_use_cumulative_time_table_sync(
160 absl::GetFlag(FLAGS_cp_use_cumulative_time_table_sync));
161 params.set_use_sequence_high_demand_tasks(
162 absl::GetFlag(FLAGS_cp_use_sequence_high_demand_tasks));
163 params.set_use_all_possible_disjunctions(
164 absl::GetFlag(FLAGS_cp_use_all_possible_disjunctions));
165 params.set_max_edge_finder_size(absl::GetFlag(FLAGS_cp_max_edge_finder_size));
166 params.set_diffn_use_cumulative(absl::GetFlag(FLAGS_cp_diffn_use_cumulative));
167 params.set_use_element_rmq(absl::GetFlag(FLAGS_cp_use_element_rmq));
168 params.set_check_solution_period(
169 absl::GetFlag(FLAGS_cp_check_solution_period));
189 return parameters_.profile_propagation() ||
190 !parameters_.profile_file().empty();
194 return parameters_.profile_local_search() ||
195 parameters_.print_local_search_profile();
199 return parameters_.trace_propagation();
203 return parameters_.name_all_variables();
239 clean_action_(nullptr),
240 clean_variable_(nullptr),
242 instruments_demons_(s->InstrumentsDemons()) {}
252 if (--freeze_level_ == 0) {
258 demon->set_stamp(stamp_ - 1);
259 if (!instruments_demons_) {
279 while (!var_queue_.empty() || !delayed_queue_.empty()) {
280 if (!var_queue_.empty()) {
281 Demon*
const demon = var_queue_.front();
282 var_queue_.pop_front();
285 DCHECK(!delayed_queue_.empty());
286 Demon*
const demon = delayed_queue_.front();
287 delayed_queue_.pop_front();
296 if (!instruments_demons_) {
298 Demon*
const demon = *it;
299 if (demon->stamp() < stamp_) {
311 Demon*
const demon = *it;
312 if (demon->stamp() < stamp_) {
335 if (demon->stamp() < stamp_) {
336 demon->set_stamp(stamp_);
337 var_queue_.push_back(demon);
338 if (freeze_level_ == 0) {
346 if (demon->stamp() < stamp_) {
347 demon->set_stamp(stamp_);
348 delayed_queue_.push_back(demon);
355 delayed_queue_.clear();
358 if (clean_action_ !=
nullptr) {
359 clean_action_(solver_);
360 clean_action_ =
nullptr;
361 }
else if (clean_variable_ !=
nullptr) {
363 clean_variable_ =
nullptr;
374 uint64_t
stamp()
const {
return stamp_; }
377 DCHECK(clean_variable_ ==
nullptr);
378 clean_action_ = std::move(
a);
382 DCHECK(clean_action_ ==
nullptr);
383 clean_variable_ =
var;
387 DCHECK(clean_variable_ ==
nullptr);
388 clean_action_ =
nullptr;
392 to_add_.push_back(c);
402 for (
int counter = 0; counter < to_add_.size(); ++counter) {
403 Constraint*
const constraint = to_add_[counter];
414 std::deque<Demon*> var_queue_;
415 std::deque<Demon*> delayed_queue_;
419 uint32_t freeze_level_;
423 std::vector<Constraint*> to_add_;
425 const bool instruments_demons_;
474 int rev_int64_index_;
475 int rev_uint64_index_;
476 int rev_double_index_;
478 int rev_boolvar_list_index_;
479 int rev_bools_index_;
480 int rev_int_memory_index_;
481 int rev_int64_memory_index_;
482 int rev_double_memory_index_;
483 int rev_object_memory_index_;
484 int rev_object_array_memory_index_;
485 int rev_memory_index_;
486 int rev_memory_array_index_;
494 rev_uint64_index_(0),
495 rev_double_index_(0),
497 rev_boolvar_list_index_(0),
499 rev_int_memory_index_(0),
500 rev_int64_memory_index_(0),
501 rev_double_memory_index_(0),
502 rev_object_memory_index_(0),
503 rev_object_array_memory_index_(0),
516 addrval() : address_(nullptr) {}
517 explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
518 void restore()
const { (*address_) = old_value_; }
533 explicit TrailPacker(
int block_size) : block_size_(block_size) {}
534 virtual ~TrailPacker() {}
535 int input_size()
const {
return block_size_ *
sizeof(addrval<T>); }
536 virtual void Pack(
const addrval<T>* block, std::string* packed_block) = 0;
537 virtual void Unpack(
const std::string& packed_block, addrval<T>* block) = 0;
540 const int block_size_;
545 class NoCompressionTrailPacker :
public TrailPacker<T> {
547 explicit NoCompressionTrailPacker(
int block_size)
548 : TrailPacker<T>(block_size) {}
549 ~NoCompressionTrailPacker()
override {}
550 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
551 DCHECK(block !=
nullptr);
552 DCHECK(packed_block !=
nullptr);
553 absl::string_view block_str(
reinterpret_cast<const char*
>(block),
555 packed_block->assign(block_str.data(), block_str.size());
557 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
558 DCHECK(block !=
nullptr);
559 memcpy(block, packed_block.c_str(), packed_block.size());
567 class ZlibTrailPacker :
public TrailPacker<T> {
569 explicit ZlibTrailPacker(
int block_size)
570 : TrailPacker<T>(block_size),
571 tmp_size_(compressBound(this->input_size())),
572 tmp_block_(new char[tmp_size_]) {}
574 ~ZlibTrailPacker()
override {}
576 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
577 DCHECK(block !=
nullptr);
578 DCHECK(packed_block !=
nullptr);
579 uLongf size = tmp_size_;
581 compress(
reinterpret_cast<Bytef*
>(tmp_block_.get()), &size,
582 reinterpret_cast<const Bytef*
>(block), this->input_size());
583 CHECK_EQ(Z_OK, result);
584 absl::string_view block_str;
585 block_str = absl::string_view(tmp_block_.get(), size);
586 packed_block->assign(block_str.data(), block_str.size());
589 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
590 DCHECK(block !=
nullptr);
591 uLongf size = this->input_size();
593 uncompress(
reinterpret_cast<Bytef*
>(block), &size,
594 reinterpret_cast<const Bytef*
>(packed_block.c_str()),
595 packed_block.size());
596 CHECK_EQ(Z_OK, result);
600 const uint64_t tmp_size_;
601 std::unique_ptr<char[]> tmp_block_;
606 class CompressedTrail {
610 ConstraintSolverParameters::TrailCompression compression_level)
611 : block_size_(block_size),
613 free_blocks_(nullptr),
614 data_(new addrval<T>[block_size]),
615 buffer_(new addrval<T>[block_size]),
619 switch (compression_level) {
620 case ConstraintSolverParameters::NO_COMPRESSION: {
621 packer_.reset(
new NoCompressionTrailPacker<T>(block_size));
624 case ConstraintSolverParameters::COMPRESS_WITH_ZLIB: {
625 packer_.reset(
new ZlibTrailPacker<T>(block_size));
629 LOG(ERROR) <<
"Should not be here";
638 memset(data_.get(), 0,
sizeof(*data_.get()) * block_size);
639 memset(buffer_.get(), 0,
sizeof(*buffer_.get()) * block_size);
643 FreeBlocks(free_blocks_);
645 const addrval<T>& Back()
const {
657 buffer_used_ =
false;
658 }
else if (blocks_ !=
nullptr) {
659 packer_->Unpack(blocks_->compressed, data_.get());
667 void PushBack(
const addrval<T>& addr_val) {
671 packer_->Pack(buffer_.get(), &blocks_->compressed);
684 int64_t size()
const {
return size_; }
692 void FreeTopBlock() {
693 Block* block = blocks_;
694 blocks_ = block->next;
695 block->compressed.clear();
696 block->next = free_blocks_;
697 free_blocks_ = block;
700 Block* block =
nullptr;
701 if (free_blocks_ !=
nullptr) {
702 block = free_blocks_;
703 free_blocks_ = block->next;
707 block->next = blocks_;
710 void FreeBlocks(Block* blocks) {
711 while (
nullptr != blocks) {
712 Block*
next = blocks->next;
718 std::unique_ptr<TrailPacker<T>> packer_;
719 const int block_size_;
722 std::unique_ptr<addrval<T>[]> data_;
723 std::unique_ptr<addrval<T>[]> buffer_;
756 ConstraintSolverParameters::TrailCompression compression_level)
757 :
rev_ints_(block_size, compression_level),
761 rev_ptrs_(block_size, compression_level) {}
764 int target = m->rev_int_index_;
765 for (
int curr =
rev_ints_.size(); curr > target; --curr) {
766 const addrval<int>& cell =
rev_ints_.Back();
772 target = m->rev_int64_index_;
773 for (
int curr =
rev_int64s_.size(); curr > target; --curr) {
780 target = m->rev_uint64_index_;
781 for (
int curr =
rev_uint64s_.size(); curr > target; --curr) {
788 target = m->rev_double_index_;
789 for (
int curr =
rev_doubles_.size(); curr > target; --curr) {
796 target = m->rev_ptr_index_;
797 for (
int curr =
rev_ptrs_.size(); curr > target; --curr) {
798 const addrval<void*>& cell =
rev_ptrs_.Back();
804 target = m->rev_boolvar_list_index_;
812 target = m->rev_bools_index_;
813 for (
int curr =
rev_bools_.size() - 1; curr >= target; --curr) {
819 target = m->rev_int_memory_index_;
825 target = m->rev_int64_memory_index_;
831 target = m->rev_double_memory_index_;
837 target = m->rev_object_memory_index_;
843 target = m->rev_object_array_memory_index_;
850 target = m->rev_memory_index_;
851 for (
int curr =
rev_memory_.size() - 1; curr >= target; --curr) {
853 ::operator
delete(
reinterpret_cast<char*
>(
rev_memory_[curr]));
862 target = m->rev_memory_array_index_;
871 void Solver::InternalSaveValue(
int* valptr) {
872 trail_->rev_ints_.PushBack(addrval<int>(valptr));
875 void Solver::InternalSaveValue(int64_t* valptr) {
876 trail_->rev_int64s_.PushBack(addrval<int64_t>(valptr));
879 void Solver::InternalSaveValue(uint64_t* valptr) {
880 trail_->rev_uint64s_.PushBack(addrval<uint64_t>(valptr));
883 void Solver::InternalSaveValue(
double* valptr) {
884 trail_->rev_doubles_.PushBack(addrval<double>(valptr));
887 void Solver::InternalSaveValue(
void** valptr) {
888 trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
894 void Solver::InternalSaveValue(
bool* valptr) {
895 trail_->rev_bools_.push_back(valptr);
896 trail_->rev_bool_value_.push_back(*valptr);
899 BaseObject* Solver::SafeRevAlloc(BaseObject* ptr) {
901 trail_->rev_object_memory_.push_back(ptr);
905 int* Solver::SafeRevAllocArray(
int* ptr) {
907 trail_->rev_int_memory_.push_back(ptr);
911 int64_t* Solver::SafeRevAllocArray(int64_t* ptr) {
913 trail_->rev_int64_memory_.push_back(ptr);
917 double* Solver::SafeRevAllocArray(
double* ptr) {
919 trail_->rev_double_memory_.push_back(ptr);
923 uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) {
925 trail_->rev_int64_memory_.push_back(
reinterpret_cast<int64_t*
>(ptr));
929 BaseObject** Solver::SafeRevAllocArray(BaseObject** ptr) {
931 trail_->rev_object_array_memory_.push_back(ptr);
935 IntVar** Solver::SafeRevAllocArray(IntVar** ptr) {
936 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
937 return reinterpret_cast<IntVar**
>(in);
940 IntExpr** Solver::SafeRevAllocArray(IntExpr** ptr) {
941 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
942 return reinterpret_cast<IntExpr**
>(in);
945 Constraint** Solver::SafeRevAllocArray(Constraint** ptr) {
946 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
950 void* Solver::UnsafeRevAllocAux(
void* ptr) {
952 trail_->rev_memory_.push_back(ptr);
956 void** Solver::UnsafeRevAllocArrayAux(
void** ptr) {
958 trail_->rev_memory_array_.push_back(ptr);
963 solver->trail_->rev_boolvar_list_.push_back(
var);
973 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
975 solution_counter_(0),
976 unchecked_solution_counter_(0),
977 decision_builder_(nullptr),
978 created_by_solve_(false),
980 left_search_depth_(0),
981 should_restart_(false),
982 should_finish_(false),
984 jmpbuf_filled_(false),
985 backtrack_at_the_end_of_the_search_(true) {}
993 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
995 solution_counter_(0),
996 unchecked_solution_counter_(0),
997 decision_builder_(nullptr),
998 created_by_solve_(false),
1000 left_search_depth_(-1),
1001 should_restart_(false),
1002 should_finish_(false),
1003 sentinel_pushed_(0),
1004 jmpbuf_filled_(false),
1005 backtrack_at_the_end_of_the_search_(true) {}
1033 if (monitor !=
nullptr) {
1034 monitor_event_listeners_[to_underlying(event)].push_back(monitor);
1039 return monitor_event_listeners_[to_underlying(event)];
1046 return unchecked_solution_counter_;
1049 decision_builder_ = db;
1058 left_search_depth_++;
1062 return backtrack_at_the_end_of_the_search_;
1065 backtrack_at_the_end_of_the_search_ = restore;
1076 if (should_finish_ || should_restart_) {
1089 void ClearBuffer() {
1090 CHECK(jmpbuf_filled_) <<
"Internal error in backtracking";
1091 jmpbuf_filled_ =
false;
1095 std::vector<StateMarker*> marker_stack_;
1096 std::vector<std::vector<SearchMonitor*>> monitor_event_listeners_;
1097 jmp_buf fail_buffer_;
1098 int64_t solution_counter_;
1099 int64_t unchecked_solution_counter_;
1101 bool created_by_solve_;
1104 int left_search_depth_;
1105 bool should_restart_;
1106 bool should_finish_;
1107 int sentinel_pushed_;
1108 bool jmpbuf_filled_;
1109 bool backtrack_at_the_end_of_the_search_;
1110 std::string search_context_;
1123 #ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK
1126 #define CP_TRY(search) \
1127 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1128 search->jmpbuf_filled_ = true; \
1129 if (setjmp(search->fail_buffer_) == 0)
1130 #define CP_ON_FAIL else
1131 #define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1)
1133 class FailException {};
1134 #define CP_TRY(search) \
1135 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1136 search->jmpbuf_filled_ = true; \
1138 #define CP_ON_FAIL catch (FailException&)
1139 #define CP_DO_FAIL(search) throw FailException()
1142 void Search::JumpBack() {
1143 if (jmpbuf_filled_) {
1144 jmpbuf_filled_ =
false;
1147 std::string explanation =
"Failure outside of search";
1159 ~ApplyBranchSelector()
override {}
1161 Decision* Next(Solver*
const s)
override {
1166 std::string DebugString()
const override {
return "Apply(BranchSelector)"; }
1174 selector_ = std::move(bs);
1183 [solve_depth](
Solver* s) {
1185 s->ActiveSearch()->SetBranchSelector(nullptr);
1189 searches_.back()->SetBranchSelector(std::move(bs));
1193 return RevAlloc(
new ApplyBranchSelector(std::move(bs)));
1203 return searches_.back()->left_search_depth();
1207 if (selector_ !=
nullptr) {
1214 for (
auto& listeners : monitor_event_listeners_) listeners.clear();
1216 left_search_depth_ = 0;
1217 selector_ =
nullptr;
1218 backtrack_at_the_end_of_the_search_ =
true;
1221 #define CALL_EVENT_LISTENERS(Event) \
1223 ForAll(GetEventListeners(Solver::MonitorEvent::k##Event), \
1224 &SearchMonitor::Event); \
1231 solution_counter_ = 0;
1232 unchecked_solution_counter_ = 0;
1290 if (!monitor->AcceptSolution()) {
1301 bool should_continue =
false;
1304 if (monitor->AtSolution()) {
1308 should_continue =
true;
1311 return should_continue;
1317 bool at_local_optimum =
false;
1320 if (monitor->LocalOptimum()) {
1321 at_local_optimum =
true;
1324 return at_local_optimum;
1331 if (!monitor->AcceptDelta(
delta, deltadelta)) {
1347 if (monitor->IsUncheckedSolutionLimitReached()) {
1360 progress =
std::max(progress, monitor->ProgressPercent());
1368 if (decision_builder_ !=
nullptr) {
1369 decision_builder_->
Accept(visitor);
1373 #undef CALL_EVENT_LISTENERS
1394 class FailDecision :
public Decision {
1396 void Apply(Solver*
const s)
override { s->Fail(); }
1397 void Refute(Solver*
const s)
override { s->Fail(); }
1402 class BalancingDecision :
public Decision {
1404 ~BalancingDecision()
override {}
1405 void Apply(Solver*
const )
override {}
1406 void Refute(Solver*
const )
override {}
1417 enum SentinelMarker {
1418 INITIAL_SEARCH_SENTINEL = 10000000,
1419 ROOT_NODE_SENTINEL = 20000000,
1420 SOLVER_CTOR_SENTINEL = 40000000
1424 extern PropagationMonitor*
BuildTrace(Solver*
const s);
1431 void CheckSolverParameters(
const ConstraintSolverParameters&
parameters) {
1433 <<
"Were parameters built using Solver::DefaultSolverParameters() ?";
1438 const ConstraintSolverParameters&
parameters)
1443 use_fast_local_search_(true),
1450 parameters_(DefaultSolverParameters()),
1453 use_fast_local_search_(true),
1458 void Solver::Init() {
1459 CheckSolverParameters(parameters_);
1460 queue_ = std::make_unique<Queue>(
this);
1461 trail_ = std::make_unique<Trail>(parameters_.trail_block_size(),
1462 parameters_.compress_trail());
1468 filtered_neighbors_ = 0;
1469 accepted_neighbors_ = 0;
1470 optimization_direction_ =
NOT_SET;
1471 timer_ = std::make_unique<ClockTimer>();
1472 searches_.assign(1,
new Search(
this, 0));
1473 fail_stamp_ = uint64_t{1};
1474 balancing_decision_ = std::make_unique<BalancingDecision>();
1475 fail_intercept_ =
nullptr;
1476 true_constraint_ =
nullptr;
1477 false_constraint_ =
nullptr;
1478 fail_decision_ = std::make_unique<FailDecision>();
1479 constraint_index_ = 0;
1480 additional_constraint_index_ = 0;
1482 propagation_monitor_.reset(
BuildTrace(
this));
1484 print_trace_ =
nullptr;
1485 anonymous_variable_index_ = 0;
1486 should_fail_ =
false;
1491 searches_.push_back(
new Search(
this));
1492 PushSentinel(SOLVER_CTOR_SENTINEL);
1493 InitCachedIntConstants();
1494 InitCachedConstraint();
1499 reinterpret_cast<LocalSearchMonitor*
>(local_search_profiler_));
1504 CHECK_EQ(2, searches_.size());
1505 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1512 DCHECK_EQ(info.
int_info, SOLVER_CTOR_SENTINEL);
1519 std::string out =
"Solver(name = \"" + name_ +
"\", state = ";
1522 out +=
"OUTSIDE_SEARCH";
1525 out +=
"IN_ROOT_NODE";
1531 out +=
"AT_SOLUTION";
1534 out +=
"NO_MORE_SOLUTIONS";
1537 out +=
"PROBLEM_INFEASIBLE";
1540 absl::StrAppendFormat(
1542 ", branches = %d, fails = %d, decisions = %d, delayed demon runs = %d, "
1543 "var demon runs = %d, normal demon runs = %d, Run time = %d ms)",
1552 return absl::ToInt64Milliseconds(timer_->GetDuration());
1556 return absl::FromUnixSeconds(0) + timer_->GetDuration();
1567 void Solver::IncrementUncheckedSolutionCounter() {
1571 bool Solver::IsUncheckedSolutionLimitReached() {
1580 ConstraintSolverStatistics stats;
1581 stats.set_num_branches(
branches());
1582 stats.set_num_failures(
failures());
1585 stats.set_duration_seconds(absl::ToDoubleSeconds(timer_->GetDuration()));
1603 m->rev_int_index_ = trail_->rev_ints_.size();
1604 m->rev_int64_index_ = trail_->rev_int64s_.size();
1605 m->rev_uint64_index_ = trail_->rev_uint64s_.size();
1606 m->rev_double_index_ = trail_->rev_doubles_.size();
1607 m->rev_ptr_index_ = trail_->rev_ptrs_.size();
1608 m->rev_boolvar_list_index_ = trail_->rev_boolvar_list_.size();
1609 m->rev_bools_index_ = trail_->rev_bools_.size();
1610 m->rev_int_memory_index_ = trail_->rev_int_memory_.size();
1611 m->rev_int64_memory_index_ = trail_->rev_int64_memory_.size();
1612 m->rev_double_memory_index_ = trail_->rev_double_memory_.size();
1613 m->rev_object_memory_index_ = trail_->rev_object_memory_.size();
1614 m->rev_object_array_memory_index_ = trail_->rev_object_array_memory_.size();
1615 m->rev_memory_index_ = trail_->rev_memory_.size();
1616 m->rev_memory_array_index_ = trail_->rev_memory_array_.size();
1618 searches_.back()->marker_stack_.push_back(m);
1619 queue_->increase_stamp();
1628 CHECK(!searches_.back()->marker_stack_.empty())
1629 <<
"PopState() on an empty stack";
1630 CHECK(info !=
nullptr);
1631 StateMarker*
const m = searches_.back()->marker_stack_.back();
1633 trail_->BacktrackTo(m);
1637 searches_.back()->marker_stack_.pop_back();
1639 queue_->increase_stamp();
1643 void Solver::check_alloc_state() {
1652 LOG(FATAL) <<
"allocating at a leaf node";
1654 LOG(FATAL) <<
"This switch was supposed to be exhaustive, but it is not!";
1658 void Solver::FreezeQueue() { queue_->Freeze(); }
1660 void Solver::UnfreezeQueue() { queue_->Unfreeze(); }
1662 void Solver::EnqueueVar(Demon*
const d) { queue_->EnqueueVar(d); }
1664 void Solver::EnqueueDelayedDemon(Demon*
const d) {
1665 queue_->EnqueueDelayedDemon(d);
1668 void Solver::ExecuteAll(
const SimpleRevFIFO<Demon*>& demons) {
1669 queue_->ExecuteAll(demons);
1672 void Solver::EnqueueAll(
const SimpleRevFIFO<Demon*>& demons) {
1673 queue_->EnqueueAll(demons);
1680 void Solver::set_action_on_fail(Action
a) {
1681 queue_->set_action_on_fail(std::move(
a));
1684 void Solver::set_variable_to_clean_on_fail(IntVar* v) {
1685 queue_->set_variable_to_clean_on_fail(v);
1688 void Solver::reset_action_on_fail() { queue_->reset_action_on_fail(); }
1691 DCHECK(c !=
nullptr);
1692 if (c == true_constraint_) {
1696 queue_->AddConstraint(c);
1698 DCHECK_GE(constraint_index_, 0);
1699 DCHECK_LE(constraint_index_, constraints_list_.size());
1700 const int constraint_parent =
1701 constraint_index_ == constraints_list_.size()
1702 ? additional_constraints_parent_list_[additional_constraint_index_]
1703 : constraint_index_;
1704 additional_constraints_list_.push_back(c);
1705 additional_constraints_parent_list_.push_back(constraint_parent);
1707 if (parameters_.print_added_constraints()) {
1710 constraints_list_.push_back(c);
1716 if (constraint !=
nullptr) {
1718 cast_constraints_.insert(constraint);
1719 cast_information_[target_var] =
1732 void Solver::ProcessConstraints() {
1735 if (parameters_.print_model()) {
1739 if (parameters_.print_model_stats()) {
1744 if (parameters_.disable_solve()) {
1745 LOG(INFO) <<
"Forcing early failure";
1750 const int constraints_size = constraints_list_.size();
1751 additional_constraints_list_.clear();
1752 additional_constraints_parent_list_.clear();
1754 for (constraint_index_ = 0; constraint_index_ < constraints_size;
1755 ++constraint_index_) {
1756 Constraint*
const constraint = constraints_list_[constraint_index_];
1757 propagation_monitor_->BeginConstraintInitialPropagation(constraint);
1758 constraint->PostAndPropagate();
1759 propagation_monitor_->EndConstraintInitialPropagation(constraint);
1761 CHECK_EQ(constraints_list_.size(), constraints_size);
1764 for (
int additional_constraint_index_ = 0;
1765 additional_constraint_index_ < additional_constraints_list_.size();
1766 ++additional_constraint_index_) {
1768 additional_constraints_list_[additional_constraint_index_];
1769 const int parent_index =
1770 additional_constraints_parent_list_[additional_constraint_index_];
1771 Constraint*
const parent = constraints_list_[parent_index];
1772 propagation_monitor_->BeginNestedConstraintInitialPropagation(parent,
1774 nested->PostAndPropagate();
1775 propagation_monitor_->EndNestedConstraintInitialPropagation(parent, nested);
1781 DCHECK(searches_.back() !=
nullptr);
1782 return searches_.back()->created_by_solve();
1786 std::vector<SearchMonitor*> monitors;
1787 monitors.push_back(m1);
1788 return Solve(db, monitors);
1792 std::vector<SearchMonitor*> monitors;
1793 return Solve(db, monitors);
1798 std::vector<SearchMonitor*> monitors;
1799 monitors.push_back(m1);
1800 monitors.push_back(m2);
1801 return Solve(db, monitors);
1806 std::vector<SearchMonitor*> monitors;
1807 monitors.push_back(m1);
1808 monitors.push_back(m2);
1809 monitors.push_back(m3);
1810 return Solve(db, monitors);
1816 std::vector<SearchMonitor*> monitors;
1817 monitors.push_back(m1);
1818 monitors.push_back(m2);
1819 monitors.push_back(m3);
1820 monitors.push_back(m4);
1821 return Solve(db, monitors);
1825 const std::vector<SearchMonitor*>& monitors) {
1827 searches_.back()->set_created_by_solve(
true);
1829 const bool solution_found = searches_.back()->solution_counter() > 0;
1831 return solution_found;
1835 std::vector<SearchMonitor*> monitors;
1836 monitors.push_back(m1);
1841 std::vector<SearchMonitor*> monitors;
1847 std::vector<SearchMonitor*> monitors;
1848 monitors.push_back(m1);
1849 monitors.push_back(m2);
1855 std::vector<SearchMonitor*> monitors;
1856 monitors.push_back(m1);
1857 monitors.push_back(m2);
1858 monitors.push_back(m3);
1865 std::vector<SearchMonitor*> monitors;
1866 monitors.push_back(m1);
1867 monitors.push_back(m2);
1868 monitors.push_back(m3);
1869 monitors.push_back(m4);
1877 const std::vector<SearchMonitor*>& monitors) {
1880 CHECK(db !=
nullptr);
1881 const bool nested = state_ ==
IN_SEARCH;
1884 LOG(FATAL) <<
"Cannot start new searches here.";
1887 Search*
const search = nested ?
new Search(
this) : searches_.back();
1894 DCHECK_GE(searches_.size(), 2);
1895 searches_.push_back(search);
1899 DCHECK_EQ(2, searches_.size());
1901 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1908 propagation_monitor_->Install();
1909 if (demon_profiler_ !=
nullptr) {
1912 local_search_monitor_->Install();
1913 if (local_search_profiler_ !=
nullptr) {
1919 if (monitor !=
nullptr) {
1923 std::vector<SearchMonitor*> extras;
1926 if (monitor !=
nullptr) {
1933 if (print_trace_ !=
nullptr) {
1937 print_trace_ =
nullptr;
1938 if (parameters_.trace_propagation()) {
1941 }
else if (parameters_.trace_search()) {
1956 PushSentinel(INITIAL_SEARCH_SENTINEL);
1962 bool Solver::BacktrackOneLevel(
Decision**
const fail_decision) {
1963 bool no_more_solutions =
false;
1964 bool end_loop =
false;
1970 CHECK_EQ(info.
ptr_info,
this) <<
"Wrong sentinel found";
1973 searches_.back()->sentinel_pushed_--;
1974 no_more_solutions =
true;
1978 LOG(ERROR) <<
"Simple markers should not be encountered during search";
1984 searches_.back()->set_search_depth(info.
depth);
1985 searches_.back()->set_search_left_depth(info.
left_depth);
1996 Search*
const search = searches_.back();
1999 if (no_more_solutions) {
2000 search->NoMoreSolutions();
2002 return no_more_solutions;
2005 void Solver::PushSentinel(
int magic_code) {
2006 StateInfo info(
this, magic_code);
2009 if (magic_code != SOLVER_CTOR_SENTINEL) {
2010 searches_.back()->sentinel_pushed_++;
2012 const int pushed = searches_.back()->sentinel_pushed_;
2013 DCHECK((magic_code == SOLVER_CTOR_SENTINEL) ||
2014 (magic_code == INITIAL_SEARCH_SENTINEL && pushed == 1) ||
2015 (magic_code == ROOT_NODE_SENTINEL && pushed == 2));
2019 Search*
const search = searches_.back();
2020 CHECK_NE(0, search->sentinel_pushed_);
2022 if (search->sentinel_pushed_ > 1) {
2023 BacktrackToSentinel(ROOT_NODE_SENTINEL);
2025 CHECK_EQ(1, search->sentinel_pushed_);
2026 PushSentinel(ROOT_NODE_SENTINEL);
2030 if (search->sentinel_pushed_ > 0) {
2031 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2033 CHECK_EQ(0, search->sentinel_pushed_);
2034 PushSentinel(INITIAL_SEARCH_SENTINEL);
2042 void Solver::BacktrackToSentinel(
int magic_code) {
2043 Search*
const search = searches_.back();
2044 bool end_loop = search->sentinel_pushed_ == 0;
2050 CHECK_EQ(info.
ptr_info,
this) <<
"Wrong sentinel found";
2051 CHECK_GE(--search->sentinel_pushed_, 0);
2074 void Solver::JumpToSentinelWhenNested() {
2075 CHECK_GT(
SolveDepth(), 1) <<
"calling JumpToSentinel from top level";
2076 Search* c = searches_.back();
2077 Search* p = ParentSearch();
2079 while (!c->marker_stack_.empty()) {
2080 StateMarker*
const m = c->marker_stack_.back();
2082 p->marker_stack_.push_back(m);
2085 CHECK_EQ(c->marker_stack_.size(), 1) <<
"Sentinel found too early";
2090 c->marker_stack_.pop_back();
2092 c->set_search_depth(0);
2093 c->set_search_left_depth(0);
2094 CHECK_EQ(found,
true) <<
"Sentinel not found";
2098 class ReverseDecision :
public Decision {
2100 explicit ReverseDecision(Decision*
const d) : decision_(d) {
2101 CHECK(d !=
nullptr);
2103 ~ReverseDecision()
override {}
2105 void Apply(Solver*
const s)
override { decision_->Refute(s); }
2107 void Refute(Solver*
const s)
override { decision_->Apply(s); }
2109 void Accept(DecisionVisitor*
const visitor)
const override {
2110 decision_->Accept(visitor);
2113 std::string DebugString()
const override {
2114 std::string str =
"Reverse(";
2115 str += decision_->DebugString();
2121 Decision*
const decision_;
2127 Search*
const search = searches_.back();
2130 const bool top_level = solve_depth <= 1;
2133 LOG(WARNING) <<
"NextSolution() called without a NewSearch before";
2144 if (BacktrackOneLevel(&fd)) {
2155 ProcessConstraints();
2157 PushSentinel(ROOT_NODE_SENTINEL);
2159 search->ClearBuffer();
2162 queue_->AfterFailure();
2163 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2172 LOG(FATAL) <<
"Should not happen";
2177 volatile bool finish =
false;
2178 volatile bool result =
false;
2183 if (fd !=
nullptr) {
2202 if (d == fail_decision_.get()) {
2207 switch (modification) {
2209 d =
RevAlloc(
new ReverseDecision(d));
2211 ABSL_FALLTHROUGH_INTENDED;
2261 queue_->AfterFailure();
2264 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2265 : INITIAL_SEARCH_SENTINEL);
2273 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2274 : INITIAL_SEARCH_SENTINEL);
2277 PushSentinel(top_level ? ROOT_NODE_SENTINEL : INITIAL_SEARCH_SENTINEL);
2280 if (BacktrackOneLevel(&fd)) {
2288 search->ClearBuffer();
2297 Search*
const search = searches_.back();
2299 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2301 CHECK_GT(searches_.size(), 2);
2302 if (search->sentinel_pushed_ > 0) {
2303 JumpToSentinelWhenNested();
2308 if (2 == searches_.size()) {
2312 if (!parameters_.profile_file().empty()) {
2313 const std::string& file_name = parameters_.profile_file();
2314 LOG(INFO) <<
"Exporting profile to " << file_name;
2317 if (parameters_.print_local_search_profile()) {
2319 if (!profile.empty()) LOG(INFO) << profile;
2323 searches_.pop_back();
2330 LOG(FATAL) <<
"CheckAssignment is only available at the top level.";
2333 Search*
const search = searches_.back();
2336 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2344 DCHECK_EQ(2, searches_.size());
2345 PushSentinel(INITIAL_SEARCH_SENTINEL);
2350 restore->
Next(
this);
2351 ProcessConstraints();
2353 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2354 search->ClearBuffer();
2360 constraint_index_ < constraints_list_.size()
2362 : additional_constraints_parent_list_[additional_constraint_index_];
2364 if (
ct->name().empty()) {
2365 LOG(INFO) <<
"Failing constraint = " <<
ct->DebugString();
2367 LOG(INFO) <<
"Failing constraint = " <<
ct->name() <<
":"
2368 <<
ct->DebugString();
2370 queue_->AfterFailure();
2371 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2380 explicit AddConstraintDecisionBuilder(
Constraint*
const ct)
2382 CHECK(
ct !=
nullptr);
2385 ~AddConstraintDecisionBuilder()
override {}
2387 Decision* Next(Solver*
const solver)
override {
2388 solver->AddConstraint(constraint_);
2392 std::string DebugString()
const override {
2393 return absl::StrFormat(
"AddConstraintDecisionBuilder(%s)",
2394 constraint_->DebugString());
2398 Constraint*
const constraint_;
2403 return RevAlloc(
new AddConstraintDecisionBuilder(
ct));
2412 std::vector<SearchMonitor*> monitors;
2413 monitors.push_back(m1);
2418 std::vector<SearchMonitor*> monitors;
2424 std::vector<SearchMonitor*> monitors;
2425 monitors.push_back(m1);
2426 monitors.push_back(m2);
2432 std::vector<SearchMonitor*> monitors;
2433 monitors.push_back(m1);
2434 monitors.push_back(m2);
2435 monitors.push_back(m3);
2440 const std::vector<SearchMonitor*>& monitors) {
2442 searches_.back()->set_created_by_solve(
true);
2443 searches_.back()->set_backtrack_at_the_end_of_the_search(
false);
2445 const bool solution_found = searches_.back()->solution_counter() > 0;
2447 return solution_found;
2451 if (fail_intercept_) {
2457 searches_.back()->BeginFail();
2458 searches_.back()->JumpBack();
2462 searches_.back()->set_should_finish(
true);
2466 searches_.back()->set_should_restart(
true);
2474 if (cast_info !=
nullptr) {
2484 if (
name !=
nullptr) {
2487 const IntegerCastInfo*
const cast_info =
2489 if (cast_info !=
nullptr && cast_info->expression !=
nullptr) {
2490 if (cast_info->expression->HasName()) {
2491 return absl::StrFormat(
"Var<%s>", cast_info->expression->name());
2492 }
else if (parameters_.name_cast_variables()) {
2493 return absl::StrFormat(
"Var<%s>", cast_info->expression->DebugString());
2495 const std::string new_name =
2496 absl::StrFormat(
"CastVar<%d>", anonymous_variable_index_++);
2497 propagation_object_names_[object] = new_name;
2501 const std::string base_name =
object->BaseName();
2502 if (parameters_.name_all_variables() && !base_name.empty()) {
2503 const std::string new_name =
2504 absl::StrFormat(
"%s_%d", base_name, anonymous_variable_index_++);
2505 propagation_object_names_[object] = new_name;
2511 void Solver::SetName(
const PropagationBaseObject*
object,
2512 const std::string&
name) {
2513 if (parameters_.store_names() &&
2514 GetName(
object) !=
name) {
2515 propagation_object_names_[object] =
name;
2520 return propagation_object_names_.contains(
2522 (!
object->BaseName().empty() && parameters_.name_all_variables());
2540 return solver_->GetName(
this);
2544 solver_->SetName(
this,
name);
2552 solver_->ExecuteAll(demons);
2556 solver_->EnqueueAll(demons);
2568 Solver*
const , std::vector<SearchMonitor*>*
const ) {}
2664 "ScalarProductGreaterOrEqual";
2692 "VariableUsageLessConstant";
2694 "WeightedSumOfAssignedEqualVariable";
2791 if (delegate !=
nullptr) {
2797 const std::string& operation,
2799 if (delegate !=
nullptr) {
2805 const std::string& operation,
2808 if (delegate !=
nullptr) {
2814 for (
int i = 0; i < variable->
size(); ++i) {
2823 const std::string& arg_name,
const std::vector<int64_t>& values) {}
2837 const std::string& arg_name,
const std::vector<IntVar*>& arguments) {
2847 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
2857 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
2865 int64_t index_max) {
2866 if (filter !=
nullptr) {
2867 std::vector<int64_t> cached_results;
2868 for (
int i = index_min; i <= index_max; ++i) {
2869 cached_results.push_back(filter(i));
2881 CHECK(eval !=
nullptr);
2882 std::vector<int64_t> cached_results;
2883 for (
int i = index_min; i <= index_max; ++i) {
2884 cached_results.push_back(eval(i));
2894 const std::string& arg_name,
2895 int64_t index_max) {
2896 CHECK(eval !=
nullptr);
2897 std::vector<int64_t> cached_results;
2898 for (
int i = 0; i <= index_max; ++i) {
2899 cached_results.push_back(eval(i));
2932 for (std::underlying_type<Solver::MonitorEvent>::type event = 0;
2939 solver()->searches_.back()->AddEventListener(event,
this);
3031 monitor->SetMin(expr, new_min);
3037 monitor->SetMax(expr, new_max);
3042 int64_t new_max)
override {
3044 monitor->SetRange(expr, new_min, new_max);
3051 monitor->SetMin(
var, new_min);
3057 monitor->SetMax(
var, new_max);
3063 monitor->SetRange(
var, new_min, new_max);
3080 const std::vector<int64_t>& values)
override {
3085 const std::vector<int64_t>& values)
override {
3099 int64_t new_max)
override {
3113 int64_t new_max)
override {
3126 int64_t new_max)
override {
3152 const std::vector<int>& rank_last,
3153 const std::vector<int>& unperformed)
override {
3155 rank_last, unperformed);
3160 if (monitor !=
nullptr) {
3161 monitors_.push_back(monitor);
3172 std::vector<PropagationMonitor*> monitors_;
3179 reinterpret_cast<class
Trace*
>(propagation_monitor_.get())->Add(monitor);
3183 return propagation_monitor_.get();
3206 neighbor_found,
delta, deltadelta);
3212 bool neighbor_found)
override {
3220 bool neighbor_found)
override {
3233 if (monitor !=
nullptr) {
3234 monitors_.push_back(monitor);
3243 return "LocalSearchMonitorPrimary";
3247 std::vector<LocalSearchMonitor*> monitors_;
3256 local_search_monitor_.get())
3261 return local_search_monitor_.get();
3265 const std::string& search_context) {
3278 if (local_search_state_ ==
nullptr) {
3279 local_search_state_ = std::make_unique<Assignment>(
this);
3281 return local_search_state_.get();
3287 : db_(db), name_(db_->GetName()), seconds_(0) {}
3297 seconds_ += timer_.Get();
3304 seconds_ += timer_.
Get();
3313 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {
3340 return solver()->cast_constraints_.contains(
this);
An Assignment is a variable -> domains mapping, used to report solutions to the user.
A BaseObject is the root of all reversibly allocated objects.
virtual std::string DebugString() const
Cast constraints are special channeling constraints designed to keep a variable in sync with an expre...
A constraint is the main modeling object.
void PostAndPropagate()
Calls Post and then Propagate to initialize the constraints.
bool IsCastConstraint() const
Is the constraint created by a cast from expression to integer variable?
virtual void InitialPropagate()=0
This method performs the initial propagation of the constraint.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
virtual IntVar * Var()
Creates a Boolean variable representing the status of the constraint (false = constraint is violated,...
std::string DebugString() const override
virtual void Post()=0
This method is called when the constraint is processed by the solver.
A DecisionBuilder is responsible for creating the search tree.
virtual Decision * Next(Solver *const s)=0
This is the main method of the decision builder class.
std::string GetName() const
virtual void Accept(ModelVisitor *const visitor) const
virtual void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras)
This method will be called at the start of the search.
std::string DebugString() const override
A Decision represents a choice point in the search tree.
virtual void Accept(DecisionVisitor *const visitor) const
Accepts the given visitor.
virtual void Apply(Solver *const s)=0
Apply will be called first when the decision is executed.
virtual void Refute(Solver *const s)=0
Refute will be called after a backtrack.
A DecisionVisitor is used to inspect a decision.
virtual void VisitSetVariableValue(IntVar *const var, int64_t value)
virtual void VisitSplitVariableDomain(IntVar *const var, int64_t value, bool start_with_lower_half)
virtual void VisitRankFirstInterval(SequenceVar *const sequence, int index)
virtual void VisitUnknownDecision()
virtual void VisitRankLastInterval(SequenceVar *const sequence, int index)
virtual void VisitScheduleOrPostpone(IntervalVar *const var, int64_t est)
virtual void VisitScheduleOrExpedite(IntervalVar *const var, int64_t est)
A Demon is the base element of a propagation queue.
void inhibit(Solver *const s)
This method inhibits the demon in the search tree below the current position.
void desinhibit(Solver *const s)
This method un-inhibits the demon that was previously inhibited.
virtual Solver::DemonPriority priority() const
This method returns the priority of the demon.
std::string DebugString() const override
virtual void Run(Solver *const s)=0
This is the main callback of the demon.
The class IntExpr is the base of all integer expressions in constraint programming.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
The class IntVar is a subset of IntExpr.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Interval variables are often used in scheduling.
virtual void Accept(ModelVisitor *const visitor) const =0
Accepts the given visitor.
Local Search Filters are used for fast neighbor pruning.
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
void Install() override
Install itself on the solver.
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void EndOperatorStart()=0
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual void BeginOperatorStart()=0
Local search operator events.
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
LocalSearchMonitor(Solver *const solver)
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
~LocalSearchMonitor() override
void BeginFiltering(const LocalSearchFilter *filter) override
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void BeginOperatorStart() override
Local search operator events.
void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta) override
void Add(LocalSearchMonitor *monitor)
LocalSearchMonitorPrimary(Solver *solver)
void BeginMakeNextNeighbor(const LocalSearchOperator *op) override
void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void BeginAcceptNeighbor(const LocalSearchOperator *op) override
void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void EndOperatorStart() override
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
void BeginFilterNeighbor(const LocalSearchOperator *op) override
std::string DebugString() const override
The base class for all local search operators.
static const char kDurationMinArgument[]
static const char kIntervalArgument[]
static const char kSolutionLimitArgument[]
static const char kSizeArgument[]
static const char kIsMember[]
static const char kCountUsedBinsExtension[]
static const char kIntervalVariable[]
static const char kObjectiveExtension[]
static const char kPower[]
static const char kEarlyDateArgument[]
static const char kMaximizeArgument[]
static const char kLateDateArgument[]
static const char kFinalStatesArgument[]
static const char kIndex2Argument[]
static const char kStartExpr[]
static const char kMinArgument[]
static const char kEndsArgument[]
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
static const char kSequenceVariable[]
static const char kDeviation[]
static const char kMirrorOperation[]
Operations.
static const char kAbs[]
Constraint and Expression types.
static const char kMember[]
static const char kDelayedPathCumul[]
virtual void VisitSequenceVariable(const SequenceVar *const variable)
static const char kVariableUsageLessConstantExtension[]
virtual void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate)
static const char kSumEqual[]
static const char kSortingConstraint[]
static const char kElementEqual[]
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 kPack[]
static const char kIsBetween[]
static const char kRangeArgument[]
static const char kLess[]
virtual void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate)
static const char kAtMost[]
static const char kDisjunctive[]
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
static const char kTargetArgument[]
static const char kActiveArgument[]
argument names:
static const char kRelaxedMaxOperation[]
void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, int64_t index_max)
Using SWIG on callbacks is troublesome, so we hide these methods during the wrapping.
static const char kSequenceArgument[]
static const char kAbsEqual[]
static const char kTimeLimitArgument[]
static const char kIntegerVariable[]
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
static const char kNullIntersect[]
virtual void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument)
Visit interval argument.
static const char kConvexPiecewise[]
static const char kBranchesLimitArgument[]
static const char kMaxArgument[]
static const char kModulo[]
static const char kCapacityArgument[]
static const char kProductOperation[]
static const char kBetween[]
static const char kIntervalsArgument[]
static const char kIntervalUnaryRelation[]
static const char kScalProd[]
static const char kTrueConstraint[]
static const char kOpposite[]
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
static const char kEvaluatorArgument[]
static const char kPositionXArgument[]
static const char kCumulsArgument[]
static const char kCircuit[]
static const char kWeightedSumOfAssignedEqualVariableExtension[]
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kRelaxedMinOperation[]
static const char kMapDomain[]
static const char kLessOrEqual[]
static const char kSizeXArgument[]
static const char kModuloArgument[]
static const char kEndMaxArgument[]
static const char kSmartTimeCheckArgument[]
static const char kValueArgument[]
static const char kIntervalDisjunction[]
static const char kDemandsArgument[]
static const char kTraceOperation[]
static const char kLightElementEqual[]
static const char kSemiContinuous[]
static const char kIsGreater[]
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint)
static const char kRelationArgument[]
static const char kEarlyCostArgument[]
static const char kVarValueWatcher[]
static const char kDurationExpr[]
static const char kIsDifferent[]
static const char kGreaterOrEqual[]
static const char kLeftArgument[]
static const char kGlobalCardinality[]
static const char kLexLess[]
virtual void BeginVisitExtension(const std::string &type)
static const char kNextsArgument[]
static const char kTransitsArgument[]
static const char kTransition[]
static const char kStartSyncOnStartOperation[]
static const char kStartMinArgument[]
static const char kUsageLessConstantExtension[]
virtual void EndVisitExtension(const std::string &type)
static const char kCumulativeArgument[]
static const char kStepArgument[]
static const char kLateCostArgument[]
static const char kMaxEqual[]
static const char kSumLessOrEqual[]
static const char kTuplesArgument[]
static const char kCountArgument[]
static const char kUsageEqualVariableExtension[]
static const char kStartMaxArgument[]
static const char kAllowedAssignments[]
virtual void EndVisitModel(const std::string &type_name)
static const char kIsGreaterOrEqual[]
static const char kPathCumul[]
static const char kDifferenceOperation[]
static const char kVarsArgument[]
static const char kSumOperation[]
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
static const char kTrace[]
static const char kRightArgument[]
static const char kIsLess[]
static const char kIsLessOrEqual[]
static const char kVariableGroupExtension[]
static const char kIndexOf[]
static const char kEndExpr[]
static const char kNotMember[]
static const char kStartsArgument[]
static const char kElement[]
static const char kSizeYArgument[]
static const char kCountEqual[]
static const char kPartialArgument[]
static const char kExpressionArgument[]
static const char kDistribute[]
static const char kFailuresLimitArgument[]
static const char kScalProdGreaterOrEqual[]
static const char kPositionYArgument[]
static const char kVarBoundWatcher[]
virtual void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments)
static const char kDivide[]
static const char kInt64ToBoolExtension[]
static const char kIntervalBinaryRelation[]
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
static const char kCardsArgument[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument)
Visit integer expression argument.
static const char kNoCycle[]
static const char kGreater[]
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
static const char kCover[]
static const char kNotBetween[]
static const char kCoefficientsArgument[]
static const char kScalProdLessOrEqual[]
static const char kEndMinArgument[]
static const char kVariableArgument[]
static const char kValuesArgument[]
static const char kMinEqual[]
static const char kEquality[]
static const char kInt64ToInt64Extension[]
static const char kSequencesArgument[]
static const char kSumGreaterOrEqual[]
static const char kFixedChargeArgument[]
static const char kDurationMaxArgument[]
static const char kLinkExprVar[]
static const char kScalProdEqual[]
static const char kProduct[]
static const char kDifference[]
static const char kCumulative[]
static const char kAllDifferent[]
static const char kSquare[]
static const char kAssumePathsArgument[]
static const char kInitialState[]
static const char kNonEqual[]
static const char kConditionalExpr[]
static const char kIsEqual[]
static const char kStartSyncOnEndOperation[]
static const char kOptionalArgument[]
static const char kIndexArgument[]
static const char kFalseConstraint[]
static const char kPerformedExpr[]
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument)
Visit sequence argument.
static const char kSearchLimitExtension[]
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint)
static const char kInversePermutation[]
static const char kCountAssignedItemsExtension[]
Extension names:
ProfiledDecisionBuilder(DecisionBuilder *db)
void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras) override
This method will be called at the start of the search.
void Accept(ModelVisitor *const visitor) const override
Decision * Next(Solver *const solver) override
This is the main method of the decision builder class.
const std::string & name() const
std::string DebugString() const override
virtual std::string name() const
Object naming.
bool HasName() const
Returns whether the object has been named or not.
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void FreezeQueue()
This method freezes the propagation queue.
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string BaseName() const
Returns a base name for automatic naming.
void set_name(const std::string &name)
void UnfreezeQueue()
This method unfreezes the propagation queue.
std::string DebugString() const override
virtual void SetValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual void SetDurationMax(IntervalVar *const var, int64_t new_max)=0
virtual void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
void Install() override
Install itself on the solver.
virtual void RankLast(SequenceVar *const var, int index)=0
~PropagationMonitor() override
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
virtual void RemoveValue(IntVar *const var, int64_t value)=0
virtual void SetValue(IntVar *const var, int64_t value)=0
virtual void SetDurationMin(IntervalVar *const var, int64_t new_min)=0
virtual void SetStartMin(IntervalVar *const var, int64_t new_min)=0
IntervalVar modifiers.
virtual void RankNotLast(SequenceVar *const var, int index)=0
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void BeginDemonRun(Demon *const demon)=0
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
virtual void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void SetEndMax(IntervalVar *const var, int64_t new_max)=0
virtual void PushContext(const std::string &context)=0
virtual void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax)=0
virtual void SetEndMin(IntervalVar *const var, int64_t new_min)=0
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void SetPerformed(IntervalVar *const var, bool value)=0
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
virtual void SetStartMax(IntervalVar *const var, int64_t new_max)=0
virtual void EndDemonRun(Demon *const demon)=0
virtual void RegisterDemon(Demon *const demon)=0
PropagationMonitor(Solver *const solver)
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
virtual void PopContext()=0
virtual void RemoveValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
void EnqueueDelayedDemon(Demon *const demon)
void reset_action_on_fail()
static constexpr int64_t kTestPeriod
void set_action_on_fail(Solver::Action a)
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void EnqueueVar(Demon *const demon)
void AddConstraint(Constraint *const c)
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
void set_variable_to_clean_on_fail(IntVar *var)
void ProcessConstraints()
void ProcessOneDemon(Demon *const demon)
void RefuteDecision(Decision *const d)
void ApplyDecision(Decision *const d)
void BeginNextDecision(DecisionBuilder *const db)
bool should_restart() const
bool should_finish() const
Search(Solver *const s, int)
const std::vector< SearchMonitor * > & GetEventListeners(Solver::MonitorEvent event) const
std::string search_context() const
void IncrementUncheckedSolutionCounter()
void SetBranchSelector(Solver::BranchSelector bs)
int64_t unchecked_solution_counter() const
bool backtrack_at_the_end_of_the_search() const
void AfterDecision(Decision *const d, bool apply)
void BeginInitialPropagation()
void set_should_restart(bool s)
void set_backtrack_at_the_end_of_the_search(bool restore)
Solver::DecisionModification ModifyDecision()
void set_decision_builder(DecisionBuilder *const db)
void IncrementSolutionCounter()
void EndInitialPropagation()
void AcceptUncheckedNeighbor()
bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
bool created_by_solve() const
void Accept(ModelVisitor *const visitor) const
void set_search_depth(int d)
void set_search_left_depth(int d)
bool IsUncheckedSolutionLimitReached()
void set_should_finish(bool s)
DecisionBuilder * decision_builder() const
int64_t solution_counter() const
void EndNextDecision(DecisionBuilder *const db, Decision *const d)
void set_created_by_solve(bool c)
int left_search_depth() const
void AddEventListener(Solver::MonitorEvent event, SearchMonitor *monitor)
void set_search_context(const std::string &search_context)
A search monitor is a simple set of callbacks to monitor all search events.
virtual void RefuteDecision(Decision *const d)
Before refuting the decision.
virtual void ApplyDecision(Decision *const d)
Before applying the decision.
virtual void RestartSearch()
Restart the search.
virtual void ExitSearch()
End of the search.
virtual bool LocalOptimum()
When a local optimum is reached.
virtual void NoMoreSolutions()
When the search tree is finished.
virtual void BeginFail()
Just when the failure occurs.
void ListenToEvent(Solver::MonitorEvent event)
virtual void AfterDecision(Decision *const d, bool apply)
Just after refuting or applying the decision, apply is true after Apply.
virtual void BeginInitialPropagation()
Before the initial propagation.
virtual void BeginNextDecision(DecisionBuilder *const b)
Before calling DecisionBuilder::Next.
virtual void PeriodicCheck()
Periodic call to check limits in long running methods.
virtual void EnterSearch()
Beginning of the search.
virtual void EndNextDecision(DecisionBuilder *const b, Decision *const d)
After calling DecisionBuilder::Next, along with the returned decision.
virtual void EndFail()
After completing the backtrack.
virtual void EndInitialPropagation()
After the initial propagation.
static constexpr int kNoProgress
virtual void AcceptUncheckedNeighbor()
After accepting an unchecked neighbor during local search.
virtual bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
virtual bool AtSolution()
This method is called when a valid solution is found.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
virtual void AcceptNeighbor()
After accepting a neighbor during local search.
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
virtual bool AcceptSolution()
This method is called when a solution is found.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
IntervalVar * Interval(int index) const
Returns the index_th interval of the sequence.
int64_t size() const
Returns the number of interval vars in the sequence.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
This iterator is not stable with respect to deletion.
This class represent a reversible FIFO structure.
DecisionModification
The Solver is responsible for creating the search tree.
@ NO_CHANGE
Keeps the default behavior, i.e.
@ SWITCH_BRANCHES
Applies right branch first.
@ KEEP_RIGHT
Left branches are ignored.
@ KEEP_LEFT
Right branches are ignored.
@ KILL_BOTH
Backtracks to the previous decisions, i.e.
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
int64_t branches() const
The number of branches explored since the creation of the solver.
void RestartCurrentSearch()
bool SolveAndCommit(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
SolveAndCommit using a decision builder and up to three search monitors, usually one for the objectiv...
Constraint * MakeFalseConstraint()
This constraint always fails.
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
static constexpr int kNumPriorities
Number of priorities for demons.
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
@ NORMAL_PRIORITY
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
@ AT_SOLUTION
After successful NextSolution and before EndSearch.
@ PROBLEM_INFEASIBLE
After search, the model is infeasible.
@ OUTSIDE_SEARCH
Before search, after search.
@ IN_ROOT_NODE
Executing the root node.
@ NO_MORE_SOLUTIONS
After failed NextSolution and before EndSearch.
@ IN_SEARCH
Executing the search code.
std::string SearchContext() const
bool CheckAssignment(Assignment *const solution)
Checks whether the given assignment satisfies all relevant constraints.
absl::Time Now() const
The 'absolute time' as seen by the solver.
DecisionBuilder * MakeConstraintAdder(Constraint *const ct)
Returns a decision builder that will add the given constraint to the model.
Assignment * GetOrCreateLocalSearchState()
Returns (or creates) an assignment representing the state of local search.
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
void AddPropagationMonitor(PropagationMonitor *const monitor)
Adds the propagation monitor to the solver.
bool CheckConstraint(Constraint *const ct)
Checks whether adding this constraint will lead to an immediate failure.
void SetSearchContext(Search *search, const std::string &search_context)
void TopPeriodicCheck()
Performs PeriodicCheck on the top-level search; for instance, can be called from a nested solve to ch...
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
int64_t wall_time() const
DEPRECATED: Use Now() instead.
std::function< bool(int64_t)> IndexFilter1
int SearchDepth() const
Gets the search depth of the current active search.
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
Adds the local search monitor to the solver.
void PushState()
The PushState and PopState methods manipulates the states of the reversible objects.
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
std::string DebugString() const
!defined(SWIG)
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
int64_t failures() const
The number of failures encountered since the creation of the solver.
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
static int64_t MemoryUsage()
Current memory usage in bytes.
int SolveDepth() const
Gets the number of nested searches.
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
bool Solve(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
std::string model_name() const
Returns the name of the model.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
MonitorEvent
Search monitor events.
@ kIsUncheckedSolutionLimitReached
SearchMonitor * MakeSearchTrace(const std::string &prefix)
Creates a search monitor that will trace precisely the behavior of the search.
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
std::string LocalSearchProfile() const
Returns local search profiling information in a human readable format.
void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
int SearchLeftDepth() const
Gets the search left depth of the current active search.
void AddBacktrackAction(Action a, bool fast)
When SaveValue() is not the best way to go, one can create a reversible action that will be called up...
int TopProgressPercent()
Returns a percentage representing the propress of the search before reaching the limits of the top-le...
bool CurrentlyInSolve() const
Returns true whether the current search has been created using a Solve() call instead of a NewSearch ...
T * RevAlloc(T *object)
Registers the given object as being reversible.
Solver(const std::string &name)
Solver API.
uint64_t stamp() const
The stamp indicates how many moves in the search tree we have performed.
bool NameAllVariables() const
Returns whether all variables should be named.
IntExpr * CastExpression(const IntVar *const var) const
!defined(SWIG)
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
ModelVisitor * MakePrintModelVisitor()
Prints the model.
std::function< void(Solver *)> Action
void set_context(const std::string &context)
Sets the current context of the search.
void ExportProfilingOverview(const std::string &filename)
Exports the profiling information in a human readable overview.
MarkerType
This enum is used internally in private methods Solver::PushState and Solver::PopState to tag states ...
void AddCastConstraint(CastConstraint *const constraint, IntVar *const target_var, IntExpr *const expr)
Adds 'constraint' to the solver and marks it as a cast constraint, that is, a constraint created call...
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
std::function< DecisionModification()> BranchSelector
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())
Decision * MakeFailDecision()
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
int64_t solutions() const
The number of solutions found since the start of the search.
std::function< IntVar *(int64_t)> Int64ToIntVar
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
void NewSearch(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
void SetDurationMax(IntervalVar *const var, int64_t new_max) override
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void SetStartMax(IntervalVar *const var, int64_t new_max) override
void SetMin(IntVar *const var, int64_t new_min) override
IntVar modifiers.
void SetValue(IntVar *const var, int64_t value) override
void PopContext() override
void SetEndMax(IntervalVar *const var, int64_t new_max) override
void EndProcessingIntegerVariable(IntVar *const var) override
void SetStartMin(IntervalVar *const var, int64_t new_min) override
IntervalVar modifiers.
void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void SetMin(IntExpr *const expr, int64_t new_min) override
IntExpr modifiers.
void SetPerformed(IntervalVar *const var, bool value) override
void BeginConstraintInitialPropagation(Constraint *const constraint) override
Propagation events.
void SetRange(IntVar *const var, int64_t new_min, int64_t new_max) override
void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void EndConstraintInitialPropagation(Constraint *const constraint) override
void SetMax(IntVar *const var, int64_t new_max) override
void StartProcessingIntegerVariable(IntVar *const var) override
void RegisterDemon(Demon *const demon) override
void EndDemonRun(Demon *const demon) override
void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed) override
void BeginDemonRun(Demon *const demon) override
void SetDurationMin(IntervalVar *const var, int64_t new_min) override
void RankLast(SequenceVar *const var, int index) override
void PushContext(const std::string &context) override
void Add(PropagationMonitor *const monitor)
void RankNotLast(SequenceVar *const var, int index) override
void RemoveValues(IntVar *const var, const std::vector< int64_t > &values) override
void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void SetMax(IntExpr *const expr, int64_t new_max) override
void RemoveValue(IntVar *const var, int64_t value) override
void SetValues(IntVar *const var, const std::vector< int64_t > &values) override
void RankFirst(SequenceVar *const var, int index) override
SequenceVar modifiers.
void SetEndMin(IntervalVar *const var, int64_t new_min) override
void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max) override
std::string DebugString() const override
void RankNotFirst(SequenceVar *const var, int index) override
void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax) override
#define CP_DO_FAIL(search)
ABSL_FLAG(bool, cp_trace_propagation, false, "Trace propagation events (constraint and demon executions," " variable modifications).")
void ConstraintSolverFailsHere()
#define CALL_EVENT_LISTENERS(Event)
GurobiMPCallbackContext * context
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
void STLDeleteElements(T *container)
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Collection of objects used to extend the Constraint Solver library.
PropagationMonitor * BuildPrintTrace(Solver *const s)
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
void InstallDemonProfiler(DemonProfiler *const monitor)
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
void CleanVariableOnFail(IntVar *const var)
ModelCache * BuildModelCache(Solver *const solver)
int64_t GetProcessMemoryUsage()
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
LocalSearchMonitor * BuildLocalSearchMonitorPrimary(Solver *const s)
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
void RestoreBoolValue(IntVar *const var)
DemonProfiler * BuildDemonProfiler(Solver *const solver)
bool AcceptDelta(Search *const search, Assignment *delta, Assignment *deltadelta)
void AcceptNeighbor(Search *const search)
PropagationMonitor * BuildTrace(Solver *const s)
void DeleteDemonProfiler(DemonProfiler *const monitor)
bool LocalOptimumReached(Search *const search)
void AcceptUncheckedNeighbor(Search *const search)
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
BaseVariableAssignmentSelector *const selector_
Holds semantic information stating that the 'expression' has been cast into 'variable' using the Var(...
Solver::Action reversible_action
StateInfo(Solver::Action a, bool fast)
StateInfo(void *pinfo, int iinfo, int d, int ld)
StateInfo(void *pinfo, int iinfo)
StateMarker(Solver::MarkerType t, const StateInfo &info)
CompressedTrail< void * > rev_ptrs_
std::vector< double * > rev_double_memory_
std::vector< int64_t * > rev_int64_memory_
std::vector< int * > rev_int_memory_
std::vector< BaseObject * > rev_object_memory_
std::vector< IntVar * > rev_boolvar_list_
std::vector< void * > rev_memory_
Trail(int block_size, ConstraintSolverParameters::TrailCompression compression_level)
std::vector< bool > rev_bool_value_
void BacktrackTo(StateMarker *m)
std::vector< bool * > rev_bools_
std::vector< void ** > rev_memory_array_
CompressedTrail< int64_t > rev_int64s_
CompressedTrail< uint64_t > rev_uint64s_
CompressedTrail< double > rev_doubles_
std::vector< BaseObject ** > rev_object_array_memory_
CompressedTrail< int > rev_ints_
#define VLOG(verboselevel)