14#ifndef ORTOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
15#define ORTOOLS_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);
279 return {.min = std::numeric_limits<int64_t>::min(),
280 .max = std::numeric_limits<int64_t>::max()};
296 void PushNode(
int node) { nodes_.push_back(node); }
301 DCHECK_LT(path, range_of_path_.Size());
302 DCHECK(!range_of_path_.HasChanged(path));
303 range_of_path_.Set(path,
304 {.begin = num_elements_.Get(), .end = nodes_.size()});
308 travel_.resize(nodes_.size(), 0);
309 travel_sum_.resize(nodes_.size(), 0);
311 num_elements_.Set(nodes_.size());
317 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
318 num_elements_.SetAndCommit(0);
329 range_of_path_.Revert();
330 num_elements_.Revert();
331 nodes_.resize(num_elements_.Get());
332 transit_.resize(num_elements_.Get());
333 travel_.resize(num_elements_.Get());
334 travel_sum_.resize(num_elements_.Get());
335 cumul_.resize(num_elements_.Get());
343 for (
const int path : range_of_path_.ChangedIndices()) {
344 committed_vehicle_breaks_[path] = vehicle_breaks_[path];
346 range_of_path_.Commit();
347 num_elements_.Commit();
350 if (num_elements_.Get() <= max_num_committed_elements_)
return;
356 range_of_path_.Commit();
357 num_elements_.SetAndCommit(nodes_.size());
362 const auto [
begin,
end] = range_of_path_.GetCommitted(path);
363 return absl::MakeConstSpan(nodes_.data() +
begin, nodes_.data() +
end);
367 absl::Span<const int>
Nodes(
int path)
const {
368 const auto [
begin,
end] = range_of_path_.Get(path);
369 return absl::MakeConstSpan(nodes_.data() +
begin, nodes_.data() +
end);
373 absl::Span<const Interval>
Transits(
int path)
const {
374 auto [
begin,
end] = range_of_path_.Get(path);
378 return absl::MakeConstSpan(transit_.data() +
begin, transit_.data() +
end);
383 auto [
begin,
end] = range_of_path_.Get(path);
387 return absl::MakeSpan(transit_.data() +
begin, transit_.data() +
end);
392 auto [
begin,
end] = range_of_path_.GetCommitted(path);
394 return absl::MakeConstSpan(travel_.data() +
begin, travel_.data() +
end);
398 absl::Span<const int64_t>
Travels(
int path)
const {
399 auto [
begin,
end] = range_of_path_.Get(path);
401 return absl::MakeConstSpan(travel_.data() +
begin, travel_.data() +
end);
406 auto [
begin,
end] = range_of_path_.Get(path);
408 return absl::MakeSpan(travel_.data() +
begin, travel_.data() +
end);
413 const auto [
begin,
end] = range_of_path_.Get(path);
414 return absl::MakeConstSpan(travel_sum_.data() +
begin,
415 travel_sum_.data() +
end);
420 const auto [
begin,
end] = range_of_path_.Get(path);
421 return absl::MakeSpan(travel_sum_.data() +
begin, travel_sum_.data() +
end);
425 absl::Span<const Interval>
Cumuls(
int path)
const {
426 const auto [
begin,
end] = range_of_path_.Get(path);
427 return absl::MakeConstSpan(cumul_.data() +
begin, cumul_.data() +
end);
432 const auto [
begin,
end] = range_of_path_.Get(path);
433 return absl::MakeSpan(cumul_.data() +
begin, cumul_.data() +
end);
442 DCHECK(range_of_path_.HasChanged(path));
443 return span_.GetMutable(path);
449 return absl::MakeConstSpan(range_of_path_.HasChanged(path)
450 ? vehicle_breaks_[path]
451 : committed_vehicle_breaks_[path]);
457 DCHECK(range_of_path_.HasChanged(path));
458 return vehicle_breaks_[path];
462 int NumNodes(
int path)
const {
return range_of_path_.Get(path).Size(); }
465 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
469 return range_of_path_.HasChanged(path);
486 std::vector<int> nodes_;
487 std::vector<Interval> transit_;
488 std::vector<int64_t> travel_;
489 std::vector<int64_t> travel_sum_;
490 std::vector<Interval> cumul_;
492 std::vector<int> temp_ints_;
493 std::vector<Interval> temp_intervals_;
494 std::vector<int64_t> temp_int64s_;
502 std::vector<std::vector<VehicleBreak>> vehicle_breaks_;
503 std::vector<std::vector<VehicleBreak>> committed_vehicle_breaks_;
507 const size_t max_num_committed_elements_;
517 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
518 max_num_committed_elements_(16 * num_nodes),
520 pre_visit_.reserve(max_num_committed_elements_);
521 post_visit_.reserve(max_num_committed_elements_);
529 DCHECK_LT(path, range_of_path_.Size());
530 DCHECK(!range_of_path_.HasChanged(path));
531 size_t num_current_elements = num_elements_.Get();
532 range_of_path_.Set(path, {.begin = num_current_elements,
533 .end = num_current_elements + new_num_nodes});
536 num_current_elements += new_num_nodes;
537 pre_visit_.resize(num_current_elements, 0);
538 post_visit_.resize(num_current_elements, 0);
539 num_elements_.Set(num_current_elements);
544 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
545 num_elements_.SetAndCommit(0);
552 range_of_path_.Revert();
553 num_elements_.Revert();
554 pre_visit_.resize(num_elements_.Get());
555 post_visit_.resize(num_elements_.Get());
562 range_of_path_.Commit();
563 num_elements_.Commit();
567 if (num_elements_.Get() <= max_num_committed_elements_)
return;
570 range_of_path_.Commit();
571 num_elements_.SetAndCommit(pre_visit_.size());
576 auto [
begin,
end] = range_of_path_.GetCommitted(path);
577 return absl::MakeConstSpan(pre_visit_.data() +
begin,
578 pre_visit_.data() +
end);
583 auto [
begin,
end] = range_of_path_.Get(path);
584 return absl::MakeConstSpan(pre_visit_.data() +
begin,
585 pre_visit_.data() +
end);
590 auto [
begin,
end] = range_of_path_.Get(path);
591 return absl::MakeSpan(pre_visit_.data() +
begin, pre_visit_.data() +
end);
597 auto [
begin,
end] = range_of_path_.GetCommitted(path);
598 return absl::MakeConstSpan(post_visit_.data() +
begin,
599 post_visit_.data() +
end);
604 const auto [
begin,
end] = range_of_path_.Get(path);
605 return absl::MakeConstSpan(post_visit_.data() +
begin,
606 post_visit_.data() +
end);
611 const auto [
begin,
end] = range_of_path_.Get(path);
612 return absl::MakeSpan(post_visit_.data() +
begin, post_visit_.data() +
end);
616 int NumNodes(
int path)
const {
return range_of_path_.Get(path).Size(); }
619 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
623 return range_of_path_.HasChanged(path);
628 std::vector<int64_t> pre_visit_;
629 std::vector<int64_t> post_visit_;
631 std::vector<int64_t> temp_int64s_;
638 const size_t max_num_committed_elements_;
bool HasChanged(size_t index) const
CommittableArray(size_t num_elements, const T &value)
T Get(size_t index) const
void Set(size_t index, const T &value)
void SetAllAndCommit(const T &value)
T & GetMutable(size_t index)
T GetCommitted(size_t index) const
const std::vector< size_t > & ChangedIndices() const
const T & GetCommitted() const
void SetAndCommit(const T &value)
CommittableValue(const T &value)
absl::Span< const int64_t > CommittedTravels(int path) const
absl::Span< Interval > MutableCumuls(int path)
int NumNodes(int path) const
absl::Span< const int64_t > Travels(int path) const
absl::Span< const Interval > Cumuls(int path) const
absl::Span< const size_t > ChangedPaths() const
DimensionValues(int num_paths, int num_nodes)
absl::Span< const VehicleBreak > VehicleBreaks(int path) const
void MakePathFromNewNodes(int path)
absl::Span< const Interval > Transits(int path) const
absl::Span< const int > Nodes(int path) const
absl::Span< Interval > MutableTransits(int path)
Interval & MutableSpan(int path)
absl::Span< int64_t > MutableTravelSums(int path)
absl::Span< int64_t > MutableTravels(int path)
bool PathHasChanged(int path) const
std::vector< VehicleBreak > & MutableVehicleBreaks(int path)
Interval Span(int path) const
absl::Span< const int > CommittedNodes(int path) const
absl::Span< const int64_t > TravelSums(int path) const
absl::Span< const int64_t > PostVisits(int path) const
absl::Span< const int64_t > CommittedPostVisits(int path) const
PrePostVisitValues(int num_paths, int num_nodes)
absl::Span< int64_t > MutablePostVisits(int path)
absl::Span< const size_t > ChangedPaths() const
bool PathHasChanged(int path) const
DimensionValues::Interval Interval
int NumNodes(int path) const
void ChangePathSize(int path, int new_num_nodes)
absl::Span< int64_t > MutablePreVisits(int path)
absl::Span< const int64_t > CommittedPreVisits(int path) const
absl::Span< const int64_t > PreVisits(int path) const
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapSub(int64_t x, int64_t y)
ClosedInterval::Iterator end(ClosedInterval interval)
bool PropagateTransitAndSpan(int path, DimensionValues &dimension_values)
void DefragmentRanges(std::vector< T > &mutable_input, CommittableArray< IndexRange > &ranges, std::vector< T > &temp_container)
ClosedInterval::Iterator begin(ClosedInterval interval)
static Interval AllIntegers()
Interval operator+(const Interval &other) const
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
Interval operator-(const Interval &other) const
bool operator!=(const Interval &other) const
bool IntersectWith(const Interval &other)
bool operator==(const VehicleBreak &other) const
bool operator==(const IndexRange &other) const
IndexRange(Index start, Index end)