Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
routing_filter_committables.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
16
17#include <algorithm>
18#include <cstddef>
19#include <cstdint>
20#include <limits>
21#include <vector>
22
23#include "absl/log/check.h"
24#include "absl/types/span.h"
25#include "ortools/util/bitset.h"
27
28namespace operations_research {
29
30// A vector that allows to revert back to a previously committed state,
31// get the set of changed indices, and get current and committed values.
32template <typename T>
34 public:
35 explicit CommittableValue(const T& value)
36 : current_(value), committed_(value) {}
37
38 const T& Get() const { return current_; }
39 const T& GetCommitted() const { return committed_; }
40
41 void Set(const T& value) { current_ = value; }
42
43 void SetAndCommit(const T& value) {
44 Set(value);
45 Commit();
46 }
47
48 void Revert() { current_ = committed_; }
49
50 void Commit() { committed_ = current_; }
51
52 private:
53 T current_;
54 T committed_;
55};
56
57template <typename T>
59 public:
60 // Makes a vector with initial elements all committed to value.
61 CommittableArray<T>(size_t num_elements, const T& value)
62 : elements_(num_elements, {value, value}), changed_(num_elements) {}
63
64 // Return the size of the vector.
65 size_t Size() const { return elements_.size(); }
66
67 // Returns a copy of the value stored at index in the current state.
68 // Does not return a reference, because the class needs to know when elements
69 // are modified.
70 T Get(size_t index) const {
71 DCHECK_LT(index, elements_.size());
72 return elements_[index].current;
73 }
74
75 // Returns a reference to the value stored at index in the current state,
76 // and sets the index as modified.
77 T& GetMutable(size_t index) {
78 DCHECK_LT(index, elements_.size());
79 changed_.Set(index);
80 return elements_[index].current;
81 }
82
83 // Set the value stored at index in the current state to given value.
84 void Set(size_t index, const T& value) {
85 DCHECK_GE(index, 0);
86 DCHECK_LT(index, elements_.size());
87 changed_.Set(index);
88 elements_[index].current = value;
89 }
90
91 // Changes the values of the vector to those in the last Commit().
92 void Revert() {
93 for (const size_t index : changed_.PositionsSetAtLeastOnce()) {
94 elements_[index].current = elements_[index].committed;
95 }
96 changed_.ResetAllToFalse();
97 }
98
99 // Makes the current state committed, clearing all changes.
100 void Commit() {
101 for (const size_t index : changed_.PositionsSetAtLeastOnce()) {
102 elements_[index].committed = elements_[index].current;
103 }
104 changed_.ResetAllToFalse();
105 }
106
107 // Sets all elements of this vector to given value, and commits to this state.
108 void SetAllAndCommit(const T& value) {
109 changed_.ResetAllToFalse();
110 elements_.assign(elements_.size(), {value, value});
111 }
112
113 // Returns a copy of the value stored at index in the last committed state.
114 T GetCommitted(size_t index) const {
115 DCHECK_LT(index, elements_.size());
116 return elements_[index].committed;
117 }
118
119 // Return true iff the value at index has been Set() since the last Commit()
120 // or Revert(), even if the current value is the same as the committed value.
121 bool HasChanged(size_t index) const { return changed_[index]; }
122
123 // Returns the set of indices that have been Set() since the last Commit() or
124 // Revert().
125 const std::vector<size_t>& ChangedIndices() const {
126 return changed_.PositionsSetAtLeastOnce();
127 }
128
129 // TODO(user): NotifyReverted(), to tell the class that the changes
130 // have brought the vector back to the committed state. This allows O(1)
131 // Revert(), Commit() and empty changed indices.
132
133 private:
134 struct VersionedElement {
135 T current;
136 T committed;
137 };
138 // Holds current and committed versions of values of this vector.
139 std::vector<VersionedElement> elements_;
140 // Holds indices that were Set() since the last Commit() or Revert().
141 SparseBitset<size_t> changed_;
142};
143
145 size_t begin = 0;
146 size_t end = 0;
147 int Size() const { return end - begin; }
148 bool operator==(const IndexRange& other) const {
149 return begin == other.begin && end == other.end;
150 }
151};
152
153// Given unchanged committable ranges representing ranges of indices in input,
154// copies the corresponding elements of input to contiguous ranges
155// of temp_container, swaps temp_container with input, and updates the
156// committable ranges to represent the new ranges in output.
157template <typename T>
158void DefragmentRanges(std::vector<T>& mutable_input,
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();
165 const auto [begin, end] = ranges.GetCommitted(i);
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()});
169 }
170 std::swap(mutable_input, temp_container);
171}
172
173// This class allows to represent a state of dimension values for all paths of
174// a vehicle routing problem. Values of interest for each path are:
175// - nodes,
176// - cumuls (min/max),
177// - transit times,
178// - sum of transit times since the beginning of the path,
179// - span (min/max).
180//
181// This class can maintain two states at once: a committed state and a current
182// state. The current state can be modified by first describing a path p to be
183// modified with PushNode() and MakePathFromNewNodes(). Then the dimension
184// values of this path can be modified with views returned by MutableXXX()
185// methods.
186//
187// When a set of paths has been modified, the caller can decide to definitely
188// change the committed state to the new state, or to revert to the committed
189// state.
190//
191// Operations are meant to be efficient:
192// - all path modifications, i.e. PushNode(), MakePathFromNewNodes(),
193// MutableXXX(), MutableSpan() operations are O(1).
194// - Revert() is O(num changed paths).
195// - Commit() has two behaviors:
196// - if there are less than max_num_committed_elements_ elements in the
197// committed state, then Commit() is O(num changed paths).
198// - otherwise, Commit() does a compaction of the committed state, in
199// O(num_nodes + num_paths).
200// The amortized cost of Commit(), when taking modifications into account,
201// is O(size of changed paths), because all modifications pay at worst
202// O(1) for its own compaction.
203//
204// Note that this class does not support the semantics associated with its
205// fields names, for instance it does not make sure that cumul_min <= cumul_max.
206// The field names are meant for readability for the user.
207// However, path sizes are enforced: if a path has n nodes, then it has
208// n fields for cumul min/max, n for transit_sums, and max(0, n-1) for transits.
210 public:
211 DimensionValues(int num_paths, int num_nodes)
212 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
213 span_(num_paths, Interval::AllIntegers()),
214 vehicle_breaks_(num_paths),
215 committed_vehicle_breaks_(num_paths),
216 max_num_committed_elements_(16 * num_nodes),
217 num_elements_(0) {
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_);
223 }
224
225 struct Interval {
226 int64_t min;
227 int64_t max;
228 // Tests inequality between intervals.
229 bool operator!=(const Interval& other) const {
230 return min != other.min || max != other.max;
231 }
232 // Tests equality between intervals.
233 bool operator==(const Interval& other) const {
234 return min == other.min && max == other.max;
235 }
236 // Returns true iff the interval is empty.
237 bool IsEmpty() const { return min > max; }
238 // Increases the min to be at least lower_bound,
239 // returns true iff the interval is nonempty.
240 bool IncreaseMin(int64_t lower_bound) {
241 min = std::max(min, lower_bound);
242 return min <= max;
243 }
244 // Decreases the max to be at most upper_bound,
245 // returns true iff the interval is nonempty.
246 bool DecreaseMax(int64_t upper_bound) {
247 max = std::min(max, upper_bound);
248 return min <= max;
249 }
250 // Intersects this interval with the other, returns true iff the interval
251 // is nonempty.
252 bool IntersectWith(const Interval& other) {
253 min = std::max(min, other.min);
254 max = std::min(max, other.max);
255 return min <= max;
256 }
257 // A set addition, with intervals: adds other.min to the min, other.max to
258 // the max, with CapAdd().
259 void Add(const Interval& other) {
260 DCHECK(!IsEmpty());
261 DCHECK(!other.IsEmpty());
262 min = CapAdd(min, other.min);
263 max = CapAdd(max, other.max);
264 }
265 // A set subtraction, with intervals: subtracts other.max from the min,
266 // other.min from the max, with CapSub().
267 void Subtract(const Interval& other) {
268 DCHECK(!IsEmpty());
269 DCHECK(!other.IsEmpty());
270 min = CapSub(min, other.max);
271 max = CapSub(max, other.min);
272 }
273 // Returns an interval containing all integers: {kint64min, kint64max}.
275 return {.min = std::numeric_limits<int64_t>::min(),
276 .max = std::numeric_limits<int64_t>::max()};
277 }
278 };
279
285 bool operator==(const VehicleBreak& other) const {
286 return start == other.start && end == other.end &&
287 duration == other.duration && is_performed == other.is_performed;
288 }
289 };
290
291 // Adds a node to new nodes.
292 void PushNode(int node) { nodes_.push_back(node); }
293
294 // Turns new nodes into a new path, allocating dimension values for it.
295 void MakePathFromNewNodes(int path) {
296 DCHECK_GE(path, 0);
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()});
301 // Allocate dimension values. We allocate n cells for all dimension values,
302 // even transits, so they can all be indexed by the same range_of_path.
303 transit_.resize(nodes_.size(), Interval::AllIntegers());
304 travel_.resize(nodes_.size(), 0);
305 travel_sum_.resize(nodes_.size(), 0);
306 cumul_.resize(nodes_.size(), Interval::AllIntegers());
307 num_elements_.Set(nodes_.size());
308 span_.Set(path, Interval::AllIntegers());
309 }
310
311 // Resets all path to empty, in both committed and current state.
312 void Reset() {
313 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
314 num_elements_.SetAndCommit(0);
315 nodes_.clear();
316 transit_.clear();
317 travel_.clear();
318 travel_sum_.clear();
319 cumul_.clear();
320 span_.SetAllAndCommit(Interval::AllIntegers());
321 }
322
323 // Clears the changed state, make it point to the committed state.
324 void Revert() {
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());
332 span_.Revert();
333 }
334
335 // Makes the committed state point to the current state.
336 // If the state representation is too large, reclaims memory by compacting
337 // the committed state.
338 void Commit() {
339 for (const int path : range_of_path_.ChangedIndices()) {
340 committed_vehicle_breaks_[path] = vehicle_breaks_[path];
341 }
342 range_of_path_.Commit();
343 num_elements_.Commit();
344 span_.Commit();
345 // If the committed data would take too much space, defragment it.
346 if (num_elements_.Get() <= max_num_committed_elements_) return;
347 DefragmentRanges(nodes_, range_of_path_, temp_ints_);
348 DefragmentRanges(transit_, range_of_path_, temp_intervals_);
349 DefragmentRanges(cumul_, range_of_path_, temp_intervals_);
350 DefragmentRanges(travel_, range_of_path_, temp_int64s_);
351 DefragmentRanges(travel_sum_, range_of_path_, temp_int64s_);
352 range_of_path_.Commit();
353 num_elements_.SetAndCommit(nodes_.size());
354 }
355
356 // Returns a const view of the nodes of the path, in the committed state.
357 absl::Span<const int> CommittedNodes(int path) const {
358 const auto [begin, end] = range_of_path_.GetCommitted(path);
359 return absl::MakeConstSpan(nodes_.data() + begin, nodes_.data() + end);
360 }
361
362 // Returns a const view of the nodes of the path, in the current state.
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);
366 }
367
368 // Returns a const view of the transits of the path, in the current state.
369 absl::Span<const Interval> Transits(int path) const {
370 auto [begin, end] = range_of_path_.Get(path);
371 // When the path is not empty, #transits = #nodes - 1.
372 // When the path is empty, begin = end, return empty span.
373 if (begin < end) --end;
374 return absl::MakeConstSpan(transit_.data() + begin, transit_.data() + end);
375 }
376
377 // Returns a mutable view of the transits of the path, in the current state.
378 absl::Span<Interval> MutableTransits(int path) {
379 auto [begin, end] = range_of_path_.Get(path);
380 // When the path is not empty, #transits = #nodes - 1.
381 // When the path is empty, begin = end, return empty span.
382 if (begin < end) --end;
383 return absl::MakeSpan(transit_.data() + begin, transit_.data() + end);
384 }
385
386 // Returns a const view of the travels of the path, in the committed state.
387 absl::Span<const int64_t> CommittedTravels(int path) const {
388 auto [begin, end] = range_of_path_.GetCommitted(path);
389 if (begin < end) --end;
390 return absl::MakeConstSpan(travel_.data() + begin, travel_.data() + end);
391 }
392
393 // Returns a const view of the travels of the path, in the current state.
394 absl::Span<const int64_t> Travels(int path) const {
395 auto [begin, end] = range_of_path_.Get(path);
396 if (begin < end) --end;
397 return absl::MakeConstSpan(travel_.data() + begin, travel_.data() + end);
398 }
399
400 // Returns a mutable view of the travels of the path, in the current state.
401 absl::Span<int64_t> MutableTravels(int path) {
402 auto [begin, end] = range_of_path_.Get(path);
403 if (begin < end) --end;
404 return absl::MakeSpan(travel_.data() + begin, travel_.data() + end);
405 }
406
407 // Returns a const view of the travel sums of the path, in the current state.
408 absl::Span<const int64_t> TravelSums(int path) const {
409 const auto [begin, end] = range_of_path_.Get(path);
410 return absl::MakeConstSpan(travel_sum_.data() + begin,
411 travel_sum_.data() + end);
412 }
413
414 // Returns a mutable view of the travel sums of the path in the current state.
415 absl::Span<int64_t> MutableTravelSums(int path) {
416 const auto [begin, end] = range_of_path_.Get(path);
417 return absl::MakeSpan(travel_sum_.data() + begin, travel_sum_.data() + end);
418 }
419
420 // Returns a const view of the cumul mins of the path, in the current state.
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);
424 }
425
426 // Returns a mutable view of the cumul mins of the path, in the current state.
427 absl::Span<Interval> MutableCumuls(int path) {
428 const auto [begin, end] = range_of_path_.Get(path);
429 return absl::MakeSpan(cumul_.data() + begin, cumul_.data() + end);
430 }
431
432 // Returns the span interval of the path, in the current state.
433 Interval Span(int path) const { return span_.Get(path); }
434
435 // Returns a mutable view of the span of the path, in the current state.
436 // The path must have been changed since the last commit.
438 DCHECK(range_of_path_.HasChanged(path));
439 return span_.GetMutable(path);
440 }
441
442 // Returns a const view of the vehicle breaks of the path, in the current
443 // state.
444 absl::Span<const VehicleBreak> VehicleBreaks(int path) const {
445 return absl::MakeConstSpan(range_of_path_.HasChanged(path)
446 ? vehicle_breaks_[path]
447 : committed_vehicle_breaks_[path]);
448 }
449
450 // Returns a mutable vector of the vehicle breaks of the path, in the current
451 // state. The path must have been changed since the last commit.
452 std::vector<VehicleBreak>& MutableVehicleBreaks(int path) {
453 DCHECK(range_of_path_.HasChanged(path));
454 return vehicle_breaks_[path];
455 }
456
457 // Returns the number of nodes of the path, in the current state.
458 int NumNodes(int path) const { return range_of_path_.Get(path).Size(); }
459 // Returns a const view of the set of paths changed, in the current state.
460 absl::Span<const size_t> ChangedPaths() const {
461 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
462 }
463 // Returns whether the given path was changed, in the current state.
464 bool PathHasChanged(int path) const {
465 return range_of_path_.HasChanged(path);
466 }
467
468 private:
469 // These vectors hold the data of both committed and current states.
470 // The ranges below determine which indices are associated to each path and
471 // each state. It is up to the user to maintain the following invariants:
472 // If range_of_path_[p] == {.begin = b, .end = e}, then, in the current
473 // state:
474 // - nodes_[i] for i in [b, e) are the nodes of the path p.
475 // - cumul_[r] + transit_[r] == cumul_[r+1] for r in [b, e-1).
476 // - travel_[r] <= transit_[r].min for r in [b, e-1).
477 // - travel_sum_[r] == sum_{r' in [0, r')} travel_[r'], for r in [b+1, e)
478 // - cumul[b] + span_[p] == cumul[e-1].
479 //
480 // The same invariants should hold for committed_range_of_path_ and the
481 // committed state.
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_;
487 // Temporary vectors used in Commit() during compaction.
488 std::vector<int> temp_ints_;
489 std::vector<Interval> temp_intervals_;
490 std::vector<int64_t> temp_int64s_;
491 // A path has a range of indices in the committed state and another one in the
492 // current state.
493 CommittableArray<IndexRange> range_of_path_;
494 // Associates span to each path.
496 // Associates vehicle breaks with each path.
497 // TODO(user): turns this into a committable vector.
498 std::vector<std::vector<VehicleBreak>> vehicle_breaks_;
499 std::vector<std::vector<VehicleBreak>> committed_vehicle_breaks_;
500 // Threshold for the size of the committed vector. This is purely heuristic:
501 // it should be more than the number of nodes so compactions do not occur at
502 // each submit, but ranges should not be too far apart to avoid cache misses.
503 const size_t max_num_committed_elements_;
504 // This locates the start of new nodes.
505 CommittableValue<size_t> num_elements_;
506};
507
509 public:
510 PrePostVisitValues(int num_paths, int num_nodes)
511 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
512 max_num_committed_elements_(16 * num_nodes),
513 num_elements_(0) {
514 pre_visit_.reserve(max_num_committed_elements_);
515 post_visit_.reserve(max_num_committed_elements_);
516 }
517
519
520 // Turns new nodes into a new path, allocating pre-post visit values for it.
521 void ChangePathSize(int path, int new_num_nodes) {
522 DCHECK_GE(path, 0);
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});
528 // Allocate dimension values. We allocate n cells for all dimension values,
529 // even transits, so they can all be indexed by the same range_of_path.
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);
534 }
535
536 // Resets all path to empty, in both committed and current state.
537 void Reset() {
538 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
539 num_elements_.SetAndCommit(0);
540 pre_visit_.clear();
541 post_visit_.clear();
542 }
543
544 // Clears the changed state, makes it point to the committed state.
545 void Revert() {
546 range_of_path_.Revert();
547 num_elements_.Revert();
548 pre_visit_.resize(num_elements_.Get());
549 post_visit_.resize(num_elements_.Get());
550 }
551
552 // Makes the committed state point to the current state.
553 // If the state representation is too large, reclaims memory by compacting
554 // the committed state.
555 void Commit() {
556 range_of_path_.Commit();
557 num_elements_.Commit();
558 // If the committed data would take too much space, compact the data:
559 // copy committed data to the end of vectors, erase old data, refresh
560 // indexing (range_of_path_).
561 if (num_elements_.Get() <= max_num_committed_elements_) return;
562 DefragmentRanges(pre_visit_, range_of_path_, temp_int64s_);
563 DefragmentRanges(post_visit_, range_of_path_, temp_int64s_);
564 range_of_path_.Commit();
565 num_elements_.SetAndCommit(pre_visit_.size());
566 }
567
568 // Returns a const view of the pre-visits of the path, in the committed state.
569 absl::Span<const int64_t> CommittedPreVisits(int path) const {
570 auto [begin, end] = range_of_path_.GetCommitted(path);
571 return absl::MakeConstSpan(pre_visit_.data() + begin,
572 pre_visit_.data() + end);
573 }
574
575 // Returns a const view of the pre-visits of the path, in the current state.
576 absl::Span<const int64_t> PreVisits(int path) const {
577 auto [begin, end] = range_of_path_.Get(path);
578 return absl::MakeConstSpan(pre_visit_.data() + begin,
579 pre_visit_.data() + end);
580 }
581
582 // Returns a mutable view of the pre-visits of the path, in the current state.
583 absl::Span<int64_t> MutablePreVisits(int path) {
584 auto [begin, end] = range_of_path_.Get(path);
585 return absl::MakeSpan(pre_visit_.data() + begin, pre_visit_.data() + end);
586 }
587
588 // Returns a const view of the post-visits of the path, in the committed
589 // state.
590 absl::Span<const int64_t> CommittedPostVisits(int path) const {
591 auto [begin, end] = range_of_path_.GetCommitted(path);
592 return absl::MakeConstSpan(post_visit_.data() + begin,
593 post_visit_.data() + end);
594 }
595
596 // Returns a const view of the post-visits of the path, in the current state.
597 absl::Span<const int64_t> PostVisits(int path) const {
598 const auto [begin, end] = range_of_path_.Get(path);
599 return absl::MakeConstSpan(post_visit_.data() + begin,
600 post_visit_.data() + end);
601 }
602
603 // Returns a mutable view of the post-visits of the path in the current state.
604 absl::Span<int64_t> MutablePostVisits(int path) {
605 const auto [begin, end] = range_of_path_.Get(path);
606 return absl::MakeSpan(post_visit_.data() + begin, post_visit_.data() + end);
607 }
608
609 // Returns the number of nodes of the path, in the current state.
610 int NumNodes(int path) const { return range_of_path_.Get(path).Size(); }
611 // Returns a const view of the set of paths changed, in the current state.
612 absl::Span<const size_t> ChangedPaths() const {
613 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
614 }
615 // Returns whether the given path was changed, in the current state.
616 bool PathHasChanged(int path) const {
617 return range_of_path_.HasChanged(path);
618 }
619
620 private:
621 // These vectors hold the data.
622 std::vector<int64_t> pre_visit_;
623 std::vector<int64_t> post_visit_;
624 // Temporary vector used in Commit() during compaction.
625 std::vector<int64_t> temp_int64s_;
626 // A path has a range of indices in the committed state and another one in the
627 // current state.
628 CommittableArray<IndexRange> range_of_path_;
629 // Threshold for the size of the committed vector. This is purely heuristic:
630 // it should be more than the number of nodes so compactions do not occur at
631 // each submit, but ranges should not be too far apart to avoid cache misses.
632 const size_t max_num_committed_elements_;
633 // This locates the start of new nodes.
634 CommittableValue<size_t> num_elements_;
635};
636
637} // namespace operations_research
638
639#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
void Revert()
Changes the values of the vector to those in the last Commit().
CommittableArray(size_t num_elements, const T &value)
Makes a vector with initial elements all committed to value.
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 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.
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.
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.
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.
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.
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 operator==(const Interval &other) const
Tests equality between intervals.
bool operator!=(const Interval &other) const
Tests inequality between intervals.
bool IsEmpty() const
Returns true iff the interval is empty.
bool operator==(const IndexRange &other) const
IndexRange(Index start, Index end)
Definition base_types.h:284