Google OR-Tools: ortools/constraint_solver/constraint_solveri.h Source File
51#ifndef ORTOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
52#define ORTOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
65#include "absl/algorithm/container.h"
66#include "absl/container/flat_hash_map.h"
67#include "absl/container/flat_hash_set.h"
69#include "absl/strings/str_cat.h"
70#include "absl/strings/str_format.h"
72#include "absl/types/span.h"
152 T data[CHUNK_SIZE];
154 explicit Chunk(const Chunk* next) : next(next) {}
162 : chunk_(l->chunks_), value_(l->Last()) {}
163 bool ok() const { return (value_ != nullptr); }
164 T operator*() const { return *value_; }
167 if (value_ == chunk_->data + CHUNK_SIZE) {
168 chunk_ = chunk_->next;
169 value_ = chunk_ ? chunk_->data : nullptr;
180 void Push(Solver* const s, T val) {
182 Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_));
183 s->SaveAndSetValue(reinterpret_cast<void**>(&chunks_),
184 reinterpret_cast<void*>(chunk));
185 pos_.SetValue(s, CHUNK_SIZE - 1);
187 pos_.Decr(s);
189 chunks_->data[pos_.Value()] = val;
194 if (chunks_ == nullptr || LastValue() != val) {
195 Push(s, val);
204 T* MutableLast() { return chunks_ ? &chunks_->data[pos_.Value()] : nullptr; }
208 DCHECK(chunks_);
209 return chunks_->data[pos_.Value()];
215 chunks_->data[pos_.Value()] = v;
225inline uint64_t Hash1(uint64_t value) {
226 value = (~value) + (value << 21);
228 value += (value << 3) + (value << 8);
229 value ^= value >> 14;
230 value += (value << 2) + (value << 4);
236inline uint64_t Hash1(uint32_t value) {
239 a = (a ^ 0xc761c23c) ^ (a >> 19);
240 a = (a + 0x165667b1) + (a << 5);
241 a = (a + 0xd3a2646c) ^ (a << 9);
242 a = (a + 0xfd7046c5) + (a << 3);
243 a = (a ^ 0xb55a4f09) ^ (a >> 16);
247inline uint64_t Hash1(int64_t value) {
248 return Hash1(static_cast<uint64_t>(value));
251inline uint64_t Hash1(int value) { return Hash1(static_cast<uint32_t>(value)); }
253inline uint64_t Hash1(void* const ptr) {
254#if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
255 defined(__aarch64__) || (defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64))
256 return Hash1(reinterpret_cast<uint64_t>(ptr));
265 if (ptrs.size() == 1) return Hash1(ptrs[0]);
266 uint64_t hash = Hash1(ptrs[0]);
267 for (int i = 1; i < ptrs.size(); ++i) {
268 hash = hash * i + Hash1(ptrs[i]);
273inline uint64_t Hash1(const std::vector<int64_t>& ptrs) {
274 if (ptrs.empty()) return 0;
275 if (ptrs.size() == 1) return Hash1(ptrs[0]);
276 uint64_t hash = Hash1(ptrs[0]);
290 array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])),
302 uint64_t code = Hash1(key) % size_.Value();
305 if (tmp->key() == key) {
316 const V& FindWithDefault(const K& key, const V& default_value) const {
317 uint64_t code = Hash1(key) % size_.Value();
320 if (tmp->key() == key) {
329 void Insert(const K& key, const V& value) {
330 const int position = Hash1(key) % size_.Value();
332 solver_->UnsafeRevAlloc(new Cell(key, value, array_[position]));
333 solver_->SaveAndSetValue(reinterpret_cast<void**>(&array_[position]),
334 reinterpret_cast<void*>(cell));
344 Cell(const K& key, const V& value, Cell* const next)
345 : key_(key), value_(value), next_(next) {}
347 void SetRevNext(Solver* const solver, Cell* const next) {
348 solver->SaveAndSetValue(reinterpret_cast<void**>(&next_),
349 reinterpret_cast<void*>(next));
352 Cell* next() const { return next_; }
354 const K& key() const { return key_; }
356 const V& value() const { return value_; }
365 Cell** const old_cell_array = array_;
366 const int old_size = size_.Value();
367 size_.SetValue(solver_, size_.Value() * 2);
369 reinterpret_cast<void**>(&array_),
371 solver_->UnsafeRevAllocArray(new Cell*[size_.Value()])));
372 memset(array_, 0, size_.Value() * sizeof(*array_));
373 for (int i = 0; i < old_size; ++i) {
374 Cell* tmp = old_cell_array[i];
376 Cell* const to_reinsert = tmp;
378 const uint64_t new_position = Hash1(to_reinsert->key()) % size_.Value();
379 to_reinsert->SetRevNext(solver_, array_[new_position]);
381 reinterpret_cast<void**>(&array_[new_position]),
382 reinterpret_cast<void*>(to_reinsert));
418 bool IsCardinalityZero() const { return bits_.Value() == uint64_t{0}; }
421 return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1));
435 explicit RevBitSet(int64_t size);
442 bool IsSet(int64_t index) const;
459 void Save(Solver* solver, int offset);
462 std::unique_ptr<uint64_t[]> bits_;
473 void SetToOne(Solver* solver, int64_t row, int64_t column);
475 void SetToZero(Solver* solver, int64_t row, int64_t column);
477 bool IsSet(int64_t row, int64_t column) const {
481 DCHECK_LT(column, columns_);
492 int64_t GetFirstBit(int row, int start) const;
509class CallMethod0 : public Demon {
511 CallMethod0(T* const ct, void (T::*method)(), const std::string& name)
512 : constraint_(ct), method_(method), name_(name) {}
542 return param->DebugString();
549 CallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
551 : constraint_(ct), method_(method), name_(name), param1_(param1) {}
558 return absl::StrCat("CallMethod_", name_, "(", constraint_->DebugString(),
579 CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name,
581 : constraint_(ct),
590 (constraint_->*method_)(param1_, param2_);
618 CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name,
619 P param1, Q param2, R param3)
620 : constraint_(ct),
630 (constraint_->*method_)(param1_, param2_, param3_);
653 P param1, Q param2, R param3) {
666class DelayedCallMethod0 : public Demon {
668 DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name)
669 : constraint_(ct), method_(method), name_(name) {}
693 const std::string& name) {
701 DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name,
703 : constraint_(ct), method_(method), name_(name), param1_(param1) {}
729 const std::string& name, P param1) {
730 return s->RevAlloc(new DelayedCallMethod1<T, P>(ct, method, name, param1));
738 const std::string& name, P param1, Q param2)
739 : constraint_(ct),
748 (constraint_->*method_)(param1_, param2_);
773 const std::string& name, P param1,
785class LightIntFunctionElementCt : public Constraint {
788 IntVar* const index, F values,
789 std::function<bool()> deep_serialize)
791 var_(var),
793 values_(std::move(values)),
794 deep_serialize_(std::move(deep_serialize)) {}
797 void Post() override {
799 solver(), this, &LightIntFunctionElementCt::IndexBound, "IndexBound");
809 std::string DebugString() const override {
810 return absl::StrFormat("LightIntFunctionElementCt(%s, %s)",
821 if (deep_serialize_ == nullptr || deep_serialize_()) {
829 void IndexBound() { var_->SetValue(values_(index_->Min())); }
843 IntVar* const index1, IntVar* const index2,
844 F values, std::function<bool()> deep_serialize)
846 var_(var),
849 values_(std::move(values)),
850 deep_serialize_(std::move(deep_serialize)) {}
852 void Post() override {
854 solver(), this, &LightIntIntFunctionElementCt::IndexBound,
855 "IndexBound");
856 index1_->WhenBound(demon);
857 index2_->WhenBound(demon);
861 std::string DebugString() const override {
874 const int64_t index1_min = index1_->Min();
875 const int64_t index1_max = index1_->Max();
878 if (deep_serialize_ == nullptr || deep_serialize_()) {
879 for (int i = index1_min; i <= index1_max; ++i) {
881 [this, i](int64_t j) { return values_(i, j); }, index2_->Min(),
891 var_->SetValue(values_(index1_->Min(), index2_->Min()));
908 IntVar* const index1, IntVar* const index2,
911 var_(var),
915 values_(std::move(values)) {}
917 void Post() override {
919 solver(), this, &LightIntIntIntFunctionElementCt::IndexBound,
920 "IndexBound");
921 index1_->WhenBound(demon);
922 index2_->WhenBound(demon);
923 index3_->WhenBound(demon);
927 std::string DebugString() const override {
947 var_->SetValue(values_(index1_->Min(), index2_->Min(), index3_->Min()));
981 virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0;
983 virtual void Start(const Assignment* assignment) = 0;
984 virtual void Reset() {}
985#ifndef SWIG
987#endif
989 virtual bool HoldsDelta() const { return false; }
997 max_inversible_index_ = candidate_values_.size();
999 committed_value_to_index_.resize(max_value + 1, -1);
1009 return committed_values_[index];
1023 return candidate_is_active_[index];
1027 candidate_is_active_.Set(index);
1029 candidate_is_active_.Clear(index);
1035 for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
1036 const int64_t value = candidate_values_[index];
1037 committed_values_[index] = value;
1038 if (index < max_inversible_index_) {
1041 committed_is_active_.CopyBucket(candidate_is_active_, index);
1047 void CheckPoint() { checkpoint_values_ = committed_values_; }
1049 void Revert(bool only_incremental) {
1050 incremental_changes_.ResetAllToFalse();
1051 if (only_incremental) return;
1053 for (const int64_t index : changes_.PositionsSetAtLeastOnce()) {
1054 const int64_t committed_value = committed_values_[index];
1055 candidate_values_[index] = committed_value;
1056 if (index < max_inversible_index_) {
1057 candidate_value_to_index_[committed_value] = index;
1059 candidate_is_active_.CopyBucket(committed_is_active_, index);
1065 return changes_.PositionsSetAtLeastOnce();
1071 void Resize(int size) {
1072 candidate_values_.resize(size);
1075 candidate_is_active_.Resize(size);
1078 incremental_changes_.ClearAndResize(size);
1089 void MarkChange(int64_t index) {
1095 std::vector<int64_t> committed_values_;
1096 std::vector<int64_t> checkpoint_values_;
1104 int64_t max_inversible_index_ = -1;
1105 std::vector<int64_t> candidate_value_to_index_;
1106 std::vector<int64_t> committed_value_to_index_;
1114class IntVarLocalSearchOperator : public LocalSearchOperator {
1120 bool keep_inverse_values = false) {
1122 if (keep_inverse_values) {
1124 for (const IntVar* const var : vars) {
1125 max_value = std::max(max_value, var->Max());
1127 state_.SetCurrentDomainInjectiveAndKeepInverseValues(max_value);
1132 bool HoldsDelta() const override { return true; }
1135 void Start(const Assignment* assignment) override {
1139 CHECK_LE(size, assignment->Size())
1140 << "Assignment contains fewer variables than operator";
1142 for (int i = 0; i < size; ++i) {
1144 if (element->Var() != vars_[i]) {
1145 CHECK(container.Contains(vars_[i]))
1146 << "Assignment does not contain operator variable " << vars_[i];
1147 element = &(container.Element(vars_[i]));
1155 virtual bool IsIncremental() const { return false; }
1157 int Size() const { return vars_.size(); }
1160 int64_t Value(int64_t index) const {
1165 IntVar* Var(int64_t index) const { return vars_[index]; }
1166 virtual bool SkipUnchanged(int) const { return false; }
1169 return state_.CheckPointValue(index);
1171 void SetValue(int64_t index, int64_t value) {
1175 return state_.CandidateIsActive(index);
1182 for (const int64_t index : state_.IncrementalIndicesChanged()) {
1184 const int64_t value = Value(index);
1187 AddToAssignment(var, value, activated, &assignment_indices_, index,
1193 const int64_t value = Value(index);
1194 const bool activated = Activated(index);
1204 void RevertChanges(bool change_was_incremental) {
1205 candidate_has_changes_ = change_was_incremental && IsIncremental();
1207 if (!candidate_has_changes_) {
1208 for (const int64_t index : state_.CandidateIndicesChanged()) {
1212 state_.Revert(candidate_has_changes_);
1215 void AddVars(const std::vector<IntVar*>& vars) {
1217 vars_.insert(vars_.end(), vars.begin(), vars.end());
1218 const int64_t size = Size();
1219 assignment_indices_.resize(size, -1);
1220 state_.Resize(size);
1227 virtual void OnStart() {}
1248 return state_.CandidateInverseValue(index);
1254 void AddToAssignment(IntVar* var, int64_t value, bool active,
1255 std::vector<int>* assignment_indices, int64_t index,
1261 if ((*assignment_indices)[index] == -1) {
1262 (*assignment_indices)[index] = container->Size();
1263 element = assignment->FastAdd(var);
1265 element = container->MutableElement((*assignment_indices)[index]);
1268 element = assignment->FastAdd(var);
1279 std::vector<IntVar*> vars_;
1280 mutable std::vector<int> assignment_indices_;
1281 bool candidate_has_changes_ = false;
1315 explicit BaseLns(const std::vector<IntVar*>& vars);
1321 bool HasFragments() const override { return true; }
1330 std::vector<int> fragment_;
1339 explicit ChangeValue(const std::vector<IntVar*>& vars);
1341 virtual int64_t ModifyValue(int64_t index, int64_t value) = 0;
1358 : use_sibling_(use_sibling) {}
1360 template <class PathOperator>
1361 void Reset(const PathOperator& path_operator, int base_index_reference) {
1364 const int64_t base_node = path_operator.BaseNode(base_index_reference);
1365 const int alternative_index =
1368 alternative_set_ =
1370 ? absl::Span<const int64_t>(
1371 path_operator.alternative_sets_[alternative_index])
1372 : absl::Span<const int64_t>();
1374 bool Next() { return ++index_ < alternative_set_.size(); }
1376 return (index_ >= alternative_set_.size()) ? -1 : alternative_set_[index_];
1389 template <class PathOperator>
1390 void Reset(const PathOperator& path_operator, int base_index_reference) {
1391 using Span = absl::Span<const int>;
1393 const int64_t base_node = path_operator.BaseNode(base_index_reference);
1394 const int64_t start_node = path_operator.StartNode(base_index_reference);
1395 const auto& get_incoming_neighbors =
1396 path_operator.iteration_parameters_.get_incoming_neighbors;
1398 path_operator.IsPathStart(base_node) || !get_incoming_neighbors
1400 : Span(get_incoming_neighbors(base_node, start_node));
1401 const auto& get_outgoing_neighbors =
1402 path_operator.iteration_parameters_.get_outgoing_neighbors;
1404 path_operator.IsPathEnd(base_node) || !get_outgoing_neighbors
1406 : Span(get_outgoing_neighbors(base_node, start_node));
1408 bool Next() {
1409 return ++index_ < incoming_neighbors_.size() + outgoing_neighbors_.size();
1412 if (index_ < incoming_neighbors_.size()) {
1413 return incoming_neighbors_[index_];
1415 const int index = index_ - incoming_neighbors_.size();
1416 return (index >= outgoing_neighbors_.size()) ? -1
1436 : path_operator_(*path_operator),
1437 base_index_reference_(base_index_reference) {}
1444 DCHECK(!alternatives_.empty());
1446 return alternatives_[1].get();
1454 if (path_operator_.ConsiderAlternatives(base_index_reference_)) {
1455 alternatives_.push_back(std::make_unique<AlternativeNodeIterator>(
1457 alternatives_.push_back(std::make_unique<AlternativeNodeIterator>(
1464 void Reset(bool update_end_nodes = false) {
1466 for (auto& alternative_iterator : alternatives_) {
1467 alternative_iterator->Reset(path_operator_, base_index_reference_);
1470 neighbors_->Reset(path_operator_, base_index_reference_);
1471 if (update_end_nodes) neighbor_end_node_ = neighbors_->GetValue();
1475 DCHECK(!finished_);
1476 for (auto& alternative_iterator : alternatives_) {
1477 if (alternative_iterator->Next()) return true;
1478 alternative_iterator->Reset(path_operator_, base_index_reference_);
1481 if (neighbors_->Next()) return true;
1482 neighbors_->Reset(path_operator_, base_index_reference_);
1485 return false;
1489 if (!neighbors_) return true;
1490 return neighbor_end_node_ == neighbors_->GetValue();
1494 const PathOperator& path_operator_;
1495 int base_index_reference_ = -1;
1497 std::vector<std::unique_ptr<AlternativeNodeIterator>> alternatives_;
1517template <bool ignore_path_vars>
1521 struct IterationParameters {
1542 std::function<const std::vector<int>&(
1545 std::function<const std::vector<int>&(
1551 const std::vector<IntVar*>& path_vars,
1555 base_nodes_(
1565 next_base_to_increment_(iteration_parameters.number_of_base_nodes),
1566 iteration_parameters_(std::move(iteration_parameters)),
1567 optimal_paths_enabled_(false),
1569 alternative_index_(next_vars.size(), -1) {
1570 DCHECK_GT(iteration_parameters_.number_of_base_nodes, 0);
1571 for (int i = 0; i < iteration_parameters_.number_of_base_nodes; ++i) {
1574 if constexpr (!ignore_path_vars) {
1577 path_basis_.push_back(0);
1578 for (int i = 1; i < iteration_parameters_.number_of_base_nodes; ++i) {
1581 if ((path_basis_.size() > 2) ||
1582 (!next_vars.empty() && !next_vars.back()
1585 .skip_locally_optimal_paths())) {
1586 iteration_parameters_.skip_locally_optimal_paths = false;
1590 const std::vector<IntVar*>& next_vars,
1591 const std::vector<IntVar*>& path_vars, int number_of_base_nodes,
1592 bool skip_locally_optimal_paths, bool accept_path_end_base,
1593 std::function<int(int64_t)> start_empty_path_class,
1594 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors,
1595 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors)
1597 {number_of_base_nodes, skip_locally_optimal_paths,
1598 accept_path_end_base, std::move(start_empty_path_class),
1614 if constexpr (ignore_path_vars) return true;
1624 int64_t Next(int64_t node) const {
1626 return Value(node);
1630 int64_t Prev(int64_t node) const {
1638 int64_t Path(int64_t node) const {
1639 if constexpr (ignore_path_vars) return 0LL;
1671 int64_t BaseNode(int i) const { return base_nodes_[i]; }
1674 return GetNodeWithDefault(base_node_iterators_[i].GetAlternativeIterator(),
1679 return GetNodeWithDefault(
1680 base_node_iterators_[i].GetSiblingAlternativeIterator(), BaseNode(i));
1683 int64_t StartNode(int i) const { return path_starts_[base_paths_[i]]; }
1685 int64_t EndNode(int i) const { return path_ends_[base_paths_[i]]; }
1687 const std::vector<int64_t>& path_starts() const { return path_starts_; }
1722 next_base_to_increment_ = base_index;
1728 int64_t OldNext(int64_t node) const {
1733 int64_t PrevNext(int64_t node) const {
1738 int64_t OldPrev(int64_t node) const {
1743 int64_t OldPath(int64_t node) const {
1749 return node_path_starts_[node];
1752 int CurrentNodePathEnd(int64_t node) const { return node_path_ends_[node]; }
1756 bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination) {
1757 if (destination == before_chain || destination == chain_end) return false;
1760 const int64_t destination_path = Path(destination);
1761 const int64_t after_chain = Next(chain_end);
1762 SetNext(chain_end, Next(destination), destination_path);
1763 if constexpr (!ignore_path_vars) {
1764 int current = destination;
1765 int next = Next(before_chain);
1766 while (current != chain_end) {
1767 SetNext(current, next, destination_path);
1769 next = Next(next);
1772 SetNext(destination, Next(before_chain), destination_path);
1774 SetNext(before_chain, after_chain, Path(before_chain));
1780 bool ReverseChain(int64_t before_chain, int64_t after_chain,
1783 int64_t path = Path(before_chain);
1784 int64_t current = Next(before_chain);
1788 int64_t current_next = Next(current);
1789 SetNext(current, after_chain, path);
1790 while (current_next != after_chain) {
1791 const int64_t next = Next(current_next);
1792 SetNext(current_next, current, path);
1796 SetNext(before_chain, current, path);
1804 bool SwapNodes(int64_t node1, int64_t node2) {
1809 if (node1 == node2) return false;
1810 const int64_t prev_node1 = Prev(node1);
1811 const bool ok = MoveChain(prev_node1, node1, Prev(node2));
1812 return MoveChain(Prev(node2), node2, prev_node1) || ok;
1816 bool MakeActive(int64_t node, int64_t destination) {
1817 if (IsPathEnd(destination)) return false;
1818 const int64_t destination_path = Path(destination);
1819 SetNext(node, Next(destination), destination_path);
1820 SetNext(destination, node, destination_path);
1825 bool MakeChainInactive(int64_t before_chain, int64_t chain_end) {
1826 const int64_t kNoPath = -1;
1829 const int64_t after_chain = Next(chain_end);
1830 int64_t current = Next(before_chain);
1831 while (current != after_chain) {
1832 const int64_t next = Next(current);
1833 SetNext(current, current, kNoPath);
1844 if (active == inactive) return false;
1845 const int64_t prev = Prev(active);
1852 if (active_chain.empty()) return false;
1853 if (active_chain == inactive_chain) return false;
1854 const int before_active_chain = Prev(active_chain.front());
1855 if (!MakeChainInactive(before_active_chain, active_chain.back())) {
1858 for (auto it = inactive_chain.crbegin(); it != inactive_chain.crend();
1860 if (!MakeActive(*it, before_active_chain)) return false;
1883 bool IsInactive(int64_t node) const {
1884 return !IsPathEnd(node) && inactives_[node];
1889 virtual bool InitPosition() const { return false; }
1898 int AddAlternativeSet(const std::vector<int64_t>& alternative_set) {
1899 const int alternative = alternative_sets_.size();
1900 for (int64_t node : alternative_set) {
1901 DCHECK_EQ(-1, alternative_index_[node]);
1902 alternative_index_[node] = alternative;
1904 alternative_sets_.push_back(alternative_set);
1905 sibling_alternative_.push_back(-1);
1911 template <typename PairType>
1913 const std::vector<PairType>& pair_alternative_sets) {
1914 for (const auto& [alternative_set, sibling_alternative_set] :
1916 sibling_alternative_.back() = AddAlternativeSet(alternative_set) + 1;
1922 int64_t GetActiveInAlternativeSet(int alternative_index) const {
1923 return alternative_index >= 0
1924 ? active_in_alternative_set_[alternative_index]
1928 int64_t GetActiveAlternativeNode(int node) const {
1929 return GetActiveInAlternativeSet(alternative_index_[node]);
1932 int GetSiblingAlternativeIndex(int node) const {
1938 return (node >= alternative_index_.size()) ? -1 : alternative_index_[node];
1942 int64_t GetActiveAlternativeSibling(int node) const {
1952 if (before_chain == chain_end || before_chain == exclude) return false;
1957 if (IsPathEnd(current)) return false;
1958 current = Next(current);
1960 if (current == exclude) return false;
1965 bool HasNeighbors() const {
1966 return iteration_parameters_.get_incoming_neighbors != nullptr ||
1967 iteration_parameters_.get_outgoing_neighbors != nullptr;
1977 Neighbor GetNeighborForBaseNode(int64_t base_index) const {
1978 auto* iterator = base_node_iterators_[base_index].GetNeighborIterator();
1980 .outgoing = iterator->IsOutgoingNeighbor()};
1986 template <class NodeIterator>
1987 static int GetNodeWithDefault(const NodeIterator* node_iterator,
1988 int default_value) {
1989 const int node = node_iterator->GetValue();
1993 void OnStart() override {
1994 optimal_paths_enabled_ = false;
1995 if (!iterators_initialized_) {
1996 iterators_initialized_ = true;
1997 for (int i = 0; i < iteration_parameters_.number_of_base_nodes; ++i) {
1998 base_node_iterators_[i].Initialize();
2002 InitializeAlternatives();
2007 bool OnSamePath(int64_t node1, int64_t node2) const {
2008 if (IsInactive(node1) != IsInactive(node2)) {
2011 for (int node = node1; !IsPathEnd(node); node = OldNext(node)) {
2016 for (int node = node2; !IsPathEnd(node); node = OldNext(node)) {
2025 for (int i = iteration_parameters_.number_of_base_nodes - 1; i >= 0; --i) {
2026 if (base_nodes_[i] != end_nodes_[i] ||
2027 !base_node_iterators_[i].HasReachedEnd()) {
2033 bool IncrementPosition() {
2034 const int base_node_size = iteration_parameters_.number_of_base_nodes;
2040 const int number_of_paths = path_starts_.size();
2046 int last_restarted = base_node_size;
2047 for (int i = base_node_size - 1; i >= 0; --i) {
2048 if (base_nodes_[i] < number_of_nexts_ && i <= next_base_to_increment_) {
2049 if (base_node_iterators_[i].Increment()) break;
2050 base_nodes_[i] = OldNext(base_nodes_[i]);
2051 base_node_iterators_[i].Reset();
2052 if (iteration_parameters_.accept_path_end_base ||
2053 !IsPathEnd(base_nodes_[i])) {
2057 base_nodes_[i] = StartNode(i);
2058 base_node_iterators_[i].Reset();
2059 last_restarted = i;
2061 next_base_to_increment_ = base_node_size;
2071 for (int i = last_restarted; i < base_node_size; ++i) {
2072 base_nodes_[i] = GetBaseNodeRestartPosition(i);
2073 base_node_iterators_[i].Reset();
2075 if (last_restarted > 0) {
2081 if (optimal_paths_enabled_ &&
2082 iteration_parameters_.skip_locally_optimal_paths) {
2083 if (path_basis_.size() > 1) {
2084 for (int i = 1; i < path_basis_.size(); ++i) {
2085 active_paths_.DeactivatePathPair(StartNode(path_basis_[i - 1]),
2086 StartNode(path_basis_[i]));
2089 active_paths_.DeactivatePathPair(StartNode(path_basis_[0]),
2090 StartNode(path_basis_[0]));
2093 std::vector<int> current_starts(base_node_size);
2094 for (int i = 0; i < base_node_size; ++i) {
2095 current_starts[i] = StartNode(i);
2099 optimal_paths_enabled_ = true;
2101 for (int i = base_node_size - 1; i >= 0; --i) {
2102 const int next_path_index = base_paths_[i] + 1;
2103 if (next_path_index < number_of_paths) {
2104 base_paths_[i] = next_path_index;
2105 base_nodes_[i] = path_starts_[next_path_index];
2106 base_node_iterators_[i].Reset();
2107 if (i == 0 || !OnSamePathAsPreviousBase(i)) {
2111 base_paths_[i] = 0;
2112 base_nodes_[i] = path_starts_[0];
2113 base_node_iterators_[i].Reset();
2116 if (!iteration_parameters_.skip_locally_optimal_paths) return CheckEnds();
2119 if (path_basis_.size() > 1) {
2120 for (int j = 1; j < path_basis_.size(); ++j) {
2121 if (active_paths_.IsPathPairActive(StartNode(path_basis_[j - 1]),
2122 StartNode(path_basis_[j]))) {
2127 if (active_paths_.IsPathPairActive(StartNode(path_basis_[0]),
2128 StartNode(path_basis_[0]))) {
2134 if (!CheckEnds()) return false;
2136 for (int i = 0; i < base_node_size; ++i) {
2137 if (StartNode(i) != current_starts[i]) {
2147 void InitializePathStarts() {
2151 std::vector<bool> has_prevs(number_of_nexts_, false);
2152 for (int i = 0; i < number_of_nexts_; ++i) {
2153 const int next = OldNext(i);
2154 if (next < number_of_nexts_) {
2157 max_next = std::max(max_next, next);
2160 if (iteration_parameters_.skip_locally_optimal_paths) {
2161 active_paths_.Initialize(
2162 [&has_prevs](int node) { return !has_prevs[node]; });
2163 for (int i = 0; i < number_of_nexts_; ++i) {
2165 int current = i;
2166 while (!IsPathEnd(current)) {
2167 if ((OldNext(current) != PrevNext(current))) {
2168 active_paths_.ActivatePath(i);
2171 current = OldNext(current);
2178 std::vector<bool> empty_found(number_of_nexts_, false);
2179 std::vector<int64_t> new_path_starts;
2180 for (int i = 0; i < number_of_nexts_; ++i) {
2182 if (IsPathEnd(OldNext(i))) {
2183 if (iteration_parameters_.start_empty_path_class != nullptr) {
2184 if (empty_found[iteration_parameters_.start_empty_path_class(i)])
2186 empty_found[iteration_parameters_.start_empty_path_class(i)] = true;
2189 new_path_starts.push_back(i);
2197 std::vector<int> node_paths(max_next + 1, -1);
2198 for (int i = 0; i < path_starts_.size(); ++i) {
2199 int node = path_starts_[i];
2200 while (!IsPathEnd(node)) {
2201 node_paths[node] = i;
2204 node_paths[node] = i;
2206 for (int j = 0; j < iteration_parameters_.number_of_base_nodes; ++j) {
2207 if (IsInactive(base_nodes_[j]) || node_paths[base_nodes_[j]] == -1) {
2210 base_nodes_[j] = GetBaseNodeRestartPosition(j);
2211 base_paths_[j] = node_paths[base_nodes_[j]];
2213 base_paths_[j] = node_paths[base_nodes_[j]];
2216 base_node_iterators_[j].Reset();
2222 absl::flat_hash_set<int> found_bases;
2223 for (int i = 0; i < path_starts_.size(); ++i) {
2226 while (index < new_path_starts.size() &&
2227 new_path_starts[index] < path_starts_[i]) {
2230 const bool found = (index < new_path_starts.size() &&
2231 new_path_starts[index] == path_starts_[i]);
2235 for (int j = 0; j < iteration_parameters_.number_of_base_nodes; ++j) {
2236 if (base_paths_[j] == i && !found_bases.contains(j)) {
2238 base_paths_[j] = new_index;
2242 base_nodes_[j] = new_path_starts[new_index];
2248 path_starts_.swap(new_path_starts);
2252 path_ends_.reserve(path_starts_.size());
2253 int64_t max_node_index = number_of_nexts_ - 1;
2254 for (const int start_node : path_starts_) {
2255 int64_t node = start_node;
2256 while (!IsPathEnd(node)) node = OldNext(node);
2257 path_ends_.push_back(node);
2258 max_node_index = std::max(max_node_index, node);
2260 node_path_starts_.assign(max_node_index + 1, -1);
2261 node_path_ends_.assign(max_node_index + 1, -1);
2262 for (int i = 0; i < path_starts_.size(); ++i) {
2263 const int64_t start_node = path_starts_[i];
2264 const int64_t end_node = path_ends_[i];
2265 int64_t node = start_node;
2266 while (!IsPathEnd(node)) {
2267 node_path_starts_[node] = start_node;
2268 node_path_ends_[node] = end_node;
2271 node_path_starts_[node] = start_node;
2272 node_path_ends_[node] = end_node;
2275 void InitializeInactives() {
2277 for (int i = 0; i < number_of_nexts_; ++i) {
2278 inactives_.push_back(OldNext(i) == i);
2281 void InitializeBaseNodes() {
2285 if (first_start_ || InitPosition()) {
2288 for (int i = 0; i < iteration_parameters_.number_of_base_nodes; ++i) {
2289 base_paths_[i] = 0;
2290 base_nodes_[i] = path_starts_[0];
2294 for (int i = 0; i < iteration_parameters_.number_of_base_nodes; ++i) {
2296 int64_t base_node = base_nodes_[i];
2297 if (RestartAtPathStartOnSynchronize() || IsInactive(base_node)) {
2298 base_node = path_starts_[base_paths_[i]];
2299 base_nodes_[i] = base_node;
2301 end_nodes_[i] = base_node;
2305 for (int i = 1; i < iteration_parameters_.number_of_base_nodes; ++i) {
2306 if (OnSamePathAsPreviousBase(i) &&
2307 !OnSamePath(base_nodes_[i - 1], base_nodes_[i])) {
2308 const int64_t base_node = base_nodes_[i - 1];
2309 base_nodes_[i] = base_node;
2310 end_nodes_[i] = base_node;
2311 base_paths_[i] = base_paths_[i - 1];
2314 for (int i = 0; i < iteration_parameters_.number_of_base_nodes; ++i) {
2315 base_node_iterators_[i].Reset(true);
2319 void InitializeAlternatives() {
2320 active_in_alternative_set_.resize(alternative_sets_.size(), -1);
2321 for (int i = 0; i < alternative_sets_.size(); ++i) {
2322 const int64_t current_active = active_in_alternative_set_[i];
2323 if (current_active >= 0 && !IsInactive(current_active)) continue;
2324 for (int64_t index : alternative_sets_[i]) {
2325 if (!IsInactive(index)) {
2326 active_in_alternative_set_[i] = index;
2335 explicit ActivePaths(int num_nodes) : start_to_path_(num_nodes, -1) {}
2336 void Clear() { to_reset_ = true; }
2338 void Initialize(T is_start) {
2339 if (is_path_pair_active_.empty()) {
2341 absl::c_fill(start_to_path_, -1);
2342 for (int i = 0; i < start_to_path_.size(); ++i) {
2344 start_to_path_[i] = num_paths_;
2350 void DeactivatePathPair(int start1, int start2) {
2352 is_path_pair_active_[start_to_path_[start1] * num_paths_ +
2353 start_to_path_[start2]] = false;
2355 void ActivatePath(int start) {
2357 const int p1 = start_to_path_[start];
2358 const int p1_block = num_paths_ * p1;
2359 for (int p2 = 0; p2 < num_paths_; ++p2) {
2360 is_path_pair_active_[p1_block + p2] = true;
2362 for (int p2_block = 0; p2_block < is_path_pair_active_.size();
2363 p2_block += num_paths_) {
2364 is_path_pair_active_[p2_block + p1] = true;
2367 bool IsPathPairActive(int start1, int start2) const {
2368 if (to_reset_) return true;
2369 return is_path_pair_active_[start_to_path_[start1] * num_paths_ +
2376 is_path_pair_active_.assign(num_paths_ * num_paths_, true);
2382 std::vector<int64_t> start_to_path_;
2383 std::vector<bool> is_path_pair_active_;
2386 std::unique_ptr<int[]> base_nodes_;
2387 std::unique_ptr<int[]> end_nodes_;
2388 std::unique_ptr<int[]> base_paths_;
2389 std::vector<int> node_path_starts_;
2390 std::vector<int> node_path_ends_;
2391 bool iterators_initialized_ = false;
2393 std::vector<BaseNodeIterators<PathOperator>> base_node_iterators_;
2395 std::vector<int64_t> path_starts_;
2396 std::vector<int64_t> path_ends_;
2397 std::vector<bool> inactives_;
2400 int next_base_to_increment_;
2401 IterationParameters iteration_parameters_;
2402 bool optimal_paths_enabled_;
2403 std::vector<int> path_basis_;
2404 ActivePaths active_paths_;
2407 std::vector<std::vector<int64_t>> alternative_sets_;
2409 std::vector<int> alternative_index_;
2410 std::vector<int64_t> active_in_alternative_set_;
2431 Solver* solver, const std::vector<IntVar*>& vars,
2432 const std::vector<IntVar*>& secondary_vars,
2433 std::function<int(int64_t)> start_empty_path_class,
2434 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2436 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2455 Solver* solver, const std::vector<IntVar*>& vars,
2456 const std::vector<IntVar*>& secondary_vars,
2457 std::function<int(int64_t)> start_empty_path_class,
2458 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2460 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2462 int64_t chain_length = 1LL, bool single_path = false,
2463 const std::string& name = "Relocate");
2476 Solver* solver, const std::vector<IntVar*>& vars,
2477 const std::vector<IntVar*>& secondary_vars,
2478 std::function<int(int64_t)> start_empty_path_class,
2479 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2481 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2497 Solver* solver, const std::vector<IntVar*>& vars,
2498 const std::vector<IntVar*>& secondary_vars,
2499 std::function<int(int64_t)> start_empty_path_class,
2500 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2502 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2515 Solver* solver, const std::vector<IntVar*>& vars,
2516 const std::vector<IntVar*>& secondary_vars,
2517 std::function<int(int64_t)> start_empty_path_class,
2518 std::function<const std::vector<int>&(int, int)> get_incoming_neighbors =
2520 std::function<const std::vector<int>&(int, int)> get_outgoing_neighbors =
2533 Solver* solver, const std::vector<IntVar*>& vars,
2534 const std::vector<IntVar*>& secondary_vars,
2535 std::function<int(int64_t)> start_empty_path_class);
2553 Solver* solver, const std::vector<IntVar*>& vars,
2554 const std::vector<IntVar*>& secondary_vars,
2555 std::function<int(int64_t)> start_empty_path_class);
2574 Solver* solver, const std::vector<IntVar*>& vars,
2575 const std::vector<IntVar*>& secondary_vars,
2576 std::function<int(int64_t)> start_empty_path_class);
2585 Solver* solver, const std::vector<IntVar*>& vars,
2586 const std::vector<IntVar*>& secondary_vars,
2587 std::function<int(int64_t)> start_empty_path_class);
2598 Solver* solver, const std::vector<IntVar*>& vars,
2599 const std::vector<IntVar*>& secondary_vars,
2600 std::function<int(int64_t)> start_empty_path_class);
2611 Solver* solver, const std::vector<IntVar*>& vars,
2612 const std::vector<IntVar*>& secondary_vars,
2613 std::function<int(int64_t)> start_empty_path_class);
2625 Solver* solver, const std::vector<IntVar*>& vars,
2626 const std::vector<IntVar*>& secondary_vars,
2627 std::function<int(int64_t)> start_empty_path_class);
2638 Solver* solver, const std::vector<IntVar*>& vars,
2639 const std::vector<IntVar*>& secondary_vars,
2640 std::function<int(int64_t)> start_empty_path_class);
2645 Solver* solver, const std::vector<IntVar*>& vars,
2646 const std::vector<IntVar*>& secondary_vars,
2647 std::function<int(int64_t)> start_empty_path_class, int max_chain_size);
2663 Solver* solver, const std::vector<IntVar*>& vars,
2664 const std::vector<IntVar*>& secondary_vars,
2665 std::function<int(int64_t)> start_empty_path_class);
2677 const std::vector<IntVar*>& vars,
2678 const std::vector<IntVar*>& secondary_vars,
2691 const std::vector<IntVar*>& vars,
2692 const std::vector<IntVar*>& secondary_vars,
2699 Solver* solver, const std::vector<IntVar*>& vars,
2700 const std::vector<IntVar*>& secondary_vars,
2710 const std::vector<IntVar*>& vars,
2711 const std::vector<IntVar*>& secondary_vars,
2712 int number_of_chunks, int chunk_size,
2713 bool unactive_fragments);
2742 DCHECK(!graph_was_built_);
2743 num_nodes_ = std::max(num_nodes_, std::max(tail.value(), head.value()) + 1);
2744 const ArcId arc_id(arcs_.size());
2745 arcs_.push_back({.tail = tail, .head = head, .arc_id = arc_id});
2764 bool operator<(const Arc& other) const {
2765 return std::tie(tail, arc_id) < std::tie(other.tail, other.arc_id);
2775 bool graph_was_built_ = false;
2779 std::vector<NodeId> nodes_to_visit_;
2801 VariableDomainId AddVariableDomain(int64_t relaxed_min, int64_t relaxed_max);
2803 bool RelaxVariableDomain(VariableDomainId domain_id);
2804 bool TightenVariableDomainMin(VariableDomainId domain_id, int64_t value);
2805 bool TightenVariableDomainMax(VariableDomainId domain_id, int64_t value);
2806 int64_t VariableDomainMin(VariableDomainId domain_id) const;
2826 return state_domains_are_all_nonempty_ && num_committed_empty_domains_ == 0;
2829 void AddWeightedSumConstraint(
2830 const std::vector<VariableDomainId>& input_domain_ids,
2831 const std::vector<int64_t>& input_weights, int64_t input_offset,
2835 void CompileConstraints();
2845 bool IntersectionIsEmpty(const VariableDomain& d1,
2846 const VariableDomain& d2) const {
2847 return d1.max < d2.min || d2.max < d1.min;
2851 struct TrailedVariableDomain {
2852 VariableDomain committed_domain;
2853 VariableDomainId domain_id;
2855 std::vector<TrailedVariableDomain> trailed_domains_;
2856 util_intops::StrongVector<VariableDomainId, bool> domain_is_trailed_;
2858 bool state_domains_are_all_nonempty_ = true;
2859 bool state_has_relaxed_domains_ = false;
2862 int num_committed_empty_domains_ = 0;
2863 int trailed_num_committed_empty_domains_ = 0;
2868 void TrailConstraint(Constraint* constraint) {
2869 trailed_constraints_.push_back(constraint);
2871 std::vector<Constraint*> trailed_constraints_;
2886 ConstraintId constraint_id;
2889 void AddDomainsConstraintDependencies(
2890 const std::vector<VariableDomainId>& domain_ids,
2891 ConstraintId constraint_id);
2893 void AddConstraintDomainDependency(ConstraintId constraint_id,
2894 VariableDomainId domain_id);
2901 const std::vector<Dependency>& ComputeSortedDependencies(
2905 using ArcId = SubDagComputer::ArcId;
2906 using NodeId = SubDagComputer::NodeId;
2913 NodeId GetOrCreateNodeOfConstraintId(ConstraintId constraint_id);
2926 std::vector<Dependency> sorted_dependencies_;
2928 DependencyGraph dependency_graph_;
2940 std::vector<Trigger> triggers_;
2948 virtual ~Constraint() = default;
2949 virtual LocalSearchState::VariableDomain Propagate(int input_index) = 0;
2951 virtual void Commit() = 0;
2952 virtual void Revert() = 0;
2956 class WeightedSum final : public Constraint {
2959 const std::vector<VariableDomainId>& input_domain_ids,
2960 const std::vector<int64_t>& input_weights, int64_t input_offset,
2962 ~WeightedSum() override = default;
2963 LocalSearchState::VariableDomain Propagate(int input_index) override;
2966 VariableDomainId Output() const override { return output_; }
2971 struct WeightedVariable {
2990 std::vector<WeightedVariable> inputs_;
2991 std::vector<WeightedVariable*> trailed_inputs_;
3004 Invariants committed_invariants_;
3007 LocalSearchState* const state_;
3008 bool constraint_is_trailed_ = false;
3011 util_intops::StrongVector<ConstraintId, std::unique_ptr<Constraint>>
3020class LocalSearchState::Variable {
3022 Variable() : state_(nullptr), domain_id_(VariableDomainId(-1)) {}
3029 return state_->VariableDomainMax(domain_id_);
3033 bool SetMin(int64_t new_min) const {
3035 return state_->TightenVariableDomainMin(domain_id_, new_min) &&
3040 bool SetMax(int64_t new_max) const {
3041 if (!Exists()) return true;
3042 return state_->TightenVariableDomainMax(domain_id_, new_max) &&
3043 state_->PropagateTighten(domain_id_);
3046 if (state_ == nullptr) return;
3047 if (state_->RelaxVariableDomain(domain_id_)) {
3051 bool Exists() const { return state_ != nullptr; }
3063#endif
3099 int64_t objective_min, int64_t objective_max) = 0;
3100 virtual bool IsIncremental() const { return false; }
3107 virtual void Synchronize(const Assignment* assignment,
3113 virtual void Reset() {}
3116 virtual int64_t GetSynchronizedObjectiveValue() const { return 0LL; }
3136 std::string DebugString() const override {
3137 return "LocalSearchFilterManager";
3153 const Assignment* deltadelta, int64_t objective_min,
3158 int64_t GetAcceptedObjectiveValue() const { return accepted_value_; }
3163 void FindIncrementalEventEnd();
3165 std::vector<FilterEvent> events_;
3166 int last_event_called_ = -1;
3171 int incremental_events_end_ = 0;
3172 int64_t synchronized_value_;
3185 bool FindIndex(IntVar* const var, int64_t* index) const {
3187 const int var_index = var->index();
3188 *index = (var_index < var_index_to_index_.size())
3189 ? var_index_to_index_[var_index]
3191 return *index != kUnassigned;
3195 void AddVars(const std::vector<IntVar*>& vars);
3196 int Size() const { return vars_.size(); }
3197 IntVar* Var(int index) const { return vars_[index]; }
3198 int64_t Value(int index) const {
3199 DCHECK(IsVarSynced(index));
3202 bool IsVarSynced(int index) const { return var_synced_[index]; }
3205 virtual void OnSynchronize(const Assignment*) {}
3206 void SynchronizeOnAssignment(const Assignment* assignment);
3209 std::vector<IntVar*> vars_;
3210 std::vector<int64_t> values_;
3211 std::vector<bool> var_synced_;
3220 std::string DebugString() const override { return "PropagationMonitor"; }
3223 virtual void BeginConstraintInitialPropagation(Constraint* constraint) = 0;
3224 virtual void EndConstraintInitialPropagation(Constraint* constraint) = 0;
3225 virtual void BeginNestedConstraintInitialPropagation(Constraint* parent,
3227 virtual void EndNestedConstraintInitialPropagation(Constraint* parent,
3234 virtual void PushContext(const std::string& context) = 0;
3238 virtual void SetMax(IntExpr* expr, int64_t new_max) = 0;
3239 virtual void SetRange(IntExpr* expr, int64_t new_min, int64_t new_max) = 0;
3243 virtual void SetRange(IntVar* var, int64_t new_min, int64_t new_max) = 0;
3247 virtual void SetValues(IntVar* var, const std::vector<int64_t>& values) = 0;
3249 const std::vector<int64_t>& values) = 0;
3254 int64_t new_max) = 0;
3258 int64_t new_max) = 0;
3270 const std::vector<int>& rank_first,
3271 const std::vector<int>& rank_last,
3272 const std::vector<int>& unperformed) = 0;
3274 void Install() override;
3282 std::string DebugString() const override { return "LocalSearchMonitor"; }
3293 bool neighbor_found) = 0;
3296 bool neighbor_found) = 0;
3308 static const int kUnboundBooleanVarValue;
3311 : IntVar(s, name), value_(kUnboundBooleanVarValue) {}
3317 int64_t Max() const override { return (value_ != 0); }
3319 void SetRange(int64_t mi, int64_t ma) override;
3321 int64_t Value() const override {
3330 uint64_t Size() const override;
3331 bool Contains(int64_t v) const override;
3337 IntVar* IsEqual(int64_t constant) override;
3338 IntVar* IsDifferent(int64_t constant) override;
3339 IntVar* IsGreaterOrEqual(int64_t constant) override;
3343 std::string BaseName() const override { return "BooleanVar"; }
3345 int RawValue() const { return value_; }
3361 : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
3364 void AddIntegerVariableEqualValueClause(IntVar* var, int64_t value);
3365 void AddIntegerVariableGreaterOrEqualValueClause(IntVar* var, int64_t value);
3366 void AddIntegerVariableLessOrEqualValueClause(IntVar* var, int64_t value);
3370 void set_symmetry_manager_and_index(SymmetryManager* manager, int index) {
3371 CHECK(symmetry_manager_ == nullptr);
3372 CHECK_EQ(-1, index_in_symmetry_manager_);
3374 index_in_symmetry_manager_ = index;
3376 SymmetryManager* symmetry_manager() const { return symmetry_manager_; }
3377 int index_in_symmetry_manager() const { return index_in_symmetry_manager_; }
3379 SymmetryManager* symmetry_manager_;
3381 int index_in_symmetry_manager_;
3388 SearchLog(Solver* solver, std::vector<IntVar*> vars, std::string vars_name,
3389 std::vector<double> scaling_factors, std::vector<double> offsets,
3390 std::function<std::string()> display_callback,
3391 bool display_on_new_solutions_only, int period);
3395 bool AtSolution() override;
3396 void BeginFail() override;
3397 void NoMoreSolutions() override;
3405 std::string DebugString() const override;
3409 virtual void OutputLine(const std::string& line);
3415 std::unique_ptr<WallTimer> timer_;
3416 const std::vector<IntVar*> vars_;
3417 const std::string vars_name_;
3418 const std::vector<double> scaling_factors_;
3419 const std::vector<double> offsets_;
3420 std::function<std::string()> display_callback_;
3421 const bool display_on_new_solutions_only_;
3424 std::vector<int64_t> objective_min_;
3425 std::vector<int64_t> objective_max_;
3426 std::vector<int64_t> last_objective_value_;
3427 absl::Duration last_objective_timestamp_;
3432 int neighbors_offset_ = 0;
3441 enum VoidConstraintType {
3447 enum VarConstantConstraintType {
3448 VAR_CONSTANT_EQUALITY = 0,
3449 VAR_CONSTANT_GREATER_OR_EQUAL,
3450 VAR_CONSTANT_LESS_OR_EQUAL,
3559 IntVar* var, int64_t value1, int64_t value2,
3563 Constraint* ct, IntVar* var, int64_t value1, int64_t value2,
3614 IntVar* var, int64_t value1, int64_t value2,
3618 IntExpr* expression, IntVar* var, int64_t value1, int64_t value2,
3624 IntVar* var, const std::vector<int64_t>& values,
3628 IntExpr* expression, IntVar* var, const std::vector<int64_t>& values,
3637 const std::vector<IntVar*>& vars,
3643 const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
3647 IntExpr* expression, const std::vector<IntVar*>& var,
3648 const std::vector<int64_t>& values,
3654 const std::vector<IntVar*>& vars, int64_t value,
3658 IntExpr* expression, const std::vector<IntVar*>& var, int64_t value,
3664 Solver* const solver_;
3672 const std::string& TypeName() const;
3673 void SetTypeName(const std::string& type_name);
3676 void SetIntegerArgument(const std::string& arg_name, int64_t value);
3677 void SetIntegerArrayArgument(const std::string& arg_name,
3678 const std::vector<int64_t>& values);
3679 void SetIntegerMatrixArgument(const std::string& arg_name,
3683 const std::vector<IntVar*>& vars);
3686 const std::vector<IntervalVar*>& vars);
3689 const std::vector<SequenceVar*>& vars);
3700 const std::string& arg_name) const;
3702 const std::string& arg_name) const;
3705 const std::string& arg_name) const;
3707 const std::string& arg_name) const;
3711 absl::flat_hash_map<std::string, int64_t> integer_argument_;
3712 absl::flat_hash_map<std::string, std::vector<int64_t>>
3714 absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
3715 absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
3716 absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
3717 absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
3718 absl::flat_hash_map<std::string, std::vector<IntVar*>>
3719 integer_variable_array_argument_;
3720 absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
3721 interval_array_argument_;
3722 absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
3723 sequence_array_argument_;
3734 void BeginVisitModel(const std::string& solver_name) override;
3735 void EndVisitModel(const std::string& solver_name) override;
3736 void BeginVisitConstraint(const std::string& type_name,
3737 const Constraint* constraint) override;
3738 void EndVisitConstraint(const std::string& type_name,
3741 const IntExpr* expr) override;
3743 const IntExpr* expr) override;
3746 const std::string& operation, int64_t value,
3747 IntVar* delegate) override;
3749 const std::string& operation, int64_t value,
3756 const std::vector<int64_t>& values) override;
3761 IntExpr* argument) override;
3763 const std::string& arg_name,
3764 const std::vector<IntVar*>& arguments) override;
3769 const std::string& arg_name,
3770 const std::vector<IntervalVar*>& arguments) override;
3775 const std::string& arg_name,
3776 const std::vector<SequenceVar*>& arguments) override;
3784 std::vector<ArgumentHolder*> holders_;
3793 values_(new T[index_max - index_min + 1]) {
3799 virtual T Evaluate(int64_t index) const {
3800 DCHECK_GE(index, index_min_);
3801 DCHECK_LE(index, index_max_);
3802 return values_[index - index_min_];
3805 void SetValue(int64_t index, T value) {
3808 values_[index - index_min_] = value;
3811 std::string DebugString() const override { return "ArrayWithOffset"; }
3816 std::unique_ptr<T[]> values_;
3824template <class T, class C>
3833 for (int i = 0; i < elements_.size(); ++i) {
3838 T At(int64_t index) const {
3839 const int64_t block_index = ComputeBlockIndex(index);
3840 const int64_t relative_index = block_index - block_offset_;
3841 if (relative_index < 0 || relative_index >= elements_.size()) {
3844 const T* block = elements_[relative_index];
3845 return block != nullptr ? block[index - block_index * block_size_] : T();
3848 void RevInsert(Solver* const solver, int64_t index, T value) {
3849 const int64_t block_index = ComputeBlockIndex(index);
3850 T* const block = GetOrCreateBlock(block_index);
3851 const int64_t residual = index - block_index * block_size_;
3852 solver->SaveAndSetValue(reinterpret_cast<C*>(&block[residual]),
3859 for (int i = 0; i < block_size_; ++i) {
3860 result[i] = T();
3867 block_offset_ = block_index;
3869 } else if (block_index < block_offset_) {
3871 } else if (block_index - block_offset_ >= elements_.size()) {
3874 T* block = elements_[block_index - block_offset_];
3877 elements_[block_index - block_offset_] = block;
3882 int64_t ComputeBlockIndex(int64_t value) const {
3883 return value >= 0 ? value / block_size_
3884 : (value - block_size_ + 1) / block_size_;
3887 void GrowUp(int64_t block_index) {
3888 elements_.resize(block_index - block_offset_ + 1);
3891 void GrowDown(int64_t block_index) {
3892 const int64_t delta = block_offset_ - block_index;
3893 block_offset_ = block_index;
3895 elements_.insert(elements_.begin(), delta, nullptr);
3898 const int64_t block_size_;
3899 std::vector<T*> elements_;
3914 : elements_(new T[capacity]),
3917 position_(new int[capacity]),
3918 delete_position_(true) {
3919 for (int i = 0; i < capacity; ++i) {
3925 RevIntSet(int capacity, int* shared_positions, int shared_positions_size)
3926 : elements_(new T[capacity]),
3929 position_(shared_positions),
3930 delete_position_(false) {
3937 if (delete_position_) {
3942 int Size() const { return num_elements_.Value(); }
3944 int Capacity() const { return capacity_; }
3946 T Element(int i) const {
3948 DCHECK_LT(i, num_elements_.Value());
3954 DCHECK_LT(i + num_elements_.Value(), capacity_);
3955 return elements_[i + num_elements_.Value()];
3959 const int position = num_elements_.Value();
3960 DCHECK_LT(position, capacity_);
3963 position_[elt] = position;
3969 SwapTo(value_index, num_elements_.Value());
3972 void Restore(Solver* const solver, const T& value_index) {
3973 SwapTo(value_index, num_elements_.Value());
3974 num_elements_.Incr(solver);
3977 void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); }
3988 if (elt == elements_[i]) {
3989 return false;
3992 return true;
3995 void SwapTo(T value_index, int next_position) {
3996 const int current_position = position_[value_index];
3997 if (current_position != next_position) {
3998 const T next_value_index = elements_[next_position];
3999 elements_[current_position] = next_value_index;
4000 elements_[next_position] = value_index;
4001 position_[value_index] = next_position;
4002 position_[next_value_index] = current_position;
4007 std::unique_ptr<T[]> elements_;
4015 const bool delete_position_;
4020class RevPartialSequence {
4022 explicit RevPartialSequence(const std::vector<int>& items)
4025 last_ranked_(items.size() - 1),
4048 int NumFirstRanked() const { return first_ranked_.Value(); }
4050 int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); }
4052 int Size() const { return size_; }
4058 return elements_[index];
4063 DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
4064 SwapTo(elt, first_ranked_.Value());
4065 first_ranked_.Incr(solver);
4069 DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
4075 const int position = position_[elt];
4076 return (position < first_ranked_.Value() ||
4081 std::string result = "[";
4082 for (int i = 0; i < first_ranked_.Value(); ++i) {
4091 if (i != last_ranked_.Value()) {
4092 result.append("-");
4096 for (int i = last_ranked_.Value() + 1; i < size_; ++i) {
4097 absl::StrAppend(&result, elements_[i]);
4107 void SwapTo(int elt, int next_position) {
4108 const int current_position = position_[elt];
4109 if (current_position != next_position) {
4110 const int next_elt = elements_[next_position];
4111 elements_[current_position] = next_elt;
4112 elements_[next_position] = elt;
4113 position_[elt] = next_position;
4119 std::vector<int> elements_;
4121 NumericalRev<int> first_ranked_;
4123 NumericalRev<int> last_ranked_;
4127 std::unique_ptr<int[]> position_;
4134class UnsortedNullableRevBitset {
4137 explicit UnsortedNullableRevBitset(int bit_size);
4143 void Init(Solver* solver, const std::vector<uint64_t>& mask);
4147 bool RevSubtract(Solver* solver, const std::vector<uint64_t>& mask);
4151 bool RevAnd(Solver* solver, const std::vector<uint64_t>& mask);
4155 int ActiveWordSize() const { return active_words_.Size(); }
4158 bool Empty() const { return active_words_.Size() == 0; }
4167 bool Intersects(const std::vector<uint64_t>& mask, int* support_index);
4170 int64_t bit_size() const { return bit_size_; }
4172 int64_t word_size() const { return word_size_; }
4174 const RevIntSet<int>& active_words() const { return active_words_; }
4177 void CleanUpActives(Solver* solver);
4180 const int64_t word_size_;
4181 RevArray<uint64_t> bits_;
4183 std::vector<int> to_remove_;
4186template <class T>
4187bool IsArrayConstant(const std::vector<T>& values, const T& value) {
4188 for (int i = 0; i < values.size(); ++i) {
4198 for (int i = 0; i < values.size(); ++i) {
4199 if (values[i] != 0 && values[i] != 1) {
4207bool AreAllOnes(const std::vector<T>& values) {
4218 for (const T& current_value : values) {
4227bool AreAllLessOrEqual(const std::vector<T>& values, const T& value) {
4228 for (const T& current_value : values) {
4229 if (current_value > value) {
4242bool AreAllNegative(const std::vector<T>& values) {
4252bool AreAllStrictlyNegative(const std::vector<T>& values) {
4253 return AreAllLessOrEqual(values, T(-1));
4257bool IsIncreasingContiguous(const std::vector<T>& values) {
4258 for (int i = 0; i < values.size() - 1; ++i) {
4267bool IsIncreasing(const std::vector<T>& values) {
4268 for (int i = 0; i < values.size() - 1; ++i) {
4269 if (values[i + 1] < values[i]) {
4277bool IsArrayInRange(const std::vector<IntVar*>& vars, T range_min,
4279 for (int i = 0; i < vars.size(); ++i) {
4280 if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) {
4287inline bool AreAllBound(const std::vector<IntVar*>& vars) {
4288 for (int i = 0; i < vars.size(); ++i) {
4289 if (!vars[i]->Bound()) {
4296inline bool AreAllBooleans(const std::vector<IntVar*>& vars) {
4314inline bool AreAllBoundTo(const std::vector<IntVar*>& vars, int64_t value) {
4315 for (int i = 0; i < vars.size(); ++i) {
4316 if (!vars[i]->Bound() || vars[i]->Min() != value) {
4323inline int64_t MaxVarArray(const std::vector<IntVar*>& vars) {
4326 for (int i = 0; i < vars.size(); ++i) {
4328 result = std::max<int64_t>(result, vars[i]->Max());
4333inline int64_t MinVarArray(const std::vector<IntVar*>& vars) {
4336 for (int i = 0; i < vars.size(); ++i) {
4338 result = std::min<int64_t>(result, vars[i]->Min());
4343inline void FillValues(const std::vector<IntVar*>& vars,
4344 std::vector<int64_t>* const values) {
4345 values->clear();
4346 values->resize(vars.size());
4347 for (int i = 0; i < vars.size(); ++i) {
4348 (*values)[i] = vars[i]->Value();
4352inline int64_t PosIntDivUp(int64_t e, int64_t v) {
4354 return (e < 0 || e % v == 0) ? e / v : e / v + 1;
4357inline int64_t PosIntDivDown(int64_t e, int64_t v) {
int64_t MemoryUsage(int unused)
AlternativeNodeIterator(bool use_sibling)
Definition constraint_solveri.h:1368
bool Next()
Definition constraint_solveri.h:1385
void Reset(const PathOperator &path_operator, int base_index_reference)
Definition constraint_solveri.h:1372
~AlternativeNodeIterator()
Definition constraint_solveri.h:1370
int GetValue() const
Definition constraint_solveri.h:1386
Argument Holder: useful when visiting a model.
Definition constraint_solveri.h:3681
const IntTupleSet & FindIntegerMatrixArgumentOrDie(const std::string &arg_name) const
void SetIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &vars)
void SetIntervalArgument(const std::string &arg_name, IntervalVar *var)
void SetIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &vars)
IntExpr * FindIntegerExpressionArgumentOrDie(const std::string &arg_name) const
bool HasIntegerExpressionArgument(const std::string &arg_name) const
Checks if arguments exist.
const std::vector< IntVar * > & FindIntegerVariableArrayArgumentOrDie(const std::string &arg_name) const
void SetSequenceArgument(const std::string &arg_name, SequenceVar *var)
bool HasIntegerVariableArrayArgument(const std::string &arg_name) const
const std::vector< int64_t > & FindIntegerArrayArgumentOrDie(const std::string &arg_name) const
int64_t FindIntegerArgumentOrDie(const std::string &arg_name) const
void SetIntegerExpressionArgument(const std::string &arg_name, IntExpr *expr)
void SetSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &vars)
int64_t FindIntegerArgumentWithDefault(const std::string &arg_name, int64_t def) const
Getters.
std::string DebugString() const override
Definition constraint_solveri.h:3823
const E & Element(const V *const var) const
E * MutableElement(const V *const var)
bool Contains(const V *const var) const
IntContainer * MutableIntVarContainer()
IntVarElement * FastAdd(IntVar *var)
Adds without checking if variable has been previously added.
AssignmentContainer< IntVar, IntVarElement > IntContainer
virtual IntVar * CastToVar()
~BaseIntExpr() override
Definition constraint_solveri.h:119
IntVar * Var() override
Creates a variable from the expression.
BaseIntExpr(Solver *const s)
Definition constraint_solveri.h:118
Here's a sample relaxing one variable at a time:
Definition constraint_solveri.h:1324
void AppendToFragment(int index)
bool HasFragments() const override
Definition constraint_solveri.h:1332
virtual void InitFragments()
BaseLns(const std::vector< IntVar * > &vars)
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
virtual bool NextFragment()=0
BaseNodeIterators(const PathOperator *path_operator, int base_index_reference)
Definition constraint_solveri.h:1446
AlternativeNodeIterator * GetAlternativeIterator() const
Definition constraint_solveri.h:1454
bool Increment()
Definition constraint_solveri.h:1485
NodeNeighborIterator * GetNeighborIterator() const
Definition constraint_solveri.h:1459
void Reset(bool update_end_nodes=false)
Definition constraint_solveri.h:1475
AlternativeNodeIterator * GetSiblingAlternativeIterator() const
Definition constraint_solveri.h:1449
void Initialize()
Definition constraint_solveri.h:1464
bool HasReachedEnd() const
Definition constraint_solveri.h:1498
virtual std::string DebugString() const
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
IntVarIterator * MakeDomainIterator(bool reversible) const override
IntVarIterator * MakeHoleIterator(bool reversible) const override
void RemoveValue(int64_t v) override
This method removes the value 'v' from the domain of the variable.
SimpleRevFIFO< Demon * > delayed_bound_demons_
Definition constraint_solveri.h:3362
void SetMax(int64_t m) override
void SetRange(int64_t mi, int64_t ma) override
This method sets both the min and the max of the expression.
void RemoveInterval(int64_t l, int64_t u) override
virtual void RestoreValue()=0
void WhenDomain(Demon *d) override
Definition constraint_solveri.h:3341
SimpleRevFIFO< Demon * > bound_demons_
Definition constraint_solveri.h:3361
static const int kUnboundBooleanVarValue
Definition constraint_solveri.h:3320
void WhenBound(Demon *d) override
bool Bound() const override
Returns true if the min and the max of the expression are equal.
Definition constraint_solveri.h:3332
int VarType() const override
Definition constraint_solveri.h:3347
int value_
Definition constraint_solveri.h:3360
IntVar * IsLessOrEqual(int64_t constant) override
std::string BaseName() const override
Returns a base name for automatic naming.
Definition constraint_solveri.h:3355
void WhenRange(Demon *d) override
Attach a demon that will watch the min or the max of the expression.
Definition constraint_solveri.h:3340
Demon proxy to a method on the constraint with no arguments.
Definition constraint_solveri.h:513
~CallMethod0() override
Definition constraint_solveri.h:518
std::string DebugString() const override
Definition constraint_solveri.h:522
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
Definition constraint_solveri.h:515
Demon proxy to a method on the constraint with one argument.
Definition constraint_solveri.h:551
~CallMethod1() override
Definition constraint_solveri.h:557
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Definition constraint_solveri.h:553
std::string DebugString() const override
Definition constraint_solveri.h:561
Demon proxy to a method on the constraint with two arguments.
Definition constraint_solveri.h:581
std::string DebugString() const override
Definition constraint_solveri.h:597
~CallMethod2() override
Definition constraint_solveri.h:591
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Definition constraint_solveri.h:583
Demon proxy to a method on the constraint with three arguments.
Definition constraint_solveri.h:620
~CallMethod3() override
Definition constraint_solveri.h:631
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
Definition constraint_solveri.h:622
std::string DebugString() const override
Definition constraint_solveri.h:637
virtual int64_t ModifyValue(int64_t index, int64_t value)=0
bool MakeOneNeighbor() override
This method should not be overridden. Override ModifyValue() instead.
ChangeValue(const std::vector< IntVar * > &vars)
Constraint(Solver *const solver)
Low-priority demon proxy to a method on the constraint with no arguments.
Definition constraint_solveri.h:670
~DelayedCallMethod0() override
Definition constraint_solveri.h:675
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
Definition constraint_solveri.h:672
std::string DebugString() const override
Definition constraint_solveri.h:683
Solver::DemonPriority priority() const override
Definition constraint_solveri.h:679
~DelayedCallMethod1() override
Definition constraint_solveri.h:709
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Definition constraint_solveri.h:705
Solver::DemonPriority priority() const override
Definition constraint_solveri.h:713
std::string DebugString() const override
Definition constraint_solveri.h:717
Low-priority demon proxy to a method on the constraint with two arguments.
Definition constraint_solveri.h:739
std::string DebugString() const override
Definition constraint_solveri.h:759
Solver::DemonPriority priority() const override
Definition constraint_solveri.h:755
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Definition constraint_solveri.h:741
~DelayedCallMethod2() override
Definition constraint_solveri.h:749
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual int64_t Min() const =0
IntVar * Var(int index) const
Definition constraint_solveri.h:3209
int64_t OldInverseValue(int64_t index) const
Definition constraint_solveri.h:1258
void AddToAssignment(IntVar *var, int64_t value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
Definition constraint_solveri.h:1262
virtual bool SkipUnchanged(int) const
Definition constraint_solveri.h:1174
virtual bool IsIncremental() const
Definition constraint_solveri.h:1163
int Size() const
Definition constraint_solveri.h:1165
virtual void OnStart()
Definition constraint_solveri.h:1235
bool Activated(int64_t index) const
Definition constraint_solveri.h:1182
void SetValue(int64_t index, int64_t value)
Definition constraint_solveri.h:1179
void Start(const Assignment *assignment) override
Definition constraint_solveri.h:1143
void RevertChanges(bool change_was_incremental)
Definition constraint_solveri.h:1212
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
void AddVars(const std::vector< IntVar * > &vars)
Definition constraint_solveri.h:1223
void Deactivate(int64_t index)
Definition constraint_solveri.h:1186
IntVar * Var(int64_t index) const
Returns the variable of given index.
Definition constraint_solveri.h:1173
int64_t Value(int64_t index) const
Definition constraint_solveri.h:1168
int64_t InverseValue(int64_t index) const
Definition constraint_solveri.h:1255
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
Definition constraint_solveri.h:1188
int64_t PrevValue(int64_t index) const
Definition constraint_solveri.h:1176
bool HoldsDelta() const override
Definition constraint_solveri.h:1140
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
Definition constraint_solveri.h:1127
void Activate(int64_t index)
Definition constraint_solveri.h:1185
int64_t OldValue(int64_t index) const
Definition constraint_solveri.h:1175
virtual bool MakeOneNeighbor()
MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator.
~IntVarLocalSearchOperator() override
Definition constraint_solveri.h:1138
int index() const
Returns the index of the variable.
LightIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index, F values, std::function< bool()> deep_serialize)
Definition constraint_solveri.h:791
~LightIntFunctionElementCt() override
Definition constraint_solveri.h:799
void InitialPropagate() override
Definition constraint_solveri.h:807
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Definition constraint_solveri.h:818
std::string DebugString() const override
Definition constraint_solveri.h:813
void Post() override
Definition constraint_solveri.h:801
~LightIntIntFunctionElementCt() override
Definition constraint_solveri.h:855
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Definition constraint_solveri.h:869
void InitialPropagate() override
Definition constraint_solveri.h:863
void Post() override
Definition constraint_solveri.h:856
LightIntIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index1, IntVar *const index2, F values, std::function< bool()> deep_serialize)
Definition constraint_solveri.h:846
std::string DebugString() const override
Definition constraint_solveri.h:865
void Post() override
Definition constraint_solveri.h:921
LightIntIntIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index1, IntVar *const index2, IntVar *const index3, F values)
Definition constraint_solveri.h:911
std::string DebugString() const override
Definition constraint_solveri.h:931
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
Definition constraint_solveri.h:935
~LightIntIntIntFunctionElementCt() override
Definition constraint_solveri.h:920
void InitialPropagate() override
Definition constraint_solveri.h:929
LocalSearchFilterManager(std::vector< FilterEvent > filter_events)
int64_t GetSynchronizedObjectiveValue() const
Definition constraint_solveri.h:3169
void Synchronize(const Assignment *assignment, const Assignment *delta)
Synchronizes all filters to assignment.
bool Accept(LocalSearchMonitor *monitor, const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)
virtual bool IsIncremental() const
Definition constraint_solveri.h:3112
virtual void Revert()
Cancels the changes made by the last Relax()/Accept() calls.
Definition constraint_solveri.h:3122
virtual bool Accept(const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max)=0
virtual int64_t GetAcceptedObjectiveValue() const
Objective value from the last time Accept() was called and returned true.
Definition constraint_solveri.h:3131
virtual void Synchronize(const Assignment *assignment, const Assignment *delta)=0
virtual bool IsActive() const =0
virtual void EndAcceptNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void BeginAcceptNeighbor(const LocalSearchOperator *op)=0
virtual void BeginFilterNeighbor(const LocalSearchOperator *op)=0
void Install() override
Install itself on the solver.
virtual void BeginFiltering(const LocalSearchFilter *filter)=0
virtual void EndFilterNeighbor(const LocalSearchOperator *op, bool neighbor_found)=0
virtual void EndFiltering(const LocalSearchFilter *filter, bool reject)=0
int64_t CheckPointValue(int64_t index) const
Definition constraint_solveri.h:1019
void SetCandidateActive(int64_t index, bool active)
Definition constraint_solveri.h:1033
void SetCurrentDomainInjectiveAndKeepInverseValues(int max_value)
Definition constraint_solveri.h:1004
void Resize(int size)
Definition constraint_solveri.h:1079
void Revert(bool only_incremental)
Definition constraint_solveri.h:1057
int64_t CandidateValue(int64_t index) const
Definition constraint_solveri.h:1012
LocalSearchOperatorState()
Definition constraint_solveri.h:1002
void CheckPoint()
Definition constraint_solveri.h:1055
void SetCandidateValue(int64_t index, int64_t value)
Definition constraint_solveri.h:1022
const std::vector< int64_t > & IncrementalIndicesChanged() const
Definition constraint_solveri.h:1075
const std::vector< int64_t > & CandidateIndicesChanged() const
Definition constraint_solveri.h:1072
int64_t CommittedInverseValue(int64_t value) const
Definition constraint_solveri.h:1092
int64_t CommittedValue(int64_t index) const
Definition constraint_solveri.h:1016
bool CandidateIsActive(int64_t index) const
Definition constraint_solveri.h:1030
int64_t CandidateInverseValue(int64_t value) const
Definition constraint_solveri.h:1089
void Commit()
Definition constraint_solveri.h:1042
The base class for all local search operators.
Definition constraint_solveri.h:985
virtual void Reset()
Definition constraint_solveri.h:992
virtual bool HoldsDelta() const
Definition constraint_solveri.h:997
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
virtual const LocalSearchOperator * Self() const
Definition constraint_solveri.h:994
virtual void EnterSearch()
Definition constraint_solveri.h:990
virtual bool HasFragments() const
Definition constraint_solveri.h:996
~LocalSearchOperator() override
Definition constraint_solveri.h:988
virtual void Start(const Assignment *assignment)=0
LocalSearchOperator()
Definition constraint_solveri.h:987
Variable()
Definition constraint_solveri.h:3034
bool Exists() const
Definition constraint_solveri.h:3063
bool SetMin(int64_t new_min) const
Definition constraint_solveri.h:3045
bool SetMax(int64_t new_max) const
Definition constraint_solveri.h:3052
void Relax() const
Definition constraint_solveri.h:3057
friend class LocalSearchState
Definition constraint_solveri.h:3067
bool StateIsFeasible() const
Definition constraint_solveri.h:2837
void ChangeRelaxedVariableDomain(VariableDomainId domain_id, int64_t min, int64_t max)
void PropagateRelax(VariableDomainId domain_id)
static Variable DummyVariable()
Variable MakeVariable(VariableDomainId domain_id)
Variable MakeVariableWithRelaxedDomain(int64_t min, int64_t max)
int64_t VariableDomainMax(VariableDomainId domain_id) const
bool PropagateTighten(VariableDomainId domain_id)
virtual void InsertVarArrayConstantArrayExpression(IntExpr *expression, const std::vector< IntVar * > &var, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type)=0
VoidConstraintType
Definition constraint_solveri.h:3453
VarArrayConstantExpressionType
Definition constraint_solveri.h:3543
@ VAR_ARRAY_CONSTANT_INDEX
Definition constraint_solveri.h:3544
@ VAR_ARRAY_CONSTANT_EXPRESSION_MAX
Definition constraint_solveri.h:3545
VarArrayConstantArrayExpressionType
Definition constraint_solveri.h:3531
@ VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX
Definition constraint_solveri.h:3533
@ VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD
Definition constraint_solveri.h:3532
virtual void InsertVarConstantConstraint(Constraint *ct, IntVar *var, int64_t value, VarConstantConstraintType type)=0
ExprExpressionType
Definition constraint_solveri.h:3482
@ EXPR_SQUARE
Definition constraint_solveri.h:3485
@ EXPR_EXPRESSION_MAX
Definition constraint_solveri.h:3486
@ EXPR_ABS
Definition constraint_solveri.h:3484
@ EXPR_OPPOSITE
Definition constraint_solveri.h:3483
virtual IntExpr * FindExprExprExpression(IntExpr *var1, IntExpr *var2, ExprExprExpressionType type) const =0
Expr Expr Expressions.
virtual Constraint * FindExprExprConstraint(IntExpr *expr1, IntExpr *expr2, ExprExprConstraintType type) const =0
Expr Expr Constraints.
virtual Constraint * FindVoidConstraint(VoidConstraintType type) const =0
Void constraints.
virtual IntExpr * FindVarArrayConstantArrayExpression(const std::vector< IntVar * > &vars, const std::vector< int64_t > &values, VarArrayConstantArrayExpressionType type) const =0
Var Array Constant Array Expressions.
virtual IntExpr * FindVarArrayExpression(const std::vector< IntVar * > &vars, VarArrayExpressionType type) const =0
Var Array Expressions.
virtual IntExpr * FindExprExpression(IntExpr *expr, ExprExpressionType type) const =0
Expr Expressions.
VarConstantConstraintType
Definition constraint_solveri.h:3459
@ VAR_CONSTANT_NON_EQUALITY
Definition constraint_solveri.h:3463
@ VAR_CONSTANT_CONSTRAINT_MAX
Definition constraint_solveri.h:3464
virtual void InsertExprExprConstraint(Constraint *ct, IntExpr *expr1, IntExpr *expr2, ExprExprConstraintType type)=0
ExprConstantExpressionType
Definition constraint_solveri.h:3508
@ EXPR_CONSTANT_SUM
Definition constraint_solveri.h:3514
@ EXPR_CONSTANT_DIVIDE
Definition constraint_solveri.h:3510
@ EXPR_CONSTANT_IS_NOT_EQUAL
Definition constraint_solveri.h:3516
@ EXPR_CONSTANT_MIN
Definition constraint_solveri.h:3513
@ EXPR_CONSTANT_IS_GREATER_OR_EQUAL
Definition constraint_solveri.h:3517
@ EXPR_CONSTANT_IS_EQUAL
Definition constraint_solveri.h:3515
@ EXPR_CONSTANT_MAX
Definition constraint_solveri.h:3512
@ EXPR_CONSTANT_IS_LESS_OR_EQUAL
Definition constraint_solveri.h:3518
@ EXPR_CONSTANT_DIFFERENCE
Definition constraint_solveri.h:3509
@ EXPR_CONSTANT_EXPRESSION_MAX
Definition constraint_solveri.h:3519
@ EXPR_CONSTANT_PROD
Definition constraint_solveri.h:3511
virtual void InsertExprExpression(IntExpr *expression, IntExpr *expr, ExprExpressionType type)=0
VarConstantArrayExpressionType
Definition constraint_solveri.h:3526
@ VAR_CONSTANT_ARRAY_EXPRESSION_MAX
Definition constraint_solveri.h:3528
@ VAR_CONSTANT_ARRAY_ELEMENT
Definition constraint_solveri.h:3527
virtual void InsertVoidConstraint(Constraint *ct, VoidConstraintType type)=0
virtual void InsertExprExprExpression(IntExpr *expression, IntExpr *var1, IntExpr *var2, ExprExprExpressionType type)=0
virtual void InsertVarConstantArrayExpression(IntExpr *expression, IntVar *var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type)=0
ExprExprExpressionType
Definition constraint_solveri.h:3489
@ EXPR_EXPR_MIN
Definition constraint_solveri.h:3494
@ EXPR_EXPR_IS_EQUAL
Definition constraint_solveri.h:3498
@ EXPR_EXPR_EXPRESSION_MAX
Definition constraint_solveri.h:3500
@ EXPR_EXPR_PROD
Definition constraint_solveri.h:3491
@ EXPR_EXPR_IS_NOT_EQUAL
Definition constraint_solveri.h:3499
@ EXPR_EXPR_MAX
Definition constraint_solveri.h:3493
@ EXPR_EXPR_DIFFERENCE
Definition constraint_solveri.h:3490
@ EXPR_EXPR_IS_LESS_OR_EQUAL
Definition constraint_solveri.h:3497
@ EXPR_EXPR_IS_LESS
Definition constraint_solveri.h:3496
@ EXPR_EXPR_SUM
Definition constraint_solveri.h:3495
@ EXPR_EXPR_DIV
Definition constraint_solveri.h:3492
virtual IntExpr * FindVarArrayConstantExpression(const std::vector< IntVar * > &vars, int64_t value, VarArrayConstantExpressionType type) const =0
Var Array Constant Expressions.
virtual void InsertExprConstantExpression(IntExpr *expression, IntExpr *var, int64_t value, ExprConstantExpressionType type)=0
VarConstantConstantExpressionType
Definition constraint_solveri.h:3521
@ VAR_CONSTANT_CONSTANT_EXPRESSION_MAX
Definition constraint_solveri.h:3523
@ VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS
Definition constraint_solveri.h:3522
virtual void InsertVarConstantConstantConstraint(Constraint *ct, IntVar *var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type)=0
virtual void InsertVarArrayConstantExpression(IntExpr *expression, const std::vector< IntVar * > &var, int64_t value, VarArrayConstantExpressionType type)=0
virtual void InsertVarConstantConstantExpression(IntExpr *expression, IntVar *var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type)=0
ExprExprConstantExpressionType
Definition constraint_solveri.h:3503
@ EXPR_EXPR_CONSTANT_CONDITIONAL
Definition constraint_solveri.h:3504
@ EXPR_EXPR_CONSTANT_EXPRESSION_MAX
Definition constraint_solveri.h:3505
virtual Constraint * FindVarConstantConstraint(IntVar *var, int64_t value, VarConstantConstraintType type) const =0
Var Constant Constraints.
virtual IntExpr * FindVarConstantArrayExpression(IntVar *var, const std::vector< int64_t > &values, VarConstantArrayExpressionType type) const =0
Var Constant Array Expressions.
VarArrayExpressionType
Definition constraint_solveri.h:3536
@ VAR_ARRAY_MIN
Definition constraint_solveri.h:3538
@ VAR_ARRAY_SUM
Definition constraint_solveri.h:3539
@ VAR_ARRAY_MAX
Definition constraint_solveri.h:3537
@ VAR_ARRAY_EXPRESSION_MAX
Definition constraint_solveri.h:3540
ExprExprConstraintType
Definition constraint_solveri.h:3472
@ EXPR_EXPR_EQUALITY
Definition constraint_solveri.h:3473
@ EXPR_EXPR_GREATER_OR_EQUAL
Definition constraint_solveri.h:3475
@ EXPR_EXPR_NON_EQUALITY
Definition constraint_solveri.h:3478
@ EXPR_EXPR_LESS_OR_EQUAL
Definition constraint_solveri.h:3477
@ EXPR_EXPR_CONSTRAINT_MAX
Definition constraint_solveri.h:3479
@ EXPR_EXPR_LESS
Definition constraint_solveri.h:3476
@ EXPR_EXPR_GREATER
Definition constraint_solveri.h:3474
ModelCache(Solver *solver)
virtual IntExpr * FindExprConstantExpression(IntExpr *expr, int64_t value, ExprConstantExpressionType type) const =0
Expr Constant Expressions.
virtual void InsertExprExprConstantExpression(IntExpr *expression, IntExpr *var1, IntExpr *var2, int64_t constant, ExprExprConstantExpressionType type)=0
virtual IntExpr * FindExprExprConstantExpression(IntExpr *var1, IntExpr *var2, int64_t constant, ExprExprConstantExpressionType type) const =0
Expr Expr Constant Expressions.
virtual IntExpr * FindVarConstantConstantExpression(IntVar *var, int64_t value1, int64_t value2, VarConstantConstantExpressionType type) const =0
Var Constant Constant Expressions.
virtual Constraint * FindVarConstantConstantConstraint(IntVar *var, int64_t value1, int64_t value2, VarConstantConstantConstraintType type) const =0
Var Constant Constant Constraints.
virtual void InsertVarArrayExpression(IntExpr *expression, const std::vector< IntVar * > &vars, VarArrayExpressionType type)=0
VarConstantConstantConstraintType
Definition constraint_solveri.h:3467
@ VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX
Definition constraint_solveri.h:3469
@ VAR_CONSTANT_CONSTANT_BETWEEN
Definition constraint_solveri.h:3468
Model Parser.
Definition constraint_solveri.h:3739
void VisitIntervalArgument(const std::string &arg_name, IntervalVar *argument) override
Visit interval argument.
void VisitIntervalArrayArgument(const std::string &arg_name, const std::vector< IntervalVar * > &arguments) override
void VisitIntervalVariable(const IntervalVar *variable, const std::string &operation, int64_t value, IntervalVar *delegate) override
void VisitIntegerArgument(const std::string &arg_name, int64_t value) override
Integer arguments.
void VisitIntegerArrayArgument(const std::string &arg_name, const std::vector< int64_t > &values) override
void VisitSequenceVariable(const SequenceVar *variable) override
void BeginVisitIntegerExpression(const std::string &type_name, const IntExpr *expr) override
void VisitSequenceArgument(const std::string &arg_name, SequenceVar *argument) override
Visit sequence argument.
void VisitSequenceArrayArgument(const std::string &arg_name, const std::vector< SequenceVar * > &arguments) override
void VisitIntegerVariable(const IntVar *variable, IntExpr *delegate) override
void VisitIntegerVariableArrayArgument(const std::string &arg_name, const std::vector< IntVar * > &arguments) override
void PushArgumentHolder()
ArgumentHolder * Top() const
void VisitIntegerMatrixArgument(const std::string &arg_name, const IntTupleSet &values) override
void EndVisitIntegerExpression(const std::string &type_name, const IntExpr *expr) override
void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *argument) override
Variables.
virtual void VisitIntegerArgument(const std::string &arg_name, int64_t value)
Visit integer arguments.
static const char kMinArgument[]
static const char kTargetArgument[]
static const char kMaxArgument[]
virtual void VisitIntegerExpressionArgument(const std::string &arg_name, IntExpr *argument)
Visit integer expression argument.
static const char kIndexArgument[]
static const char kLightElementEqual[]
virtual void BeginVisitConstraint(const std::string &type_name, const Constraint *constraint)
static const char kIndex2Argument[]
void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1 &eval, int64_t index_min, int64_t index_max)
static const char kIndex3Argument[]
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *constraint)
NodeNeighborIterator()
Definition constraint_solveri.h:1398
bool Next()
Definition constraint_solveri.h:1419
~NodeNeighborIterator()
Definition constraint_solveri.h:1399
bool IsIncomingNeighbor() const
Definition constraint_solveri.h:1430
int GetValue() const
Definition constraint_solveri.h:1422
bool IsOutgoingNeighbor() const
Definition constraint_solveri.h:1433
void Reset(const PathOperator &path_operator, int base_index_reference)
Definition constraint_solveri.h:1401
Subclass of Rev<T> which adds numerical operations.
void Decr(Solver *const s)
bool HasNeighbors() const
Definition constraint_solveri.h:1976
bool SkipUnchanged(int index) const override
Definition constraint_solveri.h:1624
bool MakeChainInactive(int64_t before_chain, int64_t chain_end)
Definition constraint_solveri.h:1836
int64_t Prev(int64_t node) const
Returns the node before node in the current delta.
Definition constraint_solveri.h:1641
bool SwapActiveAndInactive(int64_t active, int64_t inactive)
Replaces active by inactive in the current path, making active inactive.
Definition constraint_solveri.h:1854
int PathClassFromStartNode(int64_t start_node) const
Definition constraint_solveri.h:1701
int64_t Path(int64_t node) const
Definition constraint_solveri.h:1649
void AddPairAlternativeSets(const std::vector< PairType > &pair_alternative_sets)
Definition constraint_solveri.h:1923
bool MakeActive(int64_t node, int64_t destination)
Insert the inactive node after destination.
Definition constraint_solveri.h:1827
int64_t OldNext(int64_t node) const
Definition constraint_solveri.h:1739
virtual void ResetIncrementalism()
Definition constraint_solveri.h:1679
virtual bool ConsiderAlternatives(int64_t) const
Definition constraint_solveri.h:1737
bool SwapNodes(int64_t node1, int64_t node2)
Swaps the nodes node1 and node2.
Definition constraint_solveri.h:1815
int64_t BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
Definition constraint_solveri.h:1689
void SetNext(int64_t from, int64_t to, int64_t path)
Sets 'to' to be the node after 'from' on the given path.
Definition constraint_solveri.h:1877
const int number_of_nexts_
Definition constraint_solveri.h:1994
virtual bool OnSamePathAsPreviousBase(int64_t)
it's currently way more complicated to implement.
Definition constraint_solveri.h:1721
virtual int64_t GetBaseNodeRestartPosition(int base_index)
Definition constraint_solveri.h:1727
int CurrentNodePathStart(int64_t node) const
Definition constraint_solveri.h:1759
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
Definition constraint_solveri.h:1943
int64_t OldPath(int64_t node) const
Definition constraint_solveri.h:1754
int GetAlternativeIndex(int node) const
Returns the index of the alternative set of the node.
Definition constraint_solveri.h:1948
int64_t PrevNext(int64_t node) const
Definition constraint_solveri.h:1744
virtual bool InitPosition() const
Definition constraint_solveri.h:1900
int64_t OldPrev(int64_t node) const
Definition constraint_solveri.h:1749
virtual void OnNodeInitialization()
Definition constraint_solveri.h:1674
int AddAlternativeSet(const std::vector< int64_t > &alternative_set)
Definition constraint_solveri.h:1909
bool IsPathStart(int64_t node) const
Returns true if node is the first node on the path.
Definition constraint_solveri.h:1891
~PathOperator() override
Definition constraint_solveri.h:1612
bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination)
Definition constraint_solveri.h:1767
bool IsPathEnd(int64_t node) const
Definition constraint_solveri.h:1888
bool SwapActiveAndInactiveChains(absl::Span< const int64_t > active_chain, absl::Span< const int64_t > inactive_chain)
Definition constraint_solveri.h:1861
virtual bool MakeNeighbor()=0
int64_t EndNode(int i) const
Returns the end node of the ith base node.
Definition constraint_solveri.h:1696
int64_t GetActiveInAlternativeSet(int alternative_index) const
Returns the active node in the given alternative set.
Definition constraint_solveri.h:1933
PathOperator(const std::vector< IntVar * > &next_vars, const std::vector< IntVar * > &path_vars, IterationParameters iteration_parameters)
Builds an instance of PathOperator from next and path variables.
Definition constraint_solveri.h:1561
void Reset() override
Definition constraint_solveri.h:1618
virtual bool RestartAtPathStartOnSynchronize()
Definition constraint_solveri.h:1714
bool IsInactive(int64_t node) const
Returns true if node is inactive.
Definition constraint_solveri.h:1894
const std::vector< int64_t > & path_starts() const
Returns the vector of path start nodes.
Definition constraint_solveri.h:1698
bool CheckChainValidity(int64_t before_chain, int64_t chain_end, int64_t exclude) const
Definition constraint_solveri.h:1961
void ResetPosition()
Definition constraint_solveri.h:1904
bool ReverseChain(int64_t before_chain, int64_t after_chain, int64_t *chain_last)
Definition constraint_solveri.h:1791
int PathClass(int i) const
Returns the class of the path of the ith base node.
Definition constraint_solveri.h:1700
void EnterSearch() override
Definition constraint_solveri.h:1614
virtual void SetNextBaseToIncrement(int64_t base_index)
Definition constraint_solveri.h:1732
int64_t BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
Definition constraint_solveri.h:1684
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
Definition constraint_solveri.h:1659
int64_t StartNode(int i) const
Returns the start node of the ith base node.
Definition constraint_solveri.h:1694
int64_t BaseNode(int i) const
Returns the ith base node of the operator.
Definition constraint_solveri.h:1682
int CurrentNodePathEnd(int64_t node) const
Definition constraint_solveri.h:1763
std::string DebugString() const override
virtual void SetValues(IntVar *var, const std::vector< int64_t > &values)=0
virtual void SetDurationMax(IntervalVar *var, int64_t new_max)=0
virtual void SetStartMax(IntervalVar *var, int64_t new_max)=0
virtual void SetStartMin(IntervalVar *var, int64_t new_min)=0
IntervalVar modifiers.
virtual void PopContext()=0
virtual void RankSequence(SequenceVar *var, const std::vector< int > &rank_first, const std::vector< int > &rank_last, const std::vector< int > &unperformed)=0
virtual void RankNotFirst(SequenceVar *var, int index)=0
std::string DebugString() const override
Definition constraint_solveri.h:3232
virtual void RankNotLast(SequenceVar *var, int index)=0
virtual void PushContext(const std::string &context)=0
virtual void SetPerformed(IntervalVar *var, bool value)=0
virtual void SetEndMax(IntervalVar *var, int64_t new_max)=0
virtual void RemoveValue(IntVar *var, int64_t value)=0
virtual void EndDemonRun(Demon *demon)=0
virtual void SetDurationMin(IntervalVar *var, int64_t new_min)=0
virtual void RegisterDemon(Demon *demon)=0
virtual void SetMin(IntExpr *expr, int64_t new_min)=0
IntExpr modifiers.
virtual void SetEndMin(IntervalVar *var, int64_t new_min)=0
virtual void RankFirst(SequenceVar *var, int index)=0
SequenceVar modifiers.
virtual void SetMax(IntExpr *expr, int64_t new_max)=0
virtual void RankLast(SequenceVar *var, int index)=0
virtual void SetDurationRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
virtual void StartProcessingIntegerVariable(IntVar *var)=0
virtual void EndProcessingIntegerVariable(IntVar *var)=0
void Install() override
Install itself on the solver.
virtual void RemoveInterval(IntVar *var, int64_t imin, int64_t imax)=0
virtual void SetRange(IntExpr *expr, int64_t new_min, int64_t new_max)=0
virtual void BeginDemonRun(Demon *demon)=0
virtual void RemoveValues(IntVar *var, const std::vector< int64_t > &values)=0
virtual void SetStartRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
virtual void SetValue(IntVar *var, int64_t value)=0
virtual void SetEndRange(IntervalVar *var, int64_t new_min, int64_t new_max)=0
Matrix version of the RevBitSet class.
Definition constraint_solveri.h:471
bool IsSet(int64_t row, int64_t column) const
Returns whether the 'column' bit in the 'row' row is set.
Definition constraint_solveri.h:481
void ClearAll(Solver *solver)
Cleans all bits.
int64_t GetFirstBit(int row, int start) const
void SetToZero(Solver *solver, int64_t row, int64_t column)
Erases the 'column' bit in the 'row' row.
void SetToOne(Solver *solver, int64_t row, int64_t column)
Sets the 'column' bit in the 'row' row.
int64_t Cardinality() const
Returns the number of bits set to one.
void ClearAll(Solver *solver)
Cleans all bits.
void SetToZero(Solver *solver, int64_t index)
Erases the 'index' bit.
bool IsCardinalityOne() const
Does it contains only one bit set?
void SetToOne(Solver *solver, int64_t index)
Sets the 'index' bit.
friend class RevBitMatrix
Definition constraint_solveri.h:459
bool IsSet(int64_t index) const
Returns whether the 'index' bit is set.
int64_t GetFirstBit(int start) const
bool IsCardinalityZero() const
Is bitset null?
T At(int64_t index) const
Definition constraint_solveri.h:3850
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
Definition constraint_solveri.h:333
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
Definition constraint_solveri.h:305
int num_items() const
Definition constraint_solveri.h:302
~RevImmutableMultiMap()
Definition constraint_solveri.h:300
RevImmutableMultiMap(Solver *const solver, int initial_size)
Definition constraint_solveri.h:292
const V & FindWithDefault(const K &key, const V &default_value) const
Definition constraint_solveri.h:320
RevIntSet(int capacity)
Capacity is the fixed size of the set (it cannot grow).
Definition constraint_solveri.h:3925
void Insert(Solver *const solver, const T &elt)
Definition constraint_solveri.h:3970
static constexpr int kNoInserted
Definition constraint_solveri.h:3922
const_iterator begin() const
Definition constraint_solveri.h:3993
bool IsRanked(int elt) const
Definition constraint_solveri.h:4086
void RankLast(Solver *const solver, int elt)
Definition constraint_solveri.h:4080
std::string DebugString() const
Definition constraint_solveri.h:4092
RevPartialSequence(const std::vector< int > &items)
Definition constraint_solveri.h:4034
void RankFirst(Solver *const solver, int elt)
Definition constraint_solveri.h:4074
A reversible switch that can switch once from false to true.
Definition constraint_solveri.h:398
bool Switched() const
Definition constraint_solveri.h:402
RevSwitch()
Definition constraint_solveri.h:400
void Switch(Solver *const solver)
Definition constraint_solveri.h:404
virtual void OutputLine(const std::string &line)
void AcceptUncheckedNeighbor() override
After accepting an unchecked neighbor during local search.
void EndInitialPropagation() override
After the initial propagation.
void BeginInitialPropagation() override
Before the initial propagation.
void RefuteDecision(Decision *decision) override
Before refuting the decision.
std::string DebugString() const override
void ApplyDecision(Decision *decision) override
Before applying the decision.
A search monitor is a simple set of callbacks to monitor all search events.
SearchMonitor(Solver *const s)
void operator++()
Definition constraint_solveri.h:169
Iterator(const SimpleRevFIFO< T > *l)
Definition constraint_solveri.h:165
bool ok() const
Definition constraint_solveri.h:167
T operator*() const
Definition constraint_solveri.h:168
T * MutableLast()
Definition constraint_solveri.h:208
void Push(Solver *const s, T val)
Definition constraint_solveri.h:184
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
Definition constraint_solveri.h:197
SimpleRevFIFO()
Definition constraint_solveri.h:182
void SetToZero(Solver *solver, int64_t pos)
Erases the 'pos' bit.
SmallRevBitSet(int64_t size)
void SetToOne(Solver *solver, int64_t pos)
Sets the 'pos' bit.
int64_t Cardinality() const
Returns the number of bits set to one.
int64_t GetFirstOne() const
std::function< int64_t(int64_t, int64_t, int64_t)> IndexEvaluator3
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
const std::vector< ArcId > & ComputeSortedSubDagArcs(NodeId node)
void BuildGraph(int num_nodes)
friend class SymmetryManager
Definition constraint_solveri.h:3381
bool Intersects(const std::vector< uint64_t > &mask, int *support_index)
bool RevSubtract(Solver *solver, const std::vector< uint64_t > &mask)
int64_t bit_size() const
Returns the number of bits given in the constructor of the bitset.
Definition constraint_solveri.h:4182
int ActiveWordSize() const
Definition constraint_solveri.h:4167
bool RevAnd(Solver *solver, const std::vector< uint64_t > &mask)
absl::Status Exists(absl::string_view path, Options options)
For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
LocalSearchOperator * MakeExtendedSwapActive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
--— ExtendedSwapActive --—
std::string ParameterDebugString(P param)
Definition constraint_solveri.h:539
bool IsArrayConstant(const std::vector< T > &values, const T &value)
Definition constraint_solveri.h:4199
LocalSearchOperator * RelocateAndMakeInactive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
--— RelocateAndMakeInactive --—
LocalSearchOperator * MakeTSPOpt(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, Solver::IndexEvaluator3 evaluator, int chain_length)
--— TSP-based operators --—
LocalSearchOperator * MakeCross(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, std::function< const std::vector< int > &(int, int)> get_incoming_neighbors=nullptr, std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors=nullptr)
--— Cross --—
SubDagComputer::ArcId ArcId
Demon * MakeConstraintDemon3(Solver *const s, T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
Definition constraint_solveri.h:655
LocalSearchOperator * MakeSwapActive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
--— SwapActive --—
LocalSearchOperator * ExchangeAndMakeActive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
Definition constraint_solveri.h:4229
bool AreAllStrictlyPositive(const std::vector< T > &values)
Definition constraint_solveri.h:4259
bool IsArrayBoolean(const std::vector< T > &values)
Definition constraint_solveri.h:4209
LocalSearchOperator * MakeExchange(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, std::function< const std::vector< int > &(int, int)> get_incoming_neighbors=nullptr, std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors=nullptr)
--— Exchange --—
LocalSearchOperator * MakeActiveAndRelocate(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
--— MakeActiveAndRelocate --—
bool AreAllBoundOrNull(const std::vector< IntVar * > &vars, const std::vector< T > &values)
Definition constraint_solveri.h:4315
int64_t MaxVarArray(const std::vector< IntVar * > &vars)
Definition constraint_solveri.h:4335
LocalSearchOperator * MakeTSPLns(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, Solver::IndexEvaluator3 evaluator, int tsp_size)
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Definition constraint_solveri.h:612
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
Definition constraint_solveri.h:695
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Definition constraint_solveri.h:775
ClosedInterval::Iterator end(ClosedInterval interval)
LocalSearchOperator * MakeRelocate(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, std::function< const std::vector< int > &(int, int)> get_incoming_neighbors=nullptr, std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors=nullptr, int64_t chain_length=1LL, bool single_path=false, const std::string &name="Relocate")
--— Relocate --—
VarTypes
Definition constraint_solveri.h:130
@ DOMAIN_INT_VAR
Definition constraint_solveri.h:132
@ VAR_ADD_CST
Definition constraint_solveri.h:135
@ BOOLEAN_VAR
Definition constraint_solveri.h:133
@ CST_SUB_VAR
Definition constraint_solveri.h:137
@ TRACE_VAR
Definition constraint_solveri.h:139
@ OPP_VAR
Definition constraint_solveri.h:138
@ VAR_TIMES_CST
Definition constraint_solveri.h:136
@ UNSPECIFIED
Definition constraint_solveri.h:131
@ CONST_VAR
Definition constraint_solveri.h:134
bool AreAllBoundTo(const std::vector< IntVar * > &vars, int64_t value)
Returns true if all variables are assigned to 'value'.
Definition constraint_solveri.h:4326
LocalSearchOperator * RelocateAndMakeActive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
-— RelocateAndMakeActive --—
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64_t > *const values)
Definition constraint_solveri.h:4355
bool AreAllBooleans(const std::vector< IntVar * > &vars)
Definition constraint_solveri.h:4308
LocalSearchOperator * MakePathLns(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, int number_of_chunks, int chunk_size, bool unactive_fragments)
--— Path-based Large Neighborhood Search --—
int64_t MinVarArray(const std::vector< IntVar * > &vars)
Definition constraint_solveri.h:4345
LocalSearchOperator * MakeInactive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
--— MakeInactive --—
LocalSearchOperator * MakeTwoOpt(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, std::function< const std::vector< int > &(int, int)> get_incoming_neighbors=nullptr, std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors=nullptr)
--— 2Opt --—
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
Definition constraint_solveri.h:533
std::vector< int64_t > ToInt64Vector(const std::vector< int > &input)
bool AreAllPositive(const std::vector< T > &values)
Definition constraint_solveri.h:4249
LocalSearchOperator * ExchangePathStartEndsAndMakeActive(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
Definition constraint_solveri.h:731
LocalSearchOperator * MakeSwapActiveChain(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, int max_chain_size)
--— SwapActiveChain --—
LocalSearchOperator * MakeLinKernighan(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, const Solver::IndexEvaluator3 &evaluator, bool topt)
--— Lin-Kernighan --—
LocalSearchState::VariableDomainId VariableDomainId
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
Definition constraint_solveri.h:4289
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
Definition constraint_solveri.h:574
bool AreAllOnes(const std::vector< T > &values)
Definition constraint_solveri.h:4219
bool AreAllBound(const std::vector< IntVar * > &vars)
Definition constraint_solveri.h:4299
int64_t PosIntDivUp(int64_t e, int64_t v)
Definition constraint_solveri.h:4364
SubDagComputer::NodeId NodeId
trees with all degrees equal to
static int input(yyscan_t yyscanner)
#define DEFINE_STRONG_INT_TYPE(type_name, value_type)
ConstraintId constraint_id
Definition constraint_solveri.h:2898
VariableDomainId domain_id
Definition constraint_solveri.h:2896
Set of parameters used to configure how the neighborhood is traversed.
Definition constraint_solveri.h:1532
bool accept_path_end_base
True if path ends should be considered when iterating over neighbors.
Definition constraint_solveri.h:1539
std::function< int(int64_t)> start_empty_path_class
Definition constraint_solveri.h:1550
std::function< const std::vector< int > &(int, int)> get_outgoing_neighbors
Definition constraint_solveri.h:1558
bool skip_locally_optimal_paths
Definition constraint_solveri.h:1537
int number_of_base_nodes
Number of nodes needed to define a neighbor.
Definition constraint_solveri.h:1534
std::function< const std::vector< int > &(int, int)> get_incoming_neighbors
Definition constraint_solveri.h:1555
static const int64_t kint64max
static const int64_t kint64min