Google OR-Tools: ortools/constraint_solver/routing_filters.h Source File
14#ifndef ORTOOLS_CONSTRAINT_SOLVER_ROUTING_FILTERS_H_
15#define ORTOOLS_CONSTRAINT_SOLVER_ROUTING_FILTERS_H_
27#include "absl/functional/any_invocable.h"
28#include "absl/strings/string_view.h"
29#include "absl/types/span.h"
50 int path, int64_t capacity, int64_t span_upper_bound,
51 absl::Span<const DimensionValues::Interval> cumul_of_node,
52 absl::Span<const DimensionValues::Interval> slack_of_node,
53 absl::AnyInvocable<int64_t(int64_t, int64_t) const> evaluator,
58 std::optional<absl::AnyInvocable<int64_t(int64_t, int64_t) const>>
60 std::optional<absl::AnyInvocable<int64_t(int64_t, int64_t) const>>
71 absl::Span<const std::pair<int64_t, int64_t>> interbreaks);
93 const RoutingModel& routing_model, bool filter_cost);
109 bool propagate_own_objective_value,
110 bool filter_objective_cost,
127 bool propagate_own_objective_value, bool filter_objective_cost);
191 int CommittedIndex(int node) const { return committed_index_[node]; }
196 PathState(int num_nodes, std::vector<int> path_start,
197 std::vector<int> path_end);
202 int NumNodes() const { return num_nodes_; }
204 int NumPaths() const { return num_paths_; }
206 int Start(int path) const { return path_start_end_[path].start; }
208 int End(int path) const { return path_start_end_[path].end; }
213 static constexpr int kLoop = -1;
216 int Path(int node) const { return committed_paths_[node]; }
219 const std::vector<int>& ChangedPaths() const { return changed_paths_; }
221 const std::vector<int>& ChangedLoops() const { return changed_loops_; }
223 ChainRange Chains(int path) const;
225 NodeRange Nodes(int path) const;
234 void ChangePath(int path, absl::Span<const ChainBounds> chains);
237 void ChangePath(int path, const std::initializer_list<ChainBounds>& chains) {
238 changed_paths_.push_back(path);
239 const int path_begin_index = chains_.size();
240 chains_.insert(chains_.end(), chains.begin(), chains.end());
241 const int path_end_index = chains_.size();
242 paths_[path] = {path_begin_index, path_end_index};
248 void ChangeLoops(absl::Span<const int> new_loops);
260 bool IsInvalid() const { return is_invalid_; }
267 PathStartEnd(int start, int end) : start(start), end(end) {}
279 void CopyNewPathAtEndOfNodes(int path);
290 std::vector<PathStartEnd> path_start_end_;
318 std::vector<int> committed_nodes_;
320 std::vector<int> committed_paths_;
322 std::vector<int> committed_index_;
323 const int num_nodes_threshold_;
324 std::vector<ChainBounds> chains_;
325 std::vector<PathBounds> paths_;
328 std::vector<int> changed_paths_;
338 class Iterator {
344 int operator*() const { return *current_node_; }
352 explicit Iterator(const int* node) : current_node_(node) {}
361 int NumNodes() const { return end_ - begin_; }
362 int First() const { return *begin_; }
377 class Iterator {
384 return {first_node_ + current_chain_->begin_index,
394 Iterator(const ChainBounds* chain, const int* const first_node)
395 : current_chain_(chain), first_node_(first_node) {}
403 const ChainBounds* const end_chain, const int* const first_node)
404 : begin_(begin_chain), end_(end_chain), first_node_(first_node) {}
410 return (begin_ == end_) ? *this : ChainRange(begin_ + 1, end_, first_node_);
414 return (begin_ == end_) ? *this : ChainRange(begin_, end_ - 1, first_node_);
427 class Iterator {
431 if (current_node_ == end_node_) {
435 const ChainBounds bounds = *current_chain_;
436 current_node_ = first_node_ + bounds.begin_index;
437 end_node_ = first_node_ + bounds.end_index;
441 int operator*() const { return *current_node_; }
449 Iterator(const ChainBounds* current_chain, const int* const first_node)
450 : current_node_(first_node + current_chain->begin_index),
451 end_node_(first_node + current_chain->end_index),
452 current_chain_(current_chain),
453 first_node_(first_node) {}
467 Iterator begin() const { return {begin_chain_, first_node_}; }
470 Iterator end() const { return {end_chain_, first_node_}; }
484 std::unique_ptr<PathState> path_state,
485 const std::vector<IntVar*>& nexts);
495 absl::Span<const PickupDeliveryPair> pairs,
496 const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
523 std::vector<Interval> path_capacity,
524 std::vector<int> path_class,
525 std::vector<std::function<Interval(int64_t, int64_t)>>
527 std::vector<Interval> node_capacity,
532 bool Check() const;
541 inline void UpdateCumulUsingChainRIQ(int first_index, int last_index,
552 void AppendPathDemandsToSums(int path);
558 void UpdateRIQStructure(int begin_index, int end_index);
560 const PathState* const path_state_;
561 const std::vector<ExtendedInterval> path_capacity_;
562 const std::vector<int> path_class_;
563 const std::vector<std::function<Interval(int64_t, int64_t)>>
565 std::vector<ExtendedInterval> cached_demand_;
566 const std::vector<ExtendedInterval> node_capacity_;
594 std::vector<std::vector<RIQNode>> riq_;
597 const int maximum_riq_layer_size_;
610 Solver* solver, std::unique_ptr<DimensionChecker> checker,
611 absl::string_view dimension_name);
640 std::vector<PathData> path_data);
642 void Relax() const;
644 bool Check() const;
652 Solver* solver, std::unique_ptr<LightVehicleBreaksChecker> checker,
653 absl::string_view dimension_name);
752 int TreeSize() const { return tree_location_.size(); }
755 void PushBack(int64_t height, int64_t weight) {
756 elements_.push_back({.height = height, .weight = weight});
784 std::vector<Element> elements_;
793 std::vector<TreeLocation> tree_location_;
800 bool operator<(const Node& other) const {
801 return pivot_height < other.pivot_height;
803 bool operator==(const Node& other) const {
804 return pivot_height == other.pivot_height;
835 std::vector<std::vector<ElementInfo>> tree_layers_;
846 bool range_first_is_node_first;
848 bool Empty() const { return range_first_index > range_last_index; }
850 int64_t Sum(const ElementInfo* elements) const {
851 return elements[range_last_index].prefix_sum -
852 (range_first_is_node_first
854 : elements[range_first_index - 1].prefix_sum);
857 ElementRange RightSubRange(const ElementInfo* els, int pivot_index) const {
861 (range_first_index - els[range_first_index].left_index),
864 (range_last_index - els[range_last_index].left_index) -
865 static_cast<int>(els[range_last_index].is_left),
866 .range_first_is_node_first = false};
867 right.range_first_is_node_first = right.range_first_index == pivot_index;
871 ElementRange LeftSubRange(const ElementInfo* els) const {
872 return {.range_first_index = els[range_first_index].left_index,
873 .range_last_index = els[range_last_index].left_index -
874 !els[range_last_index].is_left,
875 .range_first_is_node_first = range_first_is_node_first};
896 const PathState* path_state, std::vector<int64_t> force_start_min,
897 std::vector<int64_t> force_end_min, std::vector<int> force_class,
898 std::vector<const std::function<int64_t(int64_t)>*> force_per_class,
899 std::vector<int> distance_class,
900 std::vector<const std::function<int64_t(int64_t, int64_t)>*>
902 std::vector<EnergyCost> path_energy_cost,
903 std::vector<bool> path_has_cost_when_empty);
906 int64_t CommittedCost() const { return committed_total_cost_; }
907 int64_t AcceptedCost() const { return accepted_total_cost_; }
910 int64_t ComputePathCost(int64_t path) const;
911 void CacheAndPrecomputeRangeQueriesOfPath(int path);
912 void IncrementalCacheAndPrecompute();
913 void FullCacheAndPrecompute();
915 const PathState* const path_state_;
916 const std::vector<int64_t> force_start_min_;
917 const std::vector<int64_t> force_end_min_;
918 const std::vector<int> force_class_;
919 const std::vector<int> distance_class_;
920 const std::vector<const std::function<int64_t(int64_t)>*> force_per_class_;
921 const std::vector<const std::function<int64_t(int64_t, int64_t)>*>
923 const std::vector<EnergyCost> path_energy_cost_;
924 const std::vector<bool> path_has_cost_when_empty_;
927 const int maximum_range_query_size_;
931 std::vector<int> force_rmq_index_of_node_;
939 std::vector<int> threshold_query_index_of_node_;
941 std::vector<int64_t> cached_force_;
942 std::vector<int64_t> cached_distance_;
945 int64_t committed_total_cost_;
946 int64_t accepted_total_cost_;
951 Solver* solver, std::unique_ptr<PathEnergyCostChecker> checker,
952 absl::string_view dimension_name);
957 const PathState* path_state,
958 const std::vector<RoutingDimension*>& dimensions,
959 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
962 const std::vector<RoutingDimension*>& dimensions,
963 const RoutingSearchParameters& parameters, bool filter_objective_cost,
964 bool use_chain_cumul_filter,
965 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
971 BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size,
975 int64_t objective_min, int64_t objective_max) override;
992 int NumPaths() const { return paths_metadata_.NumPaths(); }
993 int64_t Start(int i) const { return paths_metadata_.Start(i); }
994 int64_t End(int i) const { return paths_metadata_.End(i); }
995 int GetPath(int64_t node) const { return paths_metadata_.GetPath(node); }
996 int Rank(int64_t node) const { return ranks_[node]; }
1000 bool PathStartTouched(int64_t start) const { return touched_paths_[start]; }
1008 virtual void OnBeforeSynchronizePaths(bool) {}
1009 virtual void OnAfterSynchronizePaths() {}
1010 virtual void OnSynchronizePathFromStart(int64_t) {}
1011 virtual bool InitializeAcceptPath() { return true; }
1012 virtual bool AcceptPath(int64_t path_start, int64_t chain_start,
1014 virtual bool FinalizeAcceptPath(int64_t, int64_t) { return true; }
1016 void ComputePathStarts(std::vector<int64_t>* path_starts,
1017 std::vector<int>* index_to_path);
1019 void SynchronizeFullAssignment();
1021 void UpdatePathRanksFromStart(int start);
1023 const PathsMetadata& paths_metadata_;
1024 std::vector<int64_t> node_path_starts_;
1025 SparseBitset<int64_t> new_synchronized_unperformed_nodes_;
1026 std::vector<int64_t> new_nexts_;
1027 std::vector<int> delta_touched_;
1028 SparseBitset<> touched_paths_;
1030 std::vector<std::pair<int64_t, int64_t> > touched_path_chain_start_ends_;
1090 const std::vector<std::vector<double>>& rows);
1092 double Evaluate(absl::Span<const double> values) const;
1097 static constexpr int kBlockSize = 16;
1099 std::array<double, kBlockSize> coefficients;
1101 Block& BlockMultiplyAdd(const Block& other, double value) {
1104 for (int i = 0; i < kBlockSize; ++i) {
1105 coefficients[i] += other.coefficients[i] * value;
1109 Block& MaximumWith(const Block& other) {
1110 for (int i = 0; i < kBlockSize; ++i) {
1111 coefficients[i] = std::max(coefficients[i], other.coefficients[i]);
1116 return *std::max_element(coefficients.begin(), coefficients.end());
1119 std::vector<Block> blocks_;
~BasePathFilter() override=default
static const int64_t kUnassigned
Definition routing_filters.h:979
int NumPaths() const
Definition routing_filters.h:992
bool lns_detected() const
Definition routing_filters.h:1005
bool PathStartTouched(int64_t start) const
Definition routing_filters.h:1000
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size, const PathsMetadata &paths_metadata)
int64_t GetNext(int64_t node) const
Definition routing_filters.h:981
const std::vector< int64_t > & GetTouchedPathStarts() const
Definition routing_filters.h:997
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64_t objective_min, int64_t objective_max) override
bool HasAnySyncedPath() const
Definition routing_filters.h:986
int GetPath(int64_t node) const
Definition routing_filters.h:995
int Rank(int64_t node) const
Definition routing_filters.h:996
const std::vector< int64_t > & GetNewSynchronizedUnperformedNodes() const
Definition routing_filters.h:1001
void OnSynchronize(const Assignment *delta) override
int64_t Start(int i) const
Definition routing_filters.h:993
int64_t End(int i) const
Definition routing_filters.h:994
DimensionChecker(const PathState *path_state, std::vector< Interval > path_capacity, std::vector< int > path_class, std::vector< std::function< Interval(int64_t, int64_t)> > demand_per_path_class, std::vector< Interval > node_capacity, int min_range_size_for_riq=kOptimalMinRangeSizeForRIQ)
static constexpr int kOptimalMinRangeSizeForRIQ
Definition routing_filters.h:538
IntVarLocalSearchFilter(const std::vector< IntVar * > &vars)
int64_t Value(int index) const
bool IsVarSynced(int index) const
LightVehicleBreaksChecker(PathState *path_state, std::vector< PathData > path_data)
double Evaluate(absl::Span< const double > values) const
MaxLinearExpressionEvaluator(const std::vector< std::vector< double > > &rows)
PathEnergyCostChecker(const PathState *path_state, std::vector< int64_t > force_start_min, std::vector< int64_t > force_end_min, std::vector< int > force_class, std::vector< const std::function< int64_t(int64_t)> * > force_per_class, std::vector< int > distance_class, std::vector< const std::function< int64_t(int64_t, int64_t)> * > distance_per_class, std::vector< EnergyCost > path_energy_cost, std::vector< bool > path_has_cost_when_empty)
int64_t AcceptedCost() const
Definition routing_filters.h:907
int64_t CommittedCost() const
Definition routing_filters.h:906
Definition routing_filters.h:377
bool operator!=(Iterator other) const
Definition routing_filters.h:387
Chain operator*() const
Definition routing_filters.h:383
friend class ChainRange
Definition routing_filters.h:393
Iterator & operator++()
Definition routing_filters.h:379
Definition routing_filters.h:375
ChainRange DropLastChain() const
Definition routing_filters.h:413
ChainRange DropFirstChain() const
Definition routing_filters.h:409
ChainRange(const ChainBounds *const begin_chain, const ChainBounds *const end_chain, const int *const first_node)
Definition routing_filters.h:402
Iterator end() const
Definition routing_filters.h:407
Iterator begin() const
Definition routing_filters.h:406
Definition routing_filters.h:338
bool operator!=(Iterator other) const
Definition routing_filters.h:345
int operator*() const
Definition routing_filters.h:344
Iterator & operator++()
Definition routing_filters.h:340
Definition routing_filters.h:336
Chain(const int *begin_node, const int *end_node)
Definition routing_filters.h:358
int Last() const
Definition routing_filters.h:363
int NumNodes() const
Definition routing_filters.h:361
Iterator end() const
Definition routing_filters.h:365
int First() const
Definition routing_filters.h:362
Iterator begin() const
Definition routing_filters.h:364
Chain WithoutFirstNode() const
Definition routing_filters.h:367
Definition routing_filters.h:427
Iterator & operator++()
Definition routing_filters.h:429
bool operator!=(Iterator other) const
Definition routing_filters.h:442
friend class NodeRange
Definition routing_filters.h:448
int operator*() const
Definition routing_filters.h:441
Definition routing_filters.h:425
NodeRange(const ChainBounds *begin_chain, const ChainBounds *end_chain, const int *first_node)
Definition routing_filters.h:462
Iterator end() const
Definition routing_filters.h:470
Iterator begin() const
Definition routing_filters.h:467
Definition routing_filters.h:170
int NumNodes() const
Definition routing_filters.h:202
void ChangeLoops(absl::Span< const int > new_loops)
bool IsInvalid() const
Definition routing_filters.h:260
const std::vector< int > & ChangedLoops() const
Definition routing_filters.h:221
const std::vector< int > & ChangedPaths() const
Definition routing_filters.h:219
ChainBounds CommittedPathRange(int path) const
Definition routing_filters.h:192
ChainRange Chains(int path) const
static constexpr int kUnassigned
Definition routing_filters.h:212
int NumPaths() const
Definition routing_filters.h:204
void SetInvalid()
Definition routing_filters.h:259
NodeRange Nodes(int path) const
int Path(int node) const
Definition routing_filters.h:216
int End(int path) const
Definition routing_filters.h:208
PathState(int num_nodes, std::vector< int > path_start, std::vector< int > path_end)
static constexpr int kLoop
Definition routing_filters.h:213
void ChangePath(int path, const std::initializer_list< ChainBounds > &chains)
Definition routing_filters.h:237
int CommittedIndex(int node) const
Definition routing_filters.h:191
void ChangePath(int path, absl::Span< const ChainBounds > chains)
int Start(int path) const
Definition routing_filters.h:206
Definition routing_filters.h:743
void MakeTreeFromNewElements()
WeightedWaveletTree()=default
void PushBack(int64_t height, int64_t weight)
Definition routing_filters.h:755
int64_t RangeSumWithThreshold(int64_t threshold_height, int begin_index, int end_index) const
int TreeSize() const
Definition routing_filters.h:752
LocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const PathState *path_state, absl::Span< const PickupDeliveryPair > pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model)
Returns a filter computing vehicle amortized costs.
bool FillDimensionValuesFromRoutingDimension(int path, int64_t capacity, int64_t span_upper_bound, absl::Span< const DimensionValues::Interval > cumul_of_node, absl::Span< const DimensionValues::Interval > slack_of_node, absl::AnyInvocable< int64_t(int64_t, int64_t) const > evaluator, DimensionValues &dimension_values)
IntVarLocalSearchFilter * MakeRouteConstraintFilter(const RoutingModel &routing_model)
Returns a filter tracking route constraints.
IntVarLocalSearchFilter * MakeSameVehicleCostFilter(const RoutingModel &routing_model)
Returns a filter computing same vehicle costs.
IntVarLocalSearchFilter * MakeMaxActiveVehiclesFilter(const RoutingModel &routing_model)
Returns a filter ensuring that max active vehicles constraints are enforced.
void AppendLightWeightDimensionFilters(const PathState *path_state, const std::vector< RoutingDimension * > &dimensions, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model, bool filter_cost)
Returns a filter ensuring that node disjunction constraints are enforced.
LocalSearchFilter * MakePathEnergyCostFilter(Solver *solver, std::unique_ptr< PathEnergyCostChecker > checker, absl::string_view dimension_name)
IntVarLocalSearchFilter * MakeCumulBoundsPropagatorFilter(const RoutingDimension &dimension)
Returns a filter handling dimension cumul bounds.
LocalSearchFilter * MakePathStateFilter(Solver *solver, std::unique_ptr< PathState > path_state, const std::vector< IntVar * > &nexts)
ClosedInterval::Iterator end(ClosedInterval interval)
LocalSearchFilter * MakeLightVehicleBreaksFilter(Solver *solver, std::unique_ptr< LightVehicleBreaksChecker > checker, absl::string_view dimension_name)
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, bool propagate_own_objective_value, bool filter_objective_cost, bool may_use_optimizers)
Returns a filter handling dimension costs and constraints.
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(RoutingModel *routing_model)
Returns a filter checking the current solution using CP propagation.
void FillPrePostVisitValues(int path, const DimensionValues &dimension_values, std::optional< absl::AnyInvocable< int64_t(int64_t, int64_t) const > > pre_travel_evaluator, std::optional< absl::AnyInvocable< int64_t(int64_t, int64_t) const > > post_travel_evaluator, PrePostVisitValues &visit_values)
IntVarLocalSearchFilter * MakeOrderedActivityGroupFilter(const RoutingModel &routing_model)
LocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model, const PathState *path_state)
Returns a filter checking that vehicle variable domains are respected.
void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters ¶meters, bool filter_objective_cost, bool use_chain_cumul_filter, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
LocalSearchFilter * MakeResourceAssignmentFilter(LocalDimensionCumulOptimizer *lp_optimizer, LocalDimensionCumulOptimizer *mp_optimizer, bool propagate_own_objective_value, bool filter_objective_cost)
bool PropagateLightweightVehicleBreaks(int path, DimensionValues &dimension_values, absl::Span< const std::pair< int64_t, int64_t > > interbreaks)
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
Returns a filter ensuring type regulation constraints are enforced.
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(GlobalDimensionCumulOptimizer *lp_optimizer, GlobalDimensionCumulOptimizer *mp_optimizer, bool filter_objective_cost)
Returns a filter checking global linear constraints and costs.
util_intops::StrongIntRange< ElementIndex > ElementRange
IntVarLocalSearchFilter * MakeActiveNodeGroupFilter(const RoutingModel &routing_model)
LocalSearchFilter * MakeDimensionFilter(Solver *solver, std::unique_ptr< DimensionChecker > checker, absl::string_view dimension_name)
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition routing_filters.h:513
int64_t min
Definition routing_filters.h:514
int64_t num_positive_infinity
Definition routing_filters.h:517
int64_t num_negative_infinity
Definition routing_filters.h:516
int64_t max
Definition routing_filters.h:515
Definition routing_filters.h:508
int64_t min
Definition routing_filters.h:509
int64_t max
Definition routing_filters.h:510
Definition routing_filters.h:625
int64_t max_interbreak_duration
Definition routing_filters.h:626
int64_t min_break_duration
Definition routing_filters.h:627
Definition routing_filters.h:630
std::vector< VehicleBreak > vehicle_breaks
Definition routing_filters.h:631
LocalSearchState::Variable start_cumul
Definition routing_filters.h:633
LocalSearchState::Variable end_cumul
Definition routing_filters.h:634
std::vector< InterbreakLimit > interbreak_limits
Definition routing_filters.h:632
LocalSearchState::Variable total_transit
Definition routing_filters.h:635
LocalSearchState::Variable span
Definition routing_filters.h:636
Definition routing_filters.h:616
int64_t start_max
Definition routing_filters.h:618
int64_t duration_min
Definition routing_filters.h:621
bool is_performed_max
Definition routing_filters.h:623
int64_t start_min
Definition routing_filters.h:617
int64_t end_min
Definition routing_filters.h:619
int64_t end_max
Definition routing_filters.h:620
bool is_performed_min
Definition routing_filters.h:622
Definition routing_filters.h:886
int64_t cost_per_unit_above_threshold
Definition routing_filters.h:889
bool IsNull() const
Definition routing_filters.h:890
int64_t threshold
Definition routing_filters.h:887
int64_t cost_per_unit_below_threshold
Definition routing_filters.h:888
Definition routing_filters.h:184
int end_index
Definition routing_filters.h:189
ChainBounds(int begin_index, int end_index)
Definition routing_filters.h:186
int begin_index
Definition routing_filters.h:188
static const int64_t kint64max