29 #include "absl/memory/memory.h" 30 #include "absl/time/clock.h" 31 #include "absl/time/time.h" 46 ABSL_FLAG(
bool, cp_trace_propagation,
false,
47 "Trace propagation events (constraint and demon executions," 48 " variable modifications).");
49 ABSL_FLAG(
bool, cp_trace_search,
false,
"Trace search events");
50 ABSL_FLAG(
bool, cp_print_added_constraints,
false,
51 "show all constraints added to the solver.");
53 "use PrintModelVisitor on model before solving.");
55 "use StatisticsModelVisitor on model before solving.");
57 "Force failure at the beginning of a search.");
58 ABSL_FLAG(std::string, cp_profile_file,
"",
59 "Export profiling overview to file.");
60 ABSL_FLAG(
bool, cp_print_local_search_profile,
false,
61 "Print local search profiling data after solving.");
62 ABSL_FLAG(
bool, cp_name_variables,
false,
"Force all variables to have names.");
63 ABSL_FLAG(
bool, cp_name_cast_variables,
false,
64 "Name variables casted from expressions");
66 "Use small compact table constraint when possible.");
67 ABSL_FLAG(
bool, cp_use_cumulative_edge_finder,
true,
68 "Use the O(n log n) cumulative edge finding algorithm described " 69 "in 'Edge Finding Filtering Algorithm for Discrete Cumulative " 70 "Resources in O(kn log n)' by Petr Vilim, CP 2009.");
71 ABSL_FLAG(
bool, cp_use_cumulative_time_table,
true,
72 "Use a O(n^2) cumulative time table propagation algorithm.");
73 ABSL_FLAG(
bool, cp_use_cumulative_time_table_sync,
false,
74 "Use a synchronized O(n^2 log n) cumulative time table propagation " 76 ABSL_FLAG(
bool, cp_use_sequence_high_demand_tasks,
true,
77 "Use a sequence constraints for cumulative tasks that have a " 78 "demand greater than half of the capacity of the resource.");
79 ABSL_FLAG(
bool, cp_use_all_possible_disjunctions,
true,
80 "Post temporal disjunctions for all pairs of tasks sharing a " 81 "cumulative resource and that cannot overlap because the sum of " 82 "their demand exceeds the capacity.");
83 ABSL_FLAG(
int, cp_max_edge_finder_size, 50,
84 "Do not post the edge finder in the cumulative constraints if " 85 "it contains more than this number of tasks");
86 ABSL_FLAG(
bool, cp_diffn_use_cumulative,
true,
87 "Diffn constraint adds redundant cumulative constraint");
89 "If true, rmq's will be used in element expressions.");
90 ABSL_FLAG(
int, cp_check_solution_period, 1,
91 "Number of solutions explored between two solution checks during " 94 "Random seed used in several (but not all) random number " 95 "generators used by the CP solver. Use -1 to auto-generate an" 96 "undeterministic random seed.");
100 #if defined(_MSC_VER) // WINDOWS 101 #pragma warning(disable : 4351 4355) 109 template <
typename T,
typename MethodPointer,
typename... Args>
110 void ForAll(
const std::vector<T*>& objects, MethodPointer method,
111 const Args&... args) {
112 for (T*
const object : objects) {
113 DCHECK(
object !=
nullptr);
114 (
object->*method)(args...);
133 absl::GetFlag(FLAGS_cp_print_local_search_profile));
135 absl::GetFlag(FLAGS_cp_print_local_search_profile));
141 absl::GetFlag(FLAGS_cp_print_added_constraints));
144 absl::GetFlag(FLAGS_cp_use_cumulative_edge_finder));
146 absl::GetFlag(FLAGS_cp_use_cumulative_time_table));
148 absl::GetFlag(FLAGS_cp_use_cumulative_time_table_sync));
150 absl::GetFlag(FLAGS_cp_use_sequence_high_demand_tasks));
152 absl::GetFlag(FLAGS_cp_use_all_possible_disjunctions));
157 absl::GetFlag(FLAGS_cp_check_solution_period));
227 clean_action_(nullptr),
228 clean_variable_(nullptr),
230 instruments_demons_(s->InstrumentsDemons()) {}
240 if (--freeze_level_ == 0) {
246 demon->set_stamp(stamp_ - 1);
247 if (!instruments_demons_) {
267 while (!var_queue_.empty() || !delayed_queue_.empty()) {
268 if (!var_queue_.empty()) {
269 Demon*
const demon = var_queue_.front();
270 var_queue_.pop_front();
273 DCHECK(!delayed_queue_.empty());
274 Demon*
const demon = delayed_queue_.front();
275 delayed_queue_.pop_front();
284 if (!instruments_demons_) {
286 Demon*
const demon = *it;
287 if (demon->stamp() < stamp_) {
299 Demon*
const demon = *it;
300 if (demon->stamp() < stamp_) {
323 if (demon->stamp() < stamp_) {
324 demon->set_stamp(stamp_);
325 var_queue_.push_back(demon);
326 if (freeze_level_ == 0) {
334 if (demon->stamp() < stamp_) {
335 demon->set_stamp(stamp_);
336 delayed_queue_.push_back(demon);
343 delayed_queue_.clear();
346 if (clean_action_ !=
nullptr) {
347 clean_action_(solver_);
348 clean_action_ =
nullptr;
349 }
else if (clean_variable_ !=
nullptr) {
351 clean_variable_ =
nullptr;
362 uint64_t
stamp()
const {
return stamp_; }
365 DCHECK(clean_variable_ ==
nullptr);
366 clean_action_ = std::move(
a);
370 DCHECK(clean_action_ ==
nullptr);
371 clean_variable_ =
var;
375 DCHECK(clean_variable_ ==
nullptr);
376 clean_action_ =
nullptr;
380 to_add_.push_back(c);
390 for (
int counter = 0; counter < to_add_.size(); ++counter) {
391 Constraint*
const constraint = to_add_[counter];
402 std::deque<Demon*> var_queue_;
403 std::deque<Demon*> delayed_queue_;
407 uint32_t freeze_level_;
411 std::vector<Constraint*> to_add_;
413 const bool instruments_demons_;
462 int rev_int64_index_;
463 int rev_uint64_index_;
464 int rev_double_index_;
466 int rev_boolvar_list_index_;
467 int rev_bools_index_;
468 int rev_int_memory_index_;
469 int rev_int64_memory_index_;
470 int rev_double_memory_index_;
471 int rev_object_memory_index_;
472 int rev_object_array_memory_index_;
473 int rev_memory_index_;
474 int rev_memory_array_index_;
482 rev_uint64_index_(0),
483 rev_double_index_(0),
485 rev_boolvar_list_index_(0),
487 rev_int_memory_index_(0),
488 rev_int64_memory_index_(0),
489 rev_double_memory_index_(0),
490 rev_object_memory_index_(0),
491 rev_object_array_memory_index_(0),
504 addrval() : address_(nullptr) {}
505 explicit addrval(T* adr) : address_(adr), old_value_(*adr) {}
506 void restore()
const { (*address_) = old_value_; }
521 explicit TrailPacker(
int block_size) : block_size_(block_size) {}
522 virtual ~TrailPacker() {}
523 int input_size()
const {
return block_size_ *
sizeof(addrval<T>); }
524 virtual void Pack(
const addrval<T>* block, std::string* packed_block) = 0;
525 virtual void Unpack(
const std::string& packed_block, addrval<T>* block) = 0;
528 const int block_size_;
533 class NoCompressionTrailPacker :
public TrailPacker<T> {
535 explicit NoCompressionTrailPacker(
int block_size)
536 : TrailPacker<T>(block_size) {}
537 ~NoCompressionTrailPacker()
override {}
538 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
540 DCHECK(packed_block !=
nullptr);
541 absl::string_view block_str(reinterpret_cast<const char*>(block),
543 packed_block->assign(block_str.data(), block_str.size());
545 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
547 memcpy(block, packed_block.c_str(), packed_block.size());
555 class ZlibTrailPacker :
public TrailPacker<T> {
557 explicit ZlibTrailPacker(
int block_size)
558 : TrailPacker<T>(block_size),
559 tmp_size_(compressBound(this->input_size())),
560 tmp_block_(new char[tmp_size_]) {}
562 ~ZlibTrailPacker()
override {}
564 void Pack(
const addrval<T>* block, std::string* packed_block)
override {
566 DCHECK(packed_block !=
nullptr);
567 uLongf size = tmp_size_;
569 compress(reinterpret_cast<Bytef*>(tmp_block_.get()), &size,
570 reinterpret_cast<const Bytef*>(block), this->input_size());
572 absl::string_view block_str;
573 block_str = absl::string_view(tmp_block_.get(), size);
574 packed_block->assign(block_str.data(), block_str.size());
577 void Unpack(
const std::string& packed_block, addrval<T>* block)
override {
579 uLongf size = this->input_size();
581 uncompress(reinterpret_cast<Bytef*>(block), &size,
582 reinterpret_cast<const Bytef*>(packed_block.c_str()),
583 packed_block.size());
588 const uint64_t tmp_size_;
589 std::unique_ptr<char[]> tmp_block_;
594 class CompressedTrail {
599 : block_size_(block_size),
601 free_blocks_(nullptr),
602 data_(new addrval<T>[block_size]),
603 buffer_(new addrval<T>[block_size]),
607 switch (compression_level) {
609 packer_.reset(
new NoCompressionTrailPacker<T>(block_size));
613 packer_.reset(
new ZlibTrailPacker<T>(block_size));
626 memset(data_.get(), 0,
sizeof(*data_.get()) * block_size);
627 memset(buffer_.get(), 0,
sizeof(*buffer_.get()) * block_size);
631 FreeBlocks(free_blocks_);
633 const addrval<T>& Back()
const {
645 buffer_used_ =
false;
646 }
else if (blocks_ !=
nullptr) {
647 packer_->Unpack(blocks_->compressed, data_.get());
655 void PushBack(
const addrval<T>& addr_val) {
659 packer_->Pack(buffer_.get(), &blocks_->compressed);
672 int64_t size()
const {
return size_; }
680 void FreeTopBlock() {
681 Block* block = blocks_;
682 blocks_ = block->next;
683 block->compressed.clear();
684 block->next = free_blocks_;
685 free_blocks_ = block;
688 Block* block =
nullptr;
689 if (free_blocks_ !=
nullptr) {
690 block = free_blocks_;
691 free_blocks_ = block->next;
695 block->next = blocks_;
698 void FreeBlocks(Block* blocks) {
699 while (
nullptr != blocks) {
700 Block*
next = blocks->next;
706 std::unique_ptr<TrailPacker<T> > packer_;
707 const int block_size_;
710 std::unique_ptr<addrval<T>[]> data_;
711 std::unique_ptr<addrval<T>[]> buffer_;
745 :
rev_ints_(block_size, compression_level),
749 rev_ptrs_(block_size, compression_level) {}
752 int target = m->rev_int_index_;
753 for (
int curr =
rev_ints_.size(); curr > target; --curr) {
754 const addrval<int>& cell =
rev_ints_.Back();
760 target = m->rev_int64_index_;
761 for (
int curr =
rev_int64s_.size(); curr > target; --curr) {
768 target = m->rev_uint64_index_;
769 for (
int curr =
rev_uint64s_.size(); curr > target; --curr) {
776 target = m->rev_double_index_;
777 for (
int curr =
rev_doubles_.size(); curr > target; --curr) {
784 target = m->rev_ptr_index_;
785 for (
int curr =
rev_ptrs_.size(); curr > target; --curr) {
786 const addrval<void*>& cell =
rev_ptrs_.Back();
792 target = m->rev_boolvar_list_index_;
800 target = m->rev_bools_index_;
801 for (
int curr =
rev_bools_.size() - 1; curr >= target; --curr) {
807 target = m->rev_int_memory_index_;
813 target = m->rev_int64_memory_index_;
819 target = m->rev_double_memory_index_;
825 target = m->rev_object_memory_index_;
831 target = m->rev_object_array_memory_index_;
838 target = m->rev_memory_index_;
839 for (
int curr =
rev_memory_.size() - 1; curr >= target; --curr) {
841 ::operator
delete(reinterpret_cast<char*>(
rev_memory_[curr]));
850 target = m->rev_memory_array_index_;
859 void Solver::InternalSaveValue(
int* valptr) {
860 trail_->rev_ints_.PushBack(addrval<int>(valptr));
863 void Solver::InternalSaveValue(int64_t* valptr) {
864 trail_->rev_int64s_.PushBack(addrval<int64_t>(valptr));
867 void Solver::InternalSaveValue(uint64_t* valptr) {
868 trail_->rev_uint64s_.PushBack(addrval<uint64_t>(valptr));
871 void Solver::InternalSaveValue(
double* valptr) {
872 trail_->rev_doubles_.PushBack(addrval<double>(valptr));
875 void Solver::InternalSaveValue(
void** valptr) {
876 trail_->rev_ptrs_.PushBack(addrval<void*>(valptr));
882 void Solver::InternalSaveValue(
bool* valptr) {
883 trail_->rev_bools_.push_back(valptr);
884 trail_->rev_bool_value_.push_back(*valptr);
887 BaseObject* Solver::SafeRevAlloc(BaseObject* ptr) {
889 trail_->rev_object_memory_.push_back(ptr);
893 int* Solver::SafeRevAllocArray(
int* ptr) {
895 trail_->rev_int_memory_.push_back(ptr);
899 int64_t* Solver::SafeRevAllocArray(int64_t* ptr) {
901 trail_->rev_int64_memory_.push_back(ptr);
905 double* Solver::SafeRevAllocArray(
double* ptr) {
907 trail_->rev_double_memory_.push_back(ptr);
911 uint64_t* Solver::SafeRevAllocArray(uint64_t* ptr) {
913 trail_->rev_int64_memory_.push_back(reinterpret_cast<int64_t*>(ptr));
917 BaseObject** Solver::SafeRevAllocArray(BaseObject** ptr) {
919 trail_->rev_object_array_memory_.push_back(ptr);
923 IntVar** Solver::SafeRevAllocArray(IntVar** ptr) {
924 BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
925 return reinterpret_cast<IntVar**>(in);
928 IntExpr** Solver::SafeRevAllocArray(IntExpr** ptr) {
929 BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
930 return reinterpret_cast<IntExpr**>(in);
933 Constraint** Solver::SafeRevAllocArray(Constraint** ptr) {
934 BaseObject** in = SafeRevAllocArray(reinterpret_cast<BaseObject**>(ptr));
935 return reinterpret_cast<Constraint**>(in);
938 void* Solver::UnsafeRevAllocAux(
void* ptr) {
940 trail_->rev_memory_.push_back(ptr);
944 void** Solver::UnsafeRevAllocArrayAux(
void** ptr) {
946 trail_->rev_memory_array_.push_back(ptr);
951 solver->trail_->rev_boolvar_list_.push_back(
var);
962 solution_counter_(0),
963 unchecked_solution_counter_(0),
964 decision_builder_(nullptr),
965 created_by_solve_(false),
967 left_search_depth_(0),
968 should_restart_(false),
969 should_finish_(false),
971 jmpbuf_filled_(false),
972 backtrack_at_the_end_of_the_search_(true) {}
981 solution_counter_(0),
982 unchecked_solution_counter_(0),
983 decision_builder_(nullptr),
984 created_by_solve_(false),
986 left_search_depth_(-1),
987 should_restart_(false),
988 should_finish_(false),
990 jmpbuf_filled_(false),
991 backtrack_at_the_end_of_the_search_(true) {}
1024 return unchecked_solution_counter_;
1027 decision_builder_ = db;
1036 left_search_depth_++;
1040 return backtrack_at_the_end_of_the_search_;
1043 backtrack_at_the_end_of_the_search_ = restore;
1054 if (should_finish_ || should_restart_) {
1067 void ClearBuffer() {
1068 CHECK(jmpbuf_filled_) <<
"Internal error in backtracking";
1069 jmpbuf_filled_ =
false;
1073 std::vector<StateMarker*> marker_stack_;
1074 std::vector<SearchMonitor*> monitors_;
1075 jmp_buf fail_buffer_;
1076 int64_t solution_counter_;
1077 int64_t unchecked_solution_counter_;
1079 bool created_by_solve_;
1082 int left_search_depth_;
1083 bool should_restart_;
1084 bool should_finish_;
1085 int sentinel_pushed_;
1086 bool jmpbuf_filled_;
1087 bool backtrack_at_the_end_of_the_search_;
1088 std::string search_context_;
1101 #ifndef CP_USE_EXCEPTIONS_FOR_BACKTRACK 1104 #define CP_TRY(search) \ 1105 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \ 1106 search->jmpbuf_filled_ = true; \ 1107 if (setjmp(search->fail_buffer_) == 0) 1108 #define CP_ON_FAIL else 1109 #define CP_DO_FAIL(search) longjmp(search->fail_buffer_, 1) 1110 #else // CP_USE_EXCEPTIONS_FOR_BACKTRACK 1111 class FailException {};
1112 #define CP_TRY(search) \ 1113 CHECK(!search->jmpbuf_filled_) << "Fail() called outside search"; \ 1114 search->jmpbuf_filled_ = true; \ 1116 #define CP_ON_FAIL catch (FailException&) 1117 #define CP_DO_FAIL(search) throw FailException() 1118 #endif // CP_USE_EXCEPTIONS_FOR_BACKTRACK 1120 void Search::JumpBack() {
1121 if (jmpbuf_filled_) {
1122 jmpbuf_filled_ =
false;
1125 std::string explanation =
"Failure outside of search";
1137 ~ApplyBranchSelector()
override {}
1139 Decision* Next(Solver*
const s)
override {
1144 std::string DebugString()
const override {
return "Apply(BranchSelector)"; }
1152 selector_ = std::move(bs);
1161 [solve_depth](
Solver* s) {
1167 searches_.back()->SetBranchSelector(std::move(bs));
1171 return RevAlloc(
new ApplyBranchSelector(std::move(bs)));
1181 return searches_.back()->left_search_depth();
1185 if (selector_ !=
nullptr) {
1193 monitors_.push_back(m);
1200 left_search_depth_ = 0;
1201 selector_ =
nullptr;
1202 backtrack_at_the_end_of_the_search_ =
true;
1209 solution_counter_ = 0;
1210 unchecked_solution_counter_ = 0;
1264 if (!monitor->AcceptSolution()) {
1275 bool should_continue =
false;
1277 if (monitor->AtSolution()) {
1281 should_continue =
true;
1284 return should_continue;
1294 if (monitor->LocalOptimum()) {
1304 if (!monitor->AcceptDelta(
delta, deltadelta)) {
1321 if (monitor->IsUncheckedSolutionLimitReached()) {
1335 progress =
std::max(progress, monitor->ProgressPercent());
1342 if (decision_builder_ !=
nullptr) {
1343 decision_builder_->
Accept(visitor);
1366 class FailDecision :
public Decision {
1368 void Apply(Solver*
const s)
override { s->Fail(); }
1369 void Refute(Solver*
const s)
override { s->Fail(); }
1374 class BalancingDecision :
public Decision {
1376 ~BalancingDecision()
override {}
1377 void Apply(Solver*
const s)
override {}
1378 void Refute(Solver*
const s)
override {}
1390 INITIAL_SEARCH_SENTINEL = 10000000,
1391 ROOT_NODE_SENTINEL = 20000000,
1392 SOLVER_CTOR_SENTINEL = 40000000
1396 extern PropagationMonitor*
BuildTrace(Solver*
const s);
1405 <<
"Were parameters built using Solver::DefaultSolverParameters() ?";
1415 use_fast_local_search_(true),
1422 parameters_(DefaultSolverParameters()),
1425 use_fast_local_search_(true),
1430 void Solver::Init() {
1431 CheckSolverParameters(parameters_);
1432 queue_ = absl::make_unique<Queue>(
this);
1440 filtered_neighbors_ = 0;
1441 accepted_neighbors_ = 0;
1442 optimization_direction_ =
NOT_SET;
1443 timer_ = absl::make_unique<ClockTimer>();
1444 searches_.assign(1,
new Search(
this, 0));
1445 fail_stamp_ = uint64_t{1};
1446 balancing_decision_ = absl::make_unique<BalancingDecision>();
1447 fail_intercept_ =
nullptr;
1448 true_constraint_ =
nullptr;
1449 false_constraint_ =
nullptr;
1450 fail_decision_ = absl::make_unique<FailDecision>();
1451 constraint_index_ = 0;
1452 additional_constraint_index_ = 0;
1454 propagation_monitor_.reset(
BuildTrace(
this));
1456 print_trace_ =
nullptr;
1457 anonymous_variable_index_ = 0;
1458 should_fail_ =
false;
1463 searches_.push_back(
new Search(
this));
1464 PushSentinel(SOLVER_CTOR_SENTINEL);
1465 InitCachedIntConstants();
1466 InitCachedConstraint();
1471 reinterpret_cast<LocalSearchMonitor*>(local_search_profiler_));
1477 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1491 std::string out =
"Solver(name = \"" + name_ +
"\", state = ";
1494 out +=
"OUTSIDE_SEARCH";
1497 out +=
"IN_ROOT_NODE";
1503 out +=
"AT_SOLUTION";
1506 out +=
"NO_MORE_SOLUTIONS";
1509 out +=
"PROBLEM_INFEASIBLE";
1512 absl::StrAppendFormat(
1514 ", branches = %d, fails = %d, decisions = %d, delayed demon runs = %d, " 1515 "var demon runs = %d, normal demon runs = %d, Run time = %d ms)",
1524 return absl::ToInt64Milliseconds(timer_->GetDuration());
1528 return absl::FromUnixSeconds(0) + timer_->GetDuration();
1539 void Solver::IncrementUncheckedSolutionCounter() {
1543 bool Solver::IsUncheckedSolutionLimitReached() {
1575 m->rev_int_index_ = trail_->rev_ints_.size();
1576 m->rev_int64_index_ = trail_->rev_int64s_.size();
1577 m->rev_uint64_index_ = trail_->rev_uint64s_.size();
1578 m->rev_double_index_ = trail_->rev_doubles_.size();
1579 m->rev_ptr_index_ = trail_->rev_ptrs_.size();
1580 m->rev_boolvar_list_index_ = trail_->rev_boolvar_list_.size();
1581 m->rev_bools_index_ = trail_->rev_bools_.size();
1582 m->rev_int_memory_index_ = trail_->rev_int_memory_.size();
1583 m->rev_int64_memory_index_ = trail_->rev_int64_memory_.size();
1584 m->rev_double_memory_index_ = trail_->rev_double_memory_.size();
1585 m->rev_object_memory_index_ = trail_->rev_object_memory_.size();
1586 m->rev_object_array_memory_index_ = trail_->rev_object_array_memory_.size();
1587 m->rev_memory_index_ = trail_->rev_memory_.size();
1588 m->rev_memory_array_index_ = trail_->rev_memory_array_.size();
1590 searches_.back()->marker_stack_.push_back(m);
1591 queue_->increase_stamp();
1600 CHECK(!searches_.back()->marker_stack_.empty())
1601 <<
"PopState() on an empty stack";
1602 CHECK(info !=
nullptr);
1603 StateMarker*
const m = searches_.back()->marker_stack_.back();
1605 trail_->BacktrackTo(m);
1609 searches_.back()->marker_stack_.pop_back();
1611 queue_->increase_stamp();
1615 void Solver::check_alloc_state() {
1624 LOG(
FATAL) <<
"allocating at a leaf node";
1626 LOG(
FATAL) <<
"This switch was supposed to be exhaustive, but it is not!";
1630 void Solver::FreezeQueue() { queue_->Freeze(); }
1632 void Solver::UnfreezeQueue() { queue_->Unfreeze(); }
1634 void Solver::EnqueueVar(Demon*
const d) { queue_->EnqueueVar(d); }
1636 void Solver::EnqueueDelayedDemon(Demon*
const d) {
1637 queue_->EnqueueDelayedDemon(d);
1640 void Solver::ExecuteAll(
const SimpleRevFIFO<Demon*>& demons) {
1641 queue_->ExecuteAll(demons);
1644 void Solver::EnqueueAll(
const SimpleRevFIFO<Demon*>& demons) {
1645 queue_->EnqueueAll(demons);
1652 void Solver::set_action_on_fail(Action
a) {
1653 queue_->set_action_on_fail(std::move(
a));
1656 void Solver::set_variable_to_clean_on_fail(IntVar* v) {
1657 queue_->set_variable_to_clean_on_fail(v);
1660 void Solver::reset_action_on_fail() { queue_->reset_action_on_fail(); }
1664 if (c == true_constraint_) {
1668 queue_->AddConstraint(c);
1671 DCHECK_LE(constraint_index_, constraints_list_.size());
1672 const int constraint_parent =
1673 constraint_index_ == constraints_list_.size()
1674 ? additional_constraints_parent_list_[additional_constraint_index_]
1675 : constraint_index_;
1676 additional_constraints_list_.push_back(c);
1677 additional_constraints_parent_list_.push_back(constraint_parent);
1682 constraints_list_.push_back(c);
1688 if (constraint !=
nullptr) {
1690 cast_constraints_.insert(constraint);
1691 cast_information_[target_var] =
1704 void Solver::ProcessConstraints() {
1717 LOG(
INFO) <<
"Forcing early failure";
1722 const int constraints_size = constraints_list_.size();
1723 additional_constraints_list_.clear();
1724 additional_constraints_parent_list_.clear();
1726 for (constraint_index_ = 0; constraint_index_ < constraints_size;
1727 ++constraint_index_) {
1728 Constraint*
const constraint = constraints_list_[constraint_index_];
1729 propagation_monitor_->BeginConstraintInitialPropagation(constraint);
1730 constraint->PostAndPropagate();
1731 propagation_monitor_->EndConstraintInitialPropagation(constraint);
1733 CHECK_EQ(constraints_list_.size(), constraints_size);
1736 for (
int additional_constraint_index_ = 0;
1737 additional_constraint_index_ < additional_constraints_list_.size();
1738 ++additional_constraint_index_) {
1740 additional_constraints_list_[additional_constraint_index_];
1741 const int parent_index =
1742 additional_constraints_parent_list_[additional_constraint_index_];
1743 Constraint*
const parent = constraints_list_[parent_index];
1744 propagation_monitor_->BeginNestedConstraintInitialPropagation(parent,
1746 nested->PostAndPropagate();
1747 propagation_monitor_->EndNestedConstraintInitialPropagation(parent, nested);
1753 DCHECK(searches_.back() !=
nullptr);
1754 return searches_.back()->created_by_solve();
1758 std::vector<SearchMonitor*> monitors;
1759 monitors.push_back(m1);
1760 return Solve(db, monitors);
1764 std::vector<SearchMonitor*> monitors;
1765 return Solve(db, monitors);
1770 std::vector<SearchMonitor*> monitors;
1771 monitors.push_back(m1);
1772 monitors.push_back(m2);
1773 return Solve(db, monitors);
1778 std::vector<SearchMonitor*> monitors;
1779 monitors.push_back(m1);
1780 monitors.push_back(m2);
1781 monitors.push_back(m3);
1782 return Solve(db, monitors);
1788 std::vector<SearchMonitor*> monitors;
1789 monitors.push_back(m1);
1790 monitors.push_back(m2);
1791 monitors.push_back(m3);
1792 monitors.push_back(m4);
1793 return Solve(db, monitors);
1797 const std::vector<SearchMonitor*>& monitors) {
1799 searches_.back()->set_created_by_solve(
true);
1801 const bool solution_found = searches_.back()->solution_counter() > 0;
1803 return solution_found;
1807 std::vector<SearchMonitor*> monitors;
1808 monitors.push_back(m1);
1813 std::vector<SearchMonitor*> monitors;
1819 std::vector<SearchMonitor*> monitors;
1820 monitors.push_back(m1);
1821 monitors.push_back(m2);
1827 std::vector<SearchMonitor*> monitors;
1828 monitors.push_back(m1);
1829 monitors.push_back(m2);
1830 monitors.push_back(m3);
1837 std::vector<SearchMonitor*> monitors;
1838 monitors.push_back(m1);
1839 monitors.push_back(m2);
1840 monitors.push_back(m3);
1841 monitors.push_back(m4);
1849 const std::vector<SearchMonitor*>& monitors) {
1852 CHECK(db !=
nullptr);
1853 const bool nested = state_ ==
IN_SEARCH;
1856 LOG(
FATAL) <<
"Cannot start new searches here.";
1859 Search*
const search = nested ?
new Search(
this) : searches_.back();
1867 searches_.push_back(search);
1873 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
1880 propagation_monitor_->Install();
1881 if (demon_profiler_ !=
nullptr) {
1884 local_search_monitor_->Install();
1885 if (local_search_profiler_ !=
nullptr) {
1891 if (monitor !=
nullptr) {
1895 std::vector<SearchMonitor*> extras;
1898 if (monitor !=
nullptr) {
1905 if (print_trace_ !=
nullptr) {
1909 print_trace_ =
nullptr;
1928 PushSentinel(INITIAL_SEARCH_SENTINEL);
1934 bool Solver::BacktrackOneLevel(
Decision**
const fail_decision) {
1935 bool no_more_solutions =
false;
1936 bool end_loop =
false;
1945 searches_.back()->sentinel_pushed_--;
1946 no_more_solutions =
true;
1950 LOG(
ERROR) <<
"Simple markers should not be encountered during search";
1954 (*fail_decision) = reinterpret_cast<Decision*>(info.
ptr_info);
1956 searches_.back()->set_search_depth(info.
depth);
1957 searches_.back()->set_search_left_depth(info.
left_depth);
1968 Search*
const search = searches_.back();
1971 if (no_more_solutions) {
1972 search->NoMoreSolutions();
1974 return no_more_solutions;
1977 void Solver::PushSentinel(
int magic_code) {
1978 StateInfo info(
this, magic_code);
1981 if (magic_code != SOLVER_CTOR_SENTINEL) {
1982 searches_.back()->sentinel_pushed_++;
1984 const int pushed = searches_.back()->sentinel_pushed_;
1985 DCHECK((magic_code == SOLVER_CTOR_SENTINEL) ||
1986 (magic_code == INITIAL_SEARCH_SENTINEL && pushed == 1) ||
1987 (magic_code == ROOT_NODE_SENTINEL && pushed == 2));
1991 Search*
const search = searches_.back();
1992 CHECK_NE(0, search->sentinel_pushed_);
1994 if (search->sentinel_pushed_ > 1) {
1995 BacktrackToSentinel(ROOT_NODE_SENTINEL);
1997 CHECK_EQ(1, search->sentinel_pushed_);
1998 PushSentinel(ROOT_NODE_SENTINEL);
2002 if (search->sentinel_pushed_ > 0) {
2003 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2005 CHECK_EQ(0, search->sentinel_pushed_);
2006 PushSentinel(INITIAL_SEARCH_SENTINEL);
2014 void Solver::BacktrackToSentinel(
int magic_code) {
2015 Search*
const search = searches_.back();
2016 bool end_loop = search->sentinel_pushed_ == 0;
2023 CHECK_GE(--search->sentinel_pushed_, 0);
2046 void Solver::JumpToSentinelWhenNested() {
2048 Search* c = searches_.back();
2049 Search* p = ParentSearch();
2051 while (!c->marker_stack_.empty()) {
2052 StateMarker*
const m = c->marker_stack_.back();
2054 p->marker_stack_.push_back(m);
2057 CHECK_EQ(c->marker_stack_.size(), 1) <<
"Sentinel found too early";
2062 c->marker_stack_.pop_back();
2064 c->set_search_depth(0);
2065 c->set_search_left_depth(0);
2066 CHECK_EQ(found,
true) <<
"Sentinel not found";
2070 class ReverseDecision :
public Decision {
2072 explicit ReverseDecision(Decision*
const d) : decision_(d) {
2073 CHECK(d !=
nullptr);
2075 ~ReverseDecision()
override {}
2077 void Apply(Solver*
const s)
override { decision_->Refute(s); }
2079 void Refute(Solver*
const s)
override { decision_->Apply(s); }
2081 void Accept(DecisionVisitor*
const visitor)
const override {
2082 decision_->Accept(visitor);
2085 std::string DebugString()
const override {
2086 std::string str =
"Reverse(";
2087 str += decision_->DebugString();
2093 Decision*
const decision_;
2099 Search*
const search = searches_.back();
2102 const bool top_level = solve_depth <= 1;
2105 LOG(
WARNING) <<
"NextSolution() called without a NewSearch before";
2116 if (BacktrackOneLevel(&fd)) {
2127 ProcessConstraints();
2129 PushSentinel(ROOT_NODE_SENTINEL);
2131 search->ClearBuffer();
2134 queue_->AfterFailure();
2135 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2149 volatile bool finish =
false;
2150 volatile bool result =
false;
2155 if (fd !=
nullptr) {
2174 if (d == fail_decision_.get()) {
2179 switch (modification) {
2181 d =
RevAlloc(
new ReverseDecision(d));
2183 ABSL_FALLTHROUGH_INTENDED;
2233 queue_->AfterFailure();
2236 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2237 : INITIAL_SEARCH_SENTINEL);
2245 BacktrackToSentinel(top_level ? ROOT_NODE_SENTINEL
2246 : INITIAL_SEARCH_SENTINEL);
2249 PushSentinel(top_level ? ROOT_NODE_SENTINEL : INITIAL_SEARCH_SENTINEL);
2252 if (BacktrackOneLevel(&fd)) {
2260 search->ClearBuffer();
2269 Search*
const search = searches_.back();
2271 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2274 if (search->sentinel_pushed_ > 0) {
2275 JumpToSentinelWhenNested();
2280 if (2 == searches_.size()) {
2285 const std::string& file_name = parameters_.
profile_file();
2286 LOG(
INFO) <<
"Exporting profile to " << file_name;
2294 searches_.pop_back();
2301 LOG(
FATAL) <<
"CheckAssignment is only available at the top level.";
2304 Search*
const search = searches_.back();
2307 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2316 PushSentinel(INITIAL_SEARCH_SENTINEL);
2321 restore->
Next(
this);
2322 ProcessConstraints();
2324 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2325 search->ClearBuffer();
2331 constraint_index_ < constraints_list_.size()
2333 : additional_constraints_parent_list_[additional_constraint_index_];
2335 if (
ct->name().empty()) {
2336 LOG(
INFO) <<
"Failing constraint = " <<
ct->DebugString();
2338 LOG(
INFO) <<
"Failing constraint = " <<
ct->name() <<
":" 2339 <<
ct->DebugString();
2341 queue_->AfterFailure();
2342 BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
2351 explicit AddConstraintDecisionBuilder(
Constraint*
const ct)
2356 ~AddConstraintDecisionBuilder()
override {}
2358 Decision* Next(Solver*
const solver)
override {
2359 solver->AddConstraint(constraint_);
2363 std::string DebugString()
const override {
2364 return absl::StrFormat(
"AddConstraintDecisionBuilder(%s)",
2365 constraint_->DebugString());
2369 Constraint*
const constraint_;
2374 return RevAlloc(
new AddConstraintDecisionBuilder(
ct));
2383 std::vector<SearchMonitor*> monitors;
2384 monitors.push_back(m1);
2389 std::vector<SearchMonitor*> monitors;
2395 std::vector<SearchMonitor*> monitors;
2396 monitors.push_back(m1);
2397 monitors.push_back(m2);
2403 std::vector<SearchMonitor*> monitors;
2404 monitors.push_back(m1);
2405 monitors.push_back(m2);
2406 monitors.push_back(m3);
2411 const std::vector<SearchMonitor*>& monitors) {
2413 searches_.back()->set_created_by_solve(
true);
2414 searches_.back()->set_backtrack_at_the_end_of_the_search(
false);
2416 const bool solution_found = searches_.back()->solution_counter() > 0;
2418 return solution_found;
2422 if (fail_intercept_) {
2428 searches_.back()->BeginFail();
2429 searches_.back()->JumpBack();
2433 searches_.back()->set_should_finish(
true);
2437 searches_.back()->set_should_restart(
true);
2445 if (cast_info !=
nullptr) {
2455 if (
name !=
nullptr) {
2458 const IntegerCastInfo*
const cast_info =
2460 if (cast_info !=
nullptr && cast_info->expression !=
nullptr) {
2461 if (cast_info->expression->HasName()) {
2462 return absl::StrFormat(
"Var<%s>", cast_info->expression->name());
2464 return absl::StrFormat(
"Var<%s>", cast_info->expression->DebugString());
2466 const std::string new_name =
2467 absl::StrFormat(
"CastVar<%d>", anonymous_variable_index_++);
2468 propagation_object_names_[object] = new_name;
2472 const std::string base_name =
object->BaseName();
2474 const std::string new_name =
2475 absl::StrFormat(
"%s_%d", base_name, anonymous_variable_index_++);
2476 propagation_object_names_[object] = new_name;
2482 void Solver::SetName(
const PropagationBaseObject*
object,
2483 const std::string&
name) {
2485 GetName(
object) !=
name) {
2486 propagation_object_names_[object] =
name;
2492 const_cast<PropagationBaseObject*>(
object)) ||
2511 return solver_->GetName(
this);
2515 solver_->SetName(
this,
name);
2523 solver_->ExecuteAll(demons);
2527 solver_->EnqueueAll(demons);
2535 Solver*
const solver, std::vector<SearchMonitor*>*
const extras) {}
2630 "ScalarProductGreaterOrEqual";
2658 "VariableUsageLessConstant";
2660 "WeightedSumOfAssignedEqualVariable";
2757 if (delegate !=
nullptr) {
2763 const std::string& operation,
2765 if (delegate !=
nullptr) {
2771 const std::string& operation,
2774 if (delegate !=
nullptr) {
2780 for (
int i = 0; i < variable->
size(); ++i) {
2789 const std::string& arg_name,
const std::vector<int64_t>& values) {}
2803 const std::string& arg_name,
const std::vector<IntVar*>& arguments) {
2813 const std::string& arg_name,
const std::vector<IntervalVar*>& arguments) {
2823 const std::string& arg_name,
const std::vector<SequenceVar*>& arguments) {
2831 int64_t index_max) {
2832 if (filter !=
nullptr) {
2833 std::vector<int64_t> cached_results;
2834 for (
int i = index_min; i <= index_max; ++i) {
2835 cached_results.push_back(filter(i));
2847 CHECK(eval !=
nullptr);
2848 std::vector<int64_t> cached_results;
2849 for (
int i = index_min; i <= index_max; ++i) {
2850 cached_results.push_back(eval(i));
2860 const std::string& arg_name,
2861 int64_t index_max) {
2862 CHECK(eval !=
nullptr);
2863 std::vector<int64_t> cached_results;
2864 for (
int i = 0; i <= index_max; ++i) {
2865 cached_results.push_back(eval(i));
2898 solver()->searches_.back()->push_monitor(
this);
2990 monitor->SetMin(expr, new_min);
2996 monitor->SetMax(expr, new_max);
3001 int64_t new_max)
override {
3003 monitor->SetRange(expr, new_min, new_max);
3010 monitor->SetMin(
var, new_min);
3016 monitor->SetMax(
var, new_max);
3022 monitor->SetRange(
var, new_min, new_max);
3039 const std::vector<int64_t>& values)
override {
3044 const std::vector<int64_t>& values)
override {
3058 int64_t new_max)
override {
3072 int64_t new_max)
override {
3085 int64_t new_max)
override {
3111 const std::vector<int>& rank_last,
3112 const std::vector<int>& unperformed)
override {
3114 rank_last, unperformed);
3119 if (monitor !=
nullptr) {
3120 monitors_.push_back(monitor);
3131 std::vector<PropagationMonitor*> monitors_;
3138 reinterpret_cast<class Trace*>(propagation_monitor_.get())->Add(monitor);
3142 return propagation_monitor_.get();
3165 neighbor_found,
delta, deltadelta);
3171 bool neighbor_found)
override {
3179 bool neighbor_found)
override {
3192 if (monitor !=
nullptr) {
3193 monitors_.push_back(monitor);
3202 return "LocalSearchMonitorMaster";
3206 std::vector<LocalSearchMonitor*> monitors_;
3214 reinterpret_cast<class LocalSearchMonitorMaster*>(local_search_monitor_.get())
3219 return local_search_monitor_.get();
3223 const std::string& search_context) {
3236 if (local_search_state_ ==
nullptr) {
3237 local_search_state_ = absl::make_unique<Assignment>(
this);
3239 return local_search_state_.get();
3274 #undef CP_TRY // We no longer need those. Right branches are ignored.
int left_search_depth() const
Constraint * MakeFalseConstraint()
This constraint always fails.
int64_t solution_counter() const
void BeginFilterNeighbor(const LocalSearchOperator *op) override
static const char kProduct[]
::operations_research::ConstraintSolverParameters_TrailCompression compress_trail() const
Cast constraints are special channeling constraints designed to keep a variable in sync with an expre...
int64_t size() const
Returns the number of interval vars in the sequence.
static const char kDivide[]
void SetEndMin(IntervalVar *const var, int64_t new_min) override
virtual void Post()=0
This method is called when the constraint is processed by the solver.
StateInfo(void *pinfo, int iinfo, int d, int ld)
static const char kCumulsArgument[]
static const char kTrace[]
static const char kPartialArgument[]
static const char kVarBoundWatcher[]
bool print_added_constraints() const
static const char kIndexOf[]
static const char kPathCumul[]
static const char kModuloArgument[]
int SearchDepth() const
Gets the search depth of the current active search.
virtual void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments)
static const char kSearchLimitExtension[]
void set_num_solutions(::PROTOBUF_NAMESPACE_ID::int64 value)
DecisionModification
The Solver is responsible for creating the search tree.
void AddLocalSearchMonitor(LocalSearchMonitor *monitor)
Adds the local search monitor to the solver.
CompressedTrail< int > rev_ints_
void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta) override
std::string DebugString() const override
After successful NextSolution and before EndSearch.
virtual void EnterSearch()
Beginning of the search.
static const char kCountEqual[]
The base class for all local search operators.
void VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1 &eval, const std::string &arg_name, int64_t index_max)
Expands function as array when index min is 0.
void AfterDecision(Decision *const d, bool apply)
void set_profile_file(ArgT0 &&arg0, ArgT... args)
std::vector< bool * > rev_bools_
int64_t solutions() const
The number of solutions found since the start of the search.
void DeleteDemonProfiler(DemonProfiler *const monitor)
void NewSearch(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
Solver(const std::string &name)
Solver API.
bool CurrentlyInSolve() const
Returns true whether the current search has been created using a Solve() call instead of a NewSearch ...
void SetEndMax(IntervalVar *const var, int64_t new_max) override
virtual void VisitUnknownDecision()
#define CHECK_GE(val1, val2)
static const char kPower[]
static const char kDifferenceOperation[]
void RestartCurrentSearch()
virtual void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
void TopPeriodicCheck()
Performs PeriodicCheck on the top-level search; for instance, can be called from a nested solve to ch...
MarkerType
This enum is used internally in private methods Solver::PushState and Solver::PopState to tag states ...
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
After search, the model is infeasible.
StateMarker(Solver::MarkerType t, const StateInfo &info)
void SetMax(IntExpr *const expr, int64_t new_max) override
virtual void VisitRankFirstInterval(SequenceVar *const sequence, int index)
void SetDurationMax(IntervalVar *const var, int64_t new_max) override
void set_profile_propagation(bool value)
static const char kCumulative[]
virtual void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments)
static const char kEarlyCostArgument[]
virtual void SetEndMax(IntervalVar *const var, int64_t new_max)=0
static constexpr int64_t kTestPeriod
void SetStartMax(IntervalVar *const var, int64_t new_max) override
void set_decision_builder(DecisionBuilder *const db)
StateInfo(void *pinfo, int iinfo)
static int64_t MemoryUsage()
Current memory usage in bytes.
void SetMax(IntVar *const var, int64_t new_max) override
std::function< int64_t(int64_t)> IndexEvaluator1
Callback typedefs.
void SetBranchSelector(BranchSelector bs)
Sets the given branch selector on the current active search.
void SetPerformed(IntervalVar *const var, bool value) override
static const char kAllDifferent[]
virtual void InitialPropagate()=0
This method performs the initial propagation of the constraint.
static const char kOptionalArgument[]
virtual void BeginFail()
Just when the failure occurs.
static const char kIntervalUnaryRelation[]
static const char kTuplesArgument[]
virtual void EndFail()
After completing the backtrack.
void PopContext() override
static const char kMember[]
std::string DebugString() const override
#define CHECK_GT(val1, val2)
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *const constraint)
bool AcceptDelta(Search *const search, Assignment *delta, Assignment *deltadelta)
PropagationMonitor * BuildPrintTrace(Solver *const s)
void RegisterDemon(Demon *const demon) override
bool name_cast_variables() const
#define VLOG(verboselevel)
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
std::vector< void ** > rev_memory_array_
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...
static const char kMaxArgument[]
static const char kEquality[]
static const char kSequenceVariable[]
After failed NextSolution and before EndSearch.
Trail(int block_size, ConstraintSolverParameters::TrailCompression compression_level)
static const char kObjectiveExtension[]
virtual void BeginMakeNextNeighbor(const LocalSearchOperator *op)=0
virtual void RefuteDecision(Decision *const d)
Before refuting the decision.
std::function< IntVar *(int64_t)> Int64ToIntVar
virtual void VisitScheduleOrPostpone(IntervalVar *const var, int64_t est)
Backtracks to the previous decisions, i.e.
static const char kGreater[]
void set_store_names(bool value)
ConstraintSolverParameters_TrailCompression TrailCompression
void IncrementSolutionCounter()
A Demon is the base element of a propagation queue.
static const char kLinkExprVar[]
static const char kSizeXArgument[]
std::vector< double * > rev_double_memory_
virtual void SetDurationMax(IntervalVar *const var, int64_t new_max)=0
static const char kElementEqual[]
A DecisionVisitor is used to inspect a decision.
void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed) override
virtual void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
LocalSearchProfiler * BuildLocalSearchProfiler(Solver *solver)
Search(Solver *const s, int)
int64_t failures() const
The number of failures encountered since the creation of the solver.
static const char kVariableArgument[]
virtual std::string name() const
Object naming.
void BeginOperatorStart() override
Local search operator events.
static const char kIndex2Argument[]
static const char kCountArgument[]
static const char kEndsArgument[]
void InstallDemonProfiler(DemonProfiler *const monitor)
void SetStartMin(IntervalVar *const var, int64_t new_min) override
IntervalVar modifiers.
void set_print_model(bool value)
virtual void SetPerformed(IntervalVar *const var, bool value)=0
DemonProfiler * BuildDemonProfiler(Solver *const solver)
static const char kDisjunctive[]
static const char kAbsEqual[]
virtual IntVar * Var()
Creates a Boolean variable representing the status of the constraint (false = constraint is violated,...
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
void set_max_edge_finder_size(::PROTOBUF_NAMESPACE_ID::int32 value)
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
void EndFiltering(const LocalSearchFilter *filter, bool reject) override
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
virtual void BeginNextDecision(DecisionBuilder *const b)
Before calling DecisionBuilder::Next.
bool InstrumentsVariables() const
Returns whether we are tracing variables.
virtual void VisitSequenceArgument(const std::string &arg_name, SequenceVar *const argument)
Visit sequence argument.
std::vector< void * > rev_memory_
A constraint is the main modeling object.
void set_should_restart(bool s)
bool profile_local_search() const
virtual void RestartSearch()
Restart the search.
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
void set_duration_seconds(double value)
int64_t GetProcessMemoryUsage()
void AcceptUncheckedNeighbor(Search *const search)
#define DCHECK_GT(val1, val2)
const std::string & profile_file() const
virtual void Apply(Solver *const s)=0
Apply will be called first when the decision is executed.
static const char kCapacityArgument[]
void Install() override
Install itself on the solver.
virtual void RankNotLast(SequenceVar *const var, int index)=0
std::string DebugString() const override
virtual void VisitScheduleOrExpedite(IntervalVar *const var, int64_t est)
StateInfo(Solver::Action a, bool fast)
static const char kStartSyncOnStartOperation[]
bool created_by_solve() const
static const char kNoCycle[]
virtual void ExitSearch()
End of the search.
static const char kStartsArgument[]
bool IsCastConstraint() const
Is the constraint created by a cast from expression to integer variable?
static const char kDemandsArgument[]
int64_t branches() const
The number of branches explored since the creation of the solver.
virtual void Accept(DecisionVisitor *const visitor) const
Accepts the given visitor.
static const char kIsLessOrEqual[]
virtual void EndDemonRun(Demon *const demon)=0
static const char kEndMaxArgument[]
A DecisionBuilder is responsible for creating the search tree.
virtual void EndVisitModel(const std::string &type_name)
static const char kPack[]
static const char kStartExpr[]
bool InstrumentsDemons() const
Returns whether we are instrumenting demons.
int64_t unchecked_solutions() const
The number of unchecked solutions found by local search.
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.
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
virtual void RankLast(SequenceVar *const var, int index)=0
void SetRange(IntVar *const var, int64_t new_min, int64_t new_max) override
virtual Solver::DemonPriority priority() const
This method returns the priority of the demon.
static const char kDistribute[]
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
virtual void SetValue(IntVar *const var, int64_t value)=0
virtual void RegisterDemon(Demon *const demon)=0
virtual void BeginConstraintInitialPropagation(Constraint *const constraint)=0
Propagation events.
static const char kFailuresLimitArgument[]
static const char kSizeYArgument[]
static const char kTrueConstraint[]
void set_num_failures(::PROTOBUF_NAMESPACE_ID::int64 value)
static const char kRelationArgument[]
void set_print_model_stats(bool value)
virtual void BeginInitialPropagation()
Before the initial propagation.
bool print_model_stats() const
virtual void Run(Solver *const s)=0
This is the main callback of the demon.
virtual void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
virtual void VisitIntervalVariable(const IntervalVar *const variable, const std::string &operation, int64_t value, IntervalVar *const delegate)
bool CheckAssignment(Assignment *const solution)
Checks whether the given assignment satisfies all relevant constraints.
Interval variables are often used in scheduling.
static const char kSumOperation[]
void desinhibit(Solver *const s)
This method un-inhibits the demon that was previously inhibited.
static const char kMinEqual[]
virtual void VisitRankLastInterval(SequenceVar *const sequence, int index)
void BacktrackTo(StateMarker *m)
void ExportProfilingOverview(const std::string &filename)
Exports the profiling information in a human readable overview.
Executing the search code.
std::function< DecisionModification()> BranchSelector
absl::Time Now() const
The 'absolute time' as seen by the solver.
static const char kIsEqual[]
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...
void SetMin(IntVar *const var, int64_t new_min) override
IntVar modifiers.
bool LocalOptimumReached(Search *const search)
static const char kIntegerVariable[]
PropagationMonitor * GetPropagationMonitor() const
Returns the propagation monitor.
virtual void PushContext(const std::string &context)=0
void EndNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
bool IsUncheckedSolutionLimitReached()
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
static const char kProductOperation[]
virtual void BeginVisitModel(const std::string &type_name)
--— Virtual methods for visitors --—
virtual void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments)
bool NameAllVariables() const
Returns whether all variables should be named.
static const char kCountUsedBinsExtension[]
virtual void BeginOperatorStart()=0
Local search operator events.
void EnqueueVar(Demon *const demon)
VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY.
virtual void VisitIntervalArgument(const std::string &arg_name, IntervalVar *const argument)
Visit interval argument.
static const char kEvaluatorArgument[]
static const char kCircuit[]
static const char kIsLess[]
static const char kElement[]
void DeleteLocalSearchProfiler(LocalSearchProfiler *monitor)
void set_search_depth(int d)
static constexpr TrailCompression NO_COMPRESSION
void set_use_cumulative_time_table_sync(bool value)
static const char kVarValueWatcher[]
NORMAL_PRIORITY is the highest priority: Demons will be processed first.
void Add(LocalSearchMonitor *monitor)
void AcceptNeighbor(Search *const search)
virtual bool AcceptSolution()
This method is called when a solution is found.
static const char kMinArgument[]
void set_compress_trail(::operations_research::ConstraintSolverParameters_TrailCompression value)
DecisionBuilder * decision_builder() const
void RemoveValue(IntVar *const var, int64_t value) override
int SolveDepth() const
Gets the number of nested searches.
static const char kGreaterOrEqual[]
static const char kDifference[]
virtual void VisitSplitVariableDomain(IntVar *const var, int64_t value, bool start_with_lower_half)
void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested) override
virtual void RemoveValues(IntVar *const var, const std::vector< int64_t > &values)=0
virtual std::string BaseName() const
Returns a base name for automatic naming.
bool trace_search() const
LocalSearchMonitor * BuildLocalSearchMonitorMaster(Solver *const s)
void reset_action_on_fail()
void set_use_cumulative_time_table(bool value)
static const char kCover[]
static const char kPerformedExpr[]
void SetValues(IntVar *const var, const std::vector< int64_t > &values) override
void EndInitialPropagation()
std::string DebugString() const override
virtual void EndProcessingIntegerVariable(IntVar *const var)=0
void StartProcessingIntegerVariable(IntVar *const var) override
bool IsProfilingEnabled() const
Returns whether we are profiling the solver.
Holds semantic information stating that the 'expression' has been cast into 'variable' using the Var(...
void set_trace_search(bool value)
SearchMonitor * MakeSearchTrace(const std::string &prefix)
Creates a search monitor that will trace precisely the behavior of the search.
static const char kLessOrEqual[]
ConstraintSolverStatistics GetConstraintSolverStatistics() const
Returns detailed cp search statistics.
static const char kVariableGroupExtension[]
ABSL_FLAG(bool, cp_trace_propagation, false, "Trace propagation events (constraint and demon executions," " variable modifications).")
static const char kBranchesLimitArgument[]
static const char kLateDateArgument[]
void BeginConstraintInitialPropagation(Constraint *const constraint) override
Propagation events.
void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax) override
virtual void BeginNestedConstraintInitialPropagation(Constraint *const parent, Constraint *const nested)=0
virtual void NoMoreSolutions()
When the search tree is finished.
virtual bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
IntExpr * CastExpression(const IntVar *const var) const
!defined(SWIG)
void set_print_added_constraints(bool value)
static const char kUsageLessConstantExtension[]
void CleanVariableOnFail(IntVar *const var)
void SetDurationRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void EnqueueDelayedDemon(Demon *const demon)
Solver::DecisionModification ModifyDecision()
void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
static const char kCountAssignedItemsExtension[]
Extension names:
std::vector< bool > rev_bool_value_
static const char kStartSyncOnEndOperation[]
bool ContainsKey(const Collection &collection, const Key &key)
void STLDeleteElements(T *container)
virtual void SetStartRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
void AddPropagationMonitor(PropagationMonitor *const monitor)
Adds the propagation monitor to the solver.
void set_search_left_depth(int d)
static const char kDelayedPathCumul[]
static const char kIsBetween[]
ConstraintSolverParameters_TrailCompression
std::string search_context() const
void AcceptUncheckedNeighbor()
uint64_t stamp() const
The stamp indicates how many moves in the search tree we have performed.
static const char kIntervalVariable[]
bool AcceptDelta(Assignment *delta, Assignment *deltadelta)
virtual void SetEndMin(IntervalVar *const var, int64_t new_min)=0
static const char kTransitsArgument[]
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
void UnfreezeQueue()
This method unfreezes the propagation queue.
virtual void EndOperatorStart()=0
std::function< void(Solver *)> Action
void set_name(const std::string &name)
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
::PROTOBUF_NAMESPACE_ID::int32 trail_block_size() const
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given model visitor.
static constexpr int kNumPriorities
Number of priorities for demons.
static const char kFinalStatesArgument[]
void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
void push_monitor(SearchMonitor *const m)
virtual void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *const expr)
virtual void AppendMonitors(Solver *const solver, std::vector< SearchMonitor * > *const extras)
This method will be called at the start of the search.
virtual void Install()
Registers itself on the solver such that it gets notified of the search and propagation events.
int64_t wall_time() const
DEPRECATED: Use Now() instead.
void ProcessConstraints()
void set_trail_block_size(::PROTOBUF_NAMESPACE_ID::int32 value)
virtual void PeriodicCheck()
Periodic call to check limits in long running methods.
Left branches are ignored.
static const char kUsageEqualVariableExtension[]
int TopProgressPercent()
Returns a percentage representing the propress of the search before reaching the limits of the top-le...
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...
An Assignment is a variable -> domains mapping, used to report solutions to the user.
void Install() override
Registers itself on the solver such that it gets notified of the search and propagation events.
void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max) override
void ApplyDecision(Decision *const d)
LocalSearchMonitor * GetLocalSearchMonitor() const
Returns the local search monitor.
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
static const char kSmartTimeCheckArgument[]
A BaseObject is the root of all reversibly allocated objects.
virtual void SetStartMax(IntervalVar *const var, int64_t new_max)=0
The class IntVar is a subset of IntExpr.
virtual Decision * Next(Solver *const s)=0
This is the main method of the decision builder class.
#define DCHECK_GE(val1, val2)
void FinishCurrentSearch()
Tells the solver to kill or restart the current search.
virtual void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &tuples)
void ExecuteAll(const SimpleRevFIFO< Demon * > &demons)
virtual void SetValues(IntVar *const var, const std::vector< int64_t > &values)=0
void RankFirst(SequenceVar *const var, int index) override
SequenceVar modifiers.
The class IntExpr is the base of all integer expressions in constraint programming.
void BeginInitialPropagation()
static const char kIntervalBinaryRelation[]
virtual void VisitSetVariableValue(IntVar *const var, int64_t value)
static const char kBetween[]
bool backtrack_at_the_end_of_the_search() const
virtual bool LocalOptimum()
When a local optimum is reached.
void RestoreBoolValue(IntVar *const var)
LocalSearchMonitor(Solver *const solver)
void SetDurationMin(IntervalVar *const var, int64_t new_min) override
static const char kTimeLimitArgument[]
std::string DebugString() const
!defined(SWIG)
virtual void RemoveInterval(IntVar *const var, int64_t imin, int64_t imax)=0
#define CHECK_EQ(val1, val2)
static const char kVarsArgument[]
bool should_restart() const
virtual void EndNextDecision(DecisionBuilder *const b, Decision *const d)
After calling DecisionBuilder::Next, along with the returned decision.
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
bool trace_propagation() const
static const char kIntervalDisjunction[]
virtual void SetStartMin(IntervalVar *const var, int64_t new_min)=0
IntervalVar modifiers.
static const char kSumGreaterOrEqual[]
void SetValue(IntVar *const var, int64_t value) override
PropagationMonitor(Solver *const solver)
static const char kSequencesArgument[]
std::string DebugString() const override
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
static const char kIndexArgument[]
static const char kAbs[]
Constraint and Expression types.
Assignment * GetOrCreateLocalSearchState()
Returns (or creates) an assignment representing the state of local search.
void PostAndPropagate()
Calls Post and then Propagate to initialize the constraints.
This class represent a reversible FIFO structure.
bool print_local_search_profile() const
Before search, after search.
T * RevAlloc(T *object)
Registers the given object as being reversible.
virtual void EndConstraintInitialPropagation(Constraint *const constraint)=0
void RefuteDecision(Decision *const d)
void EndConstraintInitialPropagation(Constraint *const constraint) override
void BeginDemonRun(Demon *const demon) override
void RemoveValues(IntVar *const var, const std::vector< int64_t > &values) override
static const char kWeightedSumOfAssignedEqualVariableExtension[]
int64_t unchecked_solution_counter() const
DecisionBuilder * MakeApplyBranchSelector(BranchSelector bs)
Creates a decision builder that will set the branch selector.
static const char kValuesArgument[]
void set_variable_to_clean_on_fail(IntVar *var)
void set_search_context(const std::string &search_context)
void IncrementUncheckedSolutionCounter()
static const char kInitialState[]
void set_action_on_fail(Solver::Action a)
#define DCHECK(condition)
Keeps the default behavior, i.e.
static const char kAllowedAssignments[]
Search * ActiveSearch() const
Returns the active search, nullptr outside search.
A sequence variable is a variable whose domain is a set of possible orderings of the interval variabl...
virtual void BeginDemonRun(Demon *const demon)=0
void set_name_all_variables(bool value)
static const char kMaxEqual[]
DecisionBuilder * MakeConstraintAdder(Constraint *const ct)
Returns a decision builder that will add the given constraint to the model.
CompressedTrail< double > rev_doubles_
void SetBranchSelector(Solver::BranchSelector bs)
virtual void VisitIntegerVariable(const IntVar *const variable, IntExpr *const delegate)
virtual void AcceptNeighbor()
After accepting a neighbor during local search.
static const char kConditionalExpr[]
std::vector< IntVar * > rev_boolvar_list_
virtual void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values)
static const char kSquare[]
virtual std::string DebugString() const
std::function< bool(int64_t)> IndexFilter1
std::vector< BaseObject * > rev_object_memory_
virtual void SetEndRange(IntervalVar *const var, int64_t new_min, int64_t new_max)=0
static const char kLeftArgument[]
static const char kDurationMaxArgument[]
virtual void SetDurationMin(IntervalVar *const var, int64_t new_min)=0
virtual void AcceptUncheckedNeighbor()
After accepting an unchecked neighbor during local search.
BaseVariableAssignmentSelector *const selector_
void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found) override
static const char kTransition[]
void set_print_local_search_profile(bool value)
void Fail()
Abandon the current branch in the search tree. A backtrack will follow.
#define DCHECK_EQ(val1, val2)
static const char kSemiContinuous[]
virtual void RankFirst(SequenceVar *const var, int index)=0
SequenceVar modifiers.
static const char kNotBetween[]
virtual void RankSequence(SequenceVar *const var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
static const char kMirrorOperation[]
Operations.
void InternalSaveBooleanVarValue(Solver *const solver, IntVar *const var)
static const char kScalProdEqual[]
static const char kCumulativeArgument[]
virtual void EndVisitExtension(const std::string &type)
void SetSearchContext(Search *search, const std::string &search_context)
~PropagationMonitor() override
void SetMin(IntExpr *const expr, int64_t new_min) override
IntExpr modifiers.
void set_created_by_solve(bool c)
static const char kSequenceArgument[]
DemonPriority
This enum represents the three possible priorities for a demon in the Solver queue.
static const char kRelaxedMaxOperation[]
A Decision represents a choice point in the search tree.
ModelCache * BuildModelCache(Solver *const solver)
std::vector< int * > rev_int_memory_
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
static const char kIsDifferent[]
void Add(PropagationMonitor *const monitor)
static const char kModulo[]
static const char kDeviation[]
static const char kSortingConstraint[]
#define DCHECK_LE(val1, val2)
uint64_t fail_stamp() const
The fail_stamp() is incremented after each backtrack.
static const char kScalProd[]
bool IsLocalSearchProfilingEnabled() const
Returns whether we are profiling local search.
static const char kScalProdGreaterOrEqual[]
A search monitor is a simple set of callbacks to monitor all search events.
virtual void AfterDecision(Decision *const d, bool apply)
Just after refuting or applying the decision, apply is true after Apply.
std::string DebugString() const override
LocalSearchMonitorMaster(Solver *solver)
void set_use_cumulative_edge_finder(bool value)
void set_backtrack_at_the_end_of_the_search(bool restore)
virtual void PopContext()=0
void SetRange(IntExpr *const expr, int64_t new_min, int64_t new_max) override
static const char kLateCostArgument[]
void set_use_element_rmq(bool value)
void PushState()
The PushState and PopState methods manipulates the states of the reversible objects.
virtual void VisitIntegerVariableEvaluatorArgument(const std::string &arg_name, const Solver::Int64ToIntVar &arguments)
Helpers.
static const char kRangeArgument[]
static const char kInversePermutation[]
static const char kAtMost[]
virtual void StartProcessingIntegerVariable(IntVar *const var)=0
bool name_all_variables() const
bool HasName(const PropagationBaseObject *object) const
Returns whether the object has been named or not.
void EndDemonRun(Demon *const demon) override
static const char kNullIntersect[]
This iterator is not stable with respect to deletion.
static const char kSumEqual[]
Collection of objects used to extend the Constraint Solver library.
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
Solver::Action reversible_action
void set_array_split_size(::PROTOBUF_NAMESPACE_ID::int32 value)
virtual void ApplyDecision(Decision *const d)
Before applying the decision.
void BeginNextDecision(DecisionBuilder *const db)
virtual void VisitSequenceVariable(const SequenceVar *const variable)
CompressedTrail< int64_t > rev_int64s_
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *const constraint)
virtual void BeginVisitExtension(const std::string &type)
virtual void Refute(Solver *const s)=0
Refute will be called after a backtrack.
bool disable_solve() const
void set_check_solution_period(::PROTOBUF_NAMESPACE_ID::int32 value)
static const char kFalseConstraint[]
static const char kFixedChargeArgument[]
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
void ProcessOneDemon(Demon *const demon)
static const char kIsGreater[]
void InstallLocalSearchProfiler(LocalSearchProfiler *monitor)
void EnqueueAll(const SimpleRevFIFO< Demon * > &demons)
static const char kStepArgument[]
void RankLast(SequenceVar *const var, int index) override
static const char kExpressionArgument[]
virtual void RemoveValue(IntVar *const var, int64_t value)=0
virtual void Accept(ModelVisitor *const visitor) const
static const char kLexLess[]
void set_num_branches(::PROTOBUF_NAMESPACE_ID::int64 value)
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
static const char kIsGreaterOrEqual[]
void set_should_finish(bool s)
static const char kValueArgument[]
static const char kOpposite[]
static const char kSumLessOrEqual[]
void inhibit(Solver *const s)
This method inhibits the demon in the search tree below the current position.
virtual bool AtSolution()
This method is called when a valid solution is found.
static const char kActiveArgument[]
argument names:
void RankNotLast(SequenceVar *const var, int index) override
ModelVisitor * MakePrintModelVisitor()
Prints the model.
static constexpr int kNoProgress
virtual void EndMakeNextNeighbor(const LocalSearchOperator *op, bool neighbor_found, const Assignment *delta, const Assignment *deltadelta)=0
DecisionBuilder * MakeRestoreAssignment(Assignment *assignment)
Returns a DecisionBuilder which restores an Assignment (calls void Assignment::Restore())
static const char kNextsArgument[]
ModelVisitor * MakeStatisticsModelVisitor()
Displays some nice statistics on the model.
IntervalVar * Interval(int index) const
Returns the index_th interval of the sequence.
static const char kTargetArgument[]
bool should_finish() const
static const char kStartMinArgument[]
void set_trace_propagation(bool value)
void set_name_cast_variables(bool value)
void set_profile_local_search(bool value)
Applies right branch first.
void set_disable_solve(bool value)
static const char kNonEqual[]
bool Solve(DecisionBuilder *const db, const std::vector< SearchMonitor * > &monitors)
std::string SearchContext() const
GurobiMPCallbackContext * context
static const char kTraceOperation[]
std::string model_name() const
Returns the name of the model.
void set_diffn_use_cumulative(bool value)
static const char kCoefficientsArgument[]
virtual void Accept(ModelVisitor *const visitor) const =0
Accepts the given visitor.
static const char kRightArgument[]
static const char kSizeArgument[]
static const char kEndExpr[]
static const char kStartMaxArgument[]
void AddConstraint(Constraint *const c)
void FreezeQueue()
This method freezes the propagation queue.
static const char kIntervalsArgument[]
static const char kEndMinArgument[]
void ConstraintSolverFailsHere()
static const char kAssumePathsArgument[]
bool HasName() const
Returns whether the object has been named or not.
CompressedTrail< void * > rev_ptrs_
void Install() override
Install itself on the solver.
std::vector< int64_t * > rev_int64_memory_
static const char kDurationExpr[]
static const char kEarlyDateArgument[]
#define CP_DO_FAIL(search)
void set_bytes_used(::PROTOBUF_NAMESPACE_ID::int64 value)
void set_use_all_possible_disjunctions(bool value)
void EndNextDecision(DecisionBuilder *const db, Decision *const d)
void BeginAcceptNeighbor(const LocalSearchOperator *op) override
void BeginMakeNextNeighbor(const LocalSearchOperator *op) override
void Accept(ModelVisitor *const visitor) const
Local Search Filters are used for fast neighbor pruning.
bool CheckConstraint(Constraint *const ct)
Checks whether adding this constraint will lead to an immediate failure.
int SearchLeftDepth() const
Gets the search left depth of the current active search.
static const char kCardsArgument[]
void set_use_small_table(bool value)
static const char kGlobalCardinality[]
static const char kIntervalArgument[]
std::vector< BaseObject ** > rev_object_array_memory_
Decision * MakeFailDecision()
static const char kInt64ToBoolExtension[]
DELAYED_PRIORITY is the lowest priority: Demons will be processed after VAR_PRIORITY and NORMAL_PRIOR...
static const char kIsMember[]
static const char kNotMember[]
#define CHECK_NE(val1, val2)
PropagationMonitor * BuildTrace(Solver *const s)
static const char kConvexPiecewise[]
void set_use_sequence_high_demand_tasks(bool value)
virtual void EndInitialPropagation()
After the initial propagation.
std::string LocalSearchProfile() const
Returns local search profiling information in a human readable format.
~LocalSearchMonitor() override
void BeginFiltering(const LocalSearchFilter *filter) override
virtual void Accept(ModelVisitor *const visitor) const
Accepts the given visitor.
static const char kLess[]
static const char kMapDomain[]
static constexpr TrailCompression COMPRESS_WITH_ZLIB
static const char kRelaxedMinOperation[]
virtual void RankNotFirst(SequenceVar *const var, int index)=0
void RankNotFirst(SequenceVar *const var, int index) override
void EndProcessingIntegerVariable(IntVar *const var) override
static const char kMaximizeArgument[]
static const char kPositionXArgument[]
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
static const char kDurationMinArgument[]
static const char kPositionYArgument[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *const argument)
Visit integer expression argument.
void EndOperatorStart() override
void PushContext(const std::string &context) override
bool profile_propagation() const
static const char kInt64ToInt64Extension[]
CompressedTrail< uint64_t > rev_uint64s_
static const char kScalProdLessOrEqual[]
static const char kSolutionLimitArgument[]
static const char kVariableUsageLessConstantExtension[]