49#ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
50#define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_
57#include <initializer_list>
64#include "absl/algorithm/container.h"
65#include "absl/container/flat_hash_map.h"
66#include "absl/strings/str_cat.h"
103class LocalSearchMonitor;
105class BaseIntExpr :
public IntExpr {
110 IntVar*
Var()
override;
143 enum { CHUNK_SIZE = 16 };
146 const Chunk*
const next_;
147 explicit Chunk(
const Chunk*
next) : next_(
next) {}
155 : chunk_(l->chunks_), value_(l->
Last()) {}
156 bool ok()
const {
return (value_ !=
nullptr); }
160 if (value_ == chunk_->data_ + CHUNK_SIZE) {
161 chunk_ = chunk_->next_;
162 value_ = chunk_ ? chunk_->data_ :
nullptr;
174 if (pos_.
Value() == 0) {
175 Chunk*
const chunk = s->UnsafeRevAlloc(
new Chunk(chunks_));
177 reinterpret_cast<void*
>(chunk));
182 chunks_->data_[pos_.
Value()] = val;
187 if (chunks_ ==
nullptr ||
LastValue() != val) {
194 return chunks_ ? &chunks_->data_[pos_.
Value()] :
nullptr;
197 T*
MutableLast() {
return chunks_ ? &chunks_->data_[pos_.
Value()] :
nullptr; }
202 return chunks_->data_[pos_.
Value()];
208 chunks_->data_[pos_.
Value()] = v;
231 a = (
a + 0x7ed55d16) + (
a << 12);
232 a = (
a ^ 0xc761c23c) ^ (
a >> 19);
233 a = (
a + 0x165667b1) + (
a << 5);
234 a = (
a + 0xd3a2646c) ^ (
a << 9);
235 a = (
a + 0xfd7046c5) + (
a << 3);
236 a = (
a ^ 0xb55a4f09) ^ (
a >> 16);
246inline uint64_t
Hash1(
void*
const ptr) {
247#if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
248 defined(__aarch64__) || (defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64))
249 return Hash1(
reinterpret_cast<uint64_t
>(ptr));
251 return Hash1(
reinterpret_cast<uint32_t
>(ptr));
256uint64_t
Hash1(
const std::vector<T*>& ptrs) {
257 if (ptrs.empty())
return 0;
258 if (ptrs.size() == 1)
return Hash1(ptrs[0]);
260 for (
int i = 1; i < ptrs.size(); ++i) {
266inline uint64_t
Hash1(
const std::vector<int64_t>& ptrs) {
267 if (ptrs.empty())
return 0;
268 if (ptrs.size() == 1)
return Hash1(ptrs[0]);
270 for (
int i = 1; i < ptrs.size(); ++i) {
278template <
class K,
class V>
279class RevImmutableMultiMap {
283 array_(solver->UnsafeRevAllocArray(
new Cell*[initial_size])),
286 memset(array_, 0,
sizeof(*array_) * size_.
Value());
296 Cell* tmp = array_[code];
298 if (tmp->key() == key) {
311 Cell* tmp = array_[code];
313 if (tmp->key() == key) {
318 return default_value;
323 const int position =
Hash1(key) % size_.
Value();
325 solver_->UnsafeRevAlloc(
new Cell(key,
value, array_[position]));
327 reinterpret_cast<void*
>(cell));
328 num_items_.
Incr(solver_);
337 Cell(
const K& key,
const V& value, Cell*
const next)
338 : key_(key), value_(
value), next_(
next) {}
340 void SetRevNext(Solver*
const solver, Cell*
const next) {
341 solver->SaveAndSetValue(
reinterpret_cast<void**
>(&next_),
342 reinterpret_cast<void*
>(next));
345 Cell*
next()
const {
return next_; }
347 const K& key()
const {
return key_; }
349 const V&
value()
const {
return value_; }
358 Cell**
const old_cell_array = array_;
359 const int old_size = size_.
Value();
362 reinterpret_cast<void**
>(&array_),
363 reinterpret_cast<void*
>(
364 solver_->UnsafeRevAllocArray(
new Cell*[size_.
Value()])));
365 memset(array_, 0, size_.
Value() *
sizeof(*array_));
366 for (
int i = 0;
i < old_size; ++
i) {
367 Cell* tmp = old_cell_array[
i];
368 while (tmp !=
nullptr) {
369 Cell*
const to_reinsert = tmp;
371 const uint64_t new_position =
Hash1(to_reinsert->key()) % size_.
Value();
372 to_reinsert->SetRevNext(solver_, array_[new_position]);
374 reinterpret_cast<void**
>(&array_[new_position]),
375 reinterpret_cast<void*
>(to_reinsert));
380 Solver*
const solver_;
382 NumericalRev<int> size_;
383 NumericalRev<int> num_items_;
391 bool Switched()
const {
return value_; }
393 void Switch(Solver*
const solver) { solver->SaveAndSetValue(&value_,
true); }
453 void Save(
Solver* solver,
int offset);
455 const int64_t length_;
473 DCHECK_LT(
row, rows_);
475 DCHECK_LT(
column, columns_);
492 const int64_t columns_;
503class CallMethod0 :
public Demon {
506 : constraint_(
ct), method_(method), name_(
name) {}
510 void Run(
Solver*
const s)
override { (constraint_->*method_)(); }
513 return "CallMethod_" + name_ +
"(" + constraint_->DebugString() +
")";
517 T*
const constraint_;
518 void (T::*
const method_)();
519 const std::string name_;
524 const std::string&
name) {
530 return absl::StrCat(param);
536 return param->DebugString();
540template <
class T,
class P>
541class CallMethod1 :
public Demon {
545 : constraint_(
ct), method_(method), name_(
name), param1_(param1) {}
549 void Run(
Solver*
const s)
override { (constraint_->*method_)(param1_); }
552 return absl::StrCat(
"CallMethod_", name_,
"(", constraint_->DebugString(),
557 T*
const constraint_;
558 void (T::*
const method_)(P);
559 const std::string name_;
563template <
class T,
class P>
565 const std::string&
name, P param1) {
570template <
class T,
class P,
class Q>
584 (constraint_->*method_)(param1_, param2_);
588 return absl::StrCat(absl::StrCat(
"CallMethod_", name_),
589 absl::StrCat(
"(", constraint_->DebugString()),
595 T*
const constraint_;
596 void (T::*
const method_)(P, Q);
597 const std::string name_;
602template <
class T,
class P,
class Q>
604 void (T::*method)(P, Q),
const std::string&
name,
605 P param1, Q param2) {
610template <
class T,
class P,
class Q,
class R>
614 P param1, Q param2, R param3)
624 void Run(Solver*
const s)
override {
625 (constraint_->*method_)(param1_, param2_, param3_);
629 return absl::StrCat(absl::StrCat(
"CallMethod_", name_),
630 absl::StrCat(
"(", constraint_->DebugString()),
637 T*
const constraint_;
638 void (T::*
const method_)(P, Q, R);
639 const std::string name_;
645template <
class T,
class P,
class Q,
class R>
647 void (T::*method)(P, Q, R),
const std::string&
name,
648 P param1, Q param2, R param3) {
664 : constraint_(
ct), method_(method), name_(
name) {}
668 void Run(
Solver*
const s)
override { (constraint_->*method_)(); }
675 return "DelayedCallMethod_" + name_ +
"(" + constraint_->DebugString() +
680 T*
const constraint_;
681 void (T::*
const method_)();
682 const std::string name_;
688 const std::string&
name) {
693template <
class T,
class P>
698 : constraint_(
ct), method_(method), name_(
name), param1_(param1) {}
702 void Run(
Solver*
const s)
override { (constraint_->*method_)(param1_); }
709 return absl::StrCat(
"DelayedCallMethod_", name_,
"(",
710 constraint_->DebugString(),
", ",
715 T*
const constraint_;
716 void (T::*
const method_)(P);
717 const std::string name_;
721template <
class T,
class P>
723 void (T::*method)(P),
724 const std::string&
name, P param1) {
729template <
class T,
class P,
class Q>
733 const std::string&
name, P param1, Q param2)
743 (constraint_->*method_)(param1_, param2_);
751 return absl::StrCat(absl::StrCat(
"DelayedCallMethod_", name_),
752 absl::StrCat(
"(", constraint_->DebugString()),
758 T*
const constraint_;
759 void (T::*
const method_)(P, Q);
760 const std::string name_;
765template <
class T,
class P,
class Q>
767 void (T::*method)(P, Q),
768 const std::string&
name, P param1,
780class LightIntFunctionElementCt :
public Constraint {
783 IntVar*
const index, F values,
784 std::function<
bool()> deep_serialize)
788 values_(
std::move(values)),
789 deep_serialize_(
std::move(deep_serialize)) {}
792 void Post()
override {
794 solver(),
this, &LightIntFunctionElementCt::IndexBound,
"IndexBound");
805 return absl::StrFormat(
"LightIntFunctionElementCt(%s, %s)",
816 if (deep_serialize_ ==
nullptr || deep_serialize_()) {
824 void IndexBound() { var_->
SetValue(values_(index_->
Min())); }
827 IntVar*
const index_;
829 std::function<bool()> deep_serialize_;
835class LightIntIntFunctionElementCt :
public Constraint {
838 IntVar*
const index1, IntVar*
const index2,
839 F values, std::function<
bool()> deep_serialize)
844 values_(
std::move(values)),
845 deep_serialize_(
std::move(deep_serialize)) {}
847 void Post()
override {
849 solver(),
this, &LightIntIntFunctionElementCt::IndexBound,
857 return "LightIntIntFunctionElementCt";
860 void Accept(ModelVisitor*
const visitor)
const override {
869 const int64_t index1_min = index1_->
Min();
870 const int64_t index1_max = index1_->
Max();
873 if (deep_serialize_ ==
nullptr || deep_serialize_()) {
874 for (
int i = index1_min; i <= index1_max; ++i) {
875 visitor->VisitInt64ToInt64Extension(
876 [
this, i](int64_t j) {
return values_(i, j); }, index2_->
Min(),
891 IntVar*
const index1_;
892 IntVar*
const index2_;
894 std::function<bool()> deep_serialize_;
916class LocalSearchOperator :
public BaseObject {
921 virtual void Start(
const Assignment* assignment) = 0;
922 virtual void Reset() {}
935 max_inversible_index_ = candidate_values_.size();
936 candidate_value_to_index_.resize(max_value + 1, -1);
937 committed_value_to_index_.resize(max_value + 1, -1);
943 DCHECK_LT(
index, candidate_values_.size());
944 return candidate_values_[
index];
947 return committed_values_[
index];
950 return checkpoint_values_[
index];
954 if (
index < max_inversible_index_) {
961 return candidate_is_active_[
index];
976 if (
index < max_inversible_index_) {
985 void CheckPoint() { checkpoint_values_ = committed_values_; }
987 void Revert(
bool only_incremental) {
989 if (only_incremental)
return;
992 const int64_t committed_value = committed_values_[
index];
993 candidate_values_[
index] = committed_value;
994 if (
index < max_inversible_index_) {
995 candidate_value_to_index_[committed_value] =
index;
1010 candidate_values_.resize(
size);
1011 committed_values_.resize(
size);
1012 checkpoint_values_.resize(
size);
1020 return candidate_value_to_index_[
value];
1023 return committed_value_to_index_[
value];
1027 void MarkChange(int64_t
index) {
1032 std::vector<int64_t> candidate_values_;
1033 std::vector<int64_t> committed_values_;
1034 std::vector<int64_t> checkpoint_values_;
1042 int64_t max_inversible_index_ = -1;
1043 std::vector<int64_t> candidate_value_to_index_;
1044 std::vector<int64_t> committed_value_to_index_;
1058 bool keep_inverse_values =
false) {
1060 if (keep_inverse_values) {
1061 int64_t max_value = -1;
1063 max_value = std::max(max_value,
var->Max());
1070 bool HoldsDelta()
const override {
return true; }
1073 void Start(
const Assignment* assignment)
override {
1077 CHECK_LE(
size, assignment->Size())
1078 <<
"Assignment contains fewer variables than operator";
1080 for (
int i = 0; i <
size; ++i) {
1082 if (element->
Var() != vars_[i]) {
1083 CHECK(container.
Contains(vars_[i]))
1084 <<
"Assignment does not contain operator variable " << vars_[i];
1085 element = &(container.
Element(vars_[i]));
1095 int Size()
const {
return vars_.size(); }
1099 DCHECK_LT(
index, vars_.size());
1143 candidate_has_changes_ = change_was_incremental &&
IsIncremental();
1145 if (!candidate_has_changes_) {
1147 assignment_indices_[
index] = -1;
1150 state_.
Revert(candidate_has_changes_);
1154 if (!vars.empty()) {
1155 vars_.insert(vars_.end(), vars.begin(), vars.end());
1157 assignment_indices_.resize(
size, -1);
1193 std::vector<int>* assignment_indices, int64_t
index,
1194 Assignment* assignment)
const {
1196 assignment->MutableIntVarContainer();
1198 if (assignment_indices !=
nullptr) {
1199 if ((*assignment_indices)[
index] == -1) {
1200 (*assignment_indices)[
index] = container->Size();
1201 element = assignment->FastAdd(
var);
1203 element = container->MutableElement((*assignment_indices)[
index]);
1206 element = assignment->FastAdd(
var);
1217 std::vector<IntVar*> vars_;
1218 mutable std::vector<int> assignment_indices_;
1219 bool candidate_has_changes_ =
false;
1221 LocalSearchOperatorState state_;
1251class BaseLns :
public IntVarLocalSearchOperator {
1253 explicit BaseLns(
const std::vector<IntVar*>& vars);
1267 void OnStart()
override;
1268 std::vector<int> fragment_;
1277 explicit ChangeValue(
const std::vector<IntVar*>& vars);
1286 void OnStart()
override;
1307 struct IterationParameters {
1327 std::function<const std::vector<int>&(int, int)>
1332 const std::vector<IntVar*>& path_vars,
1335 const std::vector<IntVar*>& path_vars,
int number_of_base_nodes,
1336 bool skip_locally_optimal_paths,
bool accept_path_end_base,
1337 std::function<
int(int64_t)> start_empty_path_class,
1338 std::function<
const std::vector<int>&(
int,
int)> get_neighbors)
1340 {number_of_base_nodes, skip_locally_optimal_paths,
1341 accept_path_end_base, std::move(start_empty_path_class),
1342 std::move(get_neighbors)}) {}
1345 void Reset()
override;
1351 int64_t
Next(int64_t node)
const {
1381 int64_t
BaseNode(
int i)
const {
return base_nodes_[i]; }
1387 const int alternative_index = alternative_index_[
BaseNode(i)];
1388 return alternative_index >= 0
1389 ? alternative_sets_[alternative_index][base_alternatives_[i]]
1394 return base_sibling_alternatives_[
i];
1399 const int sibling_alternative_index =
1401 return sibling_alternative_index >= 0
1402 ? alternative_sets_[sibling_alternative_index]
1403 [base_sibling_alternatives_[i]]
1407 int64_t
StartNode(
int i)
const {
return path_starts_[base_paths_[i]]; }
1409 int64_t
EndNode(
int i)
const {
return path_ends_[base_paths_[i]]; }
1411 const std::vector<int64_t>&
path_starts()
const {
return path_starts_; }
1446 next_base_to_increment_ = base_index;
1452 int64_t
OldNext(int64_t node)
const {
1457 int64_t
PrevNext(int64_t node)
const {
1462 int64_t
OldPrev(int64_t node)
const {
1467 int64_t
OldPath(int64_t node)
const {
1472 return node_path_starts_[node];
1479 bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination);
1483 bool ReverseChain(int64_t before_chain, int64_t after_chain,
1484 int64_t* chain_last);
1487 bool MakeActive(int64_t node, int64_t destination);
1495 void SetNext(int64_t from, int64_t
to, int64_t path) {
1513 return !
IsPathEnd(node) && inactives_[node];
1528 const int alternative = alternative_sets_.size();
1529 for (int64_t node : alternative_set) {
1530 DCHECK_EQ(-1, alternative_index_[node]);
1531 alternative_index_[node] = alternative;
1533 alternative_sets_.push_back(alternative_set);
1534 sibling_alternative_.push_back(-1);
1540 template <
typename PairType>
1542 const std::vector<PairType>& pair_alternative_sets) {
1543 for (
const auto& [alternative_set, sibling_alternative_set] :
1544 pair_alternative_sets) {
1551 int64_t GetActiveInAlternativeSet(int alternative_index) const {
1552 return alternative_index >= 0
1553 ? active_in_alternative_set_[alternative_index]
1557 int64_t GetActiveAlternativeNode(
int node)
const {
1558 return GetActiveInAlternativeSet(alternative_index_[node]);
1561 int GetSiblingAlternativeIndex(
int node)
const {
1562 if (node >= alternative_index_.size())
return -1;
1563 const int alternative = alternative_index_[node];
1564 return alternative >= 0 ? sibling_alternative_[alternative] : -1;
1568 int64_t GetActiveAlternativeSibling(
int node)
const {
1569 if (node >= alternative_index_.size())
return -1;
1570 const int alternative = alternative_index_[node];
1571 const int sibling_alternative =
1572 alternative >= 0 ? sibling_alternative_[alternative] : -1;
1573 return GetActiveInAlternativeSet(sibling_alternative);
1577 bool CheckChainValidity(int64_t before_chain, int64_t chain_end,
1578 int64_t exclude)
const;
1580 bool HasNeighbors()
const {
1581 return iteration_parameters_.get_neighbors !=
nullptr;
1584 int GetNeighborForBaseNode(int64_t base_index)
const {
1585 DCHECK(HasNeighbors());
1586 return iteration_parameters_.get_neighbors(
1587 BaseNode(base_index),
1588 StartNode(base_index))[calls_per_base_node_[base_index]];
1591 const int number_of_nexts_;
1592 const bool ignore_path_vars_;
1595 void OnStart()
override;
1597 bool OnSamePath(int64_t node1, int64_t node2)
const;
1599 bool CheckEnds()
const {
1600 const int base_node_size = base_nodes_.size();
1601 for (
int i = base_node_size - 1; i >= 0; --i) {
1602 if (base_nodes_[i] != end_nodes_[i] || calls_per_base_node_[0] > 0) {
1608 bool IncrementPosition();
1609 void InitializePathStarts();
1610 void InitializeInactives();
1611 void InitializeBaseNodes();
1612 void InitializeAlternatives();
1617 explicit ActivePaths(
int num_nodes) : start_to_path_(num_nodes, -1) {}
1618 void Clear() { is_path_pair_active_.clear(); }
1619 template <
typename T>
1620 void Initialize(T is_start) {
1621 if (is_path_pair_active_.empty()) {
1623 absl::c_fill(start_to_path_, -1);
1624 for (
int i = 0;
i < start_to_path_.size(); ++
i) {
1626 start_to_path_[
i] = num_paths_;
1630 is_path_pair_active_.resize(num_paths_ * num_paths_,
true);
1633 void DeactivatePathPair(
int start1,
int start2) {
1634 is_path_pair_active_[start_to_path_[start1] * num_paths_ +
1635 start_to_path_[start2]] =
false;
1637 void ActivatePath(
int start) {
1638 const int p1 = start_to_path_[
start];
1639 const int p1_block = num_paths_ * p1;
1640 for (
int p2 = 0; p2 < num_paths_; ++p2) {
1641 is_path_pair_active_[p1_block + p2] =
true;
1643 for (
int p2_block = 0; p2_block < is_path_pair_active_.size();
1644 p2_block += num_paths_) {
1645 is_path_pair_active_[p2_block + p1] =
true;
1648 bool IsPathPairActive(
int start1,
int start2)
const {
1649 return is_path_pair_active_[start_to_path_[start1] * num_paths_ +
1650 start_to_path_[start2]];
1655 std::vector<int64_t> start_to_path_;
1656 std::vector<bool> is_path_pair_active_;
1659 std::vector<int> base_nodes_;
1660 std::vector<int> base_alternatives_;
1661 std::vector<int> base_sibling_alternatives_;
1662 std::vector<int> end_nodes_;
1663 std::vector<int> base_paths_;
1664 std::vector<int> node_path_starts_;
1665 std::vector<int> node_path_ends_;
1666 std::vector<int> calls_per_base_node_;
1667 std::vector<int64_t> path_starts_;
1668 std::vector<int64_t> path_ends_;
1669 std::vector<bool> inactives_;
1672 int next_base_to_increment_;
1673 IterationParameters iteration_parameters_;
1674 bool optimal_paths_enabled_;
1675 std::vector<int> path_basis_;
1676 ActivePaths active_paths_;
1679 std::vector<std::vector<int64_t>> alternative_sets_;
1681 std::vector<int> alternative_index_;
1682 std::vector<int64_t> active_in_alternative_set_;
1683 std::vector<int> sibling_alternative_;
1689 Solver* solver,
const std::vector<IntVar*>& vars,
1690 const std::vector<IntVar*>& secondary_vars,
1691 std::function<
int(int64_t)> start_empty_path_class);
1695 Solver* solver,
const std::vector<IntVar*>& vars,
1696 const std::vector<IntVar*>& secondary_vars,
1697 std::function<
int(int64_t)> start_empty_path_class,
1698 std::function<
const std::vector<int>&(
int,
int)> get_neighbors);
1732class SubDagComputer {
1736 SubDagComputer() =
default;
1741 DCHECK(!graph_was_built_);
1742 num_nodes_ = std::max(num_nodes_, std::max(
tail.value(),
head.value()) + 1);
1743 const ArcId arc_id(arcs_.size());
1744 arcs_.push_back({.tail =
tail, .head =
head, .arc_id = arc_id});
1749 void BuildGraph(
int num_nodes);
1752 const std::vector<ArcId>& ComputeSortedSubDagArcs(
NodeId node);
1757 bool HasDirectedCycle()
const;
1763 bool operator<(
const Arc& other)
const {
1764 return std::tie(
tail, arc_id) < std::tie(other.tail, other.arc_id);
1768 std::vector<Arc> arcs_;
1774 bool graph_was_built_ =
false;
1778 std::vector<NodeId> nodes_to_visit_;
1780 std::vector<ArcId> sorted_arcs_;
1794class LocalSearchState {
1800 VariableDomainId AddVariableDomain(int64_t relaxed_min, int64_t relaxed_max);
1801 void RelaxVariableDomain(VariableDomainId domain_id);
1802 bool TightenVariableDomainMin(VariableDomainId domain_id, int64_t
value);
1803 bool TightenVariableDomainMax(VariableDomainId domain_id, int64_t
value);
1804 int64_t VariableDomainMin(VariableDomainId domain_id)
const;
1805 int64_t VariableDomainMax(VariableDomainId domain_id)
const;
1806 void ChangeRelaxedVariableDomain(VariableDomainId domain_id, int64_t
min,
1818 bool StateIsFeasible()
const {
1819 return state_domains_are_all_nonempty_ && num_committed_empty_domains_ == 0;
1822 void AddWeightedSumConstraint(
1823 const std::vector<VariableDomainId>& input_domain_ids,
1824 const std::vector<int64_t>& input_weights, int64_t input_offset,
1828 void CompileConstraints();
1834 struct VariableDomain {
1838 bool IntersectionIsEmpty(
const VariableDomain& d1,
1839 const VariableDomain& d2)
const {
1840 return d1.max < d2.min || d2.max < d1.min;
1844 struct TrailedVariableDomain {
1845 VariableDomain committed_domain;
1846 VariableDomainId domain_id;
1848 std::vector<TrailedVariableDomain> trailed_domains_;
1851 bool state_domains_are_all_nonempty_ =
true;
1852 bool state_has_relaxed_domains_ =
false;
1855 int num_committed_empty_domains_ = 0;
1856 int trailed_num_committed_empty_domains_ = 0;
1861 void TrailConstraint(Constraint* constraint) {
1862 trailed_constraints_.
push_back(constraint);
1864 std::vector<Constraint*> trailed_constraints_;
1868 class DependencyGraph {
1870 DependencyGraph() {}
1879 ConstraintId constraint_id;
1882 void AddDomainsConstraintDependencies(
1883 const std::vector<VariableDomainId>& domain_ids,
1884 ConstraintId constraint_id);
1886 void AddConstraintDomainDependency(ConstraintId constraint_id,
1887 VariableDomainId domain_id);
1890 void BuildDependencyDAG(
int num_domains);
1894 const std::vector<Dependency>& ComputeSortedDependencies(
1898 using ArcId = SubDagComputer::ArcId;
1899 using NodeId = SubDagComputer::NodeId;
1906 NodeId GetOrCreateNodeOfConstraintId(ConstraintId constraint_id);
1917 int num_dag_nodes_ = 1;
1919 std::vector<Dependency> sorted_dependencies_;
1921 DependencyGraph dependency_graph_;
1927 Constraint* constraint;
1933 std::vector<Trigger> triggers_;
1941 virtual ~Constraint() =
default;
1942 virtual LocalSearchState::VariableDomain Propagate(
int input_index) = 0;
1944 virtual void Commit() = 0;
1945 virtual void Revert() = 0;
1949 class WeightedSum final :
public Constraint {
1952 const std::vector<VariableDomainId>& input_domain_ids,
1953 const std::vector<int64_t>& input_weights, int64_t input_offset,
1955 ~WeightedSum()
override =
default;
1956 LocalSearchState::VariableDomain Propagate(
int input_index)
override;
1957 void Commit()
override;
1958 void Revert()
override;
1964 struct WeightedVariable {
1967 int64_t committed_min;
1968 int64_t committed_max;
1970 VariableDomainId domain;
1973 committed_min =
min;
1974 committed_max =
max;
1978 min = committed_min;
1979 max = committed_max;
1983 std::vector<WeightedVariable> inputs_;
1984 std::vector<WeightedVariable*> trailed_inputs_;
1988 int64_t num_neg_inf;
1992 int64_t num_pos_inf;
1996 Invariants invariants_;
1997 Invariants committed_invariants_;
2000 LocalSearchState*
const state_;
2001 bool constraint_is_trailed_ =
false;
2012class LocalSearchState::Variable {
2014 int64_t Min()
const {
return state_->VariableDomainMin(domain_id_); }
2015 int64_t Max()
const {
return state_->VariableDomainMax(domain_id_); }
2016 bool SetMin(int64_t new_min) {
2017 return state_->TightenVariableDomainMin(domain_id_, new_min) &&
2018 state_->PropagateTighten(domain_id_);
2020 bool SetMax(int64_t new_max) {
2021 return state_->TightenVariableDomainMax(domain_id_, new_max) &&
2022 state_->PropagateTighten(domain_id_);
2025 state_->RelaxVariableDomain(domain_id_);
2026 state_->PropagateRelax(domain_id_);
2034 : state_(state), domain_id_(domain_id) {}
2074 virtual bool Accept(
const Assignment*
delta,
const Assignment* deltadelta,
2075 int64_t objective_min, int64_t objective_max) = 0;
2076 virtual bool IsIncremental()
const {
return false; }
2083 virtual void Synchronize(
const Assignment* assignment,
2086 virtual void Revert() {}
2089 virtual void Reset() {}
2092 virtual int64_t GetSynchronizedObjectiveValue()
const {
return 0LL; }
2095 virtual int64_t GetAcceptedObjectiveValue()
const {
return 0LL; }
2105 enum FilterEventType { kAccept, kRelax };
2106 struct FilterEvent {
2108 FilterEventType event_type;
2112 std::string DebugString()
const override {
2113 return "LocalSearchFilterManager";
2129 const Assignment* deltadelta, int64_t objective_min,
2130 int64_t objective_max);
2133 int64_t GetSynchronizedObjectiveValue()
const {
return synchronized_value_; }
2134 int64_t GetAcceptedObjectiveValue()
const {
return accepted_value_; }
2139 void FindIncrementalEventEnd();
2141 std::vector<FilterEvent> events_;
2142 int last_event_called_ = -1;
2147 int incremental_events_end_ = 0;
2148 int64_t synchronized_value_;
2149 int64_t accepted_value_;
2158 void Synchronize(
const Assignment* assignment,
2162 DCHECK(
index !=
nullptr);
2167 return *
index != kUnassigned;
2171 void AddVars(
const std::vector<IntVar*>& vars);
2172 int Size()
const {
return vars_.size(); }
2176 return values_[
index];
2178 bool IsVarSynced(
int index)
const {
return var_synced_[
index]; }
2181 virtual void OnSynchronize(
const Assignment*
delta) {}
2182 void SynchronizeOnAssignment(
const Assignment* assignment);
2185 std::vector<IntVar*>
vars_;
2186 std::vector<int64_t> values_;
2187 std::vector<bool> var_synced_;
2188 std::vector<int> var_index_to_index_;
2189 static const int kUnassigned;
2196 std::string DebugString()
const override {
return "PropagationMonitor"; }
2199 virtual void BeginConstraintInitialPropagation(
Constraint* constraint) = 0;
2200 virtual void EndConstraintInitialPropagation(
Constraint* constraint) = 0;
2201 virtual void BeginNestedConstraintInitialPropagation(
Constraint* parent,
2203 virtual void EndNestedConstraintInitialPropagation(
Constraint* parent,
2206 virtual void BeginDemonRun(
Demon* demon) = 0;
2207 virtual void EndDemonRun(
Demon* demon) = 0;
2208 virtual void StartProcessingIntegerVariable(
IntVar*
var) = 0;
2209 virtual void EndProcessingIntegerVariable(
IntVar*
var) = 0;
2210 virtual void PushContext(
const std::string&
context) = 0;
2211 virtual void PopContext() = 0;
2213 virtual void SetMin(
IntExpr* expr, int64_t new_min) = 0;
2214 virtual void SetMax(
IntExpr* expr, int64_t new_max) = 0;
2215 virtual void SetRange(
IntExpr* expr, int64_t new_min, int64_t new_max) = 0;
2218 virtual void SetMax(
IntVar*
var, int64_t new_max) = 0;
2219 virtual void SetRange(
IntVar*
var, int64_t new_min, int64_t new_max) = 0;
2222 virtual void RemoveInterval(
IntVar*
var, int64_t imin, int64_t imax) = 0;
2223 virtual void SetValues(
IntVar*
var,
const std::vector<int64_t>& values) = 0;
2225 const std::vector<int64_t>& values) = 0;
2230 int64_t new_max) = 0;
2234 int64_t new_max) = 0;
2238 int64_t new_max) = 0;
2246 const std::vector<int>& rank_first,
2247 const std::vector<int>& rank_last,
2248 const std::vector<int>& unperformed) = 0;
2250 void Install()
override;
2258 std::string DebugString()
const override {
return "LocalSearchMonitor"; }
2261 virtual void BeginOperatorStart() = 0;
2262 virtual void EndOperatorStart() = 0;
2269 bool neighbor_found) = 0;
2272 bool neighbor_found) = 0;
2276 virtual bool IsActive()
const = 0;
2279 void Install()
override;
2284 static const int kUnboundBooleanVarValue;
2291 int64_t Min()
const override {
return (value_ == 1); }
2292 void SetMin(int64_t m)
override;
2293 int64_t Max()
const override {
return (value_ != 0); }
2294 void SetMax(int64_t m)
override;
2295 void SetRange(int64_t mi, int64_t ma)
override;
2296 bool Bound()
const override {
return (value_ != kUnboundBooleanVarValue); }
2297 int64_t Value()
const override {
2298 CHECK_NE(value_, kUnboundBooleanVarValue) <<
"variable is not bound";
2301 void RemoveValue(int64_t v)
override;
2302 void RemoveInterval(int64_t l, int64_t u)
override;
2304 void WhenRange(
Demon* d)
override { WhenBound(d); }
2305 void WhenDomain(
Demon* d)
override { WhenBound(d); }
2306 uint64_t Size()
const override;
2307 bool Contains(int64_t v)
const override;
2308 IntVarIterator* MakeHoleIterator(
bool reversible)
const override;
2309 IntVarIterator* MakeDomainIterator(
bool reversible)
const override;
2310 std::string DebugString()
const override;
2313 IntVar* IsEqual(int64_t constant)
override;
2314 IntVar* IsDifferent(int64_t constant)
override;
2315 IntVar* IsGreaterOrEqual(int64_t constant)
override;
2316 IntVar* IsLessOrEqual(int64_t constant)
override;
2318 virtual void RestoreValue() = 0;
2319 std::string BaseName()
const override {
return "BooleanVar"; }
2321 int RawValue()
const {
return value_; }
2337 : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {}
2341 void AddIntegerVariableGreaterOrEqualValueClause(
IntVar*
var, int64_t
value);
2342 void AddIntegerVariableLessOrEqualValueClause(
IntVar*
var, int64_t
value);
2347 CHECK(symmetry_manager_ ==
nullptr);
2348 CHECK_EQ(-1, index_in_symmetry_manager_);
2349 symmetry_manager_ = manager;
2353 int index_in_symmetry_manager()
const {
return index_in_symmetry_manager_; }
2355 SymmetryManager* symmetry_manager_;
2357 int index_in_symmetry_manager_;
2364 SearchLog(
Solver* solver, std::vector<IntVar*> vars, std::string vars_name,
2365 std::vector<double> scaling_factors, std::vector<double> offsets,
2366 std::function<std::string()> display_callback,
2367 bool display_on_new_solutions_only,
int period);
2369 void EnterSearch()
override;
2370 void ExitSearch()
override;
2371 bool AtSolution()
override;
2372 void BeginFail()
override;
2373 void NoMoreSolutions()
override;
2375 void ApplyDecision(
Decision* decision)
override;
2377 void OutputDecision();
2379 void BeginInitialPropagation()
override;
2380 void EndInitialPropagation()
override;
2381 std::string DebugString()
const override;
2385 virtual void OutputLine(
const std::string&
line);
2391 std::unique_ptr<WallTimer> timer_;
2392 const std::vector<IntVar*>
vars_;
2393 const std::string vars_name_;
2394 const std::vector<double> scaling_factors_;
2395 const std::vector<double> offsets_;
2396 std::function<std::string()> display_callback_;
2397 const bool display_on_new_solutions_only_;
2400 std::vector<int64_t> objective_min_;
2401 std::vector<int64_t> objective_max_;
2402 int min_right_depth_;
2404 int sliding_min_depth_;
2405 int sliding_max_depth_;
2406 int neighbors_offset_ = 0;
2415 enum VoidConstraintType {
2416 VOID_FALSE_CONSTRAINT = 0,
2417 VOID_TRUE_CONSTRAINT,
2418 VOID_CONSTRAINT_MAX,
2421 enum VarConstantConstraintType {
2422 VAR_CONSTANT_EQUALITY = 0,
2423 VAR_CONSTANT_GREATER_OR_EQUAL,
2424 VAR_CONSTANT_LESS_OR_EQUAL,
2425 VAR_CONSTANT_NON_EQUALITY,
2426 VAR_CONSTANT_CONSTRAINT_MAX,
2430 VAR_CONSTANT_CONSTANT_BETWEEN = 0,
2431 VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX,
2434 enum ExprExprConstraintType {
2435 EXPR_EXPR_EQUALITY = 0,
2437 EXPR_EXPR_GREATER_OR_EQUAL,
2439 EXPR_EXPR_LESS_OR_EQUAL,
2440 EXPR_EXPR_NON_EQUALITY,
2441 EXPR_EXPR_CONSTRAINT_MAX,
2448 EXPR_EXPRESSION_MAX,
2452 EXPR_EXPR_DIFFERENCE = 0,
2459 EXPR_EXPR_IS_LESS_OR_EQUAL,
2461 EXPR_EXPR_IS_NOT_EQUAL,
2462 EXPR_EXPR_EXPRESSION_MAX,
2466 EXPR_EXPR_CONSTANT_CONDITIONAL = 0,
2467 EXPR_EXPR_CONSTANT_EXPRESSION_MAX,
2471 EXPR_CONSTANT_DIFFERENCE = 0,
2472 EXPR_CONSTANT_DIVIDE,
2477 EXPR_CONSTANT_IS_EQUAL,
2478 EXPR_CONSTANT_IS_NOT_EQUAL,
2479 EXPR_CONSTANT_IS_GREATER_OR_EQUAL,
2480 EXPR_CONSTANT_IS_LESS_OR_EQUAL,
2481 EXPR_CONSTANT_EXPRESSION_MAX,
2483 enum VarConstantConstantExpressionType {
2484 VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS = 0,
2485 VAR_CONSTANT_CONSTANT_EXPRESSION_MAX,
2489 VAR_CONSTANT_ARRAY_ELEMENT = 0,
2490 VAR_CONSTANT_ARRAY_EXPRESSION_MAX,
2494 VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD = 0,
2495 VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX,
2502 VAR_ARRAY_EXPRESSION_MAX,
2506 VAR_ARRAY_CONSTANT_INDEX = 0,
2507 VAR_ARRAY_CONSTANT_EXPRESSION_MAX,
2513 virtual void Clear() = 0;
2523 virtual Constraint* FindVarConstantConstraint(
2532 virtual Constraint* FindVarConstantConstantConstraint(
2536 virtual void InsertVarConstantConstantConstraint(
2554 virtual void InsertExprExpression(
IntExpr* expression,
IntExpr* expr,
2562 virtual void InsertExprConstantExpression(
2571 virtual void InsertExprExprExpression(
IntExpr* expression,
IntExpr* var1,
2577 virtual IntExpr* FindExprExprConstantExpression(
2581 virtual void InsertExprExprConstantExpression(
2587 virtual IntExpr* FindVarConstantConstantExpression(
2588 IntVar*
var, int64_t value1, int64_t value2,
2591 virtual void InsertVarConstantConstantExpression(
2597 virtual IntExpr* FindVarConstantArrayExpression(
2598 IntVar*
var,
const std::vector<int64_t>& values,
2601 virtual void InsertVarConstantArrayExpression(
2607 virtual IntExpr* FindVarArrayExpression(
2610 virtual void InsertVarArrayExpression(
IntExpr* expression,
2611 const std::vector<IntVar*>& vars,
2616 virtual IntExpr* FindVarArrayConstantArrayExpression(
2617 const std::vector<IntVar*>& vars,
const std::vector<int64_t>& values,
2620 virtual void InsertVarArrayConstantArrayExpression(
2622 const std::vector<int64_t>& values,
2627 virtual IntExpr* FindVarArrayConstantExpression(
2628 const std::vector<IntVar*>& vars, int64_t
value,
2631 virtual void InsertVarArrayConstantExpression(
2646 const std::string& TypeName()
const;
2647 void SetTypeName(
const std::string& type_name);
2650 void SetIntegerArgument(
const std::string& arg_name, int64_t
value);
2651 void SetIntegerArrayArgument(
const std::string& arg_name,
2652 const std::vector<int64_t>& values);
2653 void SetIntegerMatrixArgument(
const std::string& arg_name,
2655 void SetIntegerExpressionArgument(
const std::string& arg_name,
IntExpr* expr);
2656 void SetIntegerVariableArrayArgument(
const std::string& arg_name,
2657 const std::vector<IntVar*>& vars);
2658 void SetIntervalArgument(
const std::string& arg_name,
IntervalVar*
var);
2659 void SetIntervalArrayArgument(
const std::string& arg_name,
2660 const std::vector<IntervalVar*>& vars);
2661 void SetSequenceArgument(
const std::string& arg_name,
SequenceVar*
var);
2662 void SetSequenceArrayArgument(
const std::string& arg_name,
2663 const std::vector<SequenceVar*>& vars);
2666 bool HasIntegerExpressionArgument(
const std::string& arg_name)
const;
2667 bool HasIntegerVariableArrayArgument(
const std::string& arg_name)
const;
2670 int64_t FindIntegerArgumentWithDefault(
const std::string& arg_name,
2672 int64_t FindIntegerArgumentOrDie(
const std::string& arg_name)
const;
2673 const std::vector<int64_t>& FindIntegerArrayArgumentOrDie(
2674 const std::string& arg_name)
const;
2675 const IntTupleSet& FindIntegerMatrixArgumentOrDie(
2676 const std::string& arg_name)
const;
2678 IntExpr* FindIntegerExpressionArgumentOrDie(
2679 const std::string& arg_name)
const;
2680 const std::vector<IntVar*>& FindIntegerVariableArrayArgumentOrDie(
2681 const std::string& arg_name)
const;
2684 std::string type_name_;
2685 absl::flat_hash_map<std::string, int64_t> integer_argument_;
2686 absl::flat_hash_map<std::string, std::vector<int64_t>>
2687 integer_array_argument_;
2688 absl::flat_hash_map<std::string, IntTupleSet> matrix_argument_;
2689 absl::flat_hash_map<std::string, IntExpr*> integer_expression_argument_;
2690 absl::flat_hash_map<std::string, IntervalVar*> interval_argument_;
2691 absl::flat_hash_map<std::string, SequenceVar*> sequence_argument_;
2692 absl::flat_hash_map<std::string, std::vector<IntVar*>>
2693 integer_variable_array_argument_;
2694 absl::flat_hash_map<std::string, std::vector<IntervalVar*>>
2695 interval_array_argument_;
2696 absl::flat_hash_map<std::string, std::vector<SequenceVar*>>
2697 sequence_array_argument_;
2708 void BeginVisitModel(
const std::string& solver_name)
override;
2709 void EndVisitModel(
const std::string& solver_name)
override;
2710 void BeginVisitConstraint(
const std::string& type_name,
2712 void EndVisitConstraint(
const std::string& type_name,
2714 void BeginVisitIntegerExpression(
const std::string& type_name,
2716 void EndVisitIntegerExpression(
const std::string& type_name,
2717 const IntExpr* expr)
override;
2718 void VisitIntegerVariable(
const IntVar* variable,
IntExpr* delegate)
override;
2719 void VisitIntegerVariable(
const IntVar* variable,
2720 const std::string& operation, int64_t
value,
2721 IntVar* delegate)
override;
2722 void VisitIntervalVariable(
const IntervalVar* variable,
2723 const std::string& operation, int64_t
value,
2725 void VisitSequenceVariable(
const SequenceVar* variable)
override;
2727 void VisitIntegerArgument(
const std::string& arg_name,
2728 int64_t
value)
override;
2729 void VisitIntegerArrayArgument(
const std::string& arg_name,
2730 const std::vector<int64_t>& values)
override;
2731 void VisitIntegerMatrixArgument(
const std::string& arg_name,
2734 void VisitIntegerExpressionArgument(
const std::string& arg_name,
2736 void VisitIntegerVariableArrayArgument(
2737 const std::string& arg_name,
2738 const std::vector<IntVar*>& arguments)
override;
2740 void VisitIntervalArgument(
const std::string& arg_name,
2742 void VisitIntervalArrayArgument(
2743 const std::string& arg_name,
2744 const std::vector<IntervalVar*>& arguments)
override;
2746 void VisitSequenceArgument(
const std::string& arg_name,
2748 void VisitSequenceArrayArgument(
2749 const std::string& arg_name,
2750 const std::vector<SequenceVar*>& arguments)
override;
2753 void PushArgumentHolder();
2754 void PopArgumentHolder();
2758 std::vector<ArgumentHolder*> holders_;
2765 : index_min_(index_min),
2766 index_max_(index_max),
2767 values_(new T[index_max - index_min + 1]) {
2768 DCHECK_LE(index_min, index_max);
2771 ~ArrayWithOffset()
override {}
2773 virtual T Evaluate(int64_t
index)
const {
2774 DCHECK_GE(
index, index_min_);
2775 DCHECK_LE(
index, index_max_);
2780 DCHECK_GE(
index, index_min_);
2781 DCHECK_LE(
index, index_max_);
2785 std::string DebugString()
const override {
return "ArrayWithOffset"; }
2788 const int64_t index_min_;
2789 const int64_t index_max_;
2790 std::unique_ptr<T[]> values_;
2798template <
class T,
class C>
2802 : block_size_(block_size), block_offset_(0) {
2803 CHECK_GT(block_size, 0);
2807 for (
int i = 0; i < elements_.size(); ++i) {
2808 delete[] elements_[i];
2812 T At(int64_t
index)
const {
2813 const int64_t block_index = ComputeBlockIndex(
index);
2814 const int64_t relative_index = block_index - block_offset_;
2815 if (relative_index < 0 || relative_index >= elements_.size()) {
2818 const T* block = elements_[relative_index];
2819 return block !=
nullptr ? block[
index - block_index * block_size_] : T();
2823 const int64_t block_index = ComputeBlockIndex(
index);
2824 T*
const block = GetOrCreateBlock(block_index);
2825 const int64_t residual =
index - block_index * block_size_;
2827 reinterpret_cast<C
>(
value));
2831 T* NewBlock()
const {
2832 T*
const result =
new T[block_size_];
2833 for (
int i = 0; i < block_size_; ++i) {
2839 T* GetOrCreateBlock(
int block_index) {
2840 if (elements_.size() == 0) {
2841 block_offset_ = block_index;
2842 GrowUp(block_index);
2843 }
else if (block_index < block_offset_) {
2844 GrowDown(block_index);
2845 }
else if (block_index - block_offset_ >= elements_.size()) {
2846 GrowUp(block_index);
2848 T* block = elements_[block_index - block_offset_];
2849 if (block ==
nullptr) {
2851 elements_[block_index - block_offset_] = block;
2856 int64_t ComputeBlockIndex(int64_t
value)
const {
2858 : (
value - block_size_ + 1) / block_size_;
2861 void GrowUp(int64_t block_index) {
2862 elements_.resize(block_index - block_offset_ + 1);
2865 void GrowDown(int64_t block_index) {
2866 const int64_t
delta = block_offset_ - block_index;
2867 block_offset_ = block_index;
2868 DCHECK_GT(
delta, 0);
2869 elements_.insert(elements_.begin(),
delta,
nullptr);
2872 const int64_t block_size_;
2873 std::vector<T*> elements_;
2884 static constexpr int kNoInserted = -1;
2887 explicit RevIntSet(
int capacity)
2888 : elements_(new T[capacity]),
2890 capacity_(capacity),
2891 position_(new int[capacity]),
2892 delete_position_(
true) {
2893 for (
int i = 0;
i < capacity; ++
i) {
2894 position_[
i] = kNoInserted;
2899 RevIntSet(
int capacity,
int* shared_positions,
int shared_positions_size)
2900 : elements_(new T[capacity]),
2902 capacity_(capacity),
2903 position_(shared_positions),
2904 delete_position_(false) {
2905 for (
int i = 0; i < shared_positions_size; ++i) {
2906 position_[i] = kNoInserted;
2911 if (delete_position_) {
2916 int Size()
const {
return num_elements_.Value(); }
2918 int Capacity()
const {
return capacity_; }
2920 T Element(
int i)
const {
2922 DCHECK_LT(i, num_elements_.Value());
2923 return elements_[
i];
2926 T RemovedElement(
int i)
const {
2928 DCHECK_LT(i + num_elements_.Value(), capacity_);
2929 return elements_[i + num_elements_.Value()];
2932 void Insert(
Solver*
const solver,
const T& elt) {
2933 const int position = num_elements_.Value();
2934 DCHECK_LT(position, capacity_);
2935 DCHECK(NotAlreadyInserted(elt));
2936 elements_[position] = elt;
2937 position_[elt] = position;
2938 num_elements_.Incr(solver);
2941 void Remove(
Solver*
const solver,
const T& value_index) {
2942 num_elements_.Decr(solver);
2943 SwapTo(value_index, num_elements_.Value());
2946 void Restore(
Solver*
const solver,
const T& value_index) {
2947 SwapTo(value_index, num_elements_.Value());
2948 num_elements_.Incr(solver);
2951 void Clear(
Solver*
const solver) { num_elements_.SetValue(solver, 0); }
2954 typedef const T* const_iterator;
2956 const_iterator
end()
const {
return elements_.get() + num_elements_.Value(); }
2960 bool NotAlreadyInserted(
const T& elt) {
2961 for (
int i = 0; i < num_elements_.Value(); ++i) {
2962 if (elt == elements_[i]) {
2969 void SwapTo(T value_index,
int next_position) {
2970 const int current_position = position_[value_index];
2971 if (current_position != next_position) {
2972 const T next_value_index = elements_[next_position];
2973 elements_[current_position] = next_value_index;
2974 elements_[next_position] = value_index;
2975 position_[value_index] = next_position;
2976 position_[next_value_index] = current_position;
2981 std::unique_ptr<T[]> elements_;
2983 NumericalRev<int> num_elements_;
2985 const int capacity_;
2989 const bool delete_position_;
2994class RevPartialSequence {
2996 explicit RevPartialSequence(
const std::vector<int>& items)
2999 last_ranked_(items.
size() - 1),
3000 size_(items.
size()),
3001 position_(new int[size_]) {
3002 for (
int i = 0;
i < size_; ++
i) {
3003 elements_[
i] = items[
i];
3011 last_ranked_(
size - 1),
3013 position_(new int[size_]) {
3014 for (
int i = 0; i < size_; ++i) {
3022 int NumFirstRanked()
const {
return first_ranked_.Value(); }
3024 int NumLastRanked()
const {
return size_ - 1 - last_ranked_.Value(); }
3026 int Size()
const {
return size_; }
3029 const int& operator[](
int index)
const {
3030 DCHECK_GE(
index, 0);
3031 DCHECK_LT(
index, size_);
3032 return elements_[
index];
3036 void RankFirst(
Solver*
const solver,
int elt) {
3037 DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
3038 SwapTo(elt, first_ranked_.Value());
3039 first_ranked_.Incr(solver);
3042 void RankLast(
Solver*
const solver,
int elt) {
3043 DCHECK_LE(first_ranked_.Value(), last_ranked_.Value());
3044 SwapTo(elt, last_ranked_.Value());
3045 last_ranked_.Decr(solver);
3048 bool IsRanked(
int elt)
const {
3049 const int position = position_[elt];
3050 return (position < first_ranked_.Value() ||
3051 position > last_ranked_.Value());
3054 std::string DebugString()
const {
3055 std::string result =
"[";
3056 for (
int i = 0; i < first_ranked_.Value(); ++i) {
3057 absl::StrAppend(&result, elements_[i]);
3058 if (i != first_ranked_.Value() - 1) {
3063 for (
int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) {
3064 absl::StrAppend(&result, elements_[i]);
3065 if (i != last_ranked_.Value()) {
3070 for (
int i = last_ranked_.Value() + 1; i < size_; ++i) {
3071 absl::StrAppend(&result, elements_[i]);
3072 if (i != size_ - 1) {
3081 void SwapTo(
int elt,
int next_position) {
3082 const int current_position = position_[elt];
3083 if (current_position != next_position) {
3084 const int next_elt = elements_[next_position];
3085 elements_[current_position] = next_elt;
3086 elements_[next_position] = elt;
3087 position_[elt] = next_position;
3088 position_[next_elt] = current_position;
3093 std::vector<int> elements_;
3095 NumericalRev<int> first_ranked_;
3097 NumericalRev<int> last_ranked_;
3101 std::unique_ptr<int[]> position_;
3108class UnsortedNullableRevBitset {
3111 explicit UnsortedNullableRevBitset(
int bit_size);
3113 ~UnsortedNullableRevBitset() {}
3117 void Init(Solver* solver,
const std::vector<uint64_t>& mask);
3121 bool RevSubtract(Solver* solver,
const std::vector<uint64_t>& mask);
3125 bool RevAnd(
Solver* solver,
const std::vector<uint64_t>& mask);
3129 int ActiveWordSize()
const {
return active_words_.Size(); }
3132 bool Empty()
const {
return active_words_.Size() == 0; }
3141 bool Intersects(
const std::vector<uint64_t>& mask,
int* support_index);
3144 int64_t bit_size()
const {
return bit_size_; }
3146 int64_t word_size()
const {
return word_size_; }
3148 const RevIntSet<int>& active_words()
const {
return active_words_; }
3151 void CleanUpActives(Solver* solver);
3153 const int64_t bit_size_;
3154 const int64_t word_size_;
3155 RevArray<uint64_t> bits_;
3156 RevIntSet<int> active_words_;
3157 std::vector<int> to_remove_;
3162 for (
int i = 0; i < values.size(); ++i) {
3163 if (values[i] !=
value) {
3171bool IsArrayBoolean(
const std::vector<T>& values) {
3172 for (
int i = 0; i < values.size(); ++i) {
3173 if (values[i] != 0 && values[i] != 1) {
3181bool AreAllOnes(
const std::vector<T>& values) {
3186bool AreAllNull(
const std::vector<T>& values) {
3191bool AreAllGreaterOrEqual(
const std::vector<T>& values,
const T&
value) {
3192 for (
const T& current_value : values) {
3193 if (current_value <
value) {
3202 for (
const T& current_value : values) {
3203 if (current_value >
value) {
3221bool AreAllStrictlyPositive(
const std::vector<T>& values) {
3222 return AreAllGreaterOrEqual(values, T(1));
3232 for (
int i = 0; i < values.size() - 1; ++i) {
3233 if (values[i + 1] != values[i] + 1) {
3242 for (
int i = 0; i < values.size() - 1; ++i) {
3243 if (values[i + 1] < values[i]) {
3251bool IsArrayInRange(
const std::vector<IntVar*>& vars, T range_min,
3253 for (
int i = 0;
i < vars.size(); ++
i) {
3254 if (vars[
i]->Min() < range_min || vars[
i]->Max() > range_max) {
3261inline bool AreAllBound(
const std::vector<IntVar*>& vars) {
3262 for (
int i = 0;
i < vars.size(); ++
i) {
3263 if (!vars[
i]->Bound()) {
3278 const std::vector<T>& values) {
3279 for (
int i = 0;
i < vars.size(); ++
i) {
3280 if (values[i] != 0 && !vars[i]->Bound()) {
3288inline bool AreAllBoundTo(
const std::vector<IntVar*>& vars, int64_t
value) {
3289 for (
int i = 0; i < vars.size(); ++i) {
3290 if (!vars[i]->Bound() || vars[i]->Min() !=
value) {
3297inline int64_t
MaxVarArray(
const std::vector<IntVar*>& vars) {
3298 DCHECK(!vars.empty());
3300 for (
int i = 0;
i < vars.size(); ++
i) {
3302 result = std::max<int64_t>(result, vars[i]->Max());
3307inline int64_t
MinVarArray(
const std::vector<IntVar*>& vars) {
3308 DCHECK(!vars.empty());
3310 for (
int i = 0;
i < vars.size(); ++
i) {
3312 result = std::min<int64_t>(result, vars[i]->Min());
3317inline void FillValues(
const std::vector<IntVar*>& vars,
3318 std::vector<int64_t>*
const values) {
3320 values->resize(vars.size());
3321 for (
int i = 0; i < vars.size(); ++i) {
3322 (*values)[i] = vars[i]->Value();
3328 return (e < 0 || e % v == 0) ? e / v : e / v + 1;
3333 return (e >= 0 || e % v == 0) ? e / v : e / v - 1;
3336std::vector<int64_t> ToInt64Vector(
const std::vector<int>&
input);
3393 : begin_index(begin_index), end_index(end_index) {}
3397 int CommittedIndex(
int node)
const {
return committed_index_[node]; }
3398 ChainBounds CommittedPathRange(
int path)
const {
return chains_[path]; }
3402 PathState(
int num_nodes, std::vector<int> path_start,
3403 std::vector<int> path_end);
3408 int NumNodes()
const {
return num_nodes_; }
3410 int NumPaths()
const {
return num_paths_; }
3412 int Start(
int path)
const {
return path_start_end_[path].start; }
3414 int End(
int path)
const {
return path_start_end_[path].end; }
3419 int Path(
int node)
const {
return committed_paths_[node]; }
3422 const std::vector<int>& ChangedPaths()
const {
return changed_paths_; }
3424 const std::vector<int>& ChangedLoops()
const {
return changed_loops_; }
3437 void ChangePath(
int path,
const std::vector<ChainBounds>& chains);
3440 void ChangePath(
int path,
const std::initializer_list<ChainBounds>& chains) {
3441 changed_paths_.push_back(path);
3442 const int path_begin_index = chains_.size();
3443 chains_.insert(chains_.end(), chains.begin(), chains.end());
3444 const int path_end_index = chains_.size();
3445 paths_[path] = {path_begin_index, path_end_index};
3447 chains_.emplace_back(0, 0);
3451 void ChangeLoops(
const std::vector<int>& new_loops);
3460 void SetInvalid() { is_invalid_ =
true; }
3461 bool IsInvalid()
const {
return is_invalid_; }
3467 struct PathStartEnd {
3480 void CopyNewPathAtEndOfNodes(
int path);
3483 void IncrementalCommit();
3489 const int num_nodes_;
3490 const int num_paths_;
3491 std::vector<PathStartEnd> path_start_end_;
3519 std::vector<int> committed_nodes_;
3521 std::vector<int> committed_paths_;
3523 std::vector<int> committed_index_;
3524 const int num_nodes_threshold_;
3525 std::vector<ChainBounds> chains_;
3526 std::vector<PathBounds> paths_;
3529 std::vector<int> changed_paths_;
3530 std::vector<int> changed_loops_;
3533 bool is_invalid_ =
false;
3537class PathState::Chain {
3541 Iterator& operator++() {
3545 int operator*()
const {
return *current_node_; }
3547 return current_node_ != other.current_node_;
3553 explicit Iterator(
const int* node) : current_node_(node) {}
3554 const int* current_node_;
3559 Chain(
const int* begin_node,
const int* end_node)
3560 : begin_(begin_node), end_(end_node) {}
3562 int NumNodes()
const {
return end_ - begin_; }
3563 int First()
const {
return *begin_; }
3564 int Last()
const {
return *(end_ - 1); }
3565 Iterator begin()
const {
return Iterator(begin_); }
3568 Chain WithoutFirstNode()
const {
return Chain(begin_ + 1, end_); }
3571 const int*
const begin_;
3572 const int*
const end_;
3585 return {first_node_ + current_chain_->begin_index,
3586 first_node_ + current_chain_->end_index};
3588 bool operator!=(Iterator other)
const {
3589 return current_chain_ != other.current_chain_;
3596 : current_chain_(chain), first_node_(first_node) {}
3598 const int*
const first_node_;
3604 const ChainBounds*
const end_chain,
const int*
const first_node)
3605 : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
3607 Iterator begin()
const {
return {begin_, first_node_}; }
3613 const int*
const first_node_;
3624 if (current_node_ == end_node_) {
3630 end_node_ = first_node_ + bounds.
end_index;
3635 bool operator!=(
Iterator other)
const {
3636 return current_chain_ != other.current_chain_;
3643 : current_node_(first_node + current_chain->begin_index),
3644 end_node_(first_node + current_chain->end_index),
3645 current_chain_(current_chain),
3646 first_node_(first_node) {}
3647 const int* current_node_;
3648 const int* end_node_;
3650 const int*
const first_node_;
3656 const int* first_node)
3657 : begin_chain_(begin_chain),
3658 end_chain_(end_chain),
3659 first_node_(first_node) {}
3660 Iterator begin()
const {
return {begin_chain_, first_node_}; }
3663 Iterator
end()
const {
return {end_chain_, first_node_}; }
3666 const ChainBounds* begin_chain_;
3667 const ChainBounds* end_chain_;
3668 const int*
const first_node_;
3686 struct ExtendedInterval {
3689 int64_t num_negative_infinity;
3690 int64_t num_positive_infinity;
3696 std::vector<Interval> path_capacity,
3697 std::vector<int> path_class,
3698 std::vector<std::function<
Interval(int64_t, int64_t)>>
3699 demand_per_path_class,
3700 std::vector<Interval> node_capacity,
3701 int min_range_size_for_riq = kOptimalMinRangeSizeForRIQ);
3711 static constexpr int kOptimalMinRangeSizeForRIQ = 4;
3714 inline void UpdateCumulUsingChainRIQ(
int first_index,
int last_index,
3722 void IncrementalCommit();
3725 void AppendPathDemandsToSums(
int path);
3731 void UpdateRIQStructure(
int begin_index,
int end_index);
3734 const std::vector<ExtendedInterval> path_capacity_;
3735 const std::vector<int> path_class_;
3736 const std::vector<std::function<
Interval(int64_t, int64_t)>>
3737 demand_per_path_class_;
3738 std::vector<ExtendedInterval> cached_demand_;
3739 const std::vector<ExtendedInterval> node_capacity_;
3745 std::vector<int> index_;
3767 std::vector<std::vector<RIQNode>> riq_;
3770 const int maximum_riq_layer_size_;
3772 const int min_range_size_for_riq_;
3780LocalSearchFilter* MakePathStateFilter(Solver* solver,
3781 std::unique_ptr<PathState> path_state,
3782 const std::vector<IntVar*>& nexts);
3791LocalSearchFilter* MakeDimensionFilter(
3792 Solver* solver, std::unique_ptr<DimensionChecker> checker,
3793 const std::string& dimension_name);
const std::vector< IntVar * > vars_
int64_t MemoryUsage(int unused)
Argument Holder: useful when visiting a model.
const E & Element(const V *const var) const
bool Contains(const V *const var) const
AssignmentContainer< IntVar, IntVarElement > IntContainer
virtual IntVar * CastToVar()
IntVar * Var() override
Creates a variable from the expression.
BaseIntExpr(Solver *const s)
void AppendToFragment(int index)
bool HasFragments() const override
virtual void InitFragments()
BaseLns(const std::vector< IntVar * > &vars)
--— Base Large Neighborhood Search operator --—
bool MakeOneNeighbor() override
This method should not be overridden. Override NextFragment() instead.
virtual bool NextFragment()=0
void CopyBucket(const Bitset64< IndexType > &other, IndexType i)
Copies bucket containing bit i from "other" to "this".
void Clear(IndexType i)
Sets the bit at position i to 0.
void Resize(IndexType size)
void Set(IndexType i)
Sets the bit at position i to 1.
Demon proxy to a method on the constraint with no arguments.
void Run(Solver *const s) override
This is the main callback of the demon.
std::string DebugString() const override
CallMethod0(T *const ct, void(T::*method)(), const std::string &name)
Demon proxy to a method on the constraint with one argument.
void Run(Solver *const s) override
This is the main callback of the demon.
CallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
std::string DebugString() const override
Demon proxy to a method on the constraint with two arguments.
std::string DebugString() const override
CallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void Run(Solver *const s) override
This is the main callback of the demon.
Demon proxy to a method on the constraint with three arguments.
void Run(Solver *const s) override
This is the main callback of the demon.
CallMethod3(T *const ct, void(T::*method)(P, Q, R), const std::string &name, P param1, Q param2, R param3)
std::string DebugString() const override
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)
--— ChangeValue Operators --—
Constraint(Solver *const solver)
Low-priority demon proxy to a method on the constraint with no arguments.
void Run(Solver *const s) override
This is the main callback of the demon.
~DelayedCallMethod0() override
DelayedCallMethod0(T *const ct, void(T::*method)(), const std::string &name)
std::string DebugString() const override
Solver::DemonPriority priority() const override
---------------— Demon class -------------—
Low-priority demon proxy to a method on the constraint with one argument.
~DelayedCallMethod1() override
void Run(Solver *const s) override
This is the main callback of the demon.
DelayedCallMethod1(T *const ct, void(T::*method)(P), const std::string &name, P param1)
Solver::DemonPriority priority() const override
---------------— Demon class -------------—
std::string DebugString() const override
Low-priority demon proxy to a method on the constraint with two arguments.
std::string DebugString() const override
void Run(Solver *const s) override
This is the main callback of the demon.
Solver::DemonPriority priority() const override
---------------— Demon class -------------—
DelayedCallMethod2(T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
~DelayedCallMethod2() override
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
virtual int64_t Max() const =0
--— Main IntTupleSet class --—
int64_t OldInverseValue(int64_t index) const
void AddToAssignment(IntVar *var, int64_t value, bool active, std::vector< int > *assignment_indices, int64_t index, Assignment *assignment) const
virtual bool IsIncremental() const
virtual bool SkipUnchanged(int index) const
bool Activated(int64_t index) const
void SetValue(int64_t index, int64_t value)
void Start(const Assignment *assignment) override
void RevertChanges(bool change_was_incremental)
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
--— Base operator class for operators manipulating IntVars --—
void AddVars(const std::vector< IntVar * > &vars)
void Deactivate(int64_t index)
IntVar * Var(int64_t index) const
Returns the variable of given index.
int64_t Value(int64_t index) const
int64_t InverseValue(int64_t index) const
bool ApplyChanges(Assignment *delta, Assignment *deltadelta) const
int64_t PrevValue(int64_t index) const
bool HoldsDelta() const override
IntVarLocalSearchOperator(const std::vector< IntVar * > &vars, bool keep_inverse_values=false)
void Activate(int64_t index)
int64_t OldValue(int64_t index) const
virtual bool MakeOneNeighbor()
~IntVarLocalSearchOperator() override
virtual void WhenBound(Demon *d)=0
LightIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index, F values, std::function< bool()> deep_serialize)
~LightIntFunctionElementCt() override
void InitialPropagate() override
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
std::string DebugString() const override
--------------— Constraint class ----------------—
~LightIntIntFunctionElementCt() override
void Accept(ModelVisitor *const visitor) const override
Accepts the given visitor.
void InitialPropagate() override
LightIntIntFunctionElementCt(Solver *const solver, IntVar *const var, IntVar *const index1, IntVar *const index2, F values, std::function< bool()> deep_serialize)
std::string DebugString() const override
--------------— Constraint class ----------------—
int64_t CheckPointValue(int64_t index) const
void SetCandidateActive(int64_t index, bool active)
void SetCurrentDomainInjectiveAndKeepInverseValues(int max_value)
void Revert(bool only_incremental)
int64_t CandidateValue(int64_t index) const
LocalSearchOperatorState()
void SetCandidateValue(int64_t index, int64_t value)
const std::vector< int64_t > & IncrementalIndicesChanged() const
const std::vector< int64_t > & CandidateIndicesChanged() const
int64_t CommittedInverseValue(int64_t value) const
int64_t CommittedValue(int64_t index) const
bool CandidateIsActive(int64_t index) const
int64_t CandidateInverseValue(int64_t value) const
virtual bool HoldsDelta() const
virtual bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta)=0
virtual const LocalSearchOperator * Self() const
virtual bool HasFragments() const
~LocalSearchOperator() override
virtual void Start(const Assignment *assignment)=0
VarArrayConstantExpressionType
VarArrayConstantArrayExpressionType
VarConstantConstraintType
ExprConstantExpressionType
VarConstantArrayExpressionType
VarConstantConstantExpressionType
ExprExprConstantExpressionType
VarConstantConstantConstraintType
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)
virtual void EndVisitConstraint(const std::string &type_name, const Constraint *constraint)
Subclass of Rev<T> which adds numerical operations.
void Incr(Solver *const s)
void Decr(Solver *const s)
int64_t Prev(int64_t node) const
Returns the node before node in the current delta.
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.
bool MakeActive(int64_t node, int64_t destination)
Insert the inactive node after destination.
bool IsPathStart(int64_t node) const
Returns true if node is the first node on the path.
bool SkipUnchanged(int index) const override
int number_of_nexts() const
Number of next variables.
int GetSiblingAlternativeIndex(int node) const
Returns the index of the alternative set of the sibling of node.
int64_t OldNext(int64_t node) const
bool MakeChainInactive(int64_t before_chain, int64_t chain_end)
int64_t PrevNext(int64_t node) const
bool IsInactive(int64_t node) const
Returns true if node is inactive.
virtual void OnNodeInitialization()
virtual bool ConsiderAlternatives(int64_t base_index) const
const bool ignore_path_vars_
bool SwapActiveAndInactive(int64_t active, int64_t inactive)
Replaces active by inactive in the current path, making active inactive.
void AddPairAlternativeSets(const std::vector< PairType > &pair_alternative_sets)
int BaseAlternative(int i) const
Returns the alternative for the ith base node.
virtual bool RestartAtPathStartOnSynchronize()
int PathClass(int i) const
Returns the class of the path of the ith base node.
int BaseSiblingAlternative(int i) const
Returns the alternative for the sibling of the ith base node.
virtual bool InitPosition() const
int64_t EndNode(int i) const
Returns the end node of the ith base node.
int PathClassFromStartNode(int64_t start_node) const
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
int64_t BaseSiblingAlternativeNode(int i) const
Returns the alternative node for the sibling of the ith base node.
int64_t BaseAlternativeNode(int i) const
Returns the alternative node for the ith base node.
const std::vector< int64_t > & path_starts() const
Returns the vector of path start nodes.
int64_t OldPath(int64_t node) const
int CurrentNodePathStart(int64_t node) const
int AddAlternativeSet(const std::vector< int64_t > &alternative_set)
int64_t OldPrev(int64_t node) const
virtual bool MakeNeighbor()=0
int64_t Path(int64_t node) const
int CurrentNodePathEnd(int64_t node) const
bool MoveChain(int64_t before_chain, int64_t chain_end, int64_t destination)
virtual int64_t GetBaseNodeRestartPosition(int base_index)
int64_t StartNode(int i) const
Returns the start node of the ith base node.
virtual bool OnSamePathAsPreviousBase(int64_t base_index)
virtual void SetNextBaseToIncrement(int64_t base_index)
const int number_of_nexts_
bool IsPathEnd(int64_t node) const
void SetNext(int64_t from, int64_t to, int64_t path)
Sets 'to' to be the node after 'from' on the given path.
int64_t BaseNode(int i) const
Returns the ith base node of the operator.
bool ReverseChain(int64_t before_chain, int64_t after_chain, int64_t *chain_last)
A ChainRange is a range of Chains, committed or not.
A Chain is a range of committed nodes.
friend class NodeRange
Only a NodeRange can construct its Iterator.
std::string DebugString() const override
Matrix version of the RevBitSet class.
bool IsSet(int64_t row, int64_t column) const
Returns whether the 'column' bit in the 'row' row is set.
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.
RevBitSet(int64_t size)
-------— RevBitSet -------—
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
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?
void Insert(const K &key, const V &value)
Inserts (key, value) in the multi-map.
bool ContainsKey(const K &key) const
Returns true if the multi-map contains at least one instance of 'key'.
RevImmutableMultiMap(Solver *const solver, int initial_size)
const V & FindWithDefault(const K &key, const V &default_value) const
const T * const_iterator
Iterators on the indices.
--— RevPartialSequence --—
void Switch(Solver *const solver)
void SetValue(Solver *const s, const T &val)
A search monitor is a simple set of callbacks to monitor all search events.
Iterator(const SimpleRevFIFO< T > *l)
void SetLastValue(const T &v)
Sets the last value in the FIFO.
const T * Last() const
Returns the last item of the FIFO.
void Push(Solver *const s, T val)
void PushIfNotTop(Solver *const s, T val)
Pushes the var on top if is not a duplicate of the current top object.
const T & LastValue() const
Returns the last value in the FIFO.
void SetToZero(Solver *solver, int64_t pos)
Erases the 'pos' bit.
SmallRevBitSet(int64_t size)
-------— SmallRevBitSet -------—
void SetToOne(Solver *solver, int64_t pos)
Sets the 'pos' bit.
bool IsCardinalityZero() const
Is bitset null?
int64_t Cardinality() const
Returns the number of bits set to one.
int64_t GetFirstOne() const
bool IsCardinalityOne() const
Does it contains only one bit set?
For the time being, Solver is neither MT_SAFE nor MT_HOT.
void SaveAndSetValue(T *adr, T val)
All-in-one SaveAndSetValue.
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
void ClearAndResize(IntegerType size)
const std::vector< IntegerType > & PositionsSetAtLeastOnce() const
void Set(IntegerType index)
-------— Symmetry Breaking -------—
void push_back(const value_type &val)
const std::string name
A name for logging purposes.
GurobiMPCallbackContext * context
For infeasible and unbounded see Not checked if options check_solutions_if_inf_or_unbounded and the If options first_solution_only is false
problem is infeasible or unbounded (default).
bool operator!=(const IndicatorConstraint &lhs, const IndicatorConstraint &rhs)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
This checks that the variable is fixed.
In SWIG mode, we don't want anything besides these top-level includes.
std::string ParameterDebugString(P param)
bool IsArrayConstant(const std::vector< T > &values, const T &value)
LinearExpr operator*(LinearExpr lhs, double rhs)
bool AreAllLessOrEqual(const std::vector< T > &values, const T &value)
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)
bool AreAllNegative(const std::vector< T > &values)
bool AreAllGreaterOrEqual(const std::vector< T > &values, const T &value)
bool IsIncreasing(const std::vector< T > &values)
void AcceptUncheckedNeighbor(Search *search)
bool AreAllBoundOrNull(const std::vector< IntVar * > &vars, const std::vector< T > &values)
int64_t MaxVarArray(const std::vector< IntVar * > &vars)
LocalSearchOperator * MakeLocalSearchOperator(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class)
Operator Factories.
Demon * MakeConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
Demon * MakeDelayedConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
Demon * MakeDelayedConstraintDemon2(Solver *const s, T *const ct, void(T::*method)(P, Q), const std::string &name, P param1, Q param2)
void FillValues(const std::vector< IntVar * > &vars, std::vector< int64_t > *const values)
bool AreAllBooleans(const std::vector< IntVar * > &vars)
bool AreAllStrictlyNegative(const std::vector< T > &values)
int64_t MinVarArray(const std::vector< IntVar * > &vars)
void RegisterDemon(Solver *const solver, Demon *const demon, DemonProfiler *const monitor)
--— Exported Methods for Unit Tests --—
LocalSearchOperator * MakeLocalSearchOperatorWithNeighbors(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_neighbors)
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
bool IsIncreasingContiguous(const std::vector< T > &values)
bool AreAllNull(const std::vector< T > &values)
bool AreAllPositive(const std::vector< T > &values)
Demon * MakeDelayedConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
LocalSearchState::VariableDomainId VariableDomainId
int64_t PosIntDivDown(int64_t e, int64_t v)
bool IsArrayInRange(const std::vector< IntVar * > &vars, T range_min, T range_max)
Demon * MakeConstraintDemon1(Solver *const s, T *const ct, void(T::*method)(P), const std::string &name, P param1)
bool AreAllOnes(const std::vector< T > &values)
bool AreAllBound(const std::vector< IntVar * > &vars)
uint64_t Hash1(uint64_t value)
int64_t PosIntDivUp(int64_t e, int64_t v)
SubDagComputer::NodeId NodeId
trees with all degrees equal to
static int input(yyscan_t yyscanner)
std::optional< int64_t > end
#define DEFINE_STRONG_INT_TYPE(int_type_name, value_type)
Set of parameters used to configure how the neighnorhood is traversed.
std::function< int(int64_t)> start_empty_path_class
std::function< const std::vector< int > &(int, int)> get_neighbors
Callback returning neighbors of a node on a path starting at start_node.
bool accept_path_end_base
True if path ends should be considered when iterating over neighbors.
bool skip_locally_optimal_paths
int number_of_base_nodes
Number of nodes needed to define a neighbor.
static const int64_t kint64max
static const int64_t kint64min