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;
76 void Set(
size_t index,
const T& value) {
78 DCHECK_LT(index, elements_.size());
80 elements_[index].current = value;
85 for (
const size_t index : changed_.PositionsSetAtLeastOnce()) {
86 elements_[index].current = elements_[index].committed;
93 for (
const size_t index : changed_.PositionsSetAtLeastOnce()) {
94 elements_[index].committed = elements_[index].current;
102 DCHECK_EQ(0, changed_.NumberOfSetCallsWithDifferentArguments());
103 elements_.assign(elements_.size(), {value, value});
108 DCHECK_LT(index, elements_.size());
109 return elements_[index].committed;
114 bool HasChanged(
size_t index)
const {
return changed_[index]; }
119 return changed_.PositionsSetAtLeastOnce();
127 struct VersionedElement {
132 std::vector<VersionedElement> elements_;
134 SparseBitset<size_t> changed_;
176 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
177 committed_range_of_path_(num_paths, {.begin = 0, .end = 0}),
180 vehicle_breaks_(num_paths),
181 committed_vehicle_breaks_(num_paths),
182 changed_paths_(num_paths),
183 max_num_committed_elements_(16 * num_nodes) {
184 nodes_.reserve(max_num_committed_elements_);
185 transit_.reserve(max_num_committed_elements_);
186 travel_.reserve(max_num_committed_elements_);
187 travel_sum_.reserve(max_num_committed_elements_);
188 cumul_.reserve(max_num_committed_elements_);
207 min = std::max(
min, lower_bound);
213 max = std::min(
max, upper_bound);
241 return {.min = std::numeric_limits<int64_t>::min(),
242 .max = std::numeric_limits<int64_t>::max()};
258 void PushNode(
int node) { nodes_.push_back(node); }
263 DCHECK_LT(path, range_of_path_.size());
264 DCHECK(!changed_paths_[path]);
265 range_of_path_[path] = {.begin = num_current_elements_,
266 .end = nodes_.size()};
267 changed_paths_.Set(path);
271 travel_.resize(nodes_.size(), 0);
272 travel_sum_.resize(nodes_.size(), 0);
274 num_current_elements_ = nodes_.size();
280 const int num_paths = range_of_path_.size();
281 range_of_path_.assign(num_paths, {.begin = 0, .end = 0});
282 committed_range_of_path_.assign(num_paths, {.begin = 0, .end = 0});
283 changed_paths_.SparseClearAll();
284 num_current_elements_ = 0;
285 num_committed_elements_ = 0;
296 for (
const int path : changed_paths_.PositionsSetAtLeastOnce()) {
297 range_of_path_[path] = committed_range_of_path_[path];
299 changed_paths_.SparseClearAll();
300 num_current_elements_ = num_committed_elements_;
301 nodes_.resize(num_current_elements_);
302 transit_.resize(num_current_elements_);
303 travel_.resize(num_current_elements_);
304 travel_sum_.resize(num_current_elements_);
305 cumul_.resize(num_current_elements_);
312 for (
const int path : changed_paths_.PositionsSetAtLeastOnce()) {
313 committed_range_of_path_[path] = range_of_path_[path];
314 committed_span_[path] = span_[path];
315 committed_vehicle_breaks_[path] = vehicle_breaks_[path];
317 changed_paths_.SparseClearAll();
318 num_committed_elements_ = num_current_elements_;
322 if (num_current_elements_ <= max_num_committed_elements_)
return;
324 temp_transit_.clear();
325 temp_travel_.clear();
326 temp_travel_sum_.clear();
328 for (
int path = 0; path < range_of_path_.size(); ++path) {
329 if (committed_range_of_path_[path].Size() == 0)
continue;
330 const size_t new_begin = temp_nodes_.size();
331 const auto [begin, end] = committed_range_of_path_[path];
332 temp_nodes_.insert(temp_nodes_.end(), nodes_.begin() + begin,
333 nodes_.begin() + end);
334 temp_transit_.insert(temp_transit_.end(), transit_.begin() + begin,
335 transit_.begin() + end);
336 temp_travel_.insert(temp_travel_.end(), travel_.begin() + begin,
337 travel_.begin() + end);
338 temp_travel_sum_.insert(temp_travel_sum_.end(),
339 travel_sum_.begin() + begin,
340 travel_sum_.begin() + end);
341 temp_cumul_.insert(temp_cumul_.end(), cumul_.begin() + begin,
342 cumul_.begin() + end);
343 committed_range_of_path_[path] = {.begin = new_begin,
344 .end = temp_nodes_.size()};
346 std::swap(nodes_, temp_nodes_);
347 std::swap(transit_, temp_transit_);
348 std::swap(travel_, temp_travel_);
349 std::swap(travel_sum_, temp_travel_sum_);
350 std::swap(cumul_, temp_cumul_);
351 range_of_path_ = committed_range_of_path_;
352 num_committed_elements_ = nodes_.size();
353 num_current_elements_ = nodes_.size();
358 const auto [begin, end] = committed_range_of_path_[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_[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_[path];
373 if (begin < end) --end;
374 return absl::MakeConstSpan(transit_.data() + begin, transit_.data() + end);
379 auto [begin, end] = range_of_path_[path];
382 if (begin < end) --end;
383 return absl::MakeSpan(transit_.data() + begin, transit_.data() + end);
388 absl::Span<const int64_t>
Travels(
int path)
const {
389 auto [begin, end] = range_of_path_[path];
390 if (begin < end) --end;
391 return absl::MakeConstSpan(travel_.data() + begin, travel_.data() + end);
397 auto [begin, end] = range_of_path_[path];
398 if (begin < end) --end;
399 return absl::MakeSpan(travel_.data() + begin, travel_.data() + end);
404 const auto [begin, end] = range_of_path_[path];
405 return absl::MakeConstSpan(travel_sum_.data() + begin,
406 travel_sum_.data() + end);
411 const auto [begin, end] = range_of_path_[path];
412 return absl::MakeSpan(travel_sum_.data() + begin, travel_sum_.data() + end);
416 absl::Span<const Interval>
Cumuls(
int path)
const {
417 const auto [begin, end] = range_of_path_[path];
418 return absl::MakeConstSpan(cumul_.data() + begin, cumul_.data() + end);
423 const auto [begin, end] = range_of_path_[path];
424 return absl::MakeSpan(cumul_.data() + begin, cumul_.data() + end);
429 return changed_paths_[path] ? span_[path] : committed_span_[path];
434 DCHECK(changed_paths_[path]);
441 return absl::MakeConstSpan(changed_paths_[path]
442 ? vehicle_breaks_[path]
443 : committed_vehicle_breaks_[path]);
449 DCHECK(changed_paths_[path]);
450 return vehicle_breaks_[path];
454 int NumNodes(
int path)
const {
return range_of_path_[path].Size(); }
457 return absl::MakeConstSpan(changed_paths_.PositionsSetAtLeastOnce());
476 std::vector<int> nodes_;
477 std::vector<Interval> transit_;
478 std::vector<int64_t> travel_;
479 std::vector<int64_t> travel_sum_;
480 std::vector<Interval> cumul_;
482 std::vector<int> temp_nodes_;
483 std::vector<Interval> temp_transit_;
484 std::vector<int64_t> temp_travel_;
485 std::vector<int64_t> temp_travel_sum_;
486 std::vector<Interval> temp_cumul_;
492 int Size()
const {
return end - begin; }
494 std::vector<Range> range_of_path_;
495 std::vector<Range> committed_range_of_path_;
497 std::vector<Interval> span_;
498 std::vector<Interval> committed_span_;
500 std::vector<std::vector<VehicleBreak>> vehicle_breaks_;
501 std::vector<std::vector<VehicleBreak>> committed_vehicle_breaks_;
503 SparseBitset<int> changed_paths_;
507 const size_t max_num_committed_elements_;
509 size_t num_current_elements_ = 0;
510 size_t num_committed_elements_ = 0;
const T & GetCommitted() const
void SetAndCommit(const T &value)
CommittableValue(const T &value)
void Commit()
Makes the current state committed, clearing all changes.
bool HasChanged(size_t index) const
size_t Size() const
Return the size of the vector.
CommittableVector(size_t num_elements, const T &value)
Makes a vector with initial elements all committed to value.
T Get(size_t index) const
void SetAllAndCommit(const T &value)
void Set(size_t index, const T &value)
Set the value stored at index in the current state to given value.
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
void Revert()
Changes the values of the vector to those in the last Commit().
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
absl::Span< const Interval > Cumuls(int path) const
Returns a const view of the cumul mins of the path, 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.
absl::Span< const int > ChangedPaths() const
Returns a const view of the set of paths changed, in the current state.
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)
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.
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)
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