32#include "absl/flags/flag.h"
33#include "absl/log/check.h"
34#include "absl/time/time.h"
46 "Trace propagation events (constraint and demon executions,"
47 " variable modifications).");
48ABSL_FLAG(
bool, cp_trace_search,
false,
"Trace search events");
50 "show all constraints added to the solver.");
52 "use PrintModelVisitor on model before solving.");
54 "use StatisticsModelVisitor on model before solving.");
56 "Force failure at the beginning of a search.");
58 "Export profiling overview to file.");
59ABSL_FLAG(
bool, cp_print_local_search_profile,
false,
60 "Print local search profiling data after solving.");
61ABSL_FLAG(
bool, cp_name_variables,
false,
"Force all variables to have names.");
63 "Name variables casted from expressions");
65 "Use small compact table constraint when possible.");
67 "Use the O(n log n) cumulative edge finding algorithm described "
68 "in 'Edge Finding Filtering Algorithm for Discrete Cumulative "
69 "Resources in O(kn log n)' by Petr Vilim, CP 2009.");
71 "Use a O(n^2) cumulative time table propagation algorithm.");
72ABSL_FLAG(
bool, cp_use_cumulative_time_table_sync,
false,
73 "Use a synchronized O(n^2 log n) cumulative time table propagation "
75ABSL_FLAG(
bool, cp_use_sequence_high_demand_tasks,
true,
76 "Use a sequence constraints for cumulative tasks that have a "
77 "demand greater than half of the capacity of the resource.");
78ABSL_FLAG(
bool, cp_use_all_possible_disjunctions,
true,
79 "Post temporal disjunctions for all pairs of tasks sharing a "
80 "cumulative resource and that cannot overlap because the sum of "
81 "their demand exceeds the capacity.");
83 "Do not post the edge finder in the cumulative constraints if "
84 "it contains more than this number of tasks");
86 "Diffn constraint adds redundant cumulative constraint");
88 "If true, rmq's will be used in element expressions.");
90 "Number of solutions explored between two solution checks during "
93 "Random seed used in several (but not all) random number "
94 "generators used by the CP solver. Use -1 to auto-generate an"
95 "undeterministic random seed.");
100#pragma warning(disable : 4351 4355)
108template <
typename T,
typename MethodPointer,
typename... Args>
109void ForAll(
const std::vector<T*>& objects, MethodPointer method,
110 const Args&... args) {
111 for (T*
const object : objects) {
112 DCHECK(
object !=
nullptr);
113 (
object->*method)(args...);
119constexpr typename std::underlying_type<E>::type to_underlying(E e) {
120 return static_cast<typename std::underlying_type<E>::type
>(e);
139 absl::GetFlag(FLAGS_cp_print_local_search_profile));
141 absl::GetFlag(FLAGS_cp_print_local_search_profile));
147 absl::GetFlag(FLAGS_cp_print_added_constraints));
150 absl::GetFlag(FLAGS_cp_use_cumulative_edge_finder));
152 absl::GetFlag(FLAGS_cp_use_cumulative_time_table));
154 absl::GetFlag(FLAGS_cp_use_cumulative_time_table_sync));
156 absl::GetFlag(FLAGS_cp_use_sequence_high_demand_tasks));
158 absl::GetFlag(FLAGS_cp_use_all_possible_disjunctions));
163 absl::GetFlag(FLAGS_cp_check_solution_period));
183 return parameters_.profile_propagation() ||
184 !parameters_.profile_file().empty();
188 return parameters_.profile_local_search() ||
189 parameters_.print_local_search_profile();
193 return parameters_.trace_propagation();
197 return parameters_.name_all_variables();
209 if (stamp_ < std::numeric_limits<uint64_t>::max()) {
215 if (stamp_ == std::numeric_limits<uint64_t>::max()) {
233 clean_action_(nullptr),
234 clean_variable_(nullptr),
236 instruments_demons_(s->InstrumentsDemons()) {}
246 if (--freeze_level_ == 0) {
252 demon->set_stamp(stamp_ - 1);
253 if (!instruments_demons_) {
255 solver_->TopPeriodicCheck();
258 solver_->CheckFail();
260 solver_->GetPropagationMonitor()->BeginDemonRun(demon);
262 solver_->TopPeriodicCheck();
265 solver_->CheckFail();
266 solver_->GetPropagationMonitor()->EndDemonRun(demon);
273 while (!var_queue_.empty() || !delayed_queue_.empty()) {
274 if (!var_queue_.empty()) {
275 Demon*
const demon = var_queue_.front();
276 var_queue_.pop_front();
279 DCHECK(!delayed_queue_.empty());
280 Demon*
const demon = delayed_queue_.front();
281 delayed_queue_.pop_front();
290 if (!instruments_demons_) {
292 Demon*
const demon = *it;
293 if (demon->stamp() < stamp_) {
297 solver_->TopPeriodicCheck();
300 solver_->CheckFail();
305 Demon*
const demon = *it;
306 if (demon->stamp() < stamp_) {
308 solver_->GetPropagationMonitor()->BeginDemonRun(demon);
311 solver_->TopPeriodicCheck();
314 solver_->CheckFail();
315 solver_->GetPropagationMonitor()->EndDemonRun(demon);
329 if (demon->stamp() < stamp_) {
330 demon->set_stamp(stamp_);
331 var_queue_.push_back(demon);
332 if (freeze_level_ == 0) {
340 if (demon->stamp() < stamp_) {
341 demon->set_stamp(stamp_);
342 delayed_queue_.push_back(demon);
349 delayed_queue_.clear();
352 if (clean_action_ !=
nullptr) {
353 clean_action_(solver_);
354 clean_action_ =
nullptr;
355 }
else if (clean_variable_ !=
nullptr) {
357 clean_variable_ =
nullptr;
368 uint64_t
stamp()
const {
return stamp_; }
371 DCHECK(clean_variable_ ==
nullptr);
372 clean_action_ = std::move(a);
376 DCHECK(clean_action_ ==
nullptr);
377 clean_variable_ = var;
381 DCHECK(clean_variable_ ==
nullptr);
382 clean_action_ =
nullptr;
386 to_add_.push_back(c);
396 for (
int counter = 0; counter < to_add_.size(); ++counter) {
397 Constraint*
const constraint = to_add_[counter];
408 std::deque<Demon*> var_queue_;
409 std::deque<Demon*> delayed_queue_;
413 uint32_t freeze_level_;
417 std::vector<Constraint*> to_add_;
419 const bool instruments_demons_;
468 int rev_int64_index_;
469 int rev_uint64_index_;
470 int rev_double_index_;
472 int rev_boolvar_list_index_;
473 int rev_bools_index_;
474 int rev_int_memory_index_;
475 int rev_int64_memory_index_;
476 int rev_double_memory_index_;
477 int rev_object_memory_index_;
478 int rev_object_array_memory_index_;
479 int rev_memory_index_;
480 int rev_memory_array_index_;
488 rev_uint64_index_(0),
489 rev_double_index_(0),
491 rev_boolvar_list_index_(0),
493 rev_int_memory_index_(0),
494 rev_int64_memory_index_(0),
495 rev_double_memory_index_(0),
496 rev_object_memory_index_(0),
497 rev_object_array_memory_index_(0),
510 addrval() : address_(nullptr) {}
511 explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
512 void restore()
const { (*address_) = old_value_; }
527 explicit TrailPacker(
int block_size) : block_size_(block_size) {}
530 TrailPacker(
const TrailPacker&) =
delete;
531 TrailPacker& operator=(
const TrailPacker&) =
delete;
532 virtual ~TrailPacker() {}
533 int input_size()
const {
return block_size_ *
sizeof(addrval<T>); }
534 virtual void Pack(
const addrval<T>* block, std::string* packed_block) = 0;
535 virtual void Unpack(
const std::string& packed_block, addrval<T>* block) = 0;
538 const int block_size_;
542class NoCompressionTrailPacker :
public TrailPacker<T> {
544 explicit NoCompressionTrailPacker(
int block_size)
545 : TrailPacker<
T>(block_size) {}
548 NoCompressionTrailPacker(
const NoCompressionTrailPacker&) =
delete;
549 NoCompressionTrailPacker& operator=(
const NoCompressionTrailPacker&) =
delete;
550 ~NoCompressionTrailPacker()
override {}
551 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
552 DCHECK(block !=
nullptr);
553 DCHECK(packed_block !=
nullptr);
554 absl::string_view block_str(
reinterpret_cast<const char*
>(block),
556 packed_block->assign(block_str.data(), block_str.size());
558 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
559 DCHECK(block !=
nullptr);
560 memcpy(block, packed_block.c_str(), packed_block.size());
565class ZlibTrailPacker :
public TrailPacker<T> {
567 explicit ZlibTrailPacker(
int block_size)
568 : TrailPacker<
T>(block_size),
569 tmp_size_(compressBound(this->input_size())),
570 tmp_block_(new char[tmp_size_]) {}
573 ZlibTrailPacker(
const ZlibTrailPacker&) =
delete;
574 ZlibTrailPacker& operator=(
const ZlibTrailPacker&) =
delete;
576 ~ZlibTrailPacker()
override {}
578 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
579 DCHECK(block !=
nullptr);
580 DCHECK(packed_block !=
nullptr);
581 uLongf size = tmp_size_;
583 compress(
reinterpret_cast<Bytef*
>(tmp_block_.get()), &size,
584 reinterpret_cast<const Bytef*
>(block), this->input_size());
585 CHECK_EQ(Z_OK, result);
586 absl::string_view block_str;
587 block_str = absl::string_view(tmp_block_.get(), size);
588 packed_block->assign(block_str.data(), block_str.size());
591 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
592 DCHECK(block !=
nullptr);
593 uLongf size = this->input_size();
595 uncompress(
reinterpret_cast<Bytef*
>(block), &size,
596 reinterpret_cast<const Bytef*
>(packed_block.c_str()),
597 packed_block.size());
598 CHECK_EQ(Z_OK, result);
602 const uint64_t tmp_size_;
603 std::unique_ptr<char[]> tmp_block_;
607class CompressedTrail {
611 ConstraintSolverParameters::TrailCompression compression_level)
612 : block_size_(block_size),
614 free_blocks_(nullptr),
615 data_(new addrval<
T>[block_size]),
616 buffer_(new addrval<
T>[block_size]),
620 switch (compression_level) {
621 case ConstraintSolverParameters::NO_COMPRESSION: {
622 packer_.reset(
new NoCompressionTrailPacker<T>(block_size));
625 case ConstraintSolverParameters::COMPRESS_WITH_ZLIB: {
626 packer_.reset(
new ZlibTrailPacker<T>(block_size));
630 LOG(ERROR) <<
"Should not be here";
639 memset(data_.get(), 0,
sizeof(*data_.get()) * block_size);
640 memset(buffer_.get(), 0,
sizeof(*buffer_.get()) * block_size);
644 FreeBlocks(free_blocks_);
646 const addrval<T>& Back()
const {
648 DCHECK_GT(current_, 0);
649 return data_[current_ - 1];
657 current_ = block_size_;
658 buffer_used_ =
false;
659 }
else if (blocks_ !=
nullptr) {
660 packer_->Unpack(blocks_->compressed, data_.get());
662 current_ = block_size_;
668 void PushBack(
const addrval<T>& addr_val) {
669 if (current_ >= block_size_) {
672 packer_->Pack(buffer_.get(), &blocks_->compressed);
681 data_[current_] = addr_val;
685 int64_t size()
const {
return size_; }
689 std::string compressed;
693 void FreeTopBlock() {
694 Block* block = blocks_;
695 blocks_ = block->next;
696 block->compressed.clear();
697 block->next = free_blocks_;
698 free_blocks_ = block;
701 Block* block =
nullptr;
702 if (free_blocks_ !=
nullptr) {
703 block = free_blocks_;
704 free_blocks_ = block->next;
708 block->next = blocks_;
711 void FreeBlocks(Block* blocks) {
712 while (
nullptr != blocks) {
713 Block* next = blocks->next;
719 std::unique_ptr<TrailPacker<T>> packer_;
720 const int block_size_;
723 std::unique_ptr<addrval<T>[]> data_;
724 std::unique_ptr<addrval<T>[]> buffer_;
758 :
rev_ints_(block_size, compression_level),
762 rev_ptrs_(block_size, compression_level) {}
765 int target = m->rev_int_index_;
766 for (
int curr =
rev_ints_.size(); curr > target; --curr) {
767 const addrval<int>& cell =
rev_ints_.Back();
773 target = m->rev_int64_index_;
774 for (
int curr =
rev_int64s_.size(); curr > target; --curr) {
781 target = m->rev_uint64_index_;
782 for (
int curr =
rev_uint64s_.size(); curr > target; --curr) {
789 target = m->rev_double_index_;
790 for (
int curr =
rev_doubles_.size(); curr > target; --curr) {
797 target = m->rev_ptr_index_;
798 for (
int curr =
rev_ptrs_.size(); curr > target; --curr) {
799 const addrval<void*>& cell =
rev_ptrs_.Back();
805 target = m->rev_boolvar_list_index_;
813 target = m->rev_bools_index_;
814 for (
int curr =
rev_bools_.size() - 1; curr >= target; --curr) {
820 target = m->rev_int_memory_index_;
826 target = m->rev_int64_memory_index_;
832 target = m->rev_double_memory_index_;
838 target = m->rev_object_memory_index_;
844 target = m->rev_object_array_memory_index_;
851 target = m->rev_memory_index_;
852 for (
int curr =
rev_memory_.size() - 1; curr >= target; --curr) {
854 ::operator
delete(
reinterpret_cast<char*
>(
rev_memory_[curr]));
863 target = m->rev_memory_array_index_;
872void Solver::InternalSaveValue(
int* valptr) {
873 trail_->rev_ints_.PushBack(addrval<int>(valptr));
876void Solver::InternalSaveValue(int64_t* valptr) {
877 trail_->rev_int64s_.PushBack(addrval<int64_t>(valptr));
880void Solver::InternalSaveValue(uint64_t* valptr) {
881 trail_->rev_uint64s_.PushBack(addrval<uint64_t>(valptr));
884void Solver::InternalSaveValue(
double* valptr) {
885 trail_->rev_doubles_.PushBack(addrval<double>(valptr));
888void Solver::InternalSaveValue(
void** valptr) {
889 trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
895void Solver::InternalSaveValue(
bool* valptr) {
896 trail_->rev_bools_.push_back(valptr);
897 trail_->rev_bool_value_.push_back(*valptr);
902 trail_->rev_object_memory_.push_back(ptr);
906int* Solver::SafeRevAllocArray(
int* ptr) {
908 trail_->rev_int_memory_.push_back(ptr);
912int64_t* Solver::SafeRevAllocArray(int64_t* ptr) {
914 trail_->rev_int64_memory_.push_back(ptr);
918double* Solver::SafeRevAllocArray(
double* ptr) {
920 trail_->rev_double_memory_.push_back(ptr);
924uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) {
926 trail_->rev_int64_memory_.push_back(
reinterpret_cast<int64_t*
>(ptr));
932 trail_->rev_object_array_memory_.push_back(ptr);
937 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
938 return reinterpret_cast<IntVar**
>(in);
942 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
943 return reinterpret_cast<IntExpr**
>(in);
947 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
951void* Solver::UnsafeRevAllocAux(
void* ptr) {
953 trail_->rev_memory_.push_back(ptr);
957void** Solver::UnsafeRevAllocArrayAux(
void** ptr) {
959 trail_->rev_memory_array_.push_back(ptr);
964 solver->trail_->rev_boolvar_list_.push_back(var);
974 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
976 solution_counter_(0),
977 unchecked_solution_counter_(0),
978 decision_builder_(nullptr),
979 created_by_solve_(false),
981 left_search_depth_(0),
982 should_restart_(false),
983 should_finish_(false),
985 jmpbuf_filled_(false),
986 backtrack_at_the_end_of_the_search_(true) {}
994 monitor_event_listeners_(to_underlying(
Solver::MonitorEvent::kLast)),
996 solution_counter_(0),
997 unchecked_solution_counter_(0),
998 decision_builder_(nullptr),
999 created_by_solve_(false),
1001 left_search_depth_(-1),
1002 should_restart_(false),
1003 should_finish_(false),
1004 sentinel_pushed_(0),
1005 jmpbuf_filled_(false),
1006 backtrack_at_the_end_of_the_search_(true) {}
1034 if (monitor !=
nullptr) {
1035 monitor_event_listeners_[to_underlying(event)].push_back(monitor);
1040 return monitor_event_listeners_[to_underlying(event)];
1047 return unchecked_solution_counter_;
1050 decision_builder_ = db;
1059 left_search_depth_++;
1063 return backtrack_at_the_end_of_the_search_;
1066 backtrack_at_the_end_of_the_search_ = restore;
1077 if (should_finish_ || should_restart_) {
1090 void ClearBuffer() {
1091 CHECK(jmpbuf_filled_) <<
"Internal error in backtracking";
1092 jmpbuf_filled_ =
false;
1096 std::vector<StateMarker*> marker_stack_;
1097 std::vector<std::vector<SearchMonitor*>> monitor_event_listeners_;
1098 jmp_buf fail_buffer_;
1099 int64_t solution_counter_;
1100 int64_t unchecked_solution_counter_;
1102 bool created_by_solve_;
1105 int left_search_depth_;
1106 bool should_restart_;
1107 bool should_finish_;
1108 int sentinel_pushed_;
1109 bool jmpbuf_filled_;
1110 bool backtrack_at_the_end_of_the_search_;
1111 std::string search_context_;
1124#ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK
1127#define CP_TRY(search) \
1128 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1129 search->jmpbuf_filled_ = true; \
1130 if (setjmp(search->fail_buffer_) == 0)
1131#define CP_ON_FAIL else
1132#define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1)
1134class FailException {};
1135#define CP_TRY(search) \
1136 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1137 search->jmpbuf_filled_ = true; \
1139#define CP_ON_FAIL catch (FailException&)
1140#define CP_DO_FAIL(search) throw FailException()
1143void Search::JumpBack() {
1144 if (jmpbuf_filled_) {
1145 jmpbuf_filled_ =
false;
1148 std::string explanation =
"Failure outside of search";
1149 solver_->AddConstraint(solver_->MakeFalseConstraint(explanation));
1159 : selector_(
std::move(bs)) {}
1160 ~ApplyBranchSelector()
override {}
1162 Decision*
Next(Solver*
const s)
override {
1163 s->SetBranchSelector(selector_);
1167 std::string DebugString()
const override {
return "Apply(BranchSelector)"; }
1175 selector_ = std::move(bs);
1184 [solve_depth](
Solver* s) {
1190 searches_.back()->SetBranchSelector(std::move(bs));
1194 return RevAlloc(
new ApplyBranchSelector(std::move(bs)));
1204 return searches_.back()->left_search_depth();
1208 if (selector_ !=
nullptr) {
1215 for (
auto& listeners : monitor_event_listeners_) listeners.clear();
1217 left_search_depth_ = 0;
1218 selector_ =
nullptr;
1219 backtrack_at_the_end_of_the_search_ =
true;
1222#define CALL_EVENT_LISTENERS(Event) \
1224 ForAll(GetEventListeners(Solver::MonitorEvent::k##Event), \
1225 &SearchMonitor::Event); \
1232 solution_counter_ = 0;
1233 unchecked_solution_counter_ = 0;
1291 if (!monitor->AcceptSolution()) {
1302 bool should_continue =
false;
1305 if (monitor->AtSolution()) {
1309 should_continue =
true;
1312 return should_continue;
1318 bool continue_at_local_optimum =
false;
1321 if (monitor->AtLocalOptimum()) {
1322 continue_at_local_optimum =
true;
1325 return continue_at_local_optimum;
1332 if (!monitor->AcceptDelta(delta, deltadelta)) {
1348 if (monitor->IsUncheckedSolutionLimitReached()) {
1361 progress = std::max(progress, monitor->ProgressPercent());
1369 if (decision_builder_ !=
nullptr) {
1370 decision_builder_->Accept(visitor);
1374#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
1433 <<
"Were parameters built using Solver::DefaultSolverParameters() ?";
1443 use_fast_local_search_(true),
1453 use_fast_local_search_(true),
1458void Solver::Init() {
1459 CheckSolverParameters(parameters_);
1460 queue_ = std::make_unique<Queue>(
this);
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();
1560 return TopLevelSearch()->solution_counter();
1564 return TopLevelSearch()->unchecked_solution_counter();
1567void Solver::IncrementUncheckedSolutionCounter() {
1571bool Solver::IsUncheckedSolutionLimitReached() {
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);
1669 queue_->ExecuteAll(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() {
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) {
1900 print_trace_->Install();
1903 print_trace_ =
nullptr;
1904 if (parameters_.trace_propagation()) {
1906 print_trace_->Install();
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_];
2329 Constraint*
const ct = constraints_list_[index];
2330 if (ct->
name().empty()) {
2331 LOG(INFO) <<
"Failing constraint = " << ct->
DebugString();
2333 LOG(INFO) <<
"Failing constraint = " << ct->
name() <<
":"
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) {
2439 const std::string* name =
gtl::FindOrNull(propagation_object_names_,
object);
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;
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";
2733 [[maybe_unused]]
const std::string& type_name) {}
2735 [[maybe_unused]]
const std::string& type_name) {}
2738 [[maybe_unused]]
const std::string& type_name,
2739 [[maybe_unused]]
const Constraint*
const constraint) {}
2741 [[maybe_unused]]
const std::string& type_name,
2742 [[maybe_unused]]
const Constraint*
const constraint) {}
2745 [[maybe_unused]]
const std::string& type) {}
2750 [[maybe_unused]]
const std::string& type_name,
2751 [[maybe_unused]]
const IntExpr*
const expr) {}
2753 [[maybe_unused]]
const std::string& type_name,
2754 [[maybe_unused]]
const IntExpr*
const expr) {}
2757 [[maybe_unused]]
const IntVar*
const variable,
IntExpr*
const delegate) {
2758 if (delegate !=
nullptr) {
2764 [[maybe_unused]]
const IntVar*
const variable,
2765 [[maybe_unused]]
const std::string& operation,
2766 [[maybe_unused]] int64_t value,
IntVar*
const delegate) {
2767 if (delegate !=
nullptr) {
2773 [[maybe_unused]]
const IntervalVar*
const variable,
2774 [[maybe_unused]]
const std::string& operation,
2775 [[maybe_unused]] int64_t value,
IntervalVar*
const delegate) {
2776 if (delegate !=
nullptr) {
2782 for (
int i = 0; i < variable->
size(); ++i) {
2788 [[maybe_unused]]
const std::string& arg_name,
2789 [[maybe_unused]] int64_t value) {}
2792 [[maybe_unused]]
const std::string& arg_name,
2793 [[maybe_unused]]
const std::vector<int64_t>& values) {}
2796 [[maybe_unused]]
const std::string& arg_name,
2800 [[maybe_unused]]
const std::string& arg_name,
IntExpr*
const argument) {
2805 [[maybe_unused]]
const std::string& arg_name,
2809 [[maybe_unused]]
const std::string& arg_name,
2810 const std::vector<IntVar*>& arguments) {
2815 [[maybe_unused]]
const std::string& arg_name,
IntervalVar*
const argument) {
2820 [[maybe_unused]]
const std::string& arg_name,
2821 const std::vector<IntervalVar*>& arguments) {
2826 [[maybe_unused]]
const std::string& arg_name,
SequenceVar*
const argument) {
2831 [[maybe_unused]]
const std::string& arg_name,
2832 const std::vector<SequenceVar*>& arguments) {
2840 int64_t index_max) {
2841 if (filter !=
nullptr) {
2842 std::vector<int64_t> cached_results;
2843 for (
int i = index_min; i <= index_max; ++i) {
2844 cached_results.push_back(filter(i));
2856 CHECK(eval !=
nullptr);
2857 std::vector<int64_t> cached_results;
2858 for (
int i = index_min; i <= index_max; ++i) {
2859 cached_results.push_back(eval(i));
2869 const std::string& arg_name,
2870 int64_t index_max) {
2871 CHECK(eval !=
nullptr);
2872 std::vector<int64_t> cached_results;
2873 for (
int i = 0; i <= index_max; ++i) {
2874 cached_results.push_back(eval(i));
2889 [[maybe_unused]]
bool apply) {}
2909 for (std::underlying_type<Solver::MonitorEvent>::type event = 0;
2916 solver()->searches_.back()->AddEventListener(event,
this);
3008 monitor->SetMin(expr, new_min);
3014 monitor->SetMax(expr, new_max);
3019 int64_t new_max)
override {
3021 monitor->SetRange(expr, new_min, new_max);
3028 monitor->SetMin(var, new_min);
3034 monitor->SetMax(var, new_max);
3040 monitor->SetRange(var, new_min, new_max);
3057 const std::vector<int64_t>& values)
override {
3062 const std::vector<int64_t>& values)
override {
3076 int64_t new_max)
override {
3090 int64_t new_max)
override {
3103 int64_t new_max)
override {
3129 const std::vector<int>& rank_last,
3130 const std::vector<int>& unperformed)
override {
3132 rank_last, unperformed);
3137 if (monitor !=
nullptr) {
3138 monitors_.push_back(monitor);
3149 std::vector<PropagationMonitor*> monitors_;
3156 reinterpret_cast<class
Trace*
>(propagation_monitor_.get())->
Add(monitor);
3160 return propagation_monitor_.get();
3183 neighbor_found, delta, deltadelta);
3189 bool neighbor_found)
override {
3197 bool neighbor_found)
override {
3207 bool IsActive()
const override {
return !monitors_.empty(); }
3211 if (monitor !=
nullptr) {
3212 monitors_.push_back(monitor);
3221 return "LocalSearchMonitorPrimary";
3225 std::vector<LocalSearchMonitor*> monitors_;
3234 local_search_monitor_.get())
3239 return local_search_monitor_.get();
3243 absl::string_view search_context) {
3260 if (local_search_state_ ==
nullptr) {
3261 local_search_state_ = std::make_unique<Assignment>(
this);
3263 return local_search_state_.get();
3269 : db_(db), name_(db_->
GetName()), seconds_(0) {}
3277 if (timer_.IsRunning()) {
3279 seconds_ += timer_.Get();
3284 Decision*
const decision = db_->Next(solver);
3286 seconds_ += timer_.Get();
3292 return db_->DebugString();
3296 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {
3297 db_->AppendMonitors(solver, extras);
3301 db_->Accept(visitor);
3318 VLOG(3) <<
"Unknown constraint " <<
DebugString();
3323 return solver()->cast_constraints_.contains(
this);
3332 VLOG(3) <<
"Unknown expression " <<
DebugString();
virtual std::string DebugString() const
::operations_research::ConstraintSolverParameters_TrailCompression compress_trail() const
void set_profile_file(Arg_ &&arg, Args_... args)
void set_disable_solve(bool value)
void set_print_model_stats(bool value)
void set_trail_block_size(::int32_t value)
::int32_t array_split_size() const
void set_print_local_search_profile(bool value)
void set_print_model(bool value)
void set_profile_propagation(bool value)
void set_use_sequence_high_demand_tasks(bool value)
void set_check_solution_period(::int32_t value)
void set_array_split_size(::int32_t value)
ConstraintSolverParameters_TrailCompression TrailCompression
void set_use_cumulative_time_table(bool value)
void set_profile_local_search(bool value)
bool print_model_stats() const
void set_diffn_use_cumulative(bool value)
static constexpr TrailCompression NO_COMPRESSION
void set_print_added_constraints(bool value)
void set_use_cumulative_edge_finder(bool value)
void set_store_names(bool value)
void set_trace_search(bool value)
void set_trace_propagation(bool value)
void set_max_edge_finder_size(::int32_t value)
::int32_t trail_block_size() const
void set_name_all_variables(bool value)
void set_use_element_rmq(bool value)
void set_compress_trail(::operations_research::ConstraintSolverParameters_TrailCompression value)
void set_use_small_table(bool value)
void set_use_cumulative_time_table_sync(bool value)
void set_use_all_possible_disjunctions(bool value)
void set_name_cast_variables(bool value)
void set_num_branches(::int64_t value)
void set_num_solutions(::int64_t value)
void set_num_failures(::int64_t value)
void set_duration_seconds(double value)
void set_bytes_used(::int64_t value)
std::string DebugString() const override
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
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
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.
void Accept(ModelVisitor *visitor) const override
Accepts the given visitor.
virtual void Accept(ModelVisitor *visitor) const =0
Accepts the given visitor.
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)
void Install() override
Install itself on the solver.
void BeginFilterNeighbor(const LocalSearchOperator *op) override
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
void BeginFiltering(const LocalSearchFilter *filter) override
LocalSearchMonitor(Solver *solver)
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
The base class for all local search operators.
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)
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[]
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 kIndex3Argument[]
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)
std::string DebugString() const override
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)
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 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 bool AtLocalOptimum()
virtual void ExitSearch()
End of the search.
SearchMonitor(Solver *const s)
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.
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()
bool ContinueAtLocalOptimum()
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.
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
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)
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.
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.
void NewSearch(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
int SearchLeftDepth() const
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
@ 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
Returns local search profiling information in a human readable format.
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.
std::function< DecisionModification()> BranchSelector
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
IntExpr * CastExpression(const IntVar *var) const
!defined(SWIG)
DecisionBuilder * MakeConstraintAdder(Constraint *ct)
std::function< void(Solver *)> Action
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.
std::function< bool(int64_t)> IndexFilter1
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
friend class SearchMonitor
std::string SearchContext() const
SearchMonitor * MakeSearchTrace(const std::string &prefix)
std::function< IntVar *(int64_t)> Int64ToIntVar
int64_t wall_time() const
friend class PropagationBaseObject
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)
ConstraintSolverParameters parameters() const
Stored Parameters.
bool Solve(DecisionBuilder *db, const std::vector< SearchMonitor * > &monitors)
ModelVisitor * MakePrintModelVisitor()
Prints the model.
Assignment * GetOrCreateLocalSearchState()
Returns (or creates) an assignment representing the state of local search.
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.
bool AcceptSolution(Search *search) const
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)
Adds the constraint 'c' to the model.
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)
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 Install() override
Install itself on the solver.
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).")
void ConstraintSolverFailsHere()
#define CALL_EVENT_LISTENERS(Event)
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
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
void DeleteDemonProfiler(DemonProfiler *monitor)
int64_t GetProcessMemoryUsage()
void RestoreBoolValue(IntVar *var)
ModelCache * BuildModelCache(Solver *solver)
PropagationMonitor * BuildTrace(Solver *s)
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
void AcceptNeighbor(Search *search)
void AcceptUncheckedNeighbor(Search *search)
DemonProfiler * BuildDemonProfiler(Solver *solver)
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
LocalSearchMonitor * BuildLocalSearchMonitorPrimary(Solver *s)
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
bool ContinueAtLocalOptimum(Search *search)
PropagationMonitor * BuildPrintTrace(Solver *s)
void InstallDemonProfiler(DemonProfiler *monitor)
void CleanVariableOnFail(IntVar *var)
bool AcceptDelta(Search *search, Assignment *delta, Assignment *deltadelta)
StateInfo(Solver::Action a, bool fast)
Solver::Action reversible_action
StateInfo(void *pinfo, int iinfo)
StateInfo(void *pinfo, int iinfo, int d, int ld)
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_