29#include "absl/memory/memory.h"
30#include "absl/time/clock.h"
31#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...);
123 ConstraintSolverParameters params;
124 params.set_compress_trail(ConstraintSolverParameters::NO_COMPRESSION);
125 params.set_trail_block_size(8000);
126 params.set_array_split_size(16);
127 params.set_store_names(
true);
128 params.set_profile_propagation(!absl::GetFlag(FLAGS_cp_profile_file).empty());
129 params.set_trace_propagation(absl::GetFlag(FLAGS_cp_trace_propagation));
130 params.set_trace_search(absl::GetFlag(FLAGS_cp_trace_search));
131 params.set_name_all_variables(absl::GetFlag(FLAGS_cp_name_variables));
132 params.set_profile_file(absl::GetFlag(FLAGS_cp_profile_file));
133 params.set_profile_local_search(
134 absl::GetFlag(FLAGS_cp_print_local_search_profile));
135 params.set_print_local_search_profile(
136 absl::GetFlag(FLAGS_cp_print_local_search_profile));
137 params.set_print_model(absl::GetFlag(FLAGS_cp_print_model));
138 params.set_print_model_stats(absl::GetFlag(FLAGS_cp_model_stats));
139 params.set_disable_solve(absl::GetFlag(FLAGS_cp_disable_solve));
140 params.set_name_cast_variables(absl::GetFlag(FLAGS_cp_name_cast_variables));
141 params.set_print_added_constraints(
142 absl::GetFlag(FLAGS_cp_print_added_constraints));
143 params.set_use_small_table(absl::GetFlag(FLAGS_cp_use_small_table));
144 params.set_use_cumulative_edge_finder(
145 absl::GetFlag(FLAGS_cp_use_cumulative_edge_finder));
146 params.set_use_cumulative_time_table(
147 absl::GetFlag(FLAGS_cp_use_cumulative_time_table));
148 params.set_use_cumulative_time_table_sync(
149 absl::GetFlag(FLAGS_cp_use_cumulative_time_table_sync));
150 params.set_use_sequence_high_demand_tasks(
151 absl::GetFlag(FLAGS_cp_use_sequence_high_demand_tasks));
152 params.set_use_all_possible_disjunctions(
153 absl::GetFlag(FLAGS_cp_use_all_possible_disjunctions));
154 params.set_max_edge_finder_size(absl::GetFlag(FLAGS_cp_max_edge_finder_size));
155 params.set_diffn_use_cumulative(absl::GetFlag(FLAGS_cp_diffn_use_cumulative));
156 params.set_use_element_rmq(absl::GetFlag(FLAGS_cp_use_element_rmq));
157 params.set_check_solution_period(
158 absl::GetFlag(FLAGS_cp_check_solution_period));
178 return parameters_.profile_propagation() ||
179 !parameters_.profile_file().empty();
183 return parameters_.profile_local_search() ||
184 parameters_.print_local_search_profile();
188 return parameters_.trace_propagation();
192 return parameters_.name_all_variables();
228 clean_action_(nullptr),
229 clean_variable_(nullptr),
231 instruments_demons_(s->InstrumentsDemons()) {}
241 if (--freeze_level_ == 0) {
247 demon->set_stamp(stamp_ - 1);
248 if (!instruments_demons_) {
268 while (!var_queue_.empty() || !delayed_queue_.empty()) {
269 if (!var_queue_.empty()) {
270 Demon*
const demon = var_queue_.front();
271 var_queue_.pop_front();
274 DCHECK(!delayed_queue_.empty());
275 Demon*
const demon = delayed_queue_.front();
276 delayed_queue_.pop_front();
285 if (!instruments_demons_) {
287 Demon*
const demon = *it;
288 if (demon->stamp() < stamp_) {
300 Demon*
const demon = *it;
301 if (demon->stamp() < stamp_) {
324 if (demon->stamp() < stamp_) {
325 demon->set_stamp(stamp_);
326 var_queue_.push_back(demon);
327 if (freeze_level_ == 0) {
335 if (demon->stamp() < stamp_) {
336 demon->set_stamp(stamp_);
337 delayed_queue_.push_back(demon);
344 delayed_queue_.clear();
347 if (clean_action_ !=
nullptr) {
348 clean_action_(solver_);
349 clean_action_ =
nullptr;
350 }
else if (clean_variable_ !=
nullptr) {
352 clean_variable_ =
nullptr;
363 uint64_t
stamp()
const {
return stamp_; }
366 DCHECK(clean_variable_ ==
nullptr);
367 clean_action_ = std::move(
a);
371 DCHECK(clean_action_ ==
nullptr);
372 clean_variable_ =
var;
376 DCHECK(clean_variable_ ==
nullptr);
377 clean_action_ =
nullptr;
381 to_add_.push_back(c);
391 for (
int counter = 0; counter < to_add_.size(); ++counter) {
392 Constraint*
const constraint = to_add_[counter];
403 std::deque<Demon*> var_queue_;
404 std::deque<Demon*> delayed_queue_;
408 uint32_t freeze_level_;
412 std::vector<Constraint*> to_add_;
414 const bool instruments_demons_;
463 int rev_int64_index_;
464 int rev_uint64_index_;
465 int rev_double_index_;
467 int rev_boolvar_list_index_;
468 int rev_bools_index_;
469 int rev_int_memory_index_;
470 int rev_int64_memory_index_;
471 int rev_double_memory_index_;
472 int rev_object_memory_index_;
473 int rev_object_array_memory_index_;
474 int rev_memory_index_;
475 int rev_memory_array_index_;
483 rev_uint64_index_(0),
484 rev_double_index_(0),
486 rev_boolvar_list_index_(0),
488 rev_int_memory_index_(0),
489 rev_int64_memory_index_(0),
490 rev_double_memory_index_(0),
491 rev_object_memory_index_(0),
492 rev_object_array_memory_index_(0),
505 addrval() : address_(nullptr) {}
506 explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
507 void restore()
const { (*address_) = old_value_; }
522 explicit TrailPacker(
int block_size) : block_size_(block_size) {}
523 virtual ~TrailPacker() {}
524 int input_size()
const {
return block_size_ *
sizeof(addrval<T>); }
525 virtual void Pack(
const addrval<T>* block, std::string* packed_block) = 0;
526 virtual void Unpack(
const std::string& packed_block, addrval<T>* block) = 0;
529 const int block_size_;
534class NoCompressionTrailPacker :
public TrailPacker<T> {
536 explicit NoCompressionTrailPacker(
int block_size)
537 : TrailPacker<T>(block_size) {}
538 ~NoCompressionTrailPacker()
override {}
539 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
541 DCHECK(packed_block !=
nullptr);
542 absl::string_view block_str(
reinterpret_cast<const char*
>(block),
544 packed_block->assign(block_str.data(), block_str.size());
546 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
548 memcpy(block, packed_block.c_str(), packed_block.size());
556class ZlibTrailPacker :
public TrailPacker<T> {
558 explicit ZlibTrailPacker(
int block_size)
559 : TrailPacker<T>(block_size),
560 tmp_size_(compressBound(this->input_size())),
561 tmp_block_(new char[tmp_size_]) {}
563 ~ZlibTrailPacker()
override {}
565 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
567 DCHECK(packed_block !=
nullptr);
568 uLongf size = tmp_size_;
570 compress(
reinterpret_cast<Bytef*
>(tmp_block_.get()), &size,
571 reinterpret_cast<const Bytef*
>(block), this->input_size());
573 absl::string_view block_str;
574 block_str = absl::string_view(tmp_block_.get(), size);
575 packed_block->assign(block_str.data(), block_str.size());
578 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
580 uLongf size = this->input_size();
582 uncompress(
reinterpret_cast<Bytef*
>(block), &size,
583 reinterpret_cast<const Bytef*
>(packed_block.c_str()),
584 packed_block.size());
589 const uint64_t tmp_size_;
590 std::unique_ptr<char[]> tmp_block_;
595class CompressedTrail {
599 ConstraintSolverParameters::TrailCompression compression_level)
600 : block_size_(block_size),
602 free_blocks_(nullptr),
603 data_(new addrval<T>[block_size]),
604 buffer_(new addrval<T>[block_size]),
608 switch (compression_level) {
609 case ConstraintSolverParameters::NO_COMPRESSION: {
610 packer_.reset(
new NoCompressionTrailPacker<T>(block_size));
613 case ConstraintSolverParameters::COMPRESS_WITH_ZLIB: {
614 packer_.reset(
new ZlibTrailPacker<T>(block_size));
618 LOG(ERROR) <<
"Should not be here";
627 memset(data_.get(), 0,
sizeof(*data_.get()) * block_size);
628 memset(buffer_.get(), 0,
sizeof(*buffer_.get()) * block_size);
632 FreeBlocks(free_blocks_);
634 const addrval<T>& Back()
const {
646 buffer_used_ =
false;
647 }
else if (blocks_ !=
nullptr) {
648 packer_->Unpack(blocks_->compressed, data_.get());
656 void PushBack(
const addrval<T>& addr_val) {
660 packer_->Pack(buffer_.get(), &blocks_->compressed);
673 int64_t size()
const {
return size_; }
681 void FreeTopBlock() {
682 Block* block = blocks_;
683 blocks_ = block->next;
684 block->compressed.clear();
685 block->next = free_blocks_;
686 free_blocks_ = block;
689 Block* block =
nullptr;
690 if (free_blocks_ !=
nullptr) {
691 block = free_blocks_;
692 free_blocks_ = block->next;
696 block->next = blocks_;
699 void FreeBlocks(Block* blocks) {
700 while (
nullptr != blocks) {
701 Block*
next = blocks->next;
707 std::unique_ptr<TrailPacker<T> > packer_;
708 const int block_size_;
711 std::unique_ptr<addrval<T>[]> data_;
712 std::unique_ptr<addrval<T>[]> buffer_;
745 ConstraintSolverParameters::TrailCompression compression_level)
746 :
rev_ints_(block_size, compression_level),
750 rev_ptrs_(block_size, compression_level) {}
753 int target = m->rev_int_index_;
754 for (
int curr =
rev_ints_.size(); curr > target; --curr) {
755 const addrval<int>& cell =
rev_ints_.Back();
761 target = m->rev_int64_index_;
762 for (
int curr =
rev_int64s_.size(); curr > target; --curr) {
769 target = m->rev_uint64_index_;
770 for (
int curr =
rev_uint64s_.size(); curr > target; --curr) {
777 target = m->rev_double_index_;
778 for (
int curr =
rev_doubles_.size(); curr > target; --curr) {
785 target = m->rev_ptr_index_;
786 for (
int curr =
rev_ptrs_.size(); curr > target; --curr) {
787 const addrval<void*>& cell =
rev_ptrs_.Back();
793 target = m->rev_boolvar_list_index_;
801 target = m->rev_bools_index_;
802 for (
int curr =
rev_bools_.size() - 1; curr >= target; --curr) {
808 target = m->rev_int_memory_index_;
814 target = m->rev_int64_memory_index_;
820 target = m->rev_double_memory_index_;
826 target = m->rev_object_memory_index_;
832 target = m->rev_object_array_memory_index_;
839 target = m->rev_memory_index_;
840 for (
int curr =
rev_memory_.size() - 1; curr >= target; --curr) {
842 ::operator
delete(
reinterpret_cast<char*
>(
rev_memory_[curr]));
851 target = m->rev_memory_array_index_;
860void Solver::InternalSaveValue(
int* valptr) {
861 trail_->rev_ints_.PushBack(addrval<int>(valptr));
864void Solver::InternalSaveValue(int64_t* valptr) {
865 trail_->rev_int64s_.PushBack(addrval<int64_t>(valptr));
868void Solver::InternalSaveValue(uint64_t* valptr) {
869 trail_->rev_uint64s_.PushBack(addrval<uint64_t>(valptr));
872void Solver::InternalSaveValue(
double* valptr) {
873 trail_->rev_doubles_.PushBack(addrval<double>(valptr));
876void Solver::InternalSaveValue(
void** valptr) {
877 trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
883void Solver::InternalSaveValue(
bool* valptr) {
884 trail_->rev_bools_.push_back(valptr);
885 trail_->rev_bool_value_.push_back(*valptr);
888BaseObject* Solver::SafeRevAlloc(BaseObject* ptr) {
890 trail_->rev_object_memory_.push_back(ptr);
894int* Solver::SafeRevAllocArray(
int* ptr) {
896 trail_->rev_int_memory_.push_back(ptr);
900int64_t* Solver::SafeRevAllocArray(int64_t* ptr) {
902 trail_->rev_int64_memory_.push_back(ptr);
906double* Solver::SafeRevAllocArray(
double* ptr) {
908 trail_->rev_double_memory_.push_back(ptr);
912uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) {
914 trail_->rev_int64_memory_.push_back(
reinterpret_cast<int64_t*
>(ptr));
918BaseObject** Solver::SafeRevAllocArray(BaseObject** ptr) {
920 trail_->rev_object_array_memory_.push_back(ptr);
924IntVar** Solver::SafeRevAllocArray(IntVar** ptr) {
925 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
926 return reinterpret_cast<IntVar**
>(in);
929IntExpr** Solver::SafeRevAllocArray(IntExpr** ptr) {
930 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
931 return reinterpret_cast<IntExpr**
>(in);
934Constraint** Solver::SafeRevAllocArray(Constraint** ptr) {
935 BaseObject** in = SafeRevAllocArray(
reinterpret_cast<BaseObject**
>(ptr));
939void* Solver::UnsafeRevAllocAux(
void* ptr) {
941 trail_->rev_memory_.push_back(ptr);
945void** Solver::UnsafeRevAllocArrayAux(
void** ptr) {
947 trail_->rev_memory_array_.push_back(ptr);
952 solver->trail_->rev_boolvar_list_.push_back(
var);
963 solution_counter_(0),
964 unchecked_solution_counter_(0),
965 decision_builder_(nullptr),
966 created_by_solve_(false),
968 left_search_depth_(0),
969 should_restart_(false),
970 should_finish_(false),
972 jmpbuf_filled_(false),
973 backtrack_at_the_end_of_the_search_(true) {}
982 solution_counter_(0),
983 unchecked_solution_counter_(0),
984 decision_builder_(nullptr),
985 created_by_solve_(false),
987 left_search_depth_(-1),
988 should_restart_(false),
989 should_finish_(false),
991 jmpbuf_filled_(false),
992 backtrack_at_the_end_of_the_search_(true) {}
1025 return unchecked_solution_counter_;
1028 decision_builder_ = db;
1037 left_search_depth_++;
1041 return backtrack_at_the_end_of_the_search_;
1044 backtrack_at_the_end_of_the_search_ = restore;
1055 if (should_finish_ || should_restart_) {
1068 void ClearBuffer() {
1069 CHECK(jmpbuf_filled_) <<
"Internal error in backtracking";
1070 jmpbuf_filled_ =
false;
1074 std::vector<StateMarker*> marker_stack_;
1075 std::vector<SearchMonitor*> monitors_;
1076 jmp_buf fail_buffer_;
1077 int64_t solution_counter_;
1078 int64_t unchecked_solution_counter_;
1080 bool created_by_solve_;
1083 int left_search_depth_;
1084 bool should_restart_;
1085 bool should_finish_;
1086 int sentinel_pushed_;
1087 bool jmpbuf_filled_;
1088 bool backtrack_at_the_end_of_the_search_;
1089 std::string search_context_;
1102#ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK
1105#define CP_TRY(search) \
1106 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1107 search->jmpbuf_filled_ = true; \
1108 if (setjmp(search->fail_buffer_) == 0)
1109#define CP_ON_FAIL else
1110#define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1)
1112class FailException {};
1113#define CP_TRY(search) \
1114 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \
1115 search->jmpbuf_filled_ = true; \
1117#define CP_ON_FAIL catch (FailException&)
1118#define CP_DO_FAIL(search) throw FailException()
1121void Search::JumpBack() {
1122 if (jmpbuf_filled_) {
1123 jmpbuf_filled_ =
false;
1126 std::string explanation =
"Failure outside of search";
1138 ~ApplyBranchSelector()
override {}
1140 Decision* Next(Solver*
const s)
override {
1145 std::string DebugString()
const override {
return "Apply(BranchSelector)"; }
1153 selector_ = std::move(bs);
1162 [solve_depth](
Solver* s) {
1164 s->ActiveSearch()->SetBranchSelector(nullptr);
1168 searches_.back()->SetBranchSelector(std::move(bs));
1172 return RevAlloc(
new ApplyBranchSelector(std::move(bs)));
1182 return searches_.back()->left_search_depth();
1186 if (selector_ !=
nullptr) {
1194 monitors_.push_back(m);
1201 left_search_depth_ = 0;
1202 selector_ =
nullptr;
1203 backtrack_at_the_end_of_the_search_ =
true;
1210 solution_counter_ = 0;
1211 unchecked_solution_counter_ = 0;
1265 if (!monitor->AcceptSolution()) {
1276 bool should_continue =
false;
1278 if (monitor->AtSolution()) {
1282 should_continue =
true;
1285 return should_continue;
1295 if (monitor->LocalOptimum()) {
1305 if (!monitor->AcceptDelta(
delta, deltadelta)) {
1322 if (monitor->IsUncheckedSolutionLimitReached()) {
1336 progress =
std::max(progress, monitor->ProgressPercent());
1343 if (decision_builder_ !=
nullptr) {
1344 decision_builder_->
Accept(visitor);
1367class FailDecision :
public Decision {
1369 void Apply(Solver*
const s)
override { s->Fail(); }
1370 void Refute(Solver*
const s)
override { s->Fail(); }
1375class BalancingDecision :
public Decision {
1377 ~BalancingDecision()
override {}
1378 void Apply(Solver*
const s)
override {}
1379 void Refute(Solver*
const s)
override {}
1390enum SentinelMarker {
1391 INITIAL_SEARCH_SENTINEL = 10000000,
1392 ROOT_NODE_SENTINEL = 20000000,
1393 SOLVER_CTOR_SENTINEL = 40000000
1397extern PropagationMonitor*
BuildTrace(Solver*
const s);
1404void CheckSolverParameters(
const ConstraintSolverParameters&
parameters) {
1406 <<
"Were parameters built using Solver::DefaultSolverParameters() ?";
1411 const ConstraintSolverParameters&
parameters)
1416 use_fast_local_search_(true),
1423 parameters_(DefaultSolverParameters()),
1426 use_fast_local_search_(true),
1431void Solver::Init() {
1432 CheckSolverParameters(parameters_);
1433 queue_ = absl::make_unique<Queue>(
this);
1434 trail_ = absl::make_unique<Trail>(parameters_.trail_block_size(),
1435 parameters_.compress_trail());
1441 filtered_neighbors_ = 0;
1442 accepted_neighbors_ = 0;
1443 optimization_direction_ =
NOT_SET;
1444 timer_ = absl::make_unique<ClockTimer>();
1445 searches_.assign(1,
new Search(
this, 0));
1446 fail_stamp_ = uint64_t{1};
1447 balancing_decision_ = absl::make_unique<BalancingDecision>();
1448 fail_intercept_ =
nullptr;
1449 true_constraint_ =
nullptr;
1450 false_constraint_ =
nullptr;
1451 fail_decision_ = absl::make_unique<FailDecision>();
1452 constraint_index_ = 0;
1453 additional_constraint_index_ = 0;
1455 propagation_monitor_.reset(
BuildTrace(
this));
1457 print_trace_ =
nullptr;
1458 anonymous_variable_index_ = 0;
1459 should_fail_ =
false;
1464 searches_.push_back(
new Search(
this));
1465 PushSentinel(SOLVER_CTOR_SENTINEL);
1466 InitCachedIntConstants();
1467 InitCachedConstraint();
1472 reinterpret_cast<LocalSearchMonitor*
>(local_search_profiler_));
1478 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1492 std::string out =
"Solver(name = \"" + name_ +
"\", state = ";
1495 out +=
"OUTSIDE_SEARCH";
1498 out +=
"IN_ROOT_NODE";
1504 out +=
"AT_SOLUTION";
1507 out +=
"NO_MORE_SOLUTIONS";
1510 out +=
"PROBLEM_INFEASIBLE";
1513 absl::StrAppendFormat(
1515 ", branches = %d, fails = %d, decisions = %d, delayed demon runs = %d, "
1516 "var demon runs = %d, normal demon runs = %d, Run time = %d ms)",
1525 return absl::ToInt64Milliseconds(timer_->GetDuration());
1529 return absl::FromUnixSeconds(0) + timer_->GetDuration();
1540void Solver::IncrementUncheckedSolutionCounter() {
1544bool Solver::IsUncheckedSolutionLimitReached() {
1553 ConstraintSolverStatistics stats;
1554 stats.set_num_branches(
branches());
1555 stats.set_num_failures(
failures());
1558 stats.set_duration_seconds(absl::ToDoubleSeconds(timer_->GetDuration()));
1576 m->rev_int_index_ = trail_->rev_ints_.size();
1577 m->rev_int64_index_ = trail_->rev_int64s_.size();
1578 m->rev_uint64_index_ = trail_->rev_uint64s_.size();
1579 m->rev_double_index_ = trail_->rev_doubles_.size();
1580 m->rev_ptr_index_ = trail_->rev_ptrs_.size();
1581 m->rev_boolvar_list_index_ = trail_->rev_boolvar_list_.size();
1582 m->rev_bools_index_ = trail_->rev_bools_.size();
1583 m->rev_int_memory_index_ = trail_->rev_int_memory_.size();
1584 m->rev_int64_memory_index_ = trail_->rev_int64_memory_.size();
1585 m->rev_double_memory_index_ = trail_->rev_double_memory_.size();
1586 m->rev_object_memory_index_ = trail_->rev_object_memory_.size();
1587 m->rev_object_array_memory_index_ = trail_->rev_object_array_memory_.size();
1588 m->rev_memory_index_ = trail_->rev_memory_.size();
1589 m->rev_memory_array_index_ = trail_->rev_memory_array_.size();
1591 searches_.back()->marker_stack_.push_back(m);
1592 queue_->increase_stamp();
1601 CHECK(!searches_.back()->marker_stack_.empty())
1602 <<
"PopState() on an empty stack";
1603 CHECK(info !=
nullptr);
1604 StateMarker*
const m = searches_.back()->marker_stack_.back();
1606 trail_->BacktrackTo(m);
1610 searches_.back()->marker_stack_.pop_back();
1612 queue_->increase_stamp();
1616void Solver::check_alloc_state() {
1625 LOG(
FATAL) <<
"allocating at a leaf node";
1627 LOG(
FATAL) <<
"This switch was supposed to be exhaustive, but it is not!";
1631void Solver::FreezeQueue() { queue_->Freeze(); }
1633void Solver::UnfreezeQueue() { queue_->Unfreeze(); }
1635void Solver::EnqueueVar(Demon*
const d) { queue_->EnqueueVar(d); }
1637void Solver::EnqueueDelayedDemon(Demon*
const d) {
1638 queue_->EnqueueDelayedDemon(d);
1641void Solver::ExecuteAll(
const SimpleRevFIFO<Demon*>& demons) {
1642 queue_->ExecuteAll(demons);
1645void Solver::EnqueueAll(
const SimpleRevFIFO<Demon*>& demons) {
1646 queue_->EnqueueAll(demons);
1653void Solver::set_action_on_fail(Action
a) {
1654 queue_->set_action_on_fail(std::move(
a));
1657void Solver::set_variable_to_clean_on_fail(IntVar* v) {
1658 queue_->set_variable_to_clean_on_fail(v);
1661void Solver::reset_action_on_fail() { queue_->reset_action_on_fail(); }
1665 if (c == true_constraint_) {
1669 queue_->AddConstraint(c);
1672 DCHECK_LE(constraint_index_, constraints_list_.size());
1673 const int constraint_parent =
1674 constraint_index_ == constraints_list_.size()
1675 ? additional_constraints_parent_list_[additional_constraint_index_]
1676 : constraint_index_;
1677 additional_constraints_list_.push_back(c);
1678 additional_constraints_parent_list_.push_back(constraint_parent);
1680 if (parameters_.print_added_constraints()) {
1683 constraints_list_.push_back(c);
1689 if (constraint !=
nullptr) {
1691 cast_constraints_.insert(constraint);
1692 cast_information_[target_var] =
1705void Solver::ProcessConstraints() {
1708 if (parameters_.print_model()) {
1712 if (parameters_.print_model_stats()) {
1717 if (parameters_.disable_solve()) {
1718 LOG(
INFO) <<
"Forcing early failure";
1723 const int constraints_size = constraints_list_.size();
1724 additional_constraints_list_.clear();
1725 additional_constraints_parent_list_.clear();
1727 for (constraint_index_ = 0; constraint_index_ < constraints_size;
1728 ++constraint_index_) {
1729 Constraint*
const constraint = constraints_list_[constraint_index_];
1730 propagation_monitor_->BeginConstraintInitialPropagation(constraint);
1731 constraint->PostAndPropagate();
1732 propagation_monitor_->EndConstraintInitialPropagation(constraint);
1734 CHECK_EQ(constraints_list_.size(), constraints_size);
1737 for (
int additional_constraint_index_ = 0;
1738 additional_constraint_index_ < additional_constraints_list_.size();
1739 ++additional_constraint_index_) {
1741 additional_constraints_list_[additional_constraint_index_];
1742 const int parent_index =
1743 additional_constraints_parent_list_[additional_constraint_index_];
1744 Constraint*
const parent = constraints_list_[parent_index];
1745 propagation_monitor_->BeginNestedConstraintInitialPropagation(parent,
1747 nested->PostAndPropagate();
1748 propagation_monitor_->EndNestedConstraintInitialPropagation(parent, nested);
1754 DCHECK(searches_.back() !=
nullptr);
1755 return searches_.back()->created_by_solve();
1759 std::vector<SearchMonitor*> monitors;
1760 monitors.push_back(m1);
1761 return Solve(db, monitors);
1765 std::vector<SearchMonitor*> monitors;
1766 return Solve(db, monitors);
1771 std::vector<SearchMonitor*> monitors;
1772 monitors.push_back(m1);
1773 monitors.push_back(m2);
1774 return Solve(db, monitors);
1779 std::vector<SearchMonitor*> monitors;
1780 monitors.push_back(m1);
1781 monitors.push_back(m2);
1782 monitors.push_back(m3);
1783 return Solve(db, monitors);
1789 std::vector<SearchMonitor*> monitors;
1790 monitors.push_back(m1);
1791 monitors.push_back(m2);
1792 monitors.push_back(m3);
1793 monitors.push_back(m4);
1794 return Solve(db, monitors);
1798 const std::vector<SearchMonitor*>& monitors) {
1800 searches_.back()->set_created_by_solve(
true);
1802 const bool solution_found = searches_.back()->solution_counter() > 0;
1804 return solution_found;
1808 std::vector<SearchMonitor*> monitors;
1809 monitors.push_back(m1);
1814 std::vector<SearchMonitor*> monitors;
1820 std::vector<SearchMonitor*> monitors;
1821 monitors.push_back(m1);
1822 monitors.push_back(m2);
1828 std::vector<SearchMonitor*> monitors;
1829 monitors.push_back(m1);
1830 monitors.push_back(m2);
1831 monitors.push_back(m3);
1838 std::vector<SearchMonitor*> monitors;
1839 monitors.push_back(m1);
1840 monitors.push_back(m2);
1841 monitors.push_back(m3);
1842 monitors.push_back(m4);
1850 const std::vector<SearchMonitor*>& monitors) {
1853 CHECK(db !=
nullptr);
1854 const bool nested = state_ ==
IN_SEARCH;
1857 LOG(
FATAL) <<
"Cannot start new searches here.";
1860 Search*
const search = nested ?
new Search(
this) : searches_.back();
1868 searches_.push_back(search);
1874 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1881 propagation_monitor_->Install();
1882 if (demon_profiler_ !=
nullptr) {
1885 local_search_monitor_->Install();
1886 if (local_search_profiler_ !=
nullptr) {
1892 if (monitor !=
nullptr) {
1896 std::vector<SearchMonitor*> extras;
1899 if (monitor !=
nullptr) {
1906 if (print_trace_ !=
nullptr) {
1910 print_trace_ =
nullptr;
1911 if (parameters_.trace_propagation()) {
1914 }
else if (parameters_.trace_search()) {
1929 PushSentinel(INITIAL_SEARCH_SENTINEL);
1935bool Solver::BacktrackOneLevel(
Decision**
const fail_decision) {
1936 bool no_more_solutions =
false;
1937 bool end_loop =
false;
1946 searches_.back()->sentinel_pushed_--;
1947 no_more_solutions =
true;
1951 LOG(ERROR) <<
"Simple markers should not be encountered during search";
1957 searches_.back()->set_search_depth(info.
depth);
1958 searches_.back()->set_search_left_depth(info.
left_depth);
1969 Search*
const search = searches_.back();
1972 if (no_more_solutions) {
1973 search->NoMoreSolutions();
1975 return no_more_solutions;
1978void Solver::PushSentinel(
int magic_code) {
1979 StateInfo info(
this, magic_code);
1982 if (magic_code != SOLVER_CTOR_SENTINEL) {
1983 searches_.back()->sentinel_pushed_++;
1985 const int pushed = searches_.back()->sentinel_pushed_;
1986 DCHECK((magic_code == SOLVER_CTOR_SENTINEL) ||
1987 (magic_code == INITIAL_SEARCH_SENTINEL && pushed == 1) ||
1988 (magic_code == ROOT_NODE_SENTINEL && pushed == 2));
1992 Search*
const search = searches_.back();
1993 CHECK_NE(0, search->sentinel_pushed_);
1995 if (search->sentinel_pushed_ > 1) {
1996 BacktrackToSentinel(ROOT_NODE_SENTINEL);
1998 CHECK_EQ(1, search->sentinel_pushed_);
1999 PushSentinel(ROOT_NODE_SENTINEL);
2003 if (search->sentinel_pushed_ > 0) {
2004 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2006 CHECK_EQ(0, search->sentinel_pushed_);
2007 PushSentinel(INITIAL_SEARCH_SENTINEL);
2015void Solver::BacktrackToSentinel(
int magic_code) {
2016 Search*
const search = searches_.back();
2017 bool end_loop = search->sentinel_pushed_ == 0;
2024 CHECK_GE(--search->sentinel_pushed_, 0);
2047void Solver::JumpToSentinelWhenNested() {
2049 Search* c = searches_.back();
2050 Search* p = ParentSearch();
2052 while (!c->marker_stack_.empty()) {
2053 StateMarker*
const m = c->marker_stack_.back();
2055 p->marker_stack_.push_back(m);
2058 CHECK_EQ(c->marker_stack_.size(), 1) <<
"Sentinel found too early";
2063 c->marker_stack_.pop_back();
2065 c->set_search_depth(0);
2066 c->set_search_left_depth(0);
2067 CHECK_EQ(found,
true) <<
"Sentinel not found";
2071class ReverseDecision :
public Decision {
2073 explicit ReverseDecision(Decision*
const d) : decision_(d) {
2074 CHECK(d !=
nullptr);
2076 ~ReverseDecision()
override {}
2078 void Apply(Solver*
const s)
override { decision_->Refute(s); }
2080 void Refute(Solver*
const s)
override { decision_->Apply(s); }
2082 void Accept(DecisionVisitor*
const visitor)
const override {
2083 decision_->Accept(visitor);
2086 std::string DebugString()
const override {
2087 std::string str =
"Reverse(";
2088 str += decision_->DebugString();
2094 Decision*
const decision_;
2100 Search*
const search = searches_.back();
2103 const bool top_level = solve_depth <= 1;
2106 LOG(
WARNING) <<
"NextSolution() called without a NewSearch before";
2117 if (BacktrackOneLevel(&fd)) {
2128 ProcessConstraints();
2130 PushSentinel(ROOT_NODE_SENTINEL);
2132 search->ClearBuffer();
2135 queue_->AfterFailure();
2136 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2150 volatile bool finish =
false;
2151 volatile bool result =
false;
2156 if (fd !=
nullptr) {
2175 if (d == fail_decision_.get()) {
2180 switch (modification) {
2182 d =
RevAlloc(
new ReverseDecision(d));
2184 ABSL_FALLTHROUGH_INTENDED;
2234 queue_->AfterFailure();
2237 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2238 : INITIAL_SEARCH_SENTINEL);
2246 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2247 : INITIAL_SEARCH_SENTINEL);
2250 PushSentinel(top_level ? ROOT_NODE_SENTINEL : INITIAL_SEARCH_SENTINEL);
2253 if (BacktrackOneLevel(&fd)) {
2261 search->ClearBuffer();
2270 Search*
const search = searches_.back();
2272 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2275 if (search->sentinel_pushed_ > 0) {
2276 JumpToSentinelWhenNested();
2281 if (2 == searches_.size()) {
2285 if (!parameters_.profile_file().empty()) {
2286 const std::string& file_name = parameters_.profile_file();
2287 LOG(
INFO) <<
"Exporting profile to " << file_name;
2290 if (parameters_.print_local_search_profile()) {
2295 searches_.pop_back();
2302 LOG(
FATAL) <<
"CheckAssignment is only available at the top level.";
2305 Search*
const search = searches_.back();
2308 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2317 PushSentinel(INITIAL_SEARCH_SENTINEL);
2322 restore->
Next(
this);
2323 ProcessConstraints();
2325 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2326 search->ClearBuffer();
2332 constraint_index_ < constraints_list_.size()
2334 : additional_constraints_parent_list_[additional_constraint_index_];
2336 if (
ct->name().empty()) {
2337 LOG(
INFO) <<
"Failing constraint = " <<
ct->DebugString();
2339 LOG(
INFO) <<
"Failing constraint = " <<
ct->name() <<
":"
2340 <<
ct->DebugString();
2342 queue_->AfterFailure();
2343 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2352 explicit AddConstraintDecisionBuilder(
Constraint*
const ct)
2357 ~AddConstraintDecisionBuilder()
override {}
2359 Decision* Next(Solver*
const solver)
override {
2360 solver->AddConstraint(constraint_);
2364 std::string DebugString()
const override {
2365 return absl::StrFormat(
"AddConstraintDecisionBuilder(%s)",
2366 constraint_->DebugString());
2370 Constraint*
const constraint_;
2375 return RevAlloc(
new AddConstraintDecisionBuilder(
ct));
2384 std::vector<SearchMonitor*> monitors;
2385 monitors.push_back(m1);
2390 std::vector<SearchMonitor*> monitors;
2396 std::vector<SearchMonitor*> monitors;
2397 monitors.push_back(m1);
2398 monitors.push_back(m2);
2404 std::vector<SearchMonitor*> monitors;
2405 monitors.push_back(m1);
2406 monitors.push_back(m2);
2407 monitors.push_back(m3);
2412 const std::vector<SearchMonitor*>& monitors) {
2414 searches_.back()->set_created_by_solve(
true);
2415 searches_.back()->set_backtrack_at_the_end_of_the_search(
false);
2417 const bool solution_found = searches_.back()->solution_counter() > 0;
2419 return solution_found;
2423 if (fail_intercept_) {
2429 searches_.back()->BeginFail();
2430 searches_.back()->JumpBack();
2434 searches_.back()->set_should_finish(
true);
2438 searches_.back()->set_should_restart(
true);
2446 if (cast_info !=
nullptr) {
2456 if (
name !=
nullptr) {
2459 const IntegerCastInfo*
const cast_info =
2461 if (cast_info !=
nullptr && cast_info->expression !=
nullptr) {
2462 if (cast_info->expression->HasName()) {
2463 return absl::StrFormat(
"Var<%s>", cast_info->expression->name());
2464 }
else if (parameters_.name_cast_variables()) {
2465 return absl::StrFormat(
"Var<%s>", cast_info->expression->DebugString());
2467 const std::string new_name =
2468 absl::StrFormat(
"CastVar<%d>", anonymous_variable_index_++);
2469 propagation_object_names_[object] = new_name;
2473 const std::string base_name =
object->BaseName();
2474 if (parameters_.name_all_variables() && !base_name.empty()) {
2475 const std::string new_name =
2476 absl::StrFormat(
"%s_%d", base_name, anonymous_variable_index_++);
2477 propagation_object_names_[object] = new_name;
2483void Solver::SetName(
const PropagationBaseObject*
object,
2484 const std::string&
name) {
2485 if (parameters_.store_names() &&
2486 GetName(
object) !=
name) {
2487 propagation_object_names_[object] =
name;
2492 return propagation_object_names_.contains(
2494 (!
object->BaseName().empty() && parameters_.name_all_variables());
2512 return solver_->GetName(
this);
2516 solver_->SetName(
this,
name);
2524 solver_->ExecuteAll(demons);
2528 solver_->EnqueueAll(demons);
2540 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {}
2635 "ScalarProductGreaterOrEqual";
2663 "VariableUsageLessConstant";
2665 "WeightedSumOfAssignedEqualVariable";
2762 if (delegate !=
nullptr) {
2768 const std::string& operation,
2770 if (delegate !=
nullptr) {
2776 const std::string& operation,
2779 if (delegate !=
nullptr) {
2785 for (
int i = 0; i < variable->
size(); ++i) {
2794 const std::string& arg_name,
const std::vector<int64_t>& values) {}
2808 const std::string& arg_name,
const std::vector<IntVar*>& arguments) {
2818 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
2828 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
2836 int64_t index_max) {
2837 if (filter !=
nullptr) {
2838 std::vector<int64_t> cached_results;
2839 for (
int i = index_min; i <= index_max; ++i) {
2840 cached_results.push_back(filter(i));
2852 CHECK(eval !=
nullptr);
2853 std::vector<int64_t> cached_results;
2854 for (
int i = index_min; i <= index_max; ++i) {
2855 cached_results.push_back(eval(i));
2865 const std::string& arg_name,
2866 int64_t index_max) {
2867 CHECK(eval !=
nullptr);
2868 std::vector<int64_t> cached_results;
2869 for (
int i = 0; i <= index_max; ++i) {
2870 cached_results.push_back(eval(i));
2903 solver()->searches_.back()->push_monitor(
this);
2995 monitor->SetMin(expr, new_min);
3001 monitor->SetMax(expr, new_max);
3006 int64_t new_max)
override {
3008 monitor->SetRange(expr, new_min, new_max);
3015 monitor->SetMin(
var, new_min);
3021 monitor->SetMax(
var, new_max);
3027 monitor->SetRange(
var, new_min, new_max);
3044 const std::vector<int64_t>& values)
override {
3049 const std::vector<int64_t>& values)
override {
3063 int64_t new_max)
override {
3077 int64_t new_max)
override {
3090 int64_t new_max)
override {
3116 const std::vector<int>& rank_last,
3117 const std::vector<int>& unperformed)
override {
3119 rank_last, unperformed);
3124 if (monitor !=
nullptr) {
3125 monitors_.push_back(monitor);
3136 std::vector<PropagationMonitor*> monitors_;
3143 reinterpret_cast<class
Trace*
>(propagation_monitor_.get())->Add(monitor);
3147 return propagation_monitor_.get();
3170 neighbor_found,
delta, deltadelta);
3176 bool neighbor_found)
override {
3184 bool neighbor_found)
override {
3197 if (monitor !=
nullptr) {
3198 monitors_.push_back(monitor);
3207 return "LocalSearchMonitorMaster";
3211 std::vector<LocalSearchMonitor*> monitors_;
3224 return local_search_monitor_.get();
3228 const std::string& search_context) {
3241 if (local_search_state_ ==
nullptr) {
3242 local_search_state_ = absl::make_unique<Assignment>(
this);
3244 return local_search_state_.get();
3250 : db_(db), name_(db_->GetName()), seconds_(0) {}
3259 seconds_ += timer_.Get();
3265 seconds_ += timer_.
Get();
3274 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {
3301 return solver()->cast_constraints_.contains(
this);
#define DCHECK_LE(val1, val2)
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
#define CHECK_GT(val1, val2)
#define DCHECK_GE(val1, val2)
#define CHECK_NE(val1, val2)
#define DCHECK_GT(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
#define VLOG(verboselevel)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
A BaseObject is the root of all reversibly allocated objects.
virtual std::string DebugString() const
Cast constraints are special channeling constraints designed to keep a variable in sync with an expre...
A constraint is the main modeling object.
void PostAndPropagate()
Calls Post and then Propagate to initialize the constraints.
bool IsCastConstraint() const
Is the constraint created by a cast from expression to integer variable?
virtual void InitialPropagate()=0
This method performs the initial propagation of the constraint.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
virtual IntVar * Var()
Creates a Boolean variable representing the status of the constraint (false = constraint is violated,...
std::string DebugString() const override
virtual void Post()=0
This method is called when the constraint is processed by the solver.
A DecisionBuilder is responsible for creating the search tree.
virtual Decision * Next(Solver *const s)=0
This is the main method of the decision builder class.
std::string GetName() const
virtual void Accept(ModelVisitor *const visitor) const
virtual void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras)
This method will be called at the start of the search.
std::string DebugString() const override
A Decision represents a choice point in the search tree.
virtual void Accept(DecisionVisitor *const visitor) const
Accepts the given visitor.
virtual void Apply(Solver *const s)=0
Apply will be called first when the decision is executed.
virtual void Refute(Solver *const s)=0
Refute will be called after a backtrack.
A DecisionVisitor is used to inspect a decision.
virtual void VisitSetVariableValue(IntVar *const var, int64_t value)
virtual void VisitSplitVariableDomain(IntVar *const var, int64_t value, bool start_with_lower_half)
virtual void VisitRankFirstInterval(SequenceVar *const sequence, int index)
virtual void VisitUnknownDecision()
virtual void VisitRankLastInterval(SequenceVar *const sequence, int index)
virtual void VisitScheduleOrPostpone(IntervalVar *const var, int64_t est)
virtual void VisitScheduleOrExpedite(IntervalVar *const var, int64_t est)
A Demon is the base element of a propagation queue.
void inhibit(Solver *const s)
This method inhibits the demon in the search tree below the current position.
void desinhibit(Solver *const s)
This method un-inhibits the demon that was previously inhibited.
virtual Solver::DemonPriority priority() const
This method returns the priority of the demon.
std::string DebugString() const override
virtual void Run(Solver *const s)=0
This is the main callback of the demon.
The class IntExpr is the base of all integer expressions in constraint programming.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
The class IntVar is a subset of IntExpr.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Interval variables are often used in scheduling.
virtual void Accept(ModelVisitor *const visitor) const =0
Accepts the given visitor.
Local Search Filters are used for fast neighbor pruning.
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
void Install() override
Install itself on the solver.
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void EndOperatorStart()=0
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual void BeginOperatorStart()=0
Local search operator events.
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
LocalSearchMonitor(Solver *const solver)
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
~LocalSearchMonitor() override
void BeginFiltering(const LocalSearchFilter *filter) override
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void BeginOperatorStart() override
Local search operator events.
void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta) override
void Add(LocalSearchMonitor *monitor)
void BeginMakeNextNeighbor(const LocalSearchOperator *op) override
void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void BeginAcceptNeighbor(const LocalSearchOperator *op) override
void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void EndOperatorStart() override
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
LocalSearchMonitorMaster(Solver *solver)
void BeginFilterNeighbor(const LocalSearchOperator *op) override
std::string DebugString() const override
The base class for all local search operators.
static const char kDurationMinArgument[]
static const char kIntervalArgument[]
static const char kSolutionLimitArgument[]
static const char kSizeArgument[]
static const char kIsMember[]
static const char kCountUsedBinsExtension[]
static const char kIntervalVariable[]
static const char kObjectiveExtension[]
static const char kPower[]
static const char kEarlyDateArgument[]
static const char kMaximizeArgument[]
static const char kLateDateArgument[]
static const char kFinalStatesArgument[]
static const char kIndex2Argument[]
static const char kStartExpr[]
static const char kMinArgument[]
static const char kEndsArgument[]
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
static const char kSequenceVariable[]
static const char kDeviation[]
static const char kMirrorOperation[]
Operations.
static const char kAbs[]
Constraint and Expression types.
static const char kMember[]
static const char kDelayedPathCumul[]
virtual void VisitSequenceVariable(const SequenceVar *const variable)
static const char kVariableUsageLessConstantExtension[]
virtual void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate)
static const char kSumEqual[]
static const char kSortingConstraint[]
static const char kElementEqual[]
void VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1 &eval, const std::string &arg_name, int64_t index_max)
Expands function as array when index min is 0.
static const char kPack[]
static const char kIsBetween[]
static const char kRangeArgument[]
static const char kLess[]
virtual void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate)
static const char kAtMost[]
static const char kDisjunctive[]
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
static const char kTargetArgument[]
static const char kActiveArgument[]
argument names:
static const char kRelaxedMaxOperation[]
void VisitInt64ToBoolExtension(Solver::IndexFilter1 filter, int64_t index_min, int64_t index_max)
Using SWIG on callbacks is troublesome, so we hide these methods during the wrapping.
static const char kSequenceArgument[]
static const char kAbsEqual[]
static const char kTimeLimitArgument[]
static const char kIntegerVariable[]
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
static const char kNullIntersect[]
virtual void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument)
Visit interval argument.
static const char kConvexPiecewise[]
static const char kBranchesLimitArgument[]
static const char kMaxArgument[]
static const char kModulo[]
static const char kCapacityArgument[]
static const char kProductOperation[]
static const char kBetween[]
static const char kIntervalsArgument[]
static const char kIntervalUnaryRelation[]
static const char kScalProd[]
static const char kTrueConstraint[]
static const char kOpposite[]
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
static const char kEvaluatorArgument[]
static const char kPositionXArgument[]
static const char kCumulsArgument[]
static const char kCircuit[]
static const char kWeightedSumOfAssignedEqualVariableExtension[]
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kRelaxedMinOperation[]
static const char kMapDomain[]
static const char kLessOrEqual[]
static const char kSizeXArgument[]
static const char kModuloArgument[]
static const char kEndMaxArgument[]
static const char kSmartTimeCheckArgument[]
static const char kValueArgument[]
static const char kIntervalDisjunction[]
static const char kDemandsArgument[]
static const char kTraceOperation[]
static const char kSemiContinuous[]
static const char kIsGreater[]
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint)
static const char kRelationArgument[]
static const char kEarlyCostArgument[]
static const char kVarValueWatcher[]
static const char kDurationExpr[]
static const char kIsDifferent[]
static const char kGreaterOrEqual[]
static const char kLeftArgument[]
static const char kGlobalCardinality[]
static const char kLexLess[]
virtual void BeginVisitExtension(const std::string &type)
static const char kNextsArgument[]
static const char kTransitsArgument[]
static const char kTransition[]
static const char kStartSyncOnStartOperation[]
static const char kStartMinArgument[]
static const char kUsageLessConstantExtension[]
virtual void EndVisitExtension(const std::string &type)
static const char kCumulativeArgument[]
static const char kStepArgument[]
static const char kLateCostArgument[]
static const char kMaxEqual[]
static const char kSumLessOrEqual[]
static const char kTuplesArgument[]
static const char kCountArgument[]
static const char kUsageEqualVariableExtension[]
static const char kStartMaxArgument[]
static const char kAllowedAssignments[]
virtual void EndVisitModel(const std::string &type_name)
static const char kIsGreaterOrEqual[]
static const char kPathCumul[]
static const char kDifferenceOperation[]
static const char kVarsArgument[]
static const char kSumOperation[]
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
static const char kTrace[]
static const char kRightArgument[]
static const char kIsLess[]
static const char kIsLessOrEqual[]
static const char kVariableGroupExtension[]
static const char kIndexOf[]
static const char kEndExpr[]
static const char kNotMember[]
static const char kStartsArgument[]
static const char kElement[]
static const char kSizeYArgument[]
static const char kCountEqual[]
static const char kPartialArgument[]
static const char kExpressionArgument[]
static const char kDistribute[]
static const char kFailuresLimitArgument[]
static const char kScalProdGreaterOrEqual[]
static const char kPositionYArgument[]
static const char kVarBoundWatcher[]
virtual void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments)
static const char kDivide[]
static const char kInt64ToBoolExtension[]
static const char kIntervalBinaryRelation[]
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
static const char kCardsArgument[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument)
Visit integer expression argument.
static const char kNoCycle[]
static const char kGreater[]
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
static const char kCover[]
static const char kNotBetween[]
static const char kCoefficientsArgument[]
static const char kScalProdLessOrEqual[]
static const char kEndMinArgument[]
static const char kVariableArgument[]
static const char kValuesArgument[]
static const char kMinEqual[]
static const char kEquality[]
static const char kInt64ToInt64Extension[]
static const char kSequencesArgument[]
static const char kSumGreaterOrEqual[]
static const char kFixedChargeArgument[]
static const char kDurationMaxArgument[]
static const char kLinkExprVar[]
static const char kScalProdEqual[]
static const char kProduct[]
static const char kDifference[]
static const char kCumulative[]
static const char kAllDifferent[]
static const char kSquare[]
static const char kAssumePathsArgument[]
static const char kInitialState[]
static const char kNonEqual[]
static const char kConditionalExpr[]
static const char kIsEqual[]
static const char kStartSyncOnEndOperation[]
static const char kOptionalArgument[]
static const char kIndexArgument[]
static const char kFalseConstraint[]
static const char kPerformedExpr[]
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument)
Visit sequence argument.
static const char kSearchLimitExtension[]
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint)
static const char kInversePermutation[]
static const char kCountAssignedItemsExtension[]
Extension names:
ProfiledDecisionBuilder(DecisionBuilder *db)
void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras) override
This method will be called at the start of the search.
void Accept(ModelVisitor *const visitor) const override
Decision * Next(Solver *const solver) override
This is the main method of the decision builder class.
std::string DebugString() const override
virtual std::string name() const
Object naming.
bool HasName() const
Returns whether the object has been named or not.
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void FreezeQueue()
This method freezes the propagation queue.
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual std::string BaseName() const
Returns a base name for automatic naming.
void set_name(const std::string &name)
void UnfreezeQueue()
This method unfreezes the propagation queue.
std::string DebugString() const override
virtual void SetValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual void SetDurationMax(IntervalVar *const var, int64_t new_max)=0
virtual void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
void Install() override
Install itself on the solver.
virtual void RankLast(SequenceVar *const var, int index)=0
~PropagationMonitor() override
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
virtual void RemoveValue(IntVar *const var, int64_t value)=0
virtual void SetValue(IntVar *const var, int64_t value)=0
virtual void SetDurationMin(IntervalVar *const var, int64_t new_min)=0
virtual void SetStartMin(IntervalVar *const var, int64_t new_min)=0
IntervalVar modifiers.
virtual void RankNotLast(SequenceVar *const var, int index)=0
virtual void RankNotFirst(SequenceVar *const var, int index)=0
virtual void BeginDemonRun(Demon *const demon)=0
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
virtual void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void SetEndMax(IntervalVar *const var, int64_t new_max)=0
virtual void PushContext(const std::string &context)=0
virtual void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax)=0
virtual void SetEndMin(IntervalVar *const var, int64_t new_min)=0
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void SetPerformed(IntervalVar *const var, bool value)=0
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
virtual void SetStartMax(IntervalVar *const var, int64_t new_max)=0
virtual void EndDemonRun(Demon *const demon)=0
virtual void RegisterDemon(Demon *const demon)=0
PropagationMonitor(Solver *const solver)
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
virtual void PopContext()=0
virtual void RemoveValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
void EnqueueDelayedDemon(Demon *const demon)
void reset_action_on_fail()
static constexpr int64_t kTestPeriod
void set_action_on_fail(Solver::Action a)
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
void EnqueueVar(Demon *const demon)
void AddConstraint(Constraint *const c)
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
void set_variable_to_clean_on_fail(IntVar *var)
void ProcessConstraints()
void ProcessOneDemon(Demon *const demon)
void RefuteDecision(Decision *const d)
void ApplyDecision(Decision *const d)
DecisionBuilder * decision_builder() const
void BeginNextDecision(DecisionBuilder *const db)
bool should_restart() const
bool should_finish() const
Search(Solver *const s, int)
std::string search_context() const
void IncrementUncheckedSolutionCounter()
void SetBranchSelector(Solver::BranchSelector bs)
int64_t unchecked_solution_counter() const
bool backtrack_at_the_end_of_the_search() const
void AfterDecision(Decision *const d, bool apply)
void BeginInitialPropagation()
void set_should_restart(bool s)
void set_backtrack_at_the_end_of_the_search(bool restore)
Solver::DecisionModification ModifyDecision()
void push_monitor(SearchMonitor *const m)
void set_decision_builder(DecisionBuilder *const db)
void IncrementSolutionCounter()
void EndInitialPropagation()
void AcceptUncheckedNeighbor()
bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
bool created_by_solve() const
void Accept(ModelVisitor *const visitor) const
void set_search_depth(int d)
void set_search_left_depth(int d)
bool IsUncheckedSolutionLimitReached()
void set_should_finish(bool s)
int64_t solution_counter() const
void EndNextDecision(DecisionBuilder *const db, Decision *const d)
void set_created_by_solve(bool c)
int left_search_depth() const
void set_search_context(const std::string &search_context)
A search monitor is a simple set of callbacks to monitor all search events.
virtual void RefuteDecision(Decision *const d)
Before refuting the decision.
virtual void ApplyDecision(Decision *const d)
Before applying the decision.
virtual void RestartSearch()
Restart the search.
virtual void ExitSearch()
End of the search.
virtual bool LocalOptimum()
When a local optimum is reached.
virtual void NoMoreSolutions()
When the search tree is finished.
virtual void BeginFail()
Just when the failure occurs.
virtual void AfterDecision(Decision *const d, bool apply)
Just after refuting or applying the decision, apply is true after Apply.
virtual void BeginInitialPropagation()
Before the initial propagation.
virtual void BeginNextDecision(DecisionBuilder *const b)
Before calling DecisionBuilder::Next.
virtual void PeriodicCheck()
Periodic call to check limits in long running methods.
virtual void EnterSearch()
Beginning of the search.
virtual void EndNextDecision(DecisionBuilder *const b, Decision *const d)
After calling DecisionBuilder::Next, along with the returned decision.
virtual void EndFail()
After completing the backtrack.
virtual void EndInitialPropagation()
After the initial propagation.
static constexpr int kNoProgress
virtual void AcceptUncheckedNeighbor()
After accepting an unchecked neighbor during local search.
virtual bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
virtual bool AtSolution()
This method is called when a valid solution is found.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
virtual void AcceptNeighbor()
After accepting a neighbor during local search.
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
virtual bool AcceptSolution()
This method is called when a solution is found.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
IntervalVar * Interval(int index) const
Returns the index_th interval of the sequence.
int64_t size() const
Returns the number of interval vars in the sequence.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
This iterator is not stable with respect to deletion.
This class represent a reversible FIFO structure.
DecisionModification
The Solver is responsible for creating the search tree.
@ NO_CHANGE
Keeps the default behavior, i.e.
@ SWITCH_BRANCHES
Applies right branch first.
@ KEEP_RIGHT
Left branches are ignored.
@ KEEP_LEFT
Right branches are ignored.
@ KILL_BOTH
Backtracks to the previous decisions, i.e.
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
int64_t branches() const
The number of branches explored since the creation of the solver.
void RestartCurrentSearch()
bool SolveAndCommit(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
SolveAndCommit using a decision builder and up to three search monitors, usually one for the objectiv...
Constraint * MakeFalseConstraint()
This constraint always fails.
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
static constexpr int kNumPriorities
Number of priorities for demons.
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
@ VAR_PRIORITY
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
@ DELAYED_PRIORITY
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
@ NORMAL_PRIORITY
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
@ AT_SOLUTION
After successful NextSolution and before EndSearch.
@ PROBLEM_INFEASIBLE
After search, the model is infeasible.
@ OUTSIDE_SEARCH
Before search, after search.
@ IN_ROOT_NODE
Executing the root node.
@ NO_MORE_SOLUTIONS
After failed NextSolution and before EndSearch.
@ IN_SEARCH
Executing the search code.
std::string SearchContext() const
bool CheckAssignment(Assignment *const solution)
Checks whether the given assignment satisfies all relevant constraints.
absl::Time Now() const
The 'absolute time' as seen by the solver.
DecisionBuilder * MakeConstraintAdder(Constraint *const ct)
Returns a decision builder that will add the given constraint to the model.
Assignment * GetOrCreateLocalSearchState()
Returns (or creates) an assignment representing the state of local search.
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
void AddPropagationMonitor(PropagationMonitor *const monitor)
Adds the propagation monitor to the solver.
bool CheckConstraint(Constraint *const ct)
Checks whether adding this constraint will lead to an immediate failure.
void SetSearchContext(Search *search, const std::string &search_context)
void TopPeriodicCheck()
Performs PeriodicCheck on the top-level search; for instance, can be called from a nested solve to ch...
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
int64_t wall_time() const
DEPRECATED: Use Now() instead.
std::function< bool(int64_t)> IndexFilter1
int SearchDepth() const
Gets the search depth of the current active search.
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
Adds the local search monitor to the solver.
void PushState()
The PushState and PopState methods manipulates the states of the reversible objects.
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
std::string DebugString() const
!defined(SWIG)
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
int64_t failures() const
The number of failures encountered since the creation of the solver.
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
static int64_t MemoryUsage()
Current memory usage in bytes.
int SolveDepth() const
Gets the number of nested searches.
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
bool Solve(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
std::string model_name() const
Returns the name of the model.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
SearchMonitor * MakeSearchTrace(const std::string &prefix)
Creates a search monitor that will trace precisely the behavior of the search.
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
std::string LocalSearchProfile() const
Returns local search profiling information in a human readable format.
void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
int SearchLeftDepth() const
Gets the search left depth of the current active search.
void AddBacktrackAction(Action a, bool fast)
When SaveValue() is not the best way to go, one can create a reversible action that will be called up...
int TopProgressPercent()
Returns a percentage representing the propress of the search before reaching the limits of the top-le...
bool CurrentlyInSolve() const
Returns true whether the current search has been created using a Solve() call instead of a NewSearch ...
Solver(const std::string &name)
Solver API.
uint64_t stamp() const
The stamp indicates how many moves in the search tree we have performed.
bool NameAllVariables() const
Returns whether all variables should be named.
IntExpr * CastExpression(const IntVar *const var) const
!defined(SWIG)
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
ModelVisitor * MakePrintModelVisitor()
Prints the model.
std::function< void(Solver *)> Action
void ExportProfilingOverview(const std::string &filename)
Exports the profiling information in a human readable overview.
MarkerType
This enum is used internally in private methods Solver::PushState and Solver::PopState to tag states ...
void AddCastConstraint(CastConstraint *const constraint, IntVar *const target_var, IntExpr *const expr)
Adds 'constraint' to the solver and marks it as a cast constraint, that is, a constraint created call...
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
std::function< DecisionModification()> BranchSelector
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())
Decision * MakeFailDecision()
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
int64_t solutions() const
The number of solutions found since the start of the search.
std::function< IntVar *(int64_t)> Int64ToIntVar
T * RevAlloc(T *object)
Registers the given object as being reversible.
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
void NewSearch(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
void SetDurationMax(IntervalVar *const var, int64_t new_max) override
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void SetStartMax(IntervalVar *const var, int64_t new_max) override
void SetMin(IntVar *const var, int64_t new_min) override
IntVar modifiers.
void SetValue(IntVar *const var, int64_t value) override
void PopContext() override
void SetEndMax(IntervalVar *const var, int64_t new_max) override
void EndProcessingIntegerVariable(IntVar *const var) override
void SetStartMin(IntervalVar *const var, int64_t new_min) override
IntervalVar modifiers.
void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void SetMin(IntExpr *const expr, int64_t new_min) override
IntExpr modifiers.
void SetPerformed(IntervalVar *const var, bool value) override
void BeginConstraintInitialPropagation(Constraint *const constraint) override
Propagation events.
void SetRange(IntVar *const var, int64_t new_min, int64_t new_max) override
void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void EndConstraintInitialPropagation(Constraint *const constraint) override
void SetMax(IntVar *const var, int64_t new_max) override
void StartProcessingIntegerVariable(IntVar *const var) override
void RegisterDemon(Demon *const demon) override
void EndDemonRun(Demon *const demon) override
void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed) override
void BeginDemonRun(Demon *const demon) override
void SetDurationMin(IntervalVar *const var, int64_t new_min) override
void RankLast(SequenceVar *const var, int index) override
void PushContext(const std::string &context) override
void Add(PropagationMonitor *const monitor)
void RankNotLast(SequenceVar *const var, int index) override
void RemoveValues(IntVar *const var, const std::vector< int64_t > &values) override
void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
void SetMax(IntExpr *const expr, int64_t new_max) override
void RemoveValue(IntVar *const var, int64_t value) override
void SetValues(IntVar *const var, const std::vector< int64_t > &values) override
void RankFirst(SequenceVar *const var, int index) override
SequenceVar modifiers.
void SetEndMin(IntervalVar *const var, int64_t new_min) override
void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max) override
std::string DebugString() const override
void RankNotFirst(SequenceVar *const var, int index) override
void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax) override
#define CP_DO_FAIL(search)
ABSL_FLAG(bool, cp_trace_propagation, false, "Trace propagation events (constraint and demon executions," " variable modifications).")
void ConstraintSolverFailsHere()
GurobiMPCallbackContext * context
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
void STLDeleteElements(T *container)
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Collection of objects used to extend the Constraint Solver library.
PropagationMonitor * BuildPrintTrace(Solver *const s)
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
void InstallDemonProfiler(DemonProfiler *const monitor)
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
void CleanVariableOnFail(IntVar *const var)
ModelCache * BuildModelCache(Solver *const solver)
int64_t GetProcessMemoryUsage()
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
void RestoreBoolValue(IntVar *const var)
DemonProfiler * BuildDemonProfiler(Solver *const solver)
bool AcceptDelta(Search *const search, Assignment *delta, Assignment *deltadelta)
void AcceptNeighbor(Search *const search)
LocalSearchMonitor * BuildLocalSearchMonitorMaster(Solver *const s)
PropagationMonitor * BuildTrace(Solver *const s)
void DeleteDemonProfiler(DemonProfiler *const monitor)
bool LocalOptimumReached(Search *const search)
void AcceptUncheckedNeighbor(Search *const search)
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
BaseVariableAssignmentSelector *const selector_
Holds semantic information stating that the 'expression' has been cast into 'variable' using the Var(...
Solver::Action reversible_action
StateInfo(Solver::Action a, bool fast)
StateInfo(void *pinfo, int iinfo, int d, int ld)
StateInfo(void *pinfo, int iinfo)
StateMarker(Solver::MarkerType t, const StateInfo &info)
CompressedTrail< void * > rev_ptrs_
std::vector< double * > rev_double_memory_
std::vector< int64_t * > rev_int64_memory_
std::vector< int * > rev_int_memory_
std::vector< BaseObject * > rev_object_memory_
std::vector< IntVar * > rev_boolvar_list_
std::vector< void * > rev_memory_
Trail(int block_size, ConstraintSolverParameters::TrailCompression compression_level)
std::vector< bool > rev_bool_value_
void BacktrackTo(StateMarker *m)
std::vector< bool * > rev_bools_
std::vector< void ** > rev_memory_array_
CompressedTrail< int64_t > rev_int64s_
CompressedTrail< uint64_t > rev_uint64s_
CompressedTrail< double > rev_doubles_
std::vector< BaseObject ** > rev_object_array_memory_
CompressedTrail< int > rev_ints_