14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
23#include "absl/log/check.h"
24#include "absl/types/span.h"
36 : current_(value), committed_(value) {}
38 const T&
Get()
const {
return current_; }
41 void Set(
const T& value) { current_ = value; }
48 void Revert() { current_ = committed_; }
50 void Commit() { committed_ = current_; }
62 : elements_(num_elements, {value, value}), changed_(num_elements) {}
65 size_t Size()
const {
return elements_.size(); }
70 T
Get(
size_t index)
const {
71 DCHECK_LT(index, elements_.size());
72 return elements_[index].current;
78 DCHECK_LT(index, elements_.size());
80 return elements_[index].current;
84 void Set(
size_t index,
const T& value) {
86 DCHECK_LT(index, elements_.size());
88 elements_[index].current = value;
93 for (
const size_t index : changed_.PositionsSetAtLeastOnce()) {
94 elements_[index].current = elements_[index].committed;
96 changed_.ResetAllToFalse();
101 for (
const size_t index : changed_.PositionsSetAtLeastOnce()) {
102 elements_[index].committed = elements_[index].current;
104 changed_.ResetAllToFalse();
109 changed_.ResetAllToFalse();
110 elements_.assign(elements_.size(), {value, value});
115 DCHECK_LT(index, elements_.size());
116 return elements_[index].committed;
121 bool HasChanged(
size_t index)
const {
return changed_[index]; }
126 return changed_.PositionsSetAtLeastOnce();
134 struct VersionedElement {
139 std::vector<VersionedElement> elements_;
141 SparseBitset<size_t> changed_;
160 std::vector<T>& temp_container) {
161 temp_container.clear();
162 const int num_ranges = ranges.
Size();
163 for (
int i = 0; i < num_ranges; ++i) {
164 const size_t new_begin = temp_container.size();
166 temp_container.insert(temp_container.end(), mutable_input.begin() +
begin,
167 mutable_input.begin() +
end);
168 ranges.
Set(i, {.begin = new_begin, .end = temp_container.size()});
170 std::swap(mutable_input, temp_container);
212 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
214 vehicle_breaks_(num_paths),
215 committed_vehicle_breaks_(num_paths),
216 max_num_committed_elements_(16 * num_nodes),
218 nodes_.reserve(max_num_committed_elements_);
219 transit_.reserve(max_num_committed_elements_);
220 travel_.reserve(max_num_committed_elements_);
221 travel_sum_.reserve(max_num_committed_elements_);
222 cumul_.reserve(max_num_committed_elements_);
241 min = std::max(
min, lower_bound);
247 max = std::min(
max, upper_bound);
275 return {.min = std::numeric_limits<int64_t>::min(),
276 .max = std::numeric_limits<int64_t>::max()};
292 void PushNode(
int node) { nodes_.push_back(node); }
297 DCHECK_LT(path, range_of_path_.Size());
298 DCHECK(!range_of_path_.HasChanged(path));
299 range_of_path_.Set(path,
300 {.begin = num_elements_.Get(), .end = nodes_.size()});
304 travel_.resize(nodes_.size(), 0);
305 travel_sum_.resize(nodes_.size(), 0);
307 num_elements_.Set(nodes_.size());
313 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
314 num_elements_.SetAndCommit(0);
325 range_of_path_.Revert();
326 num_elements_.Revert();
327 nodes_.resize(num_elements_.Get());
328 transit_.resize(num_elements_.Get());
329 travel_.resize(num_elements_.Get());
330 travel_sum_.resize(num_elements_.Get());
331 cumul_.resize(num_elements_.Get());
339 for (
const int path : range_of_path_.ChangedIndices()) {
340 committed_vehicle_breaks_[path] = vehicle_breaks_[path];
342 range_of_path_.Commit();
343 num_elements_.Commit();
346 if (num_elements_.Get() <= max_num_committed_elements_)
return;
352 range_of_path_.Commit();
353 num_elements_.SetAndCommit(nodes_.size());
358 const auto [
begin,
end] = range_of_path_.GetCommitted(path);
359 return absl::MakeConstSpan(nodes_.data() +
begin, nodes_.data() +
end);
363 absl::Span<const int>
Nodes(
int path)
const {
364 const auto [
begin,
end] = range_of_path_.Get(path);
365 return absl::MakeConstSpan(nodes_.data() +
begin, nodes_.data() +
end);
369 absl::Span<const Interval>
Transits(
int path)
const {
370 auto [
begin,
end] = range_of_path_.Get(path);
374 return absl::MakeConstSpan(transit_.data() +
begin, transit_.data() +
end);
379 auto [
begin,
end] = range_of_path_.Get(path);
383 return absl::MakeSpan(transit_.data() +
begin, transit_.data() +
end);
388 auto [
begin,
end] = range_of_path_.GetCommitted(path);
390 return absl::MakeConstSpan(travel_.data() +
begin, travel_.data() +
end);
394 absl::Span<const int64_t>
Travels(
int path)
const {
395 auto [
begin,
end] = range_of_path_.Get(path);
397 return absl::MakeConstSpan(travel_.data() +
begin, travel_.data() +
end);
402 auto [
begin,
end] = range_of_path_.Get(path);
404 return absl::MakeSpan(travel_.data() +
begin, travel_.data() +
end);
409 const auto [
begin,
end] = range_of_path_.Get(path);
410 return absl::MakeConstSpan(travel_sum_.data() +
begin,
411 travel_sum_.data() +
end);
416 const auto [
begin,
end] = range_of_path_.Get(path);
417 return absl::MakeSpan(travel_sum_.data() +
begin, travel_sum_.data() +
end);
421 absl::Span<const Interval>
Cumuls(
int path)
const {
422 const auto [
begin,
end] = range_of_path_.Get(path);
423 return absl::MakeConstSpan(cumul_.data() +
begin, cumul_.data() +
end);
428 const auto [
begin,
end] = range_of_path_.Get(path);
429 return absl::MakeSpan(cumul_.data() +
begin, cumul_.data() +
end);
438 DCHECK(range_of_path_.HasChanged(path));
439 return span_.GetMutable(path);
445 return absl::MakeConstSpan(range_of_path_.HasChanged(path)
446 ? vehicle_breaks_[path]
447 : committed_vehicle_breaks_[path]);
453 DCHECK(range_of_path_.HasChanged(path));
454 return vehicle_breaks_[path];
458 int NumNodes(
int path)
const {
return range_of_path_.Get(path).Size(); }
461 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
465 return range_of_path_.HasChanged(path);
482 std::vector<int> nodes_;
483 std::vector<Interval> transit_;
484 std::vector<int64_t> travel_;
485 std::vector<int64_t> travel_sum_;
486 std::vector<Interval> cumul_;
488 std::vector<int> temp_ints_;
489 std::vector<Interval> temp_intervals_;
490 std::vector<int64_t> temp_int64s_;
498 std::vector<std::vector<VehicleBreak>> vehicle_breaks_;
499 std::vector<std::vector<VehicleBreak>> committed_vehicle_breaks_;
503 const size_t max_num_committed_elements_;
511 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
512 max_num_committed_elements_(16 * num_nodes),
514 pre_visit_.reserve(max_num_committed_elements_);
515 post_visit_.reserve(max_num_committed_elements_);
523 DCHECK_LT(path, range_of_path_.Size());
524 DCHECK(!range_of_path_.HasChanged(path));
525 size_t num_current_elements = num_elements_.Get();
526 range_of_path_.Set(path, {.begin = num_current_elements,
527 .end = num_current_elements + new_num_nodes});
530 num_current_elements += new_num_nodes;
531 pre_visit_.resize(num_current_elements, 0);
532 post_visit_.resize(num_current_elements, 0);
533 num_elements_.Set(num_current_elements);
538 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
539 num_elements_.SetAndCommit(0);
546 range_of_path_.Revert();
547 num_elements_.Revert();
548 pre_visit_.resize(num_elements_.Get());
549 post_visit_.resize(num_elements_.Get());
556 range_of_path_.Commit();
557 num_elements_.Commit();
561 if (num_elements_.Get() <= max_num_committed_elements_)
return;
564 range_of_path_.Commit();
565 num_elements_.SetAndCommit(pre_visit_.size());
570 auto [
begin,
end] = range_of_path_.GetCommitted(path);
571 return absl::MakeConstSpan(pre_visit_.data() +
begin,
572 pre_visit_.data() +
end);
577 auto [
begin,
end] = range_of_path_.Get(path);
578 return absl::MakeConstSpan(pre_visit_.data() +
begin,
579 pre_visit_.data() +
end);
584 auto [
begin,
end] = range_of_path_.Get(path);
585 return absl::MakeSpan(pre_visit_.data() +
begin, pre_visit_.data() +
end);
591 auto [
begin,
end] = range_of_path_.GetCommitted(path);
592 return absl::MakeConstSpan(post_visit_.data() +
begin,
593 post_visit_.data() +
end);
598 const auto [
begin,
end] = range_of_path_.Get(path);
599 return absl::MakeConstSpan(post_visit_.data() +
begin,
600 post_visit_.data() +
end);
605 const auto [
begin,
end] = range_of_path_.Get(path);
606 return absl::MakeSpan(post_visit_.data() +
begin, post_visit_.data() +
end);
610 int NumNodes(
int path)
const {
return range_of_path_.Get(path).Size(); }
613 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
617 return range_of_path_.HasChanged(path);
622 std::vector<int64_t> pre_visit_;
623 std::vector<int64_t> post_visit_;
625 std::vector<int64_t> temp_int64s_;
632 const size_t max_num_committed_elements_;
void Revert()
Changes the values of the vector to those in the last Commit().
bool HasChanged(size_t index) const
CommittableArray(size_t num_elements, const T &value)
Makes a vector with initial elements all committed to value.
T Get(size_t index) const
void Set(size_t index, const T &value)
Set the value stored at index in the current state to given value.
void SetAllAndCommit(const T &value)
Sets all elements of this vector to given value, and commits to this state.
void Commit()
Makes the current state committed, clearing all changes.
T & GetMutable(size_t index)
T GetCommitted(size_t index) const
Returns a copy of the value stored at index in the last committed state.
const std::vector< size_t > & ChangedIndices() const
size_t Size() const
Return the size of the vector.
const T & GetCommitted() const
void SetAndCommit(const T &value)
CommittableValue(const T &value)
absl::Span< const int64_t > CommittedTravels(int path) const
Returns a const view of the travels of the path, in the committed state.
void Reset()
Resets all path to empty, in both committed and current state.
absl::Span< Interval > MutableCumuls(int path)
Returns a mutable view of the cumul mins of the path, in the current state.
int NumNodes(int path) const
Returns the number of nodes of the path, in the current state.
absl::Span< const int64_t > Travels(int path) const
Returns a const view of the travels of the path, in the current state.
absl::Span< const Interval > Cumuls(int path) const
Returns a const view of the cumul mins of the path, in the current state.
absl::Span< const size_t > ChangedPaths() const
Returns a const view of the set of paths changed, in the current state.
DimensionValues(int num_paths, int num_nodes)
absl::Span< const VehicleBreak > VehicleBreaks(int path) const
void MakePathFromNewNodes(int path)
Turns new nodes into a new path, allocating dimension values for it.
void Revert()
Clears the changed state, make it point to the committed state.
absl::Span< const Interval > Transits(int path) const
Returns a const view of the transits of the path, in the current state.
absl::Span< const int > Nodes(int path) const
Returns a const view of the nodes of the path, in the current state.
absl::Span< Interval > MutableTransits(int path)
Returns a mutable view of the transits of the path, in the current state.
Interval & MutableSpan(int path)
absl::Span< int64_t > MutableTravelSums(int path)
Returns a mutable view of the travel sums of the path in the current state.
absl::Span< int64_t > MutableTravels(int path)
Returns a mutable view of the travels of the path, in the current state.
bool PathHasChanged(int path) const
Returns whether the given path was changed, in the current state.
std::vector< VehicleBreak > & MutableVehicleBreaks(int path)
Interval Span(int path) const
Returns the span interval of the path, in the current state.
void PushNode(int node)
Adds a node to new nodes.
absl::Span< const int > CommittedNodes(int path) const
Returns a const view of the nodes of the path, in the committed state.
absl::Span< const int64_t > TravelSums(int path) const
Returns a const view of the travel sums of the path, in the current state.
void Reset()
Resets all path to empty, in both committed and current state.
absl::Span< const int64_t > PostVisits(int path) const
Returns a const view of the post-visits of the path, in the current state.
absl::Span< const int64_t > CommittedPostVisits(int path) const
void Revert()
Clears the changed state, makes it point to the committed state.
PrePostVisitValues(int num_paths, int num_nodes)
absl::Span< int64_t > MutablePostVisits(int path)
Returns a mutable view of the post-visits of the path in the current state.
absl::Span< const size_t > ChangedPaths() const
Returns a const view of the set of paths changed, in the current state.
bool PathHasChanged(int path) const
Returns whether the given path was changed, in the current state.
DimensionValues::Interval Interval
int NumNodes(int path) const
Returns the number of nodes of the path, in the current state.
void ChangePathSize(int path, int new_num_nodes)
Turns new nodes into a new path, allocating pre-post visit values for it.
absl::Span< int64_t > MutablePreVisits(int path)
Returns a mutable view of the pre-visits of the path, in the current state.
absl::Span< const int64_t > CommittedPreVisits(int path) const
Returns a const view of the pre-visits of the path, in the committed state.
absl::Span< const int64_t > PreVisits(int path) const
Returns a const view of the pre-visits of the path, in the current state.
In SWIG mode, we don't want anything besides these top-level includes.
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapSub(int64_t x, int64_t y)
ClosedInterval::Iterator end(ClosedInterval interval)
void DefragmentRanges(std::vector< T > &mutable_input, CommittableArray< IndexRange > &ranges, std::vector< T > &temp_container)
ClosedInterval::Iterator begin(ClosedInterval interval)
static Interval AllIntegers()
Returns an interval containing all integers: {kint64min, kint64max}.
bool IncreaseMin(int64_t lower_bound)
void Subtract(const Interval &other)
void Add(const Interval &other)
bool DecreaseMax(int64_t upper_bound)
bool operator==(const Interval &other) const
Tests equality between intervals.
bool operator!=(const Interval &other) const
Tests inequality between intervals.
bool IntersectWith(const Interval &other)
bool IsEmpty() const
Returns true iff the interval is empty.
bool operator==(const VehicleBreak &other) const
bool operator==(const IndexRange &other) const
IndexRange(Index start, Index end)