33#include "absl/flags/flag.h"
34#include "absl/log/check.h"
35#include "absl/time/time.h"
48 "Trace propagation events (constraint and demon executions,"
49 " variable modifications).");
50ABSL_FLAG(
bool, cp_trace_search,
false,
"Trace search events");
52 "show all constraints added to the solver.");
54 "use PrintModelVisitor on model before solving.");
56 "use StatisticsModelVisitor on model before solving.");
58 "Force failure at the beginning of a search.");
60 "Export profiling overview to file.");
61ABSL_FLAG(
bool, cp_print_local_search_profile,
false,
62 "Print local search profiling data after solving.");
63ABSL_FLAG(
bool, cp_name_variables,
false,
"Force all variables to have names.");
65 "Name variables casted from expressions");
67 "Use small compact table constraint when possible.");
69 "Use the O(n log n) cumulative edge finding algorithm described "
70 "in 'Edge Finding Filtering Algorithm for Discrete Cumulative "
71 "Resources in O(kn log n)' by Petr Vilim, CP 2009.");
73 "Use a O(n^2) cumulative time table propagation algorithm.");
74ABSL_FLAG(
bool, cp_use_cumulative_time_table_sync,
false,
75 "Use a synchronized O(n^2 log n) cumulative time table propagation "
77ABSL_FLAG(
bool, cp_use_sequence_high_demand_tasks,
true,
78 "Use a sequence constraints for cumulative tasks that have a "
79 "demand greater than half of the capacity of the resource.");
80ABSL_FLAG(
bool, cp_use_all_possible_disjunctions,
true,
81 "Post temporal disjunctions for all pairs of tasks sharing a "
82 "cumulative resource and that cannot overlap because the sum of "
83 "their demand exceeds the capacity.");
85 "Do not post the edge finder in the cumulative constraints if "
86 "it contains more than this number of tasks");
88 "Diffn constraint adds redundant cumulative constraint");
90 "If true, rmq's will be used in element expressions.");
92 "Number of solutions explored between two solution checks during "
95 "Random seed used in several (but not all) random number "
96 "generators used by the CP solver. Use -1 to auto-generate an"
97 "undeterministic random seed.");
102#pragma warning(disable : 4351 4355)
110template <
typename T,
typename MethodPointer,
typename... Args>
111void ForAll(
const std::vector<T*>& objects, MethodPointer method,
112 const Args&... args) {
113 for (T*
const object : objects) {
114 DCHECK(
object !=
nullptr);
115 (
object->*method)(args...);
121constexpr typename std::underlying_type<E>::type to_underlying(E e) {
122 return static_cast<typename std::underlying_type<E>::type
>(e);
130 ConstraintSolverParameters params;
131 params.set_compress_trail(ConstraintSolverParameters::NO_COMPRESSION);
132 params.set_trail_block_size(8000);
133 params.set_array_split_size(16);
134 params.set_store_names(
true);
135 params.set_profile_propagation(!absl::GetFlag(FLAGS_cp_profile_file).empty());
136 params.set_trace_propagation(absl::GetFlag(FLAGS_cp_trace_propagation));
137 params.set_trace_search(absl::GetFlag(FLAGS_cp_trace_search));
138 params.set_name_all_variables(absl::GetFlag(FLAGS_cp_name_variables));
139 params.set_profile_file(absl::GetFlag(FLAGS_cp_profile_file));
140 params.set_profile_local_search(
141 absl::GetFlag(FLAGS_cp_print_local_search_profile));
142 params.set_print_local_search_profile(
143 absl::GetFlag(FLAGS_cp_print_local_search_profile));
144 params.set_print_model(absl::GetFlag(FLAGS_cp_print_model));
145 params.set_print_model_stats(absl::GetFlag(FLAGS_cp_model_stats));
146 params.set_disable_solve(absl::GetFlag(FLAGS_cp_disable_solve));
147 params.set_name_cast_variables(absl::GetFlag(FLAGS_cp_name_cast_variables));
148 params.set_print_added_constraints(
149 absl::GetFlag(FLAGS_cp_print_added_constraints));
150 params.set_use_small_table(absl::GetFlag(FLAGS_cp_use_small_table));
151 params.set_use_cumulative_edge_finder(
152 absl::GetFlag(FLAGS_cp_use_cumulative_edge_finder));
153 params.set_use_cumulative_time_table(
154 absl::GetFlag(FLAGS_cp_use_cumulative_time_table));
155 params.set_use_cumulative_time_table_sync(
156 absl::GetFlag(FLAGS_cp_use_cumulative_time_table_sync));
157 params.set_use_sequence_high_demand_tasks(
158 absl::GetFlag(FLAGS_cp_use_sequence_high_demand_tasks));
159 params.set_use_all_possible_disjunctions(
160 absl::GetFlag(FLAGS_cp_use_all_possible_disjunctions));
161 params.set_max_edge_finder_size(absl::GetFlag(FLAGS_cp_max_edge_finder_size));
162 params.set_diffn_use_cumulative(absl::GetFlag(FLAGS_cp_diffn_use_cumulative));
163 params.set_use_element_rmq(absl::GetFlag(FLAGS_cp_use_element_rmq));
164 params.set_check_solution_period(
165 absl::GetFlag(FLAGS_cp_check_solution_period));
185 return parameters_.profile_propagation() ||
186 !parameters_.profile_file().empty();
190 return parameters_.profile_local_search() ||
191 parameters_.print_local_search_profile();
195 return parameters_.trace_propagation();
199 return parameters_.name_all_variables();
211 if (stamp_ < std::numeric_limits<uint64_t>::max()) {
217 if (stamp_ == std::numeric_limits<uint64_t>::max()) {
235 clean_action_(nullptr),
236 clean_variable_(nullptr),
238 instruments_demons_(s->InstrumentsDemons()) {}
248 if (--freeze_level_ == 0) {
254 demon->set_stamp(stamp_ - 1);
255 if (!instruments_demons_) {
275 while (!var_queue_.empty() || !delayed_queue_.empty()) {
276 if (!var_queue_.empty()) {
277 Demon*
const demon = var_queue_.front();
278 var_queue_.pop_front();
281 DCHECK(!delayed_queue_.empty());
282 Demon*
const demon = delayed_queue_.front();
283 delayed_queue_.pop_front();
292 if (!instruments_demons_) {
294 Demon*
const demon = *it;
295 if (demon->stamp() < stamp_) {
307 Demon*
const demon = *it;
308 if (demon->stamp() < stamp_) {
331 if (demon->stamp() < stamp_) {
332 demon->set_stamp(stamp_);
333 var_queue_.push_back(demon);
334 if (freeze_level_ == 0) {
342 if (demon->stamp() < stamp_) {
343 demon->set_stamp(stamp_);
344 delayed_queue_.push_back(demon);
351 delayed_queue_.clear();
354 if (clean_action_ !=
nullptr) {
355 clean_action_(solver_);
356 clean_action_ =
nullptr;
357 }
else if (clean_variable_ !=
nullptr) {
359 clean_variable_ =
nullptr;
370 uint64_t
stamp()
const {
return stamp_; }
373 DCHECK(clean_variable_ ==
nullptr);
374 clean_action_ = std::move(
a);
378 DCHECK(clean_action_ ==
nullptr);
379 clean_variable_ =
var;
383 DCHECK(clean_variable_ ==
nullptr);
384 clean_action_ =
nullptr;
388 to_add_.push_back(c);
398 for (
int counter = 0; counter < to_add_.size(); ++counter) {
399 Constraint*
const constraint = to_add_[counter];
410 std::deque<Demon*> var_queue_;
411 std::deque<Demon*> delayed_queue_;
415 uint32_t freeze_level_;
419 std::vector<Constraint*> to_add_;
421 const bool instruments_demons_;
470 int rev_int64_index_;
471 int rev_uint64_index_;
472 int rev_double_index_;
474 int rev_boolvar_list_index_;
475 int rev_bools_index_;
476 int rev_int_memory_index_;
477 int rev_int64_memory_index_;
478 int rev_double_memory_index_;
479 int rev_object_memory_index_;
480 int rev_object_array_memory_index_;
481 int rev_memory_index_;
482 int rev_memory_array_index_;
490 rev_uint64_index_(0),
491 rev_double_index_(0),
493 rev_boolvar_list_index_(0),
495 rev_int_memory_index_(0),
496 rev_int64_memory_index_(0),
497 rev_double_memory_index_(0),
498 rev_object_memory_index_(0),
499 rev_object_array_memory_index_(0),
512 addrval() : address_(nullptr) {}
513 explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
514 void restore()
const { (*address_) = old_value_; }
529 explicit TrailPacker(
int block_size) : block_size_(block_size) {}
532 TrailPacker(
const TrailPacker&) =
delete;
533 TrailPacker& operator=(
const TrailPacker&) =
delete;
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_;
544class NoCompressionTrailPacker :
public TrailPacker<T> {
546 explicit NoCompressionTrailPacker(
int block_size)
547 : TrailPacker<T>(block_size) {}
550 NoCompressionTrailPacker(
const NoCompressionTrailPacker&) =
delete;
551 NoCompressionTrailPacker& operator=(
const NoCompressionTrailPacker&) =
delete;
552 ~NoCompressionTrailPacker()
override {}
553 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
554 DCHECK(block !=
nullptr);
555 DCHECK(packed_block !=
nullptr);
556 absl::string_view block_str(
reinterpret_cast<const char*
>(block),
558 packed_block->assign(block_str.data(), block_str.size());
560 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
561 DCHECK(block !=
nullptr);
562 memcpy(block, packed_block.c_str(), packed_block.size());
567class 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_]) {}
575 ZlibTrailPacker(
const ZlibTrailPacker&) =
delete;
576 ZlibTrailPacker& operator=(
const ZlibTrailPacker&) =
delete;
578 ~ZlibTrailPacker()
override {}
580 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
581 DCHECK(block !=
nullptr);
582 DCHECK(packed_block !=
nullptr);
583 uLongf
size = tmp_size_;
585 compress(
reinterpret_cast<Bytef*
>(tmp_block_.get()), &
size,
586 reinterpret_cast<const Bytef*
>(block), this->input_size());
587 CHECK_EQ(Z_OK, result);
588 absl::string_view block_str;
589 block_str = absl::string_view(tmp_block_.get(),
size);
590 packed_block->assign(block_str.data(), block_str.size());
593 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
594 DCHECK(block !=
nullptr);
595 uLongf
size = this->input_size();
597 uncompress(
reinterpret_cast<Bytef*
>(block), &
size,
598 reinterpret_cast<const Bytef*
>(packed_block.c_str()),
599 packed_block.size());
600 CHECK_EQ(Z_OK, result);
604 const uint64_t tmp_size_;
605 std::unique_ptr<char[]> tmp_block_;
609class CompressedTrail {
613 ConstraintSolverParameters::TrailCompression compression_level)
614 : block_size_(block_size),
616 free_blocks_(nullptr),
617 data_(new addrval<T>[block_size]),
618 buffer_(new addrval<T>[block_size]),
622 switch (compression_level) {
623 case ConstraintSolverParameters::NO_COMPRESSION: {
624 packer_.reset(
new NoCompressionTrailPacker<T>(block_size));
627 case ConstraintSolverParameters::COMPRESS_WITH_ZLIB: {
628 packer_.reset(
new ZlibTrailPacker<T>(block_size));
632 LOG(ERROR) <<
"Should not be here";
641 memset(data_.get(), 0,
sizeof(*data_.get()) * block_size);
642 memset(buffer_.get(), 0,
sizeof(*buffer_.get()) * block_size);
646 FreeBlocks(free_blocks_);
648 const addrval<T>& Back()
const {
650 DCHECK_GT(current_, 0);
651 return data_[current_ - 1];
659 current_ = block_size_;
660 buffer_used_ =
false;
661 }
else if (blocks_ !=
nullptr) {
662 packer_->Unpack(blocks_->compressed, data_.get());
664 current_ = block_size_;
670 void PushBack(
const addrval<T>& addr_val) {
671 if (current_ >= block_size_) {
674 packer_->Pack(buffer_.get(), &blocks_->compressed);
683 data_[current_] = addr_val;
687 int64_t
size()
const {
return size_; }
695 void FreeTopBlock() {
696 Block* block = blocks_;
697 blocks_ = block->next;
698 block->compressed.clear();
699 block->next = free_blocks_;
700 free_blocks_ = block;
703 Block* block =
nullptr;
704 if (free_blocks_ !=
nullptr) {
705 block = free_blocks_;
706 free_blocks_ = block->next;
710 block->next = blocks_;
713 void FreeBlocks(Block* blocks) {
714 while (
nullptr != blocks) {
715 Block*
next = blocks->next;
721 std::unique_ptr<TrailPacker<T>> packer_;
722 const int block_size_;
725 std::unique_ptr<addrval<T>[]> data_;
726 std::unique_ptr<addrval<T>[]> buffer_;
759 ConstraintSolverParameters::TrailCompression compression_level)
760 :
rev_ints_(block_size, compression_level),
764 rev_ptrs_(block_size, compression_level) {}
767 int target = m->rev_int_index_;
768 for (
int curr =
rev_ints_.size(); curr > target; --curr) {
769 const addrval<int>& cell =
rev_ints_.Back();
775 target = m->rev_int64_index_;
776 for (
int curr =
rev_int64s_.size(); curr > target; --curr) {
783 target = m->rev_uint64_index_;
784 for (
int curr =
rev_uint64s_.size(); curr > target; --curr) {
791 target = m->rev_double_index_;
792 for (
int curr =
rev_doubles_.size(); curr > target; --curr) {
799 target = m->rev_ptr_index_;
800 for (
int curr =
rev_ptrs_.size(); curr > target; --curr) {
801 const addrval<void*>& cell =
rev_ptrs_.Back();
807 target = m->rev_boolvar_list_index_;
815 target = m->rev_bools_index_;
816 for (
int curr =
rev_bools_.size() - 1; curr >= target; --curr) {
822 target = m->rev_int_memory_index_;
828 target = m->rev_int64_memory_index_;
834 target = m->rev_double_memory_index_;
840 target = m->rev_object_memory_index_;
846 target = m->rev_object_array_memory_index_;
853 target = m->rev_memory_index_;
854 for (
int curr =
rev_memory_.size() - 1; curr >= target; --curr) {
856 ::operator
delete(
reinterpret_cast<char*
>(
rev_memory_[curr]));
865 target = m->rev_memory_array_index_;
874void Solver::InternalSaveValue(
int* valptr) {
875 trail_->rev_ints_.PushBack(addrval<int>(valptr));
878void Solver::InternalSaveValue(int64_t* valptr) {
879 trail_->rev_int64s_.PushBack(addrval<int64_t>(valptr));
882void Solver::InternalSaveValue(uint64_t* valptr) {
883 trail_->rev_uint64s_.PushBack(addrval<uint64_t>(valptr));
886void Solver::InternalSaveValue(
double* valptr) {
887 trail_->rev_doubles_.PushBack(addrval<double>(valptr));
890void Solver::InternalSaveValue(
void** valptr) {
891 trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
897void Solver::InternalSaveValue(
bool* valptr) {
898 trail_->rev_bools_.push_back(valptr);
899 trail_->rev_bool_value_.push_back(*valptr);
902BaseObject* Solver::SafeRevAlloc(BaseObject* ptr) {
904 trail_->rev_object_memory_.push_back(ptr);
908int* Solver::SafeRevAllocArray(
int* ptr) {
910 trail_->rev_int_memory_.push_back(ptr);
914int64_t* Solver::SafeRevAllocArray(int64_t* ptr) {
916 trail_->rev_int64_memory_.push_back(ptr);
920double* Solver::SafeRevAllocArray(
double* ptr) {
922 trail_->rev_double_memory_.push_back(ptr);
926uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) {
928 trail_->rev_int64_memory_.push_back(
reinterpret_cast<int64_t*
>(ptr));
932BaseObject** Solver::SafeRevAllocArray(BaseObject** ptr) {
934 trail_->rev_object_array_memory_.push_back(ptr);
938IntVar** Solver::SafeRevAllocArray(IntVar** ptr) {
939 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
940 return reinterpret_cast<IntVar**
>(in);
943IntExpr** Solver::SafeRevAllocArray(IntExpr** ptr) {
944 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
945 return reinterpret_cast<IntExpr**
>(in);
948Constraint** Solver::SafeRevAllocArray(Constraint** ptr) {
949 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
953void* Solver::UnsafeRevAllocAux(
void* ptr) {
955 trail_->rev_memory_.push_back(ptr);
959void** Solver::UnsafeRevAllocArrayAux(
void** ptr) {
961 trail_->rev_memory_array_.push_back(ptr);
966 solver->trail_->rev_boolvar_list_.push_back(
var);
976 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
978 solution_counter_(0),
979 unchecked_solution_counter_(0),
980 decision_builder_(nullptr),
981 created_by_solve_(false),
983 left_search_depth_(0),
984 should_restart_(false),
985 should_finish_(false),
987 jmpbuf_filled_(false),
988 backtrack_at_the_end_of_the_search_(true) {}
996 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
998 solution_counter_(0),
999 unchecked_solution_counter_(0),
1000 decision_builder_(nullptr),
1001 created_by_solve_(false),
1003 left_search_depth_(-1),
1004 should_restart_(false),
1005 should_finish_(false),
1006 sentinel_pushed_(0),
1007 jmpbuf_filled_(false),
1008 backtrack_at_the_end_of_the_search_(true) {}
1036 if (monitor !=
nullptr) {
1037 monitor_event_listeners_[to_underlying(event)].push_back(monitor);
1042 return monitor_event_listeners_[to_underlying(event)];
1049 return unchecked_solution_counter_;
1052 decision_builder_ = db;
1061 left_search_depth_++;
1065 return backtrack_at_the_end_of_the_search_;
1068 backtrack_at_the_end_of_the_search_ = restore;
1079 if (should_finish_ || should_restart_) {
1092 void ClearBuffer() {
1093 CHECK(jmpbuf_filled_) <<
"Internal error in backtracking";
1094 jmpbuf_filled_ =
false;
1098 std::vector<StateMarker*> marker_stack_;
1099 std::vector<std::vector<SearchMonitor*>> monitor_event_listeners_;
1100 jmp_buf fail_buffer_;
1101 int64_t solution_counter_;
1102 int64_t unchecked_solution_counter_;
1104 bool created_by_solve_;
1107 int left_search_depth_;
1108 bool should_restart_;
1109 bool should_finish_;
1110 int sentinel_pushed_;
1111 bool jmpbuf_filled_;
1112 bool backtrack_at_the_end_of_the_search_;
1113 std::string search_context_;
1126#ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK
1129#define CP_TRY(search) \
1130 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1131 search->jmpbuf_filled_ = true; \
1132 if (setjmp(search->fail_buffer_) == 0)
1133#define CP_ON_FAIL else
1134#define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1)
1136class FailException {};
1137#define CP_TRY(search) \
1138 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1139 search->jmpbuf_filled_ = true; \
1141#define CP_ON_FAIL catch (FailException&)
1142#define CP_DO_FAIL(search) throw FailException()
1145void Search::JumpBack() {
1146 if (jmpbuf_filled_) {
1147 jmpbuf_filled_ =
false;
1150 std::string explanation =
"Failure outside of search";
1161 : selector_(
std::move(bs)) {}
1162 ~ApplyBranchSelector()
override {}
1164 Decision*
Next(Solver*
const s)
override {
1165 s->SetBranchSelector(selector_);
1169 std::string DebugString()
const override {
return "Apply(BranchSelector)"; }
1177 selector_ = std::move(bs);
1186 [solve_depth](
Solver* s) {
1192 searches_.back()->SetBranchSelector(std::move(bs));
1196 return RevAlloc(
new ApplyBranchSelector(std::move(bs)));
1206 return searches_.back()->left_search_depth();
1210 if (selector_ !=
nullptr) {
1217 for (
auto& listeners : monitor_event_listeners_) listeners.clear();
1219 left_search_depth_ = 0;
1220 selector_ =
nullptr;
1221 backtrack_at_the_end_of_the_search_ =
true;
1224#define CALL_EVENT_LISTENERS(Event) \
1226 ForAll(GetEventListeners(Solver::MonitorEvent::k##Event), \
1227 &SearchMonitor::Event); \
1234 solution_counter_ = 0;
1235 unchecked_solution_counter_ = 0;
1293 if (!monitor->AcceptSolution()) {
1304 bool should_continue =
false;
1307 if (monitor->AtSolution()) {
1311 should_continue =
true;
1314 return should_continue;
1320 bool at_local_optimum =
false;
1323 if (monitor->LocalOptimum()) {
1324 at_local_optimum =
true;
1327 return at_local_optimum;
1334 if (!monitor->AcceptDelta(
delta, deltadelta)) {
1350 if (monitor->IsUncheckedSolutionLimitReached()) {
1363 progress = std::max(progress, monitor->ProgressPercent());
1371 if (decision_builder_ !=
nullptr) {
1372 decision_builder_->
Accept(visitor);
1376#undef CALL_EVENT_LISTENERS
1394class FailDecision :
public Decision {
1396 void Apply(Solver*
const s)
override { s->Fail(); }
1397 void Refute(Solver*
const s)
override { s->Fail(); }
1402class BalancingDecision :
public Decision {
1404 ~BalancingDecision()
override {}
1405 void Apply(Solver*
const )
override {}
1406 void Refute(Solver*
const )
override {}
1417enum SentinelMarker {
1418 INITIAL_SEARCH_SENTINEL = 10000000,
1419 ROOT_NODE_SENTINEL = 20000000,
1420 SOLVER_CTOR_SENTINEL = 40000000
1424extern PropagationMonitor*
BuildTrace(Solver* s);
1431void 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),
1458void 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();
1567void Solver::IncrementUncheckedSolutionCounter() {
1571bool 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();
1643void 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!";
1658void Solver::FreezeQueue() { queue_->Freeze(); }
1660void Solver::UnfreezeQueue() { queue_->Unfreeze(); }
1662void Solver::EnqueueVar(Demon*
const d) { queue_->EnqueueVar(d); }
1664void Solver::EnqueueDelayedDemon(Demon*
const d) {
1665 queue_->EnqueueDelayedDemon(d);
1668void Solver::ExecuteAll(
const SimpleRevFIFO<Demon*>& demons) {
1669 queue_->ExecuteAll(demons);
1672void Solver::EnqueueAll(
const SimpleRevFIFO<Demon*>& demons) {
1673 queue_->EnqueueAll(demons);
1680void Solver::set_action_on_fail(Action
a) {
1681 queue_->set_action_on_fail(std::move(
a));
1684void Solver::set_variable_to_clean_on_fail(IntVar* v) {
1685 queue_->set_variable_to_clean_on_fail(v);
1688void 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()) {
1708 LOG(INFO) << c->DebugString();
1710 constraints_list_.push_back(c);
1716 if (constraint !=
nullptr) {
1718 cast_constraints_.insert(constraint);
1719 cast_information_[target_var] =
1732void 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 return Solve(db, std::vector<SearchMonitor*>{m1});
1793 return Solve(db, {m1, m2});
1798 return Solve(db, {m1, m2, m3});
1804 return Solve(db, {m1, m2, m3, m4});
1808 const std::vector<SearchMonitor*>& monitors) {
1810 searches_.back()->set_created_by_solve(
true);
1812 const bool solution_found = searches_.back()->solution_counter() > 0;
1814 return solution_found;
1818 return NewSearch(db, std::vector<SearchMonitor*>{m1});
1843 const std::vector<SearchMonitor*>& monitors) {
1846 CHECK(db !=
nullptr);
1847 const bool nested = state_ ==
IN_SEARCH;
1850 LOG(FATAL) <<
"Cannot start new searches here.";
1853 Search*
const search = nested ?
new Search(
this) : searches_.back();
1860 DCHECK_GE(searches_.size(), 2);
1861 searches_.push_back(search);
1865 DCHECK_EQ(2, searches_.size());
1867 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1874 propagation_monitor_->Install();
1875 if (demon_profiler_ !=
nullptr) {
1878 local_search_monitor_->Install();
1879 if (local_search_profiler_ !=
nullptr) {
1885 if (monitor !=
nullptr) {
1889 std::vector<SearchMonitor*> extras;
1892 if (monitor !=
nullptr) {
1899 if (print_trace_ !=
nullptr) {
1903 print_trace_ =
nullptr;
1904 if (parameters_.trace_propagation()) {
1907 }
else if (parameters_.trace_search()) {
1922 PushSentinel(INITIAL_SEARCH_SENTINEL);
1928bool Solver::BacktrackOneLevel(
Decision**
const fail_decision) {
1929 bool no_more_solutions =
false;
1930 bool end_loop =
false;
1936 CHECK_EQ(info.
ptr_info,
this) <<
"Wrong sentinel found";
1939 searches_.back()->sentinel_pushed_--;
1940 no_more_solutions =
true;
1944 LOG(ERROR) <<
"Simple markers should not be encountered during search";
1950 searches_.back()->set_search_depth(info.
depth);
1951 searches_.back()->set_search_left_depth(info.
left_depth);
1962 Search*
const search = searches_.back();
1965 if (no_more_solutions) {
1966 search->NoMoreSolutions();
1968 return no_more_solutions;
1971void Solver::PushSentinel(
int magic_code) {
1972 StateInfo info(
this, magic_code);
1975 if (magic_code != SOLVER_CTOR_SENTINEL) {
1976 searches_.back()->sentinel_pushed_++;
1978 const int pushed = searches_.back()->sentinel_pushed_;
1979 DCHECK((magic_code == SOLVER_CTOR_SENTINEL) ||
1980 (magic_code == INITIAL_SEARCH_SENTINEL && pushed == 1) ||
1981 (magic_code == ROOT_NODE_SENTINEL && pushed == 2));
1985 Search*
const search = searches_.back();
1986 CHECK_NE(0, search->sentinel_pushed_);
1988 if (search->sentinel_pushed_ > 1) {
1989 BacktrackToSentinel(ROOT_NODE_SENTINEL);
1991 CHECK_EQ(1, search->sentinel_pushed_);
1992 PushSentinel(ROOT_NODE_SENTINEL);
1996 if (search->sentinel_pushed_ > 0) {
1997 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1999 CHECK_EQ(0, search->sentinel_pushed_);
2000 PushSentinel(INITIAL_SEARCH_SENTINEL);
2008void Solver::BacktrackToSentinel(
int magic_code) {
2009 Search*
const search = searches_.back();
2010 bool end_loop = search->sentinel_pushed_ == 0;
2016 CHECK_EQ(info.
ptr_info,
this) <<
"Wrong sentinel found";
2017 CHECK_GE(--search->sentinel_pushed_, 0);
2040void Solver::JumpToSentinelWhenNested() {
2041 CHECK_GT(
SolveDepth(), 1) <<
"calling JumpToSentinel from top level";
2042 Search*
c = searches_.back();
2043 Search* p = ParentSearch();
2045 while (!
c->marker_stack_.empty()) {
2046 StateMarker*
const m =
c->marker_stack_.back();
2048 p->marker_stack_.push_back(m);
2051 CHECK_EQ(
c->marker_stack_.size(), 1) <<
"Sentinel found too early";
2056 c->marker_stack_.pop_back();
2058 c->set_search_depth(0);
2059 c->set_search_left_depth(0);
2060 CHECK_EQ(found,
true) <<
"Sentinel not found";
2064class ReverseDecision :
public Decision {
2066 explicit ReverseDecision(Decision*
const d) : decision_(d) {
2067 CHECK(d !=
nullptr);
2069 ~ReverseDecision()
override {}
2071 void Apply(Solver*
const s)
override { decision_->Refute(s); }
2073 void Refute(Solver*
const s)
override { decision_->Apply(s); }
2075 void Accept(DecisionVisitor*
const visitor)
const override {
2076 decision_->Accept(visitor);
2079 std::string DebugString()
const override {
2080 std::string str =
"Reverse(";
2081 str += decision_->DebugString();
2087 Decision*
const decision_;
2093 Search*
const search = searches_.back();
2096 const bool top_level = solve_depth <= 1;
2099 LOG(WARNING) <<
"NextSolution() called without a NewSearch before";
2110 if (BacktrackOneLevel(&fd)) {
2121 ProcessConstraints();
2123 PushSentinel(ROOT_NODE_SENTINEL);
2125 search->ClearBuffer();
2128 queue_->AfterFailure();
2129 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2138 LOG(FATAL) <<
"Should not happen";
2143 volatile bool finish =
false;
2144 volatile bool result =
false;
2149 if (fd !=
nullptr) {
2168 if (d == fail_decision_.get()) {
2173 switch (modification) {
2175 d =
RevAlloc(
new ReverseDecision(d));
2177 ABSL_FALLTHROUGH_INTENDED;
2227 queue_->AfterFailure();
2230 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2231 : INITIAL_SEARCH_SENTINEL);
2239 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2240 : INITIAL_SEARCH_SENTINEL);
2243 PushSentinel(top_level ? ROOT_NODE_SENTINEL : INITIAL_SEARCH_SENTINEL);
2246 if (BacktrackOneLevel(&fd)) {
2254 search->ClearBuffer();
2263 Search*
const search = searches_.back();
2265 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2267 CHECK_GT(searches_.size(), 2);
2268 if (search->sentinel_pushed_ > 0) {
2269 JumpToSentinelWhenNested();
2274 if (2 == searches_.size()) {
2278 if (!parameters_.profile_file().empty()) {
2279 const std::string& file_name = parameters_.profile_file();
2280 LOG(INFO) <<
"Exporting profile to " << file_name;
2283 if (parameters_.print_local_search_profile()) {
2285 if (!profile.empty()) LOG(INFO) << profile;
2289 searches_.pop_back();
2296 LOG(FATAL) <<
"CheckAssignment is only available at the top level.";
2299 Search*
const search = searches_.back();
2302 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2310 DCHECK_EQ(2, searches_.size());
2311 PushSentinel(INITIAL_SEARCH_SENTINEL);
2316 restore->
Next(
this);
2317 ProcessConstraints();
2319 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2320 search->ClearBuffer();
2326 constraint_index_ < constraints_list_.size()
2328 : additional_constraints_parent_list_[additional_constraint_index_];
2330 if (
ct->name().empty()) {
2331 LOG(INFO) <<
"Failing constraint = " <<
ct->DebugString();
2333 LOG(INFO) <<
"Failing constraint = " <<
ct->name() <<
":"
2334 <<
ct->DebugString();
2336 queue_->AfterFailure();
2337 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2346 explicit AddConstraintDecisionBuilder(
Constraint*
const ct)
2348 CHECK(
ct !=
nullptr);
2351 ~AddConstraintDecisionBuilder()
override {}
2353 Decision*
Next(Solver*
const solver)
override {
2354 solver->AddConstraint(constraint_);
2358 std::string DebugString()
const override {
2359 return absl::StrFormat(
"AddConstraintDecisionBuilder(%s)",
2360 constraint_->DebugString());
2364 Constraint*
const constraint_;
2369 return RevAlloc(
new AddConstraintDecisionBuilder(
ct));
2396 const std::vector<SearchMonitor*>& monitors) {
2398 searches_.back()->set_created_by_solve(
true);
2399 searches_.back()->set_backtrack_at_the_end_of_the_search(
false);
2401 const bool solution_found = searches_.back()->solution_counter() > 0;
2403 return solution_found;
2407 if (fail_intercept_) {
2413 searches_.back()->BeginFail();
2414 searches_.back()->JumpBack();
2418 searches_.back()->set_should_finish(
true);
2422 searches_.back()->set_should_restart(
true);
2430 if (cast_info !=
nullptr) {
2440 if (
name !=
nullptr) {
2443 const IntegerCastInfo*
const cast_info =
2445 if (cast_info !=
nullptr && cast_info->expression !=
nullptr) {
2446 if (cast_info->expression->HasName()) {
2447 return absl::StrFormat(
"Var<%s>", cast_info->expression->name());
2448 }
else if (parameters_.name_cast_variables()) {
2449 return absl::StrFormat(
"Var<%s>", cast_info->expression->DebugString());
2451 const std::string new_name =
2452 absl::StrFormat(
"CastVar<%d>", anonymous_variable_index_++);
2453 propagation_object_names_[object] = new_name;
2457 const std::string base_name =
object->BaseName();
2458 if (parameters_.name_all_variables() && !base_name.empty()) {
2459 const std::string new_name =
2460 absl::StrFormat(
"%s_%d", base_name, anonymous_variable_index_++);
2461 propagation_object_names_[object] = new_name;
2467void Solver::SetName(
const PropagationBaseObject*
object,
2468 absl::string_view
name) {
2469 if (parameters_.store_names() &&
2470 GetName(
object) !=
name) {
2471 propagation_object_names_[object] =
name;
2476 return propagation_object_names_.contains(
2478 (!
object->BaseName().empty() && parameters_.name_all_variables());
2496 return solver_->GetName(
this);
2500 solver_->SetName(
this,
name);
2508 solver_->ExecuteAll(demons);
2512 solver_->EnqueueAll(demons);
2524 Solver*
const , std::vector<SearchMonitor*>*
const ) {}
2535 [[maybe_unused]] int64_t
value) {}
2537 [[maybe_unused]]
IntVar*
const var, [[maybe_unused]] int64_t
value,
2538 [[maybe_unused]]
bool start_with_lower_half) {}
2541 [[maybe_unused]]
IntervalVar*
const var, [[maybe_unused]] int64_t est) {}
2543 [[maybe_unused]]
IntervalVar*
const var, [[maybe_unused]] int64_t est) {}
2545 [[maybe_unused]]
SequenceVar*
const sequence, [[maybe_unused]]
int index) {}
2548 [[maybe_unused]]
SequenceVar*
const sequence, [[maybe_unused]]
int index) {}
2622 "ScalarProductGreaterOrEqual";
2650 "VariableUsageLessConstant";
2652 "WeightedSumOfAssignedEqualVariable";
2732 [[maybe_unused]]
const std::string& type_name) {}
2734 [[maybe_unused]]
const std::string& type_name) {}
2737 [[maybe_unused]]
const std::string& type_name,
2738 [[maybe_unused]]
const Constraint*
const constraint) {}
2740 [[maybe_unused]]
const std::string& type_name,
2741 [[maybe_unused]]
const Constraint*
const constraint) {}
2744 [[maybe_unused]]
const std::string& type) {}
2749 [[maybe_unused]]
const std::string& type_name,
2750 [[maybe_unused]]
const IntExpr*
const expr) {}
2752 [[maybe_unused]]
const std::string& type_name,
2753 [[maybe_unused]]
const IntExpr*
const expr) {}
2756 [[maybe_unused]]
const IntVar*
const variable,
IntExpr*
const delegate) {
2757 if (delegate !=
nullptr) {
2763 [[maybe_unused]]
const IntVar*
const variable,
2764 [[maybe_unused]]
const std::string& operation,
2765 [[maybe_unused]] int64_t
value,
IntVar*
const delegate) {
2766 if (delegate !=
nullptr) {
2772 [[maybe_unused]]
const IntervalVar*
const variable,
2773 [[maybe_unused]]
const std::string& operation,
2775 if (delegate !=
nullptr) {
2781 for (
int i = 0; i < variable->
size(); ++i) {
2787 [[maybe_unused]]
const std::string& arg_name,
2788 [[maybe_unused]] int64_t
value) {}
2791 [[maybe_unused]]
const std::string& arg_name,
2792 [[maybe_unused]]
const std::vector<int64_t>& values) {}
2795 [[maybe_unused]]
const std::string& arg_name,
2799 [[maybe_unused]]
const std::string& arg_name,
IntExpr*
const argument) {
2804 [[maybe_unused]]
const std::string& arg_name,
2808 [[maybe_unused]]
const std::string& arg_name,
2809 const std::vector<IntVar*>& arguments) {
2814 [[maybe_unused]]
const std::string& arg_name,
IntervalVar*
const argument) {
2819 [[maybe_unused]]
const std::string& arg_name,
2820 const std::vector<IntervalVar*>& arguments) {
2825 [[maybe_unused]]
const std::string& arg_name,
SequenceVar*
const argument) {
2830 [[maybe_unused]]
const std::string& arg_name,
2831 const std::vector<SequenceVar*>& arguments) {
2839 int64_t index_max) {
2840 if (filter !=
nullptr) {
2841 std::vector<int64_t> cached_results;
2842 for (
int i = index_min; i <= index_max; ++i) {
2843 cached_results.push_back(filter(i));
2855 CHECK(eval !=
nullptr);
2856 std::vector<int64_t> cached_results;
2857 for (
int i = index_min; i <= index_max; ++i) {
2858 cached_results.push_back(eval(i));
2868 const std::string& arg_name,
2869 int64_t index_max) {
2870 CHECK(eval !=
nullptr);
2871 std::vector<int64_t> cached_results;
2872 for (
int i = 0; i <= index_max; ++i) {
2873 cached_results.push_back(eval(i));
2888 [[maybe_unused]]
bool apply) {}
2908 for (std::underlying_type<Solver::MonitorEvent>::type event = 0;
2915 solver()->searches_.back()->AddEventListener(event,
this);
3007 monitor->SetMin(expr, new_min);
3013 monitor->SetMax(expr, new_max);
3018 int64_t new_max)
override {
3020 monitor->SetRange(expr, new_min, new_max);
3027 monitor->SetMin(
var, new_min);
3033 monitor->SetMax(
var, new_max);
3039 monitor->SetRange(
var, new_min, new_max);
3056 const std::vector<int64_t>& values)
override {
3061 const std::vector<int64_t>& values)
override {
3075 int64_t new_max)
override {
3089 int64_t new_max)
override {
3102 int64_t new_max)
override {
3128 const std::vector<int>& rank_last,
3129 const std::vector<int>& unperformed)
override {
3131 rank_last, unperformed);
3136 if (monitor !=
nullptr) {
3137 monitors_.push_back(monitor);
3148 std::vector<PropagationMonitor*> monitors_;
3155 reinterpret_cast<class
Trace*
>(propagation_monitor_.get())->
Add(monitor);
3159 return propagation_monitor_.get();
3182 neighbor_found,
delta, deltadelta);
3188 bool neighbor_found)
override {
3196 bool neighbor_found)
override {
3206 bool IsActive()
const override {
return !monitors_.empty(); }
3210 if (monitor !=
nullptr) {
3211 monitors_.push_back(monitor);
3220 return "LocalSearchMonitorPrimary";
3224 std::vector<LocalSearchMonitor*> monitors_;
3233 local_search_monitor_.get())
3238 return local_search_monitor_.get();
3242 absl::string_view search_context) {
3255 if (local_search_state_ ==
nullptr) {
3256 local_search_state_ = std::make_unique<Assignment>(
this);
3258 return local_search_state_.get();
3264 : db_(db), name_(db_->GetName()), seconds_(0) {}
3274 seconds_ += timer_.
Get();
3281 seconds_ += timer_.
Get();
3290 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {
3312 VLOG(3) <<
"Unknown constraint " <<
DebugString();
3317 return solver()->cast_constraints_.contains(
this);
3326 VLOG(3) <<
"Unknown expression " <<
DebugString();
void Start()
When Start() is called multiple times, only the most recent is used.
virtual std::string DebugString() const
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.
virtual Decision * Next(Solver *s)=0
virtual void Accept(ModelVisitor *visitor) const
virtual void AppendMonitors(Solver *solver, std::vector< SearchMonitor * > *extras)
std::string GetName() const
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 VisitUnknownDecision()
virtual void VisitScheduleOrExpedite(IntervalVar *var, int64_t est)
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.
virtual void Apply(Solver *s)=0
Apply will be called first when the decision is executed.
virtual void Accept(DecisionVisitor *visitor) const
Accepts the given visitor.
virtual void Run(Solver *s)=0
This is the main callback of the demon.
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 void Accept(ModelVisitor *visitor) const
Accepts the given visitor.
--— Main IntTupleSet class --—
void Accept(ModelVisitor *visitor) const override
Accepts the given visitor.
virtual void Accept(ModelVisitor *visitor) const =0
Accepts the given visitor.
-------— Local Search Monitor Primary -------—
LocalSearchMonitorPrimary(Solver *solver)
std::string DebugString() const override
void EndOperatorStart() override
void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta) override
void BeginOperatorStart() override
Local search operator events.
void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void BeginMakeNextNeighbor(const LocalSearchOperator *op) override
void BeginAcceptNeighbor(const LocalSearchOperator *op) override
bool IsActive() const override
void Add(LocalSearchMonitor *monitor)
Does not take ownership of monitor.
void BeginFilterNeighbor(const LocalSearchOperator *op) override
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
void BeginFiltering(const LocalSearchFilter *filter) override
LocalSearchMonitor(Solver *solver)
-------— Local Search Monitor --------—
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual void BeginOperatorStart()=0
Local search operator events.
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
~LocalSearchMonitor() override
void Install() override
Install itself on the solver.
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void EndOperatorStart()=0
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
--— LocalSearchProfiler --—
static const char kCumulsArgument[]
static const char kStartMaxArgument[]
static const char kVarValueWatcher[]
static const char kConvexPiecewise[]
static const char kScalProdGreaterOrEqual[]
static const char kStepArgument[]
static const char kLexLess[]
virtual void VisitSequenceVariable(const SequenceVar *variable)
static const char kGreaterOrEqual[]
static const char kSolutionLimitArgument[]
static const char kAbsEqual[]
static const char kNullIntersect[]
static const char kStartExpr[]
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 kIndexOf[]
static const char kVariableUsageLessConstantExtension[]
static const char kDeviation[]
static const char kSequenceArgument[]
static const char kAssumePathsArgument[]
void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, int64_t index_max)
--— Helpers --—
static const char kIntervalBinaryRelation[]
static const char kIntegerVariable[]
static const char kDifferenceOperation[]
static const char kInitialState[]
static const char kIsMember[]
static const char kTraceOperation[]
static const char kSearchLimitExtension[]
static const char kEndsArgument[]
static const char kRelaxedMinOperation[]
static const char kFalseConstraint[]
static const char kFixedChargeArgument[]
static const char kDurationMaxArgument[]
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 kSumOperation[]
static const char kIntervalVariable[]
static const char kFinalStatesArgument[]
static const char kNoCycle[]
static const char kElement[]
static const char kSequenceVariable[]
static const char kTuplesArgument[]
static const char kFailuresLimitArgument[]
static const char kMirrorOperation[]
Operations.
static const char kMinEqual[]
static const char kEarlyCostArgument[]
static const char kInt64ToInt64Extension[]
static const char kNotBetween[]
static const char kDistribute[]
static const char kOpposite[]
static const char kTransition[]
static const char kActiveArgument[]
argument names:
static const char kObjectiveExtension[]
static const char kIsGreater[]
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
static const char kDifference[]
static const char kDurationMinArgument[]
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *expr)
static const char kNextsArgument[]
static const char kProduct[]
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
static const char kRangeArgument[]
static const char kCircuit[]
static const char kLateCostArgument[]
static const char kEndMinArgument[]
static const char kMinArgument[]
virtual void VisitIntegerVariable(const IntVar *variable, IntExpr *delegate)
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
static const char kCoefficientsArgument[]
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
static const char kExpressionArgument[]
static const char kTrace[]
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kTargetArgument[]
~ModelVisitor() override
Methods.
static const char kMapDomain[]
static const char kStartsArgument[]
static const char kIntervalDisjunction[]
static const char kPositionXArgument[]
static const char kStartSyncOnStartOperation[]
static const char kRelationArgument[]
static const char kIsDifferent[]
static const char kSortingConstraint[]
static const char kSizeArgument[]
static const char kMember[]
static const char kModulo[]
static const char kSumGreaterOrEqual[]
static const char kIntervalUnaryRelation[]
static const char kMaxArgument[]
virtual void EndVisitModel(const std::string &type_name)
static const char kProductOperation[]
static const char kTransitsArgument[]
static const char kPerformedExpr[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *argument)
Visit integer expression argument.
static const char kNotMember[]
static const char kValueArgument[]
static const char kEndExpr[]
static const char kLessOrEqual[]
static const char kMaxEqual[]
static const char kLateDateArgument[]
static const char kRightArgument[]
static const char kEarlyDateArgument[]
static const char kScalProdLessOrEqual[]
static const char kIsGreaterOrEqual[]
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
static const char kCapacityArgument[]
static const char kSumLessOrEqual[]
static const char kModuloArgument[]
static const char kVarBoundWatcher[]
static const char kIsEqual[]
static const char kCumulative[]
static const char kScalProdEqual[]
static const char kSizeYArgument[]
static const char kSequencesArgument[]
static const char kEndMaxArgument[]
static const char kDurationExpr[]
static const char kVariableGroupExtension[]
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
static const char kAllDifferent[]
static const char kValuesArgument[]
static const char kIsLess[]
static const char kIndexArgument[]
static const char kPack[]
static const char kPathCumul[]
static const char kRelaxedMaxOperation[]
static const char kScalProd[]
static const char kAtMost[]
static const char kStartSyncOnEndOperation[]
static const char kUsageLessConstantExtension[]
static const char kMaximizeArgument[]
static const char kLightElementEqual[]
static const char kElementEqual[]
static const char kCumulativeArgument[]
static const char kSquare[]
static const char kIntervalArgument[]
static const char kPositionYArgument[]
static const char kIsBetween[]
static const char kVarsArgument[]
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *constraint)
static const char kVariableArgument[]
static const char kLinkExprVar[]
static const char kBranchesLimitArgument[]
static const char kIndex2Argument[]
static const char kSumEqual[]
virtual void EndVisitExtension(const std::string &type)
static const char kUsageEqualVariableExtension[]
static const char kSemiContinuous[]
static const char kDemandsArgument[]
static const char kDisjunctive[]
static const char kNonEqual[]
static const char kCountEqual[]
static const char kSizeXArgument[]
static const char kGreater[]
static const char kEquality[]
static const char kLeftArgument[]
static const char kGlobalCardinality[]
static const char kInversePermutation[]
static const char kCountAssignedItemsExtension[]
Extension names:
virtual void VisitIntervalVariable(const IntervalVar *variable, const std::string &operation, int64_t value, IntervalVar *delegate)
static const char kCountUsedBinsExtension[]
static const char kStartMinArgument[]
static const char kOptionalArgument[]
static const char kCountArgument[]
static const char kConditionalExpr[]
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
static const char kTrueConstraint[]
static const char kPartialArgument[]
static const char kDelayedPathCumul[]
virtual void BeginVisitExtension(const std::string &type)
static const char kWeightedSumOfAssignedEqualVariableExtension[]
static const char kInt64ToBoolExtension[]
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *argument)
Visit sequence argument.
static const char kEvaluatorArgument[]
static const char kCover[]
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *expr)
static const char kAbs[]
Constraint and Expression types.
static const char kSmartTimeCheckArgument[]
static const char kCardsArgument[]
static const char kBetween[]
static const char kDivide[]
static const char kAllowedAssignments[]
static const char kTimeLimitArgument[]
static const char kPower[]
static const char kIsLessOrEqual[]
static const char kLess[]
static const char kIntervalsArgument[]
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *constraint)
ProfiledDecisionBuilder(DecisionBuilder *db)
--------------— ProfiledDecisionBuilder ---------—
std::string DebugString() const override
-------— Decision Builder -------—
Decision * Next(Solver *solver) override
void Accept(ModelVisitor *visitor) const override
const std::string & name() const
void AppendMonitors(Solver *solver, std::vector< SearchMonitor * > *extras) override
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string name() const
Object naming.
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string BaseName() const
Returns a base name for automatic naming.
void set_name(absl::string_view name)
std::string DebugString() const override
bool HasName() const
Returns whether the object has been named or not.
virtual void SetValues(IntVar *var, const std::vector< int64_t > &values)=0
virtual void SetDurationMax(IntervalVar *var, int64_t new_max)=0
virtual void SetStartMax(IntervalVar *var, int64_t new_max)=0
virtual void SetStartMin(IntervalVar *var, int64_t new_min)=0
IntervalVar modifiers.
virtual void PopContext()=0
virtual void RankSequence(SequenceVar *var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
virtual void RankNotFirst(SequenceVar *var, int index)=0
virtual void BeginNestedConstraintInitialPropagation(Constraint *parent, Constraint *nested)=0
virtual void RankNotLast(SequenceVar *var, int index)=0
virtual void PushContext(const std::string &context)=0
virtual void SetPerformed(IntervalVar *var, bool value)=0
virtual void SetEndMax(IntervalVar *var, int64_t new_max)=0
virtual void RemoveValue(IntVar *var, int64_t value)=0
virtual void BeginConstraintInitialPropagation(Constraint *constraint)=0
Propagation events.
virtual void EndDemonRun(Demon *demon)=0
virtual void SetDurationMin(IntervalVar *var, int64_t new_min)=0
virtual void RegisterDemon(Demon *demon)=0
virtual void SetEndMin(IntervalVar *var, int64_t new_min)=0
virtual void RankFirst(SequenceVar *var, int index)=0
SequenceVar modifiers.
virtual void RankLast(SequenceVar *var, int index)=0
virtual void SetDurationRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
virtual void EndNestedConstraintInitialPropagation(Constraint *parent, Constraint *nested)=0
PropagationMonitor(Solver *solver)
-------— Propagation Monitor --------—
virtual void StartProcessingIntegerVariable(IntVar *var)=0
virtual void EndProcessingIntegerVariable(IntVar *var)=0
void Install() override
Install itself on the solver.
virtual void RemoveInterval(IntVar *var, int64_t imin, int64_t imax)=0
virtual void BeginDemonRun(Demon *demon)=0
~PropagationMonitor() override
virtual void RemoveValues(IntVar *var, const std::vector< int64_t > &values)=0
virtual void SetStartRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
virtual void EndConstraintInitialPropagation(Constraint *constraint)=0
virtual void SetValue(IntVar *var, int64_t value)=0
virtual void SetEndRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
void ProcessConstraints()
void ProcessOneDemon(Demon *const demon)
void EnqueueDelayedDemon(Demon *const demon)
void EnqueueVar(Demon *const demon)
void AddConstraint(Constraint *const c)
static constexpr int64_t kTestPeriod
void set_action_on_fail(Solver::Action a)
void reset_action_on_fail()
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void set_variable_to_clean_on_fail(IntVar *var)
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
A search monitor is a simple set of callbacks to monitor all search events.
static constexpr int kNoProgress
virtual void Install()
A search monitors adds itself on the active search.
virtual bool AtSolution()
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 bool LocalOptimum()
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 bool AcceptSolution()
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 set_search_context(absl::string_view search_context)
bool created_by_solve() const
void set_created_by_solve(bool c)
void set_search_depth(int d)
bool should_finish() const
void IncrementSolutionCounter()
void AddEventListener(Solver::MonitorEvent event, SearchMonitor *monitor)
Search(Solver *const s, int)
bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
void set_decision_builder(DecisionBuilder *const db)
void set_search_left_depth(int d)
bool should_restart() const
int64_t unchecked_solution_counter() const
void ApplyDecision(Decision *d)
void IncrementUncheckedSolutionCounter()
void BeginNextDecision(DecisionBuilder *db)
void set_backtrack_at_the_end_of_the_search(bool restore)
void EndInitialPropagation()
void Accept(ModelVisitor *visitor) const
DecisionBuilder * decision_builder() const
bool backtrack_at_the_end_of_the_search() const
void BeginInitialPropagation()
Solver::DecisionModification ModifyDecision()
void AcceptUncheckedNeighbor()
int64_t solution_counter() const
const std::vector< SearchMonitor * > & GetEventListeners(Solver::MonitorEvent event) const
std::string search_context() const
void set_should_finish(bool s)
bool IsUncheckedSolutionLimitReached()
void set_should_restart(bool s)
void RefuteDecision(Decision *d)
void EndNextDecision(DecisionBuilder *db, Decision *d)
int left_search_depth() const
void SetBranchSelector(Solver::BranchSelector bs)
void AfterDecision(Decision *d, bool apply)
virtual void Accept(ModelVisitor *visitor) const
Accepts the given visitor.
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.
This iterator is not stable with respect to deletion.
For the time being, Solver is neither MT_SAFE nor MT_HOT.
static ConstraintSolverParameters DefaultSolverParameters()
--— ConstraintSolverParameters --—
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
bool CurrentlyInSolve() const
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
void ExportProfilingOverview(const std::string &filename)
bool NextSolution()
Search for the next solution in the search tree.
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
int64_t branches() const
The number of branches explored since the creation of the solver.
std::function< DecisionModification()> BranchSelector
int64_t solutions() const
The number of solutions found since the start of the search.
bool NameAllVariables() const
Returns whether all variables should be named.
void AddPropagationMonitor(PropagationMonitor *monitor)
static constexpr int kNumPriorities
Number of priorities for demons.
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
@ NORMAL_PRIORITY
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
std::function< void(Solver *)> Action
void NewSearch(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
Opens a new top level search.
std::function< bool(int64_t)> IndexFilter1
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
int SearchLeftDepth() const
@ 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.
void set_context(absl::string_view context)
Sets the current context of the search.
std::string LocalSearchProfile() const
bool CheckAssignment(Assignment *solution)
Checks whether the given assignment satisfies all relevant constraints.
void AddBacktrackAction(Action a, bool fast)
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
std::string model_name() const
Returns the name of the model.
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
IntExpr * CastExpression(const IntVar *var) const
!defined(SWIG)
DecisionBuilder * MakeConstraintAdder(Constraint *ct)
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
void Accept(ModelVisitor *visitor) const
Accepts the given model visitor.
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
MonitorEvent
Search monitor events.
@ kIsUncheckedSolutionLimitReached
@ kLast
Dummy event whose underlying int is the number of MonitorEvent enums.
std::string SearchContext() const
SearchMonitor * MakeSearchTrace(const std::string &prefix)
int64_t wall_time() const
std::function< IntVar *(int64_t)> Int64ToIntVar
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
void SetSearchContext(Search *search, absl::string_view search_context)
void RestartCurrentSearch()
std::string DebugString() const
!defined(SWIG)
bool Solve(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
ModelVisitor * MakePrintModelVisitor()
Prints the model.
Constraint * MakeFalseConstraint()
This constraint always fails.
Assignment * GetOrCreateLocalSearchState()
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
int64_t failures() const
The number of failures encountered since the creation of the solver.
bool CheckConstraint(Constraint *ct)
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
Decision * MakeFailDecision()
Solver(const std::string &name)
Solver API.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
static int64_t MemoryUsage()
Current memory usage in bytes.
void AddConstraint(Constraint *c)
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
bool SolveAndCommit(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
void AddCastConstraint(CastConstraint *constraint, IntVar *target_var, IntExpr *expr)
void BeginDemonRun(Demon *const demon) override
void RegisterDemon(Demon *const demon) override
void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax) override
void RemoveValues(IntVar *const var, const std::vector< int64_t > &values) override
void RankNotFirst(SequenceVar *const var, int index) override
void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void RankLast(SequenceVar *const var, int index) override
void SetMax(IntExpr *const expr, int64_t new_max) override
void SetEndMin(IntervalVar *const var, int64_t new_min) override
void SetMin(IntExpr *const expr, int64_t new_min) override
IntExpr modifiers.
void SetMax(IntVar *const var, int64_t new_max) override
void Add(PropagationMonitor *const monitor)
Does not take ownership of monitor.
void BeginConstraintInitialPropagation(Constraint *const constraint) override
Propagation events.
void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed) override
void SetMin(IntVar *const var, int64_t new_min) override
IntVar modifiers.
void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max) override
void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void SetValue(IntVar *const var, int64_t value) override
std::string DebugString() const override
void SetRange(IntVar *const var, int64_t new_min, int64_t new_max) 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 SetPerformed(IntervalVar *const var, bool value) override
void SetValues(IntVar *const var, const std::vector< int64_t > &values) override
void PushContext(const std::string &context) override
void RemoveValue(IntVar *const var, int64_t value) override
void EndConstraintInitialPropagation(Constraint *const constraint) override
void RankFirst(SequenceVar *const var, int index) override
SequenceVar modifiers.
void SetStartMax(IntervalVar *const var, int64_t new_max) override
void EndProcessingIntegerVariable(IntVar *const var) override
void EndDemonRun(Demon *const demon) override
void SetDurationMax(IntervalVar *const var, int64_t new_max) override
void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void SetDurationMin(IntervalVar *const var, int64_t new_min) override
void SetEndMax(IntervalVar *const var, int64_t new_max) override
void PopContext() override
void StartProcessingIntegerVariable(IntVar *const var) override
void RankNotLast(SequenceVar *const var, int index) override
#define CP_DO_FAIL(search)
ABSL_FLAG(bool, cp_trace_propagation, false, "Trace propagation events (constraint and demon executions," " variable modifications).")
These flags are used to set the fields in the DefaultSolverParameters proto.
void ConstraintSolverFailsHere()
#define CALL_EVENT_LISTENERS(Event)
const std::string name
A name for logging purposes.
GurobiMPCallbackContext * context
void STLDeleteElements(T *container)
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false
problem is infeasible or unbounded (default).
In SWIG mode, we don't want anything besides these top-level includes.
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
void DeleteDemonProfiler(DemonProfiler *monitor)
int64_t GetProcessMemoryUsage()
GetProcessMemoryUsage.
void RestoreBoolValue(IntVar *var)
--— Trail --—
ModelCache * BuildModelCache(Solver *solver)
PropagationMonitor * BuildTrace(Solver *s)
void AcceptNeighbor(Search *search)
Notifies the search that a neighbor has been accepted by local search.
void AcceptUncheckedNeighbor(Search *search)
DemonProfiler * BuildDemonProfiler(Solver *solver)
bool LocalOptimumReached(Search *search)
Returns true if a local optimum has been reached and cannot be improved.
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
LocalSearchMonitor * BuildLocalSearchMonitorPrimary(Solver *s)
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
PropagationMonitor * BuildPrintTrace(Solver *s)
void InstallDemonProfiler(DemonProfiler *monitor)
--— Forward Declarations and Profiling Support --—
void CleanVariableOnFail(IntVar *var)
---------------— Queue class ---------------—
bool AcceptDelta(Search *search, Assignment *delta, Assignment *deltadelta)
---------------— StateMarker / StateInfo struct --------—
StateInfo(Solver::Action a, bool fast)
Solver::Action reversible_action
StateInfo(void *pinfo, int iinfo)
StateInfo(void *pinfo, int iinfo, int d, int ld)
StateInfo()
additional information on the choice point.
StateMarker(Solver::MarkerType t, const StateInfo &info)
std::vector< int * > rev_int_memory_
std::vector< IntVar * > rev_boolvar_list_
CompressedTrail< int64_t > rev_int64s_
CompressedTrail< int > rev_ints_
std::vector< BaseObject * > rev_object_memory_
CompressedTrail< double > rev_doubles_
std::vector< double * > rev_double_memory_
std::vector< void ** > rev_memory_array_
void BacktrackTo(StateMarker *m)
std::vector< int64_t * > rev_int64_memory_
std::vector< void * > rev_memory_
CompressedTrail< uint64_t > rev_uint64s_
std::vector< bool * > rev_bools_
Trail(int block_size, ConstraintSolverParameters::TrailCompression compression_level)
std::vector< bool > rev_bool_value_
CompressedTrail< void * > rev_ptrs_
std::vector< BaseObject ** > rev_object_array_memory_