Google OR-Tools v9.15
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 ORTOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
15#define ORTOOLS_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 // Set addition of intervals: adds other.min to the min, other.max to the
258 // max, with CapAdd().
259 Interval operator+(const Interval& other) const {
260 DCHECK(!IsEmpty());
261 DCHECK(!other.IsEmpty());
262 return {.min = CapAdd(min, other.min), .max = CapAdd(max, other.max)};
263 }
264 // Set addition, with intervals: adds other.min to the min, other.max to
265 // the max, with CapAdd().
266 void Add(const Interval& other) { *this = *this + other; }
267 // Set subtraction, with intervals: subtracts other.max from the min,
268 // other.min from the max, with CapSub().
269 Interval operator-(const Interval& other) const {
270 DCHECK(!IsEmpty());
271 DCHECK(!other.IsEmpty());
272 return {.min = CapSub(min, other.max), .max = CapSub(max, other.min)};
273 }
274 // Set subtraction, with intervals: subtracts other.max from the min,
275 // other.min from the max, with CapSub().
276 void Subtract(const Interval& other) { *this = *this - other; }
277 // Returns an interval containing all integers: {kint64min, kint64max}.
279 return {.min = std::numeric_limits<int64_t>::min(),
280 .max = std::numeric_limits<int64_t>::max()};
281 }
282 };
283
289 bool operator==(const VehicleBreak& other) const {
290 return start == other.start && end == other.end &&
291 duration == other.duration && is_performed == other.is_performed;
292 }
293 };
294
295 // Adds a node to new nodes.
296 void PushNode(int node) { nodes_.push_back(node); }
297
298 // Turns new nodes into a new path, allocating dimension values for it.
299 void MakePathFromNewNodes(int path) {
300 DCHECK_GE(path, 0);
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()});
305 // Allocate dimension values. We allocate n cells for all dimension values,
306 // even transits, so they can all be indexed by the same range_of_path.
307 transit_.resize(nodes_.size(), Interval::AllIntegers());
308 travel_.resize(nodes_.size(), 0);
309 travel_sum_.resize(nodes_.size(), 0);
310 cumul_.resize(nodes_.size(), Interval::AllIntegers());
311 num_elements_.Set(nodes_.size());
312 span_.Set(path, Interval::AllIntegers());
313 }
314
315 // Resets all path to empty, in both committed and current state.
316 void Reset() {
317 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
318 num_elements_.SetAndCommit(0);
319 nodes_.clear();
320 transit_.clear();
321 travel_.clear();
322 travel_sum_.clear();
323 cumul_.clear();
324 span_.SetAllAndCommit(Interval::AllIntegers());
325 }
326
327 // Clears the changed state, make it point to the committed state.
328 void Revert() {
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());
336 span_.Revert();
337 }
338
339 // Makes the committed state point to the current state.
340 // If the state representation is too large, reclaims memory by compacting
341 // the committed state.
342 void Commit() {
343 for (const int path : range_of_path_.ChangedIndices()) {
344 committed_vehicle_breaks_[path] = vehicle_breaks_[path];
345 }
346 range_of_path_.Commit();
347 num_elements_.Commit();
348 span_.Commit();
349 // If the committed data would take too much space, defragment it.
350 if (num_elements_.Get() <= max_num_committed_elements_) return;
351 DefragmentRanges(nodes_, range_of_path_, temp_ints_);
352 DefragmentRanges(transit_, range_of_path_, temp_intervals_);
353 DefragmentRanges(cumul_, range_of_path_, temp_intervals_);
354 DefragmentRanges(travel_, range_of_path_, temp_int64s_);
355 DefragmentRanges(travel_sum_, range_of_path_, temp_int64s_);
356 range_of_path_.Commit();
357 num_elements_.SetAndCommit(nodes_.size());
358 }
359
360 // Returns a const view of the nodes of the path, in the committed state.
361 absl::Span<const int> CommittedNodes(int path) const {
362 const auto [begin, end] = range_of_path_.GetCommitted(path);
363 return absl::MakeConstSpan(nodes_.data() + begin, nodes_.data() + end);
364 }
365
366 // Returns a const view of the nodes of the path, in the current state.
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);
370 }
371
372 // Returns a const view of the transits of the path, in the current state.
373 absl::Span<const Interval> Transits(int path) const {
374 auto [begin, end] = range_of_path_.Get(path);
375 // When the path is not empty, #transits = #nodes - 1.
376 // When the path is empty, begin = end, return empty span.
377 if (begin < end) --end;
378 return absl::MakeConstSpan(transit_.data() + begin, transit_.data() + end);
379 }
380
381 // Returns a mutable view of the transits of the path, in the current state.
382 absl::Span<Interval> MutableTransits(int path) {
383 auto [begin, end] = range_of_path_.Get(path);
384 // When the path is not empty, #transits = #nodes - 1.
385 // When the path is empty, begin = end, return empty span.
386 if (begin < end) --end;
387 return absl::MakeSpan(transit_.data() + begin, transit_.data() + end);
388 }
389
390 // Returns a const view of the travels of the path, in the committed state.
391 absl::Span<const int64_t> CommittedTravels(int path) const {
392 auto [begin, end] = range_of_path_.GetCommitted(path);
393 if (begin < end) --end;
394 return absl::MakeConstSpan(travel_.data() + begin, travel_.data() + end);
395 }
396
397 // Returns a const view of the travels of the path, in the current state.
398 absl::Span<const int64_t> Travels(int path) const {
399 auto [begin, end] = range_of_path_.Get(path);
400 if (begin < end) --end;
401 return absl::MakeConstSpan(travel_.data() + begin, travel_.data() + end);
402 }
403
404 // Returns a mutable view of the travels of the path, in the current state.
405 absl::Span<int64_t> MutableTravels(int path) {
406 auto [begin, end] = range_of_path_.Get(path);
407 if (begin < end) --end;
408 return absl::MakeSpan(travel_.data() + begin, travel_.data() + end);
409 }
410
411 // Returns a const view of the travel sums of the path, in the current state.
412 absl::Span<const int64_t> TravelSums(int path) const {
413 const auto [begin, end] = range_of_path_.Get(path);
414 return absl::MakeConstSpan(travel_sum_.data() + begin,
415 travel_sum_.data() + end);
416 }
417
418 // Returns a mutable view of the travel sums of the path in the current state.
419 absl::Span<int64_t> MutableTravelSums(int path) {
420 const auto [begin, end] = range_of_path_.Get(path);
421 return absl::MakeSpan(travel_sum_.data() + begin, travel_sum_.data() + end);
422 }
423
424 // Returns a const view of the cumul mins of the path, in the current state.
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);
428 }
429
430 // Returns a mutable view of the cumul mins of the path, in the current state.
431 absl::Span<Interval> MutableCumuls(int path) {
432 const auto [begin, end] = range_of_path_.Get(path);
433 return absl::MakeSpan(cumul_.data() + begin, cumul_.data() + end);
434 }
435
436 // Returns the span interval of the path, in the current state.
437 Interval Span(int path) const { return span_.Get(path); }
438
439 // Returns a mutable view of the span of the path, in the current state.
440 // The path must have been changed since the last commit.
442 DCHECK(range_of_path_.HasChanged(path));
443 return span_.GetMutable(path);
444 }
445
446 // Returns a const view of the vehicle breaks of the path, in the current
447 // state.
448 absl::Span<const VehicleBreak> VehicleBreaks(int path) const {
449 return absl::MakeConstSpan(range_of_path_.HasChanged(path)
450 ? vehicle_breaks_[path]
451 : committed_vehicle_breaks_[path]);
452 }
453
454 // Returns a mutable vector of the vehicle breaks of the path, in the current
455 // state. The path must have been changed since the last commit.
456 std::vector<VehicleBreak>& MutableVehicleBreaks(int path) {
457 DCHECK(range_of_path_.HasChanged(path));
458 return vehicle_breaks_[path];
459 }
460
461 // Returns the number of nodes of the path, in the current state.
462 int NumNodes(int path) const { return range_of_path_.Get(path).Size(); }
463 // Returns a const view of the set of paths changed, in the current state.
464 absl::Span<const size_t> ChangedPaths() const {
465 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
466 }
467 // Returns whether the given path was changed, in the current state.
468 bool PathHasChanged(int path) const {
469 return range_of_path_.HasChanged(path);
470 }
471
472 private:
473 // These vectors hold the data of both committed and current states.
474 // The ranges below determine which indices are associated to each path and
475 // each state. It is up to the user to maintain the following invariants:
476 // If range_of_path_[p] == {.begin = b, .end = e}, then, in the current
477 // state:
478 // - nodes_[i] for i in [b, e) are the nodes of the path p.
479 // - cumul_[r] + transit_[r] == cumul_[r+1] for r in [b, e-1).
480 // - travel_[r] <= transit_[r].min for r in [b, e-1).
481 // - travel_sum_[r] == sum_{r' in [0, r')} travel_[r'], for r in [b+1, e)
482 // - cumul[b] + span_[p] == cumul[e-1].
483 //
484 // The same invariants should hold for committed_range_of_path_ and the
485 // committed state.
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_;
491 // Temporary vectors used in Commit() during compaction.
492 std::vector<int> temp_ints_;
493 std::vector<Interval> temp_intervals_;
494 std::vector<int64_t> temp_int64s_;
495 // A path has a range of indices in the committed state and another one in the
496 // current state.
497 CommittableArray<IndexRange> range_of_path_;
498 // Associates span to each path.
500 // Associates vehicle breaks with each path.
501 // TODO(user): turns this into a committable vector.
502 std::vector<std::vector<VehicleBreak>> vehicle_breaks_;
503 std::vector<std::vector<VehicleBreak>> committed_vehicle_breaks_;
504 // Threshold for the size of the committed vector. This is purely heuristic:
505 // it should be more than the number of nodes so compactions do not occur at
506 // each submit, but ranges should not be too far apart to avoid cache misses.
507 const size_t max_num_committed_elements_;
508 // This locates the start of new nodes.
509 CommittableValue<size_t> num_elements_;
510};
511
512bool PropagateTransitAndSpan(int path, DimensionValues& dimension_values);
513
515 public:
516 PrePostVisitValues(int num_paths, int num_nodes)
517 : range_of_path_(num_paths, {.begin = 0, .end = 0}),
518 max_num_committed_elements_(16 * num_nodes),
519 num_elements_(0) {
520 pre_visit_.reserve(max_num_committed_elements_);
521 post_visit_.reserve(max_num_committed_elements_);
522 }
523
525
526 // Turns new nodes into a new path, allocating pre-post visit values for it.
527 void ChangePathSize(int path, int new_num_nodes) {
528 DCHECK_GE(path, 0);
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});
534 // Allocate dimension values. We allocate n cells for all dimension values,
535 // even transits, so they can all be indexed by the same range_of_path.
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);
540 }
541
542 // Resets all path to empty, in both committed and current state.
543 void Reset() {
544 range_of_path_.SetAllAndCommit({.begin = 0, .end = 0});
545 num_elements_.SetAndCommit(0);
546 pre_visit_.clear();
547 post_visit_.clear();
548 }
549
550 // Clears the changed state, makes it point to the committed state.
551 void Revert() {
552 range_of_path_.Revert();
553 num_elements_.Revert();
554 pre_visit_.resize(num_elements_.Get());
555 post_visit_.resize(num_elements_.Get());
556 }
557
558 // Makes the committed state point to the current state.
559 // If the state representation is too large, reclaims memory by compacting
560 // the committed state.
561 void Commit() {
562 range_of_path_.Commit();
563 num_elements_.Commit();
564 // If the committed data would take too much space, compact the data:
565 // copy committed data to the end of vectors, erase old data, refresh
566 // indexing (range_of_path_).
567 if (num_elements_.Get() <= max_num_committed_elements_) return;
568 DefragmentRanges(pre_visit_, range_of_path_, temp_int64s_);
569 DefragmentRanges(post_visit_, range_of_path_, temp_int64s_);
570 range_of_path_.Commit();
571 num_elements_.SetAndCommit(pre_visit_.size());
572 }
573
574 // Returns a const view of the pre-visits of the path, in the committed state.
575 absl::Span<const int64_t> CommittedPreVisits(int path) const {
576 auto [begin, end] = range_of_path_.GetCommitted(path);
577 return absl::MakeConstSpan(pre_visit_.data() + begin,
578 pre_visit_.data() + end);
579 }
580
581 // Returns a const view of the pre-visits of the path, in the current state.
582 absl::Span<const int64_t> PreVisits(int path) const {
583 auto [begin, end] = range_of_path_.Get(path);
584 return absl::MakeConstSpan(pre_visit_.data() + begin,
585 pre_visit_.data() + end);
586 }
587
588 // Returns a mutable view of the pre-visits of the path, in the current state.
589 absl::Span<int64_t> MutablePreVisits(int path) {
590 auto [begin, end] = range_of_path_.Get(path);
591 return absl::MakeSpan(pre_visit_.data() + begin, pre_visit_.data() + end);
592 }
593
594 // Returns a const view of the post-visits of the path, in the committed
595 // state.
596 absl::Span<const int64_t> CommittedPostVisits(int path) const {
597 auto [begin, end] = range_of_path_.GetCommitted(path);
598 return absl::MakeConstSpan(post_visit_.data() + begin,
599 post_visit_.data() + end);
600 }
601
602 // Returns a const view of the post-visits of the path, in the current state.
603 absl::Span<const int64_t> PostVisits(int path) const {
604 const auto [begin, end] = range_of_path_.Get(path);
605 return absl::MakeConstSpan(post_visit_.data() + begin,
606 post_visit_.data() + end);
607 }
608
609 // Returns a mutable view of the post-visits of the path in the current state.
610 absl::Span<int64_t> MutablePostVisits(int path) {
611 const auto [begin, end] = range_of_path_.Get(path);
612 return absl::MakeSpan(post_visit_.data() + begin, post_visit_.data() + end);
613 }
614
615 // Returns the number of nodes of the path, in the current state.
616 int NumNodes(int path) const { return range_of_path_.Get(path).Size(); }
617 // Returns a const view of the set of paths changed, in the current state.
618 absl::Span<const size_t> ChangedPaths() const {
619 return absl::MakeConstSpan(range_of_path_.ChangedIndices());
620 }
621 // Returns whether the given path was changed, in the current state.
622 bool PathHasChanged(int path) const {
623 return range_of_path_.HasChanged(path);
624 }
625
626 private:
627 // These vectors hold the data.
628 std::vector<int64_t> pre_visit_;
629 std::vector<int64_t> post_visit_;
630 // Temporary vector used in Commit() during compaction.
631 std::vector<int64_t> temp_int64s_;
632 // A path has a range of indices in the committed state and another one in the
633 // current state.
634 CommittableArray<IndexRange> range_of_path_;
635 // Threshold for the size of the committed vector. This is purely heuristic:
636 // it should be more than the number of nodes so compactions do not occur at
637 // each submit, but ranges should not be too far apart to avoid cache misses.
638 const size_t max_num_committed_elements_;
639 // This locates the start of new nodes.
640 CommittableValue<size_t> num_elements_;
641};
642
643} // namespace operations_research
644
645#endif // ORTOOLS_CONSTRAINT_SOLVER_ROUTING_FILTER_COMMITTABLES_H_
CommittableArray(size_t num_elements, const T &value)
const std::vector< size_t > & ChangedIndices() const
absl::Span< const int64_t > CommittedTravels(int path) const
absl::Span< Interval > MutableCumuls(int path)
absl::Span< const int64_t > Travels(int path) const
absl::Span< const Interval > Cumuls(int path) const
absl::Span< const size_t > ChangedPaths() const
absl::Span< const VehicleBreak > VehicleBreaks(int path) const
absl::Span< const Interval > Transits(int path) const
absl::Span< const int > Nodes(int path) const
absl::Span< Interval > MutableTransits(int path)
absl::Span< int64_t > MutableTravelSums(int path)
absl::Span< int64_t > MutableTravels(int path)
std::vector< VehicleBreak > & MutableVehicleBreaks(int path)
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
absl::Span< const size_t > ChangedPaths() const
void ChangePathSize(int path, int new_num_nodes)
absl::Span< const int64_t > CommittedPreVisits(int path) const
absl::Span< const int64_t > PreVisits(int path) const
OR-Tools root namespace.
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)
bool operator==(const IndexRange &other) const
IndexRange(Index start, Index end)
Definition base_types.h:284