C++ Reference

C++ Reference: Routing

routing.h
Go to the documentation of this file.
1 // Copyright 2010-2018 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 
68 // TODO(user): Add a section on costs (vehicle arc costs, span costs,
69 // disjunctions costs).
70 //
156 
157 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
158 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
159 
160 #include <cstddef>
161 #include <functional>
162 #include <memory>
163 #include <queue>
164 #include <string>
165 #include <utility>
166 #include <vector>
167 
168 #include "absl/container/flat_hash_map.h"
169 #include "absl/container/flat_hash_set.h"
170 #include "absl/functional/bind_front.h"
171 #include "absl/hash/hash.h"
172 #include "absl/time/time.h"
173 #include "ortools/base/adjustable_priority_queue-inl.h"
174 #include "ortools/base/adjustable_priority_queue.h"
175 #include "ortools/base/commandlineflags.h"
176 #include "ortools/base/hash.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
179 #include "ortools/base/strong_vector.h"
186 #include "ortools/glop/lp_solver.h"
187 #include "ortools/glop/parameters.pb.h"
188 #include "ortools/graph/graph.h"
189 #include "ortools/lp_data/lp_data.h"
190 #include "ortools/lp_data/lp_types.h"
191 #include "ortools/sat/theta_tree.h"
192 #include "ortools/util/range_query_function.h"
193 #include "ortools/util/sorted_interval_list.h"
194 
195 namespace operations_research {
196 
197 class GlobalDimensionCumulOptimizer;
198 class LocalDimensionCumulOptimizer;
199 class LocalSearchOperator;
200 #ifndef SWIG
201 class IntVarFilteredDecisionBuilder;
202 class IntVarFilteredHeuristic;
203 class IndexNeighborFinder;
204 #endif
205 class RoutingDimension;
206 #ifndef SWIG
207 using util::ReverseArcListGraph;
208 class SweepArranger;
209 #endif
210 struct SweepIndex;
211 
213  public:
215  enum Status {
226  };
227 
236  };
237  typedef RoutingCostClassIndex CostClassIndex;
238  typedef RoutingDimensionIndex DimensionIndex;
239  typedef RoutingDisjunctionIndex DisjunctionIndex;
240  typedef RoutingVehicleClassIndex VehicleClassIndex;
243 
244 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
245 #if !defined(SWIG)
248 #endif // SWIG
249 
250 #if !defined(SWIG)
251  struct StateDependentTransit {
264  RangeIntToIntFunction* transit;
265  RangeMinMaxIndexFunction* transit_plus_identity;
266  };
267  typedef std::function<StateDependentTransit(int64, int64)>
269 #endif // SWIG
270 
271 #if !defined(SWIG)
272  struct CostClass {
275 
290 
296  struct DimensionCost {
300  bool operator<(const DimensionCost& cost) const {
303  }
304  return cost_coefficient < cost.cost_coefficient;
305  }
306  };
307  std::vector<DimensionCost>
309 
312 
314  static bool LessThan(const CostClass& a, const CostClass& b) {
315  if (a.evaluator_index != b.evaluator_index) {
316  return a.evaluator_index < b.evaluator_index;
317  }
320  }
321  };
322 
323  struct VehicleClass {
327  int64 fixed_cost;
332  // TODO(user): Find equivalent start/end nodes wrt dimensions and
333  // callbacks.
338  absl::StrongVector<DimensionIndex, int64> dimension_start_cumuls_min;
339  absl::StrongVector<DimensionIndex, int64> dimension_start_cumuls_max;
340  absl::StrongVector<DimensionIndex, int64> dimension_end_cumuls_min;
341  absl::StrongVector<DimensionIndex, int64> dimension_end_cumuls_max;
342  absl::StrongVector<DimensionIndex, int64> dimension_capacities;
345  absl::StrongVector<DimensionIndex, int64> dimension_evaluator_classes;
348 
350  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
351  };
352 #endif // defined(SWIG)
353 
360  int64 fixed_cost;
361 
362  bool operator<(const VehicleClassEntry& other) const {
363  return std::tie(fixed_cost, vehicle_class) <
364  std::tie(other.fixed_cost, other.vehicle_class);
365  }
366  };
367 
368  int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
369 
370  int Type(int vehicle) const {
371  DCHECK_LT(vehicle, type_index_of_vehicle.size());
372  return type_index_of_vehicle[vehicle];
373  }
374 
375  std::vector<int> type_index_of_vehicle;
376  // clang-format off
377  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
378  std::vector<std::deque<int> > vehicles_per_vehicle_class;
379  // clang-format on
380  };
381 
383  static const int64 kNoPenalty;
384 
388 
392 
396  explicit RoutingModel(const RoutingIndexManager& index_manager);
397  RoutingModel(const RoutingIndexManager& index_manager,
398  const RoutingModelParameters& parameters);
400 
407  const TransitCallback2& TransitCallback(int callback_index) const {
408  CHECK_LT(callback_index, transit_evaluators_.size());
409  return transit_evaluators_[callback_index];
410  }
411  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
412  CHECK_LT(callback_index, unary_transit_evaluators_.size());
413  return unary_transit_evaluators_[callback_index];
414  }
416  int callback_index) const {
417  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
418  return state_dependent_transit_evaluators_[callback_index];
419  }
420 
422 
434 
443  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
444  bool fix_start_cumul_to_zero, const std::string& name);
446  const std::vector<int>& evaluator_indices, int64 slack_max,
447  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
448  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
449  std::vector<int64> vehicle_capacities,
450  bool fix_start_cumul_to_zero,
451  const std::string& name);
453  const std::vector<int>& evaluator_indices, int64 slack_max,
454  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
455  const std::string& name);
462  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
463  int64 slack_max,
464  bool fix_start_cumul_to_zero,
465  const std::string& name);
466  bool AddConstantDimension(int64 value, int64 capacity,
467  bool fix_start_cumul_to_zero,
468  const std::string& name) {
469  return AddConstantDimensionWithSlack(value, capacity, 0,
470  fix_start_cumul_to_zero, name);
471  }
479  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
480  bool fix_start_cumul_to_zero,
481  const std::string& name);
490  std::vector<std::vector<int64> /*needed_for_swig*/> values,
491  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
499  const std::vector<int>& pure_transits,
500  const std::vector<int>& dependent_transits,
501  const RoutingDimension* base_dimension, int64 slack_max,
502  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
503  const std::string& name) {
504  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
505  pure_transits, dependent_transits, base_dimension, slack_max,
506  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
507  }
508 
511  const std::vector<int>& transits, const RoutingDimension* base_dimension,
512  int64 slack_max, std::vector<int64> vehicle_capacities,
513  bool fix_start_cumul_to_zero, const std::string& name);
516  int transit, const RoutingDimension* base_dimension, int64 slack_max,
517  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
518  const std::string& name);
520  int pure_transit, int dependent_transit,
521  const RoutingDimension* base_dimension, int64 slack_max,
522  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
523  const std::string& name);
524 
527  const std::function<int64(int64)>& f, int64 domain_start,
528  int64 domain_end);
529 
540  std::vector<IntVar*> spans,
541  std::vector<IntVar*> total_slacks);
542 
544  // TODO(user): rename.
545  std::vector<std::string> GetAllDimensionNames() const;
547  const std::vector<RoutingDimension*>& GetDimensions() const {
548  return dimensions_.get();
549  }
551  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
552  // clang-format off
555  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
557  return global_dimension_optimizers_;
558  }
559  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
561  return local_dimension_optimizers_;
562  }
563  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
565  return local_dimension_mp_optimizers_;
566  }
567  // clang-format on
568 
572  const RoutingDimension& dimension) const;
574  const RoutingDimension& dimension) const;
576  const RoutingDimension& dimension) const;
577 
579  bool HasDimension(const std::string& dimension_name) const;
582  const std::string& dimension_name) const;
586  const std::string& dimension_name) const;
591  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
592  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
593  primary_constrained_dimension_ = dimension_name;
594  }
596  const std::string& GetPrimaryConstrainedDimension() const {
597  return primary_constrained_dimension_;
598  }
615  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
616  int64 penalty = kNoPenalty,
617  int64 max_cardinality = 1);
619  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
620  int64 index) const {
621  return index_to_disjunctions_[index];
622  }
626  template <typename F>
628  int64 index, int64 max_cardinality, F f) const {
629  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
630  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
631  for (const int64 d_index : disjunctions_[disjunction].indices) {
632  f(d_index);
633  }
634  }
635  }
636  }
637 #if !defined(SWIGPYTHON)
638  const std::vector<int64>& GetDisjunctionIndices(
641  DisjunctionIndex index) const {
642  return disjunctions_[index].indices;
643  }
644 #endif // !defined(SWIGPYTHON)
645  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
647  return disjunctions_[index].value.penalty;
648  }
652  return disjunctions_[index].value.max_cardinality;
653  }
655  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
660  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
667 
671  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
672  int64 cost);
673 
678  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
679  int64 index);
680 
682  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
683  return allowed_vehicles_[index].empty() ||
684  allowed_vehicles_[index].find(vehicle) !=
685  allowed_vehicles_[index].end();
686  }
687 
702  // TODO(user): Remove this when model introspection detects linked nodes.
703  void AddPickupAndDelivery(int64 pickup, int64 delivery);
708  DisjunctionIndex delivery_disjunction);
709  // clang-format off
713  const std::vector<std::pair<int, int> >&
714  GetPickupIndexPairs(int64 node_index) const;
716  const std::vector<std::pair<int, int> >&
717  GetDeliveryIndexPairs(int64 node_index) const;
718  // clang-format on
719 
724  int vehicle);
726  int vehicle) const;
729 
731 
732 #ifndef SWIG
733  const IndexPairs& GetPickupAndDeliveryPairs() const {
735  return pickup_delivery_pairs_;
736  }
737  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
739  return pickup_delivery_disjunctions_;
740  }
746  DCHECK(closed_);
747  return implicit_pickup_delivery_pairs_without_alternatives_;
748  }
749 #endif // SWIG
750  enum VisitTypePolicy {
777  };
778  // TODO(user): Support multiple visit types per node?
779  void SetVisitType(int64 index, int type, VisitTypePolicy type_policy);
780  int GetVisitType(int64 index) const;
781  const std::vector<int>& GetSingleNodesOfType(int type) const;
782  const std::vector<int>& GetPairIndicesOfType(int type) const;
786  // TODO(user): Reconsider the logic and potentially remove the need to
789  int GetNumberOfVisitTypes() const { return num_visit_types_; }
790 #ifndef SWIG
791  const std::vector<std::vector<int>>& GetTopologicallySortedVisitTypes()
792  const {
793  DCHECK(closed_);
794  return topologically_sorted_visit_types_;
795  }
796 #endif // SWIG
797  void AddHardTypeIncompatibility(int type1, int type2);
802  void AddTemporalTypeIncompatibility(int type1, int type2);
804  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
805  int type) const;
806  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
807  int type) const;
811  return has_hard_type_incompatibilities_;
812  }
814  return has_temporal_type_incompatibilities_;
815  }
827  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
833  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
840  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
841  // clang-format off
844  const std::vector<absl::flat_hash_set<int> >&
847  const std::vector<absl::flat_hash_set<int> >&
850  const std::vector<absl::flat_hash_set<int> >&
852  // clang-format on
856  return has_same_vehicle_type_requirements_;
857  }
859  return has_temporal_type_requirements_;
860  }
861 
864  bool HasTypeRegulations() const {
868  }
869 
874  int64 UnperformedPenalty(int64 var_index) const;
878  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
882  int64 GetDepot() const;
883 
888  void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
889  max_active_vehicles_ = max_active_vehicles;
890  }
892  int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
896  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
898  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
901  void SetFixedCostOfAllVehicles(int64 cost);
903  void SetFixedCostOfVehicle(int64 cost, int vehicle);
907  int64 GetFixedCostOfVehicle(int vehicle) const;
908 
924  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
925  int64 quadratic_cost_factor);
927  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
928  int64 quadratic_cost_factor,
929  int vehicle);
930 
931  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
932  return linear_cost_factor_of_vehicle_;
933  }
934  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
935  return quadratic_cost_factor_of_vehicle_;
936  }
937 
938  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
939  DCHECK_LT(vehicle, vehicles_);
940  consider_empty_route_costs_[vehicle] = consider_costs;
941  }
942 
943  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
944  DCHECK_LT(vehicle, vehicles_);
945  return consider_empty_route_costs_[vehicle];
946  }
947 
950 #ifndef SWIG
952  return first_solution_evaluator_;
953  }
954 #endif
957  first_solution_evaluator_ = std::move(evaluator);
958  }
963  void AddSearchMonitor(SearchMonitor* const monitor);
967  void AddAtSolutionCallback(std::function<void()> callback);
981  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
988  void CloseModel();
992  const RoutingSearchParameters& search_parameters);
999  const Assignment* Solve(const Assignment* assignment = nullptr);
1008  const RoutingSearchParameters& search_parameters,
1009  std::vector<const Assignment*>* solutions = nullptr);
1011  const Assignment* assignment,
1012  const RoutingSearchParameters& search_parameters,
1013  std::vector<const Assignment*>* solutions = nullptr);
1020  Assignment* target_assignment, const RoutingModel* source_model,
1021  const Assignment* source_assignment);
1027  // TODO(user): Add support for non-homogeneous costs and disjunctions.
1030  Status status() const { return status_; }
1039  IntVar* ApplyLocks(const std::vector<int64>& locks);
1048  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
1049  bool close_routes);
1054  const Assignment* const PreAssignment() const { return preassignment_; }
1055  Assignment* MutablePreAssignment() { return preassignment_; }
1059  bool WriteAssignment(const std::string& file_name) const;
1063  Assignment* ReadAssignment(const std::string& file_name);
1073  const std::vector<std::vector<int64>>& routes,
1074  bool ignore_inactive_indices);
1091  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
1092  bool ignore_inactive_indices, bool close_routes,
1093  Assignment* const assignment) const;
1097  void AssignmentToRoutes(const Assignment& assignment,
1098  std::vector<std::vector<int64>>* const routes) const;
1103 #ifndef SWIG
1104  std::vector<std::vector<int64>> GetRoutesFromAssignment(
1105  const Assignment& assignment);
1106 #endif
1107  Assignment* CompactAssignment(const Assignment& assignment) const;
1130  void AddToAssignment(IntVar* const var);
1131  void AddIntervalToAssignment(IntervalVar* const interval);
1143  const Assignment* original_assignment, absl::Duration duration_limit);
1144 #ifndef SWIG
1145  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1147  sweep_arranger_.reset(sweep_arranger);
1148  }
1150  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1151 #endif
1152  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1158  CHECK(filter != nullptr);
1159  if (closed_) {
1160  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1161  }
1162  extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1163  extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1164  }
1165 
1168  int64 Start(int vehicle) const { return starts_[vehicle]; }
1170  int64 End(int vehicle) const { return ends_[vehicle]; }
1172  bool IsStart(int64 index) const;
1174  bool IsEnd(int64 index) const { return index >= Size(); }
1177  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1181  int64 Next(const Assignment& assignment, int64 index) const;
1183  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1184 
1185 #if !defined(SWIGPYTHON)
1186  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1191  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1192 #endif
1193  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1196  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1200  IntVar* ActiveVehicleVar(int vehicle) const {
1201  return vehicle_active_[vehicle];
1202  }
1205  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1206  return vehicle_costs_considered_[vehicle];
1207  }
1210  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1212  IntVar* CostVar() const { return cost_; }
1213 
1216  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1217  int64 vehicle) const;
1220  return costs_are_homogeneous_across_vehicles_;
1221  }
1224  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1225  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1226  }
1229  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1236  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1237  int64 /*CostClassIndex*/ cost_class_index) const;
1240  DCHECK(closed_);
1241  DCHECK_GE(vehicle, 0);
1242  DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1243  DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1244  return cost_class_index_of_vehicle_[vehicle];
1245  }
1248  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1249  DCHECK(closed_);
1250  if (cost_class_index == kCostClassIndexOfZeroCost) {
1251  return has_vehicle_with_zero_cost_class_;
1252  }
1253  return cost_class_index < cost_classes_.size();
1254  }
1256  int GetCostClassesCount() const { return cost_classes_.size(); }
1259  return std::max(0, GetCostClassesCount() - 1);
1260  }
1262  DCHECK(closed_);
1263  return vehicle_class_index_of_vehicle_[vehicle];
1264  }
1266  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1268  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1269  DCHECK(closed_);
1270  return same_vehicle_groups_[same_vehicle_group_[node]];
1271  }
1272 
1274  DCHECK(closed_);
1275  return vehicle_type_container_;
1276  }
1277 
1296  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1302  const Assignment& solution_assignment,
1303  const std::string& dimension_to_print) const;
1309 #ifndef SWIG
1310  std::vector<std::vector<std::pair<int64, int64>>> GetCumulBounds(
1311  const Assignment& solution_assignment, const RoutingDimension& dimension);
1312 #endif
1313  Solver* solver() const { return solver_.get(); }
1316 
1318  bool CheckLimit() {
1319  DCHECK(limit_ != nullptr);
1320  return limit_->Check();
1321  }
1322 
1324  absl::Duration RemainingTime() const {
1325  DCHECK(limit_ != nullptr);
1326  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1327  }
1328 
1331  int nodes() const { return nodes_; }
1333  int vehicles() const { return vehicles_; }
1335  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1336 
1340  const RoutingSearchParameters& search_parameters) const;
1342  const RoutingSearchParameters& search_parameters) const;
1344  operations_research::FirstSolutionStrategy::Value
1346  return automatic_first_solution_strategy_;
1347  }
1348 
1350  bool IsMatchingModel() const;
1351 
1352 #ifndef SWIG
1353  using GetTabuVarsCallback =
1356  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1357 
1358  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1359 #endif // SWIG
1360 
1362  // TODO(user): Find a way to test and restrict the access at the same time.
1375  const RoutingDimension* dimension,
1376  std::function<int64(int64)> initializer);
1377 #ifndef SWIG
1378  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1383  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1384  std::vector<IntVar*> variables);
1385 #endif
1386  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1400  const RoutingDimension* dimension);
1401 
1402  private:
1404  enum RoutingLocalSearchOperator {
1405  RELOCATE = 0,
1406  RELOCATE_PAIR,
1407  LIGHT_RELOCATE_PAIR,
1408  RELOCATE_NEIGHBORS,
1409  EXCHANGE,
1410  EXCHANGE_PAIR,
1411  CROSS,
1412  CROSS_EXCHANGE,
1413  TWO_OPT,
1414  OR_OPT,
1415  GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1416  LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1417  GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1418  LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1419  RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1420  GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1421  LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1422  RELOCATE_EXPENSIVE_CHAIN,
1423  LIN_KERNIGHAN,
1424  TSP_OPT,
1425  MAKE_ACTIVE,
1426  RELOCATE_AND_MAKE_ACTIVE,
1427  MAKE_ACTIVE_AND_RELOCATE,
1428  MAKE_INACTIVE,
1429  MAKE_CHAIN_INACTIVE,
1430  SWAP_ACTIVE,
1431  EXTENDED_SWAP_ACTIVE,
1432  NODE_PAIR_SWAP,
1433  PATH_LNS,
1434  FULL_PATH_LNS,
1435  TSP_LNS,
1436  INACTIVE_LNS,
1437  EXCHANGE_RELOCATE_PAIR,
1438  RELOCATE_SUBTRIP,
1439  EXCHANGE_SUBTRIP,
1440  LOCAL_SEARCH_OPERATOR_COUNTER
1441  };
1442 
1446  template <typename T>
1447  struct ValuedNodes {
1448  std::vector<int64> indices;
1449  T value;
1450  };
1451  struct DisjunctionValues {
1452  int64 penalty;
1453  int64 max_cardinality;
1454  };
1455  typedef ValuedNodes<DisjunctionValues> Disjunction;
1456 
1459  struct CostCacheElement {
1464  int index;
1465  CostClassIndex cost_class_index;
1466  int64 cost;
1467  };
1468 
1470  void Initialize();
1471  void AddNoCycleConstraintInternal();
1472  bool AddDimensionWithCapacityInternal(
1473  const std::vector<int>& evaluator_indices, int64 slack_max,
1474  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1475  const std::string& name);
1476  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1477  const std::vector<int>& pure_transits,
1478  const std::vector<int>& dependent_transits,
1479  const RoutingDimension* base_dimension, int64 slack_max,
1480  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1481  const std::string& name);
1482  bool InitializeDimensionInternal(
1483  const std::vector<int>& evaluator_indices,
1484  const std::vector<int>& state_dependent_evaluator_indices,
1485  int64 slack_max, bool fix_start_cumul_to_zero,
1486  RoutingDimension* dimension);
1487  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1488 
1516  void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1517 
1518  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1519  void ComputeVehicleClasses();
1527  void ComputeVehicleTypes();
1537  void FinalizeVisitTypes();
1538  // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_.
1539  void TopologicallySortVisitTypes();
1540  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1541  CostClassIndex cost_class_index) const;
1542  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1543  int node_index,
1544  std::vector<IntVar*>* cost_elements);
1545  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1546  std::vector<IntVar*>* cost_elements);
1547  Assignment* DoRestoreAssignment();
1548  static const CostClassIndex kCostClassIndexOfZeroCost;
1549  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1550  DCHECK_LT(0, vehicles_);
1551  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1552  : kCostClassIndexOfZeroCost)
1553  .value();
1554  }
1555  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1556  const CostClass& cost_class) const;
1558  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1560  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1561  const std::vector<int64>& deliveries);
1564  IntVar* CreateSameVehicleCost(int vehicle_index);
1567  int FindNextActive(int index, const std::vector<int64>& indices) const;
1568 
1571  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1572  int vehicle) const;
1580  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1581  Assignment* compact_assignment) const;
1582 
1583  void QuietCloseModel();
1584  void QuietCloseModelWithParameters(
1585  const RoutingSearchParameters& parameters) {
1586  if (!closed_) {
1587  CloseModelWithParameters(parameters);
1588  }
1589  }
1590 
1592  bool SolveMatchingModel(Assignment* assignment,
1593  const RoutingSearchParameters& parameters);
1594 #ifndef SWIG
1595  bool AppendAssignmentIfFeasible(
1597  const Assignment& assignment,
1598  std::vector<std::unique_ptr<Assignment>>* assignments);
1599 #endif
1600  void LogSolution(const RoutingSearchParameters& parameters,
1602  const std::string& description, int64 solution_cost,
1603  int64 start_time_ms);
1606  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1607  bool check_compact_assignment) const;
1612  std::string FindErrorInSearchParametersForModel(
1613  const RoutingSearchParameters& search_parameters) const;
1615  void SetupSearch(const RoutingSearchParameters& search_parameters);
1617  // TODO(user): Document each auxiliary method.
1618  Assignment* GetOrCreateAssignment();
1619  Assignment* GetOrCreateTmpAssignment();
1620  RegularLimit* GetOrCreateLimit();
1621  RegularLimit* GetOrCreateLocalSearchLimit();
1622  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1623  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1624  LocalSearchOperator* CreateInsertionOperator();
1625  LocalSearchOperator* CreateMakeInactiveOperator();
1626  template <class T>
1627  LocalSearchOperator* CreateCPOperator(const T& operator_factory) {
1628  return operator_factory(solver_.get(), nexts_,
1630  ? std::vector<IntVar*>()
1631  : vehicle_vars_,
1632  vehicle_start_class_callback_);
1633  }
1634  template <class T>
1635  LocalSearchOperator* CreateCPOperator() {
1636  return CreateCPOperator(absl::bind_front(MakeLocalSearchOperator<T>));
1637  }
1638  template <class T, class Arg>
1639  LocalSearchOperator* CreateOperator(const Arg& arg) {
1640  return solver_->RevAlloc(new T(nexts_,
1642  ? std::vector<IntVar*>()
1643  : vehicle_vars_,
1644  vehicle_start_class_callback_, arg));
1645  }
1646  template <class T>
1647  LocalSearchOperator* CreatePairOperator() {
1648  return CreateOperator<T>(pickup_delivery_pairs_);
1649  }
1650  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1651  LocalSearchOperator* ConcatenateOperators(
1652  const RoutingSearchParameters& search_parameters,
1653  const std::vector<LocalSearchOperator*>& operators) const;
1654  LocalSearchOperator* GetNeighborhoodOperators(
1655  const RoutingSearchParameters& search_parameters) const;
1656  std::vector<LocalSearchFilterManager::FilterEvent>
1657  GetOrCreateLocalSearchFilters(const RoutingSearchParameters& parameters,
1658  bool filter_cost = true);
1659  LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1660  const RoutingSearchParameters& parameters);
1661  std::vector<LocalSearchFilterManager::FilterEvent>
1662  GetOrCreateFeasibilityFilters(const RoutingSearchParameters& parameters);
1663  LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1664  const RoutingSearchParameters& parameters);
1665  LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1666  const RoutingSearchParameters& parameters);
1667  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1668  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1669  void CreateFirstSolutionDecisionBuilders(
1670  const RoutingSearchParameters& search_parameters);
1671  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1672  const RoutingSearchParameters& search_parameters) const;
1673  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1674  const RoutingSearchParameters& parameters) const;
1675  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1676  const RoutingSearchParameters& search_parameters);
1677  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1678  const RoutingSearchParameters& search_parameters);
1679  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1680  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1681  void SetupAssignmentCollector(
1682  const RoutingSearchParameters& search_parameters);
1683  void SetupTrace(const RoutingSearchParameters& search_parameters);
1684  void SetupImprovementLimit(const RoutingSearchParameters& search_parameters);
1685  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1686  bool UsesLightPropagation(
1687  const RoutingSearchParameters& search_parameters) const;
1688  GetTabuVarsCallback tabu_var_callback_;
1689 
1690  // Detects implicit pickup delivery pairs. These pairs are
1691  // non-pickup/delivery pairs for which there exists a unary dimension such
1692  // that the demand d of the implicit pickup is positive and the demand of the
1693  // implicit delivery is equal to -d.
1694  void DetectImplicitPickupAndDeliveries();
1695 
1696  int GetVehicleStartClass(int64 start) const;
1697 
1698  void InitSameVehicleGroups(int number_of_groups) {
1699  same_vehicle_group_.assign(Size(), 0);
1700  same_vehicle_groups_.assign(number_of_groups, {});
1701  }
1702  void SetSameVehicleGroup(int index, int group) {
1703  same_vehicle_group_[index] = group;
1704  same_vehicle_groups_[group].push_back(index);
1705  }
1706 
1708  std::unique_ptr<Solver> solver_;
1709  int nodes_;
1710  int vehicles_;
1711  int max_active_vehicles_;
1712  Constraint* no_cycle_constraint_ = nullptr;
1714  std::vector<IntVar*> nexts_;
1715  std::vector<IntVar*> vehicle_vars_;
1716  std::vector<IntVar*> active_;
1717  // The following vectors are indexed by vehicle index.
1718  std::vector<IntVar*> vehicle_active_;
1719  std::vector<IntVar*> vehicle_costs_considered_;
1724  std::vector<IntVar*> is_bound_to_end_;
1725  mutable RevSwitch is_bound_to_end_ct_added_;
1727  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1728  absl::StrongVector<DimensionIndex, RoutingDimension*> dimensions_;
1729  // clang-format off
1733  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1734  global_dimension_optimizers_;
1735  absl::StrongVector<DimensionIndex, int> global_optimizer_index_;
1736  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1737  local_dimension_optimizers_;
1738  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1739  local_dimension_mp_optimizers_;
1740  // clang-format off
1741  absl::StrongVector<DimensionIndex, int> local_optimizer_index_;
1742  std::string primary_constrained_dimension_;
1744  IntVar* cost_ = nullptr;
1745  std::vector<int> vehicle_to_transit_cost_;
1746  std::vector<int64> fixed_cost_of_vehicle_;
1747  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1748  bool has_vehicle_with_zero_cost_class_;
1749  std::vector<int64> linear_cost_factor_of_vehicle_;
1750  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1751  bool vehicle_amortized_cost_factors_set_;
1762  std::vector<bool> consider_empty_route_costs_;
1763 #ifndef SWIG
1764  absl::StrongVector<CostClassIndex, CostClass> cost_classes_;
1765 #endif // SWIG
1766  bool costs_are_homogeneous_across_vehicles_;
1767  bool cache_callbacks_;
1768  mutable std::vector<CostCacheElement> cost_cache_;
1769  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1770 #ifndef SWIG
1771  absl::StrongVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1772 #endif // SWIG
1773  VehicleTypeContainer vehicle_type_container_;
1774  std::function<int(int64)> vehicle_start_class_callback_;
1776  absl::StrongVector<DisjunctionIndex, Disjunction> disjunctions_;
1777  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1779  std::vector<ValuedNodes<int64> > same_vehicle_costs_;
1781 #ifndef SWIG
1782  std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1783 #endif // SWIG
1784  IndexPairs pickup_delivery_pairs_;
1786  IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
1787  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1788  pickup_delivery_disjunctions_;
1789  // clang-format off
1790  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1791  // vector of pairs {pair_index, pickup_index} such that
1792  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1793  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1794  // Same as above for deliveries.
1795  std::vector<std::vector<std::pair<int, int> > >
1796  index_to_delivery_index_pairs_;
1797  // clang-format on
1798  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1799  // Same vehicle group to which a node belongs.
1800  std::vector<int> same_vehicle_group_;
1801  // Same vehicle node groups.
1802  std::vector<std::vector<int>> same_vehicle_groups_;
1803  // Node visit types
1804  // Variable index to visit type index.
1805  std::vector<int> index_to_visit_type_;
1806  // Variable index to VisitTypePolicy.
1807  std::vector<VisitTypePolicy> index_to_type_policy_;
1808  // clang-format off
1809  std::vector<std::vector<int> > single_nodes_of_type_;
1810  std::vector<std::vector<int> > pair_indices_of_type_;
1811 
1812  std::vector<absl::flat_hash_set<int> >
1813  hard_incompatible_types_per_type_index_;
1814  bool has_hard_type_incompatibilities_;
1815  std::vector<absl::flat_hash_set<int> >
1816  temporal_incompatible_types_per_type_index_;
1817  bool has_temporal_type_incompatibilities_;
1818 
1819  std::vector<std::vector<absl::flat_hash_set<int> > >
1820  same_vehicle_required_type_alternatives_per_type_index_;
1821  bool has_same_vehicle_type_requirements_;
1822  std::vector<std::vector<absl::flat_hash_set<int> > >
1823  required_type_alternatives_when_adding_type_index_;
1824  std::vector<std::vector<absl::flat_hash_set<int> > >
1825  required_type_alternatives_when_removing_type_index_;
1826  bool has_temporal_type_requirements_;
1827  absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
1828  trivially_infeasible_visit_types_to_policies_;
1829 
1830  // Visit types sorted topologically based on required-->dependent requirement
1831  // arcs between the types (if the requirement/dependency graph is acyclic).
1832  // Visit types of the same topological level are sorted in each sub-vector
1833  // by decreasing requirement "tightness", computed as the pair of the two
1834  // following criteria:
1835  //
1836  // 1) How highly *dependent* this type is, determined by
1837  // (total number of required alternative sets for that type)
1838  // / (average number of types in the required alternative sets)
1839  // 2) How highly *required* this type t is, computed as
1840  // SUM_{S required set containing t} ( 1 / |S| ),
1841  // i.e. the sum of reverse number of elements of all required sets
1842  // containing the type t.
1843  //
1844  // The higher these two numbers, the tighter the type is wrt requirements.
1845  std::vector<std::vector<int> > topologically_sorted_visit_types_;
1846  // clang-format on
1847  int num_visit_types_;
1848  // Two indices are equivalent if they correspond to the same node (as given
1849  // to the constructors taking a RoutingIndexManager).
1850  std::vector<int> index_to_equivalence_class_;
1851  std::vector<int> index_to_vehicle_;
1852  std::vector<int64> starts_;
1853  std::vector<int64> ends_;
1854  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1855  // anymore.
1856  RoutingIndexManager manager_;
1857  int start_end_count_;
1858  // Model status
1859  bool closed_ = false;
1860  Status status_ = ROUTING_NOT_SOLVED;
1861  bool enable_deep_serialization_ = true;
1862 
1863  // Search data
1864  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1865  std::vector<IntVarFilteredDecisionBuilder*>
1866  first_solution_filtered_decision_builders_;
1867  Solver::IndexEvaluator2 first_solution_evaluator_;
1868  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
1869  FirstSolutionStrategy::UNSET;
1870  std::vector<LocalSearchOperator*> local_search_operators_;
1871  std::vector<SearchMonitor*> monitors_;
1872  SolutionCollector* collect_assignments_ = nullptr;
1873  SolutionCollector* collect_one_assignment_ = nullptr;
1874  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1875  DecisionBuilder* solve_db_ = nullptr;
1876  DecisionBuilder* improve_db_ = nullptr;
1877  DecisionBuilder* restore_assignment_ = nullptr;
1878  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1879  Assignment* assignment_ = nullptr;
1880  Assignment* preassignment_ = nullptr;
1881  Assignment* tmp_assignment_ = nullptr;
1882  std::vector<IntVar*> extra_vars_;
1883  std::vector<IntervalVar*> extra_intervals_;
1884  std::vector<LocalSearchOperator*> extra_operators_;
1885  LocalSearchFilterManager* local_search_filter_manager_ = nullptr;
1886  LocalSearchFilterManager* feasibility_filter_manager_ = nullptr;
1887  LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr;
1888  std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
1889 #ifndef SWIG
1890  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1891  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1892  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1893  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1894  std::unique_ptr<SweepArranger> sweep_arranger_;
1895 #endif
1896 
1897  RegularLimit* limit_ = nullptr;
1898  RegularLimit* ls_limit_ = nullptr;
1899  RegularLimit* lns_limit_ = nullptr;
1900  RegularLimit* first_solution_lns_limit_ = nullptr;
1901 
1902  typedef std::pair<int64, int64> CacheKey;
1903  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1904  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1905  StateDependentTransitCallbackCache;
1906 
1907  std::vector<TransitCallback1> unary_transit_evaluators_;
1908  std::vector<TransitCallback2> transit_evaluators_;
1909  // The following vector stores a boolean per transit_evaluator_, indicating
1910  // whether the transits are all positive.
1911  // is_transit_evaluator_positive_ will be set to true only when registering a
1912  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1913  // The actual positivity of the transit values will only be checked in debug
1914  // mode, when calling RegisterPositiveTransitCallback().
1915  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1916  // transits are known to be positive, as the positivity of a callback will
1917  // allow some improvements in the solver, but will entail in errors if the
1918  // transits are falsely assumed positive.
1919  std::vector<bool> is_transit_evaluator_positive_;
1920  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1921  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1922  state_dependent_transit_evaluators_cache_;
1923 
1924  friend class RoutingDimension;
1926 
1927  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1928 };
1929 
1932  public:
1934  static const char kLightElement[];
1935  static const char kLightElement2[];
1936  static const char kRemoveValues[];
1937 };
1938 
1939 #if !defined(SWIG)
1940 class DisjunctivePropagator {
1943  public:
1949  struct Tasks {
1951  std::vector<int64> start_min;
1952  std::vector<int64> start_max;
1953  std::vector<int64> duration_min;
1954  std::vector<int64> duration_max;
1955  std::vector<int64> end_min;
1956  std::vector<int64> end_max;
1957  std::vector<bool> is_preemptible;
1958  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1959  std::vector<std::pair<int64, int64>> distance_duration;
1960  int64 span_min = 0;
1961  int64 span_max = kint64max;
1962 
1963  void Clear() {
1964  start_min.clear();
1965  start_max.clear();
1966  duration_min.clear();
1967  duration_max.clear();
1968  end_min.clear();
1969  end_max.clear();
1970  is_preemptible.clear();
1971  forbidden_intervals.clear();
1972  distance_duration.clear();
1973  span_min = 0;
1974  span_max = kint64max;
1975  num_chain_tasks = 0;
1976  }
1977  };
1978 
1981  bool Propagate(Tasks* tasks);
1982 
1984  bool Precedences(Tasks* tasks);
1987  bool MirrorTasks(Tasks* tasks);
1989  bool EdgeFinding(Tasks* tasks);
1996  bool DistanceDuration(Tasks* tasks);
1999  bool ChainSpanMin(Tasks* tasks);
2005 
2006  private:
2009  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
2011  std::vector<int> tasks_by_start_min_;
2012  std::vector<int> tasks_by_end_max_;
2013  std::vector<int> event_of_task_;
2014  std::vector<int> nonchain_tasks_by_start_max_;
2016  std::vector<int64> total_duration_before_;
2017 };
2018 
2020  std::vector<int64> min_travels;
2021  std::vector<int64> max_travels;
2022  std::vector<int64> pre_travels;
2023  std::vector<int64> post_travels;
2024 };
2025 
2026 void AppendTasksFromPath(const std::vector<int64>& path,
2027  const TravelBounds& travel_bounds,
2028  const RoutingDimension& dimension,
2030 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
2032 void FillPathEvaluation(const std::vector<int64>& path,
2033  const RoutingModel::TransitCallback2& evaluator,
2034  std::vector<int64>* values);
2035 void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64>& path,
2036  const RoutingDimension& dimension,
2037  TravelBounds* travel_bounds);
2038 #endif // !defined(SWIG)
2039 
2051  public:
2053  std::string DebugString() const override {
2054  return "GlobalVehicleBreaksConstraint";
2055  }
2056 
2057  void Post() override;
2058  void InitialPropagate() override;
2059 
2060  private:
2061  void PropagateNode(int node);
2062  void PropagateVehicle(int vehicle);
2063  void PropagateMaxBreakDistance(int vehicle);
2064 
2065  const RoutingModel* model_;
2066  const RoutingDimension* const dimension_;
2067  std::vector<Demon*> vehicle_demons_;
2068  std::vector<int64> path_;
2069 
2074  void FillPartialPathOfVehicle(int vehicle);
2075  void FillPathTravels(const std::vector<int64>& path);
2076 
2087  class TaskTranslator {
2088  public:
2089  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
2090  : start_(start),
2091  before_start_(before_start),
2092  after_start_(after_start) {}
2093  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2094  TaskTranslator() {}
2095 
2096  void SetStartMin(int64 value) {
2097  if (start_ != nullptr) {
2098  start_->SetMin(CapAdd(before_start_, value));
2099  } else if (interval_ != nullptr) {
2100  interval_->SetStartMin(value);
2101  }
2102  }
2103  void SetStartMax(int64 value) {
2104  if (start_ != nullptr) {
2105  start_->SetMax(CapAdd(before_start_, value));
2106  } else if (interval_ != nullptr) {
2107  interval_->SetStartMax(value);
2108  }
2109  }
2110  void SetDurationMin(int64 value) {
2111  if (interval_ != nullptr) {
2112  interval_->SetDurationMin(value);
2113  }
2114  }
2115  void SetEndMin(int64 value) {
2116  if (start_ != nullptr) {
2117  start_->SetMin(CapSub(value, after_start_));
2118  } else if (interval_ != nullptr) {
2119  interval_->SetEndMin(value);
2120  }
2121  }
2122  void SetEndMax(int64 value) {
2123  if (start_ != nullptr) {
2124  start_->SetMax(CapSub(value, after_start_));
2125  } else if (interval_ != nullptr) {
2126  interval_->SetEndMax(value);
2127  }
2128  }
2129 
2130  private:
2131  IntVar* start_ = nullptr;
2132  int64 before_start_;
2133  int64 after_start_;
2134  IntervalVar* interval_ = nullptr;
2135  };
2136 
2138  std::vector<TaskTranslator> task_translators_;
2139 
2141  DisjunctivePropagator disjunctive_propagator_;
2142  DisjunctivePropagator::Tasks tasks_;
2143 
2145  TravelBounds travel_bounds_;
2146 };
2147 
2149  public:
2150  explicit TypeRegulationsChecker(const RoutingModel& model);
2152 
2153  bool CheckVehicle(int vehicle,
2154  const std::function<int64(int64)>& next_accessor);
2155 
2156  protected:
2157 #ifndef SWIG
2159 #endif // SWIG
2160 
2177  };
2178 
2183  bool TypeOccursOnRoute(int type) const;
2190  bool TypeCurrentlyOnRoute(int type, int pos) const;
2191 
2192  void InitializeCheck(int vehicle,
2193  const std::function<int64(int64)>& next_accessor);
2194  virtual void OnInitializeCheck() {}
2195  virtual bool HasRegulationsToCheck() const = 0;
2196  virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2197  int pos) = 0;
2198  virtual bool FinalizeCheck() const { return true; }
2199 
2201 
2202  private:
2203  std::vector<TypePolicyOccurrence> occurrences_of_type_;
2204  std::vector<int64> current_route_visits_;
2205 };
2206 
2209  public:
2211  bool check_hard_incompatibilities);
2213 
2214  private:
2215  bool HasRegulationsToCheck() const override;
2216  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2220  bool check_hard_incompatibilities_;
2221 };
2222 
2225  public:
2226  explicit TypeRequirementChecker(const RoutingModel& model)
2227  : TypeRegulationsChecker(model) {}
2229 
2230  private:
2231  bool HasRegulationsToCheck() const override;
2232  void OnInitializeCheck() override {
2233  types_with_same_vehicle_requirements_on_route_.clear();
2234  }
2235  // clang-format off
2238  bool CheckRequiredTypesCurrentlyOnRoute(
2239  const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2240  int pos);
2241  // clang-format on
2242  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2243  bool FinalizeCheck() const override;
2244 
2245  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2246 };
2247 
2289  public:
2290  explicit TypeRegulationsConstraint(const RoutingModel& model);
2291 
2292  void Post() override;
2293  void InitialPropagate() override;
2294 
2295  private:
2296  void PropagateNodeRegulations(int node);
2297  void CheckRegulationsOnVehicle(int vehicle);
2298 
2299  const RoutingModel& model_;
2300  TypeIncompatibilityChecker incompatibility_checker_;
2301  TypeRequirementChecker requirement_checker_;
2302  std::vector<Demon*> vehicle_demons_;
2303 };
2304 #if !defined SWIG
2305 class SimpleBoundCosts {
2318  public:
2319  struct BoundCost {
2320  int64 bound;
2321  int64 cost;
2322  };
2323  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2324  : bound_costs_(num_bounds, default_bound_cost) {}
2325  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2326  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2327  int Size() { return bound_costs_.size(); }
2330 
2331  private:
2332  std::vector<BoundCost> bound_costs_;
2333 };
2334 #endif // !defined SWIG
2335 
2353 // TODO(user): Break constraints need to know the service time of nodes
2357  public:
2360  RoutingModel* model() const { return model_; }
2364  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2367  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2368  int64 vehicle_class) const {
2369  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2370  to_index);
2371  }
2374  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2375  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2376  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2377  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2378 
2379 #if !defined(SWIGPYTHON)
2380  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2383  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2384  const std::vector<IntVar*>& transits() const { return transits_; }
2385  const std::vector<IntVar*>& slacks() const { return slacks_; }
2386 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2387  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2389  return forbidden_intervals_;
2390  }
2392  SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index,
2393  int64 min_value,
2394  int64 max_value) const;
2398  int64 min_value) const {
2399  DCHECK_LT(index, forbidden_intervals_.size());
2400  const SortedDisjointIntervalList& forbidden_intervals =
2401  forbidden_intervals_[index];
2402  const auto first_forbidden_interval_it =
2403  forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2404  if (first_forbidden_interval_it != forbidden_intervals.end() &&
2405  min_value >= first_forbidden_interval_it->start) {
2407  return CapAdd(first_forbidden_interval_it->end, 1);
2408  }
2410  return min_value;
2411  }
2417  int64 max_value) const {
2418  DCHECK_LT(index, forbidden_intervals_.size());
2419  const SortedDisjointIntervalList& forbidden_intervals =
2420  forbidden_intervals_[index];
2421  const auto last_forbidden_interval_it =
2422  forbidden_intervals.LastIntervalLessOrEqual(max_value);
2423  if (last_forbidden_interval_it != forbidden_intervals.end() &&
2424  max_value <= last_forbidden_interval_it->end) {
2426  return CapSub(last_forbidden_interval_it->start, 1);
2427  }
2429  return max_value;
2430  }
2432  const std::vector<int64>& vehicle_capacities() const {
2433  return vehicle_capacities_;
2434  }
2438  return model_->TransitCallback(
2439  class_evaluators_[vehicle_to_class_[vehicle]]);
2440  }
2445  int vehicle) const {
2446  return model_->UnaryTransitCallbackOrNull(
2447  class_evaluators_[vehicle_to_class_[vehicle]]);
2448  }
2451  bool AreVehicleTransitsPositive(int vehicle) const {
2452  return model()->is_transit_evaluator_positive_
2453  [class_evaluators_[vehicle_to_class_[vehicle]]];
2454  }
2455  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2456 #endif
2457 #endif
2458  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2462  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2469  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2476  void SetGlobalSpanCostCoefficient(int64 coefficient);
2477 
2478 #ifndef SWIG
2479  void SetCumulVarPiecewiseLinearCost(int64 index,
2484  const PiecewiseLinearFunction& cost);
2487  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2490  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2491  int64 index) const;
2492 #endif
2493 
2502  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2503  int64 coefficient);
2506  bool HasCumulVarSoftUpperBound(int64 index) const;
2510  int64 GetCumulVarSoftUpperBound(int64 index) const;
2514  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2515 
2525  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2526  int64 coefficient);
2529  bool HasCumulVarSoftLowerBound(int64 index) const;
2533  int64 GetCumulVarSoftLowerBound(int64 index) const;
2537  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2553  // TODO(user): Remove if !defined when routing.i is repaired.
2554 #if !defined(SWIGPYTHON)
2555  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2556  int pre_travel_evaluator,
2557  int post_travel_evaluator);
2558 #endif // !defined(SWIGPYTHON)
2559 
2561  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2562  std::vector<int64> node_visit_transits);
2563 
2568  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2569  int vehicle);
2574  bool HasBreakConstraints() const;
2575 #if !defined(SWIGPYTHON)
2579  std::vector<IntervalVar*> breaks, int vehicle,
2580  std::vector<int64> node_visit_transits,
2581  std::function<int64(int64, int64)> group_delays);
2582 
2584  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2585  int vehicle) const;
2588  // clang-format off
2589  const std::vector<std::pair<int64, int64> >&
2591  // clang-format on
2592 #endif
2593  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2594  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2595 
2597  const RoutingDimension* base_dimension() const { return base_dimension_; }
2605  int64 ShortestTransitionSlack(int64 node) const;
2606 
2608  const std::string& name() const { return name_; }
2609 
2611 #ifndef SWIG
2612  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2613  return path_precedence_graph_;
2614  }
2615 #endif // SWIG
2616 
2626  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2627 
2629  PickupToDeliveryLimitFunction limit_function, int pair_index);
2630 
2632 #ifndef SWIG
2633  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2634  int delivery) const;
2635 
2637  int64 first_node;
2639  int64 offset;
2640  };
2641 
2643  node_precedences_.push_back(precedence);
2644  }
2645  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2646  return node_precedences_;
2647  }
2648 #endif // SWIG
2649 
2650  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2651  AddNodePrecedence({first_node, second_node, offset});
2652  }
2653 
2654  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2655  return vehicle_span_upper_bounds_[vehicle];
2656  }
2657 #ifndef SWIG
2658  const std::vector<int64>& vehicle_span_upper_bounds() const {
2659  return vehicle_span_upper_bounds_;
2660  }
2661 #endif // SWIG
2662  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2663  return vehicle_span_cost_coefficients_[vehicle];
2664  }
2665 #ifndef SWIG
2666  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2667  return vehicle_span_cost_coefficients_;
2668  }
2669 #endif // SWIG
2671  return global_span_cost_coefficient_;
2672  }
2673 
2675  DCHECK_GE(global_optimizer_offset_, 0);
2676  return global_optimizer_offset_;
2677  }
2678  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2679  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2680  return 0;
2681  }
2682  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2683  return local_optimizer_offset_for_vehicle_[vehicle];
2684  }
2685 #if !defined SWIG
2689  int vehicle) {
2690  if (!HasSoftSpanUpperBounds()) {
2691  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2692  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2693  }
2694  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2695  }
2696  bool HasSoftSpanUpperBounds() const {
2697  return vehicle_soft_span_upper_bound_ != nullptr;
2698  }
2700  int vehicle) const {
2701  DCHECK(HasSoftSpanUpperBounds());
2702  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2703  }
2707  SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2709  vehicle_quadratic_cost_soft_span_upper_bound_ =
2710  absl::make_unique<SimpleBoundCosts>(
2711  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2712  }
2713  vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2714  bound_cost;
2715  }
2717  return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2718  }
2720  int vehicle) const {
2722  return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2723  }
2724 #endif
2725 
2726  private:
2727  struct SoftBound {
2728  IntVar* var;
2729  int64 bound;
2730  int64 coefficient;
2731  };
2732 
2733  struct PiecewiseLinearCost {
2734  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2735  IntVar* var;
2736  std::unique_ptr<PiecewiseLinearFunction> cost;
2737  };
2738 
2739  class SelfBased {};
2740  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2741  const std::string& name,
2742  const RoutingDimension* base_dimension);
2743  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2744  const std::string& name, SelfBased);
2745  void Initialize(const std::vector<int>& transit_evaluators,
2746  const std::vector<int>& state_dependent_transit_evaluators,
2747  int64 slack_max);
2748  void InitializeCumuls();
2749  void InitializeTransits(
2750  const std::vector<int>& transit_evaluators,
2751  const std::vector<int>& state_dependent_transit_evaluators,
2752  int64 slack_max);
2753  void InitializeTransitVariables(int64 slack_max);
2755  void SetupCumulVarSoftUpperBoundCosts(
2756  std::vector<IntVar*>* cost_elements) const;
2758  void SetupCumulVarSoftLowerBoundCosts(
2759  std::vector<IntVar*>* cost_elements) const;
2760  void SetupCumulVarPiecewiseLinearCosts(
2761  std::vector<IntVar*>* cost_elements) const;
2764  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2765  void SetupSlackAndDependentTransitCosts() const;
2767  void CloseModel(bool use_light_propagation);
2768 
2769  void SetOffsetForGlobalOptimizer(int64 offset) {
2770  global_optimizer_offset_ = std::max(Zero(), offset);
2771  }
2773  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2775  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2776  [](int64 offset) { return std::max(Zero(), offset); });
2777  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2778  }
2779 
2780  std::vector<IntVar*> cumuls_;
2781  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2782  std::vector<IntVar*> capacity_vars_;
2783  const std::vector<int64> vehicle_capacities_;
2784  std::vector<IntVar*> transits_;
2785  std::vector<IntVar*> fixed_transits_;
2788  std::vector<int> class_evaluators_;
2789  std::vector<int64> vehicle_to_class_;
2790 #ifndef SWIG
2791  ReverseArcListGraph<int, int> path_precedence_graph_;
2792 #endif
2793  // For every {first_node, second_node, offset} element in node_precedences_,
2794  // if both first_node and second_node are performed, then
2795  // cumuls_[second_node] must be greater than (or equal to)
2796  // cumuls_[first_node] + offset.
2797  std::vector<NodePrecedence> node_precedences_;
2798 
2799  // The transits of a dimension may depend on its cumuls or the cumuls of
2800  // another dimension. There can be no cycles, except for self loops, a
2801  // typical example for this is a time dimension.
2802  const RoutingDimension* const base_dimension_;
2803 
2804  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2805  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2806  // class.
2807  std::vector<int> state_dependent_class_evaluators_;
2808  std::vector<int64> state_dependent_vehicle_to_class_;
2809 
2810  // For each pickup/delivery pair_index for which limits have been set,
2811  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2812  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2813  std::vector<PickupToDeliveryLimitFunction>
2814  pickup_to_delivery_limits_per_pair_index_;
2815 
2816  // Used if some vehicle has breaks in this dimension, typically time.
2817  bool break_constraints_are_initialized_ = false;
2818  // clang-format off
2819  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2820  std::vector<std::vector<std::pair<int64, int64> > >
2821  vehicle_break_distance_duration_;
2822  // clang-format on
2823  // For each vehicle, stores the part of travel that is made directly
2824  // after (before) the departure (arrival) node of the travel.
2825  // These parts of the travel are non-interruptible, in particular by a break.
2826  std::vector<int> vehicle_pre_travel_evaluators_;
2827  std::vector<int> vehicle_post_travel_evaluators_;
2828 
2829  std::vector<IntVar*> slacks_;
2830  std::vector<IntVar*> dependent_transits_;
2831  std::vector<int64> vehicle_span_upper_bounds_;
2832  int64 global_span_cost_coefficient_;
2833  std::vector<int64> vehicle_span_cost_coefficients_;
2834  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2835  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2836  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2837  RoutingModel* const model_;
2838  const std::string name_;
2839  int64 global_optimizer_offset_;
2840  std::vector<int64> local_optimizer_offset_for_vehicle_;
2842  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2843  std::unique_ptr<SimpleBoundCosts>
2844  vehicle_quadratic_cost_soft_span_upper_bound_;
2845  friend class RoutingModel;
2848  const std::vector<RoutingDimension*>& dimensions,
2849  const RoutingSearchParameters& parameters, bool filter_objective_cost,
2850  std::vector<LocalSearchFilterManager::FilterEvent>* filters);
2851 
2852  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2853 };
2854 
2855 #ifndef SWIG
2856 class SweepArranger {
2859  public:
2860  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2861  virtual ~SweepArranger() {}
2862  void ArrangeIndices(std::vector<int64>* indices);
2863  void SetSectors(int sectors) { sectors_ = sectors; }
2864 
2865  private:
2866  std::vector<int> coordinates_;
2867  int sectors_;
2868 
2869  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2870 };
2871 #endif
2872 
2876  std::vector<IntVar*> variables,
2877  std::vector<int64> targets);
2878 
2879 #ifndef SWIG
2880 // Helper class that stores vehicles by their type. Two vehicles have the same
2881 // "vehicle type" iff they have the same cost class and start/end nodes.
2883  public:
2885  const RoutingModel::VehicleTypeContainer& vehicle_type_container)
2886  : vehicle_type_container_(&vehicle_type_container) {}
2887 
2888  int NumTypes() const { return vehicle_type_container_->NumTypes(); }
2889 
2890  int Type(int vehicle) const { return vehicle_type_container_->Type(vehicle); }
2891 
2892  void Reset() {
2893  sorted_vehicle_classes_per_type_ =
2894  vehicle_type_container_->sorted_vehicle_classes_per_type;
2895  const std::vector<std::deque<int>>& vehicles_per_class =
2896  vehicle_type_container_->vehicles_per_vehicle_class;
2897  vehicles_per_vehicle_class_.resize(vehicles_per_class.size());
2898  for (int i = 0; i < vehicles_per_vehicle_class_.size(); i++) {
2899  vehicles_per_vehicle_class_[i].resize(vehicles_per_class[i].size());
2900  std::copy(vehicles_per_class[i].begin(), vehicles_per_class[i].end(),
2901  vehicles_per_vehicle_class_[i].begin());
2902  }
2903  }
2904 
2905  int GetVehicleOfType(int type) const {
2906  DCHECK_LT(type, NumTypes());
2907  const std::set<VehicleClassEntry>& vehicle_classes =
2908  sorted_vehicle_classes_per_type_[type];
2909  if (vehicle_classes.empty()) {
2910  return -1;
2911  }
2912  const int vehicle_class = (vehicle_classes.begin())->vehicle_class;
2913  DCHECK(!vehicles_per_vehicle_class_[vehicle_class].empty());
2914  return vehicles_per_vehicle_class_[vehicle_class][0];
2915  }
2916 
2917  void ReinjectVehicleOfClass(int vehicle, int vehicle_class,
2918  int64 fixed_cost) {
2919  std::vector<int>& vehicles = vehicles_per_vehicle_class_[vehicle_class];
2920  if (vehicles.empty()) {
2921  // Add the vehicle class entry to the set (it was removed when
2922  // vehicles_per_vehicle_class_[vehicle_class] got empty).
2923  std::set<VehicleClassEntry>& vehicle_classes =
2924  sorted_vehicle_classes_per_type_[Type(vehicle)];
2925  const auto& insertion =
2926  vehicle_classes.insert({vehicle_class, fixed_cost});
2927  DCHECK(insertion.second);
2928  }
2929  vehicles.push_back(vehicle);
2930  }
2931 
2932  // Searches for the best compatible vehicle of the given type, i.e. the first
2933  // vehicle v of type 'type' for which vehicle_is_compatible(v) returns true.
2934  // If a compatible vehicle is found, its index is removed from
2935  // vehicles_per_vehicle_class_ and returned.
2936  // Returns -1 otherwise.
2938  int type, std::function<bool(int)> vehicle_is_compatible);
2939 
2940  private:
2941  using VehicleClassEntry =
2943  const RoutingModel::VehicleTypeContainer* const vehicle_type_container_;
2944  // clang-format off
2945  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
2946  std::vector<std::vector<int> > vehicles_per_vehicle_class_;
2947  // clang-format on
2948 };
2949 
2962 
2964 // TODO(user): Eventually move this to the core CP solver library
2967  public:
2969  std::unique_ptr<IntVarFilteredHeuristic> heuristic);
2970 
2972 
2973  Decision* Next(Solver* solver) override;
2974 
2975  std::string DebugString() const override;
2976 
2978  int64 number_of_decisions() const;
2979  int64 number_of_rejects() const;
2980 
2981  private:
2982  const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
2983 };
2984 
2987  public:
2988  IntVarFilteredHeuristic(Solver* solver, const std::vector<IntVar*>& vars,
2989  LocalSearchFilterManager* filter_manager);
2990 
2992 
2996 
2999  int64 number_of_decisions() const { return number_of_decisions_; }
3000  int64 number_of_rejects() const { return number_of_rejects_; }
3001 
3002  virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; }
3003 
3004  protected:
3008  virtual bool InitializeSolution() { return true; }
3010  virtual bool BuildSolutionInternal() = 0;
3014  bool Commit();
3016  virtual bool StopSearch() { return false; }
3019  void SetValue(int64 index, int64 value) {
3020  if (!is_in_delta_[index]) {
3021  delta_->FastAdd(vars_[index])->SetValue(value);
3022  delta_indices_.push_back(index);
3023  is_in_delta_[index] = true;
3024  } else {
3025  delta_->SetValue(vars_[index], value);
3026  }
3027  }
3030  int64 Value(int64 index) const {
3031  return assignment_->IntVarContainer().Element(index).Value();
3032  }
3034  bool Contains(int64 index) const {
3035  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
3036  }
3039  int Size() const { return vars_.size(); }
3041  IntVar* Var(int64 index) const { return vars_[index]; }
3044 
3046 
3047  private:
3050  bool FilterAccept();
3051 
3052  Solver* solver_;
3053  const std::vector<IntVar*> vars_;
3054  Assignment* const delta_;
3055  std::vector<int> delta_indices_;
3056  std::vector<bool> is_in_delta_;
3057  Assignment* const empty_;
3058  LocalSearchFilterManager* filter_manager_;
3060  int64 number_of_decisions_;
3061  int64 number_of_rejects_;
3062 };
3063 
3066  public:
3068  LocalSearchFilterManager* filter_manager);
3072  const std::function<int64(int64)>& next_accessor);
3073  RoutingModel* model() const { return model_; }
3075  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
3077  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
3088 
3089  protected:
3090  bool StopSearch() override { return model_->CheckLimit(); }
3091  virtual void SetVehicleIndex(int64 node, int vehicle) {}
3092  virtual void ResetVehicleIndices() {}
3093 
3094  private:
3096  bool InitializeSolution() override;
3097 
3098  RoutingModel* const model_;
3099  std::vector<int64> start_chain_ends_;
3100  std::vector<int64> end_chain_starts_;
3101 };
3102 
3104  public:
3107  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3108  std::function<int64(int64)> penalty_evaluator,
3109  LocalSearchFilterManager* filter_manager);
3111 
3112  protected:
3113  typedef std::pair<int64, int64> ValuedPosition;
3114  struct StartEndValue {
3115  int64 distance;
3116  int vehicle;
3117 
3118  bool operator<(const StartEndValue& other) const {
3119  return std::tie(distance, vehicle) <
3120  std::tie(other.distance, other.vehicle);
3121  }
3122  };
3123  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
3124 
3130  // clang-format off
3131  std::vector<std::vector<StartEndValue> >
3132  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
3133 
3138  template <class Queue>
3140  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
3141  Queue* priority_queue);
3142  // clang-format on
3143 
3148  void InsertBetween(int64 node, int64 predecessor, int64 successor);
3154  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
3155  std::vector<ValuedPosition>* valued_positions);
3160  // TODO(user): Replace 'insert_before' and 'insert_after' by 'predecessor'
3161  // and 'successor' in the code.
3162  int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert,
3163  int64 insert_after,
3164  int64 insert_before,
3165  int vehicle) const;
3168  int64 GetUnperformedValue(int64 node_to_insert) const;
3169 
3170  std::function<int64(int64, int64, int64)> evaluator_;
3171  std::function<int64(int64)> penalty_evaluator_;
3172 };
3173 
3183  public:
3202  };
3203 
3206  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3207  std::function<int64(int64)> penalty_evaluator,
3208  LocalSearchFilterManager* filter_manager,
3211  bool BuildSolutionInternal() override;
3212  std::string DebugString() const override {
3213  return "GlobalCheapestInsertionFilteredHeuristic";
3214  }
3215 
3216  private:
3217  class PairEntry;
3218  class NodeEntry;
3219  typedef absl::flat_hash_set<PairEntry*> PairEntries;
3220  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
3221 
3228  void InsertPairsAndNodesByRequirementTopologicalOrder();
3229 
3236  void InsertPairs(const std::vector<int>& pair_indices);
3237 
3245  void InsertNodesOnRoutes(const std::vector<int>& nodes,
3246  const absl::flat_hash_set<int>& vehicles);
3247 
3253  void SequentialInsertNodes(const std::vector<int>& nodes);
3254 
3258  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
3259  std::vector<int>* unused_vehicles,
3260  absl::flat_hash_set<int>* used_vehicles);
3261 
3265  void InsertFarthestNodesAsSeeds();
3266 
3275  template <class Queue>
3276  int InsertSeedNode(
3277  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
3278  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
3279  // clang-format on
3280 
3283  void InitializePairPositions(
3284  const std::vector<int>& pair_indices,
3285  AdjustablePriorityQueue<PairEntry>* priority_queue,
3286  std::vector<PairEntries>* pickup_to_entries,
3287  std::vector<PairEntries>* delivery_to_entries);
3293  void InitializeInsertionEntriesPerformingPair(
3294  int64 pickup, int64 delivery, int64 penalty,
3295  AdjustablePriorityQueue<PairEntry>* priority_queue,
3296  std::vector<PairEntries>* pickup_to_entries,
3297  std::vector<PairEntries>* delivery_to_entries);
3300  void UpdatePairPositions(const std::vector<int>& pair_indices, int vehicle,
3301  int64 insert_after,
3302  AdjustablePriorityQueue<PairEntry>* priority_queue,
3303  std::vector<PairEntries>* pickup_to_entries,
3304  std::vector<PairEntries>* delivery_to_entries) {
3305  UpdatePickupPositions(pair_indices, vehicle, insert_after, priority_queue,
3306  pickup_to_entries, delivery_to_entries);
3307  UpdateDeliveryPositions(pair_indices, vehicle, insert_after, priority_queue,
3308  pickup_to_entries, delivery_to_entries);
3309  }
3312  void UpdatePickupPositions(const std::vector<int>& pair_indices, int vehicle,
3313  int64 pickup_insert_after,
3314  AdjustablePriorityQueue<PairEntry>* priority_queue,
3315  std::vector<PairEntries>* pickup_to_entries,
3316  std::vector<PairEntries>* delivery_to_entries);
3319  void UpdateDeliveryPositions(
3320  const std::vector<int>& pair_indices, int vehicle,
3321  int64 delivery_insert_after,
3322  AdjustablePriorityQueue<PairEntry>* priority_queue,
3323  std::vector<PairEntries>* pickup_to_entries,
3324  std::vector<PairEntries>* delivery_to_entries);
3327  void DeletePairEntry(PairEntry* entry,
3328  AdjustablePriorityQueue<PairEntry>* priority_queue,
3329  std::vector<PairEntries>* pickup_to_entries,
3330  std::vector<PairEntries>* delivery_to_entries);
3333  void InitializePositions(const std::vector<int>& nodes,
3334  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3335  std::vector<NodeEntries>* position_to_node_entries,
3336  const absl::flat_hash_set<int>& vehicles);
3342  void InitializeInsertionEntriesPerformingNode(
3343  int64 node, int64 penalty, const absl::flat_hash_set<int>& vehicles,
3344  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3345  std::vector<NodeEntries>* position_to_node_entries);
3348  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
3349  int64 insert_after, bool all_vehicles,
3350  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3351  std::vector<NodeEntries>* node_entries);
3354  void DeleteNodeEntry(NodeEntry* entry,
3355  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3356  std::vector<NodeEntries>* node_entries);
3357 
3360  void ComputeNeighborhoods();
3361 
3364  bool IsNeighborForCostClass(int cost_class, int64 node_index,
3365  int64 neighbor_index) const;
3366 
3368  const std::vector<int64>& GetNeighborsOfNodeForCostClass(
3369  int cost_class, int64 node_index) const {
3370  return gci_params_.neighbors_ratio == 1
3371  ? all_nodes_
3372  : node_index_to_neighbors_by_cost_class_[node_index][cost_class]
3373  ->PositionsSetAtLeastOnce();
3374  }
3375 
3376  int64 NumNonStartEndNodes() const {
3377  return model()->Size() - model()->vehicles();
3378  }
3379 
3380  void ResetVehicleIndices() override {
3381  node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
3382  }
3383 
3384  void SetVehicleIndex(int64 node, int vehicle) override {
3385  DCHECK_LT(node, node_index_to_vehicle_.size());
3386  node_index_to_vehicle_[node] = vehicle;
3387  }
3388 
3391  bool CheckVehicleIndices() const;
3392 
3393  GlobalCheapestInsertionParameters gci_params_;
3395  std::vector<int> node_index_to_vehicle_;
3396 
3397  // clang-format off
3398  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3399  node_index_to_neighbors_by_cost_class_;
3400  // clang-format on
3401 
3405  std::vector<int64> all_nodes_;
3406 };
3407 
3415  public:
3418  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3419  LocalSearchFilterManager* filter_manager);
3421  bool BuildSolutionInternal() override;
3422  std::string DebugString() const override {
3423  return "LocalCheapestInsertionFilteredHeuristic";
3424  }
3425 
3426  private:
3432  void ComputeEvaluatorSortedPositions(int64 node,
3433  std::vector<int64>* sorted_positions);
3438  void ComputeEvaluatorSortedPositionsOnRouteAfter(
3439  int64 node, int64 start, int64 next_after_start,
3440  std::vector<int64>* sorted_positions);
3441 
3442  std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
3443 };
3444 
3448  public:
3450  LocalSearchFilterManager* filter_manager);
3452  bool BuildSolutionInternal() override;
3453 
3454  private:
3455  class PartialRoutesAndLargeVehicleIndicesFirst {
3456  public:
3457  explicit PartialRoutesAndLargeVehicleIndicesFirst(
3458  const CheapestAdditionFilteredHeuristic& builder)
3459  : builder_(builder) {}
3460  bool operator()(int vehicle1, int vehicle2) const;
3461 
3462  private:
3463  const CheapestAdditionFilteredHeuristic& builder_;
3464  };
3466  template <typename Iterator>
3467  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
3468  Iterator end) const {
3469  const int size = model()->Size();
3470  std::vector<int64> nexts;
3471  for (Iterator it = start; it != end; ++it) {
3472  const int64 next = *it;
3473  if (next != node && (next >= size || !Contains(next))) {
3474  nexts.push_back(next);
3475  }
3476  }
3477  return nexts;
3478  }
3480  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
3481  virtual int64 FindTopSuccessor(int64 node,
3482  const std::vector<int64>& successors) = 0;
3483 };
3484 
3489  public:
3492  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
3493  LocalSearchFilterManager* filter_manager);
3495  std::string DebugString() const override {
3496  return "EvaluatorCheapestAdditionFilteredHeuristic";
3497  }
3498 
3499  private:
3501  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3502  int64 FindTopSuccessor(int64 node,
3503  const std::vector<int64>& successors) override;
3504 
3505  std::function<int64(int64, int64)> evaluator_;
3506 };
3507 
3512  public:
3516  LocalSearchFilterManager* filter_manager);
3518  std::string DebugString() const override {
3519  return "ComparatorCheapestAdditionFilteredHeuristic";
3520  }
3521 
3522  private:
3524  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3525  int64 FindTopSuccessor(int64 node,
3526  const std::vector<int64>& successors) override;
3527 
3528  Solver::VariableValueComparator comparator_;
3529 };
3530 
3540  public:
3544  double neighbors_ratio = 1.0;
3550  bool add_reverse_arcs = false;
3553  double arc_coefficient = 1.0;
3554  };
3555 
3557  const RoutingIndexManager* manager,
3558  SavingsParameters parameters,
3559  LocalSearchFilterManager* filter_manager);
3561  bool BuildSolutionInternal() override;
3562 
3563  protected:
3564  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
3565 
3566  template <typename S>
3568 
3569  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3570 
3571  virtual void BuildRoutesFromSavings() = 0;
3572 
3574  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3575  return saving.second / size_squared_;
3576  }
3578  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3579  return (saving.second % size_squared_) / Size();
3580  }
3582  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3583  return (saving.second % size_squared_) % Size();
3584  }
3586  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3587 
3597  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3598  int64 after_node);
3599 
3600  // clang-format off
3601  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3602  // clang-format on
3603  std::unique_ptr<VehicleTypeCurator> vehicle_type_curator_;
3604 
3605  private:
3610  // clang-format off
3611  void AddSymmetricArcsToAdjacencyLists(
3612  std::vector<std::vector<int64> >* adjacency_lists);
3613  // clang-format on
3614 
3621  void ComputeSavings();
3623  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3624  int after_node) const {
3625  return std::make_pair(saving, vehicle_type * size_squared_ +
3626  before_node * Size() + after_node);
3627  }
3628 
3632  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3633 
3634  const RoutingIndexManager* const manager_;
3635  const SavingsParameters savings_params_;
3636  int64 size_squared_;
3637 
3639 };
3640 
3642  public:
3644  const RoutingIndexManager* manager,
3645  SavingsParameters parameters,
3646  LocalSearchFilterManager* filter_manager)
3647  : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
3649  std::string DebugString() const override {
3650  return "SequentialSavingsFilteredHeuristic";
3651  }
3652 
3653  private:
3658  void BuildRoutesFromSavings() override;
3659  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3660 };
3661 
3663  public:
3665  const RoutingIndexManager* manager,
3666  SavingsParameters parameters,
3667  LocalSearchFilterManager* filter_manager)
3668  : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
3670  std::string DebugString() const override {
3671  return "ParallelSavingsFilteredHeuristic";
3672  }
3673 
3674  private:
3685  void BuildRoutesFromSavings() override;
3686 
3687  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3688 
3693  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3694  int64 after_node);
3695 
3697  std::vector<int64> first_node_on_route_;
3698  std::vector<int64> last_node_on_route_;
3702  std::vector<int> vehicle_of_first_or_last_node_;
3703 };
3704 
3708 
3710  public:
3712  LocalSearchFilterManager* filter_manager,
3713  bool use_minimum_matching);
3715  bool BuildSolutionInternal() override;
3716  std::string DebugString() const override {
3717  return "ChristofidesFilteredHeuristic";
3718  }
3719 
3720  private:
3721  const bool use_minimum_matching_;
3722 };
3723 #endif // SWIG
3724 
3730  const RoutingSearchParameters& search_parameters,
3731  const Assignment* initial_solution,
3732  Assignment* solution);
3733 
3735 
3737  public:
3738  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size);
3739  ~BasePathFilter() override {}
3740  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3741  int64 objective_min, int64 objective_max) override;
3742  void OnSynchronize(const Assignment* delta) override;
3743 
3744  protected:
3745  static const int64 kUnassigned;
3746 
3747  int64 GetNext(int64 node) const {
3748  return (new_nexts_[node] == kUnassigned)
3749  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3750  : new_nexts_[node];
3751  }
3752  int NumPaths() const { return starts_.size(); }
3753  int64 Start(int i) const { return starts_[i]; }
3754  int GetPath(int64 node) const { return paths_[node]; }
3755  int Rank(int64 node) const { return ranks_[node]; }
3756  bool IsDisabled() const { return status_ == DISABLED; }
3757  const std::vector<int64>& GetTouchedPathStarts() const {
3758  return touched_paths_.PositionsSetAtLeastOnce();
3759  }
3760  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3761  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3762  }
3763 
3764  private:
3765  enum Status { UNKNOWN, ENABLED, DISABLED };
3766 
3767  virtual bool DisableFiltering() const { return false; }
3768  virtual void OnBeforeSynchronizePaths() {}
3769  virtual void OnAfterSynchronizePaths() {}
3770  virtual void OnSynchronizePathFromStart(int64 start) {}
3771  virtual void InitializeAcceptPath() {}
3772  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3773  int64 chain_end) = 0;
3774  virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min,
3775  int64 objective_max) {
3776  return true;
3777  }
3779  void ComputePathStarts(std::vector<int64>* path_starts,
3780  std::vector<int>* index_to_path);
3781  bool HavePathsChanged();
3782  void SynchronizeFullAssignment();
3783  void UpdateAllRanks();
3784  void UpdatePathRanksFromStart(int start);
3785 
3786  std::vector<int64> node_path_starts_;
3787  std::vector<int64> starts_;
3788  std::vector<int> paths_;
3789  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3790  std::vector<int64> new_nexts_;
3791  std::vector<int> delta_touched_;
3792  SparseBitset<> touched_paths_;
3793  // clang-format off
3794  std::vector<std::pair<int64, int64> > touched_path_chain_start_ends_;
3795  // clang-format on
3796  std::vector<int> ranks_;
3797 
3798  Status status_;
3799 };
3800 
3805 // TODO(user): Also call the solution finalizer on variables, with the
3811 // TODO(user): Avoid such false negatives.
3813  public:
3814  explicit CPFeasibilityFilter(RoutingModel* routing_model);
3815  ~CPFeasibilityFilter() override {}
3816  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3817  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3818  int64 objective_min, int64 objective_max) override;
3819  void OnSynchronize(const Assignment* delta) override;
3820 
3821  private:
3822  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3823 
3824  static const int64 kUnassigned;
3825  const RoutingModel* const model_;
3826  Solver* const solver_;
3827  Assignment* const assignment_;
3828  Assignment* const temp_assignment_;
3829  DecisionBuilder* const restore_;
3830  SearchLimit* const limit_;
3831 };
3832 
3833 #if !defined(SWIG)
3835  const RoutingModel& routing_model);
3837  const RoutingModel& routing_model);
3839  const RoutingModel& routing_model);
3841  const RoutingModel& routing_model);
3843  const std::vector<RoutingDimension*>& dimensions,
3844  const RoutingSearchParameters& parameters, bool filter_objective_cost,
3845  std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3847  const PathState* path_state,
3848  const std::vector<RoutingDimension*>& dimensions,
3849  std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3851  const RoutingDimension& dimension,
3852  const RoutingSearchParameters& parameters,
3853  bool propagate_own_objective_value, bool filter_objective_cost,
3854  bool can_use_lp = true);
3856  const RoutingDimension& dimension);
3858  GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost);
3860  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3861  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3863  const RoutingModel& routing_model);
3865  const RoutingModel& routing_model, const RoutingDimension& dimension);
3867 #endif
3868 
3869 } // namespace operations_research
3870 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
Definition: routing.h:268
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:591
friend class RoutingModel
Definition: routing.h:2845
TypeRegulationsConstraint(const RoutingModel &model)
The class IntVar is a subset of IntExpr.
bool operator<(const DimensionCost &cost) const
Definition: routing.h:300
virtual ~IntVarFilteredHeuristic()
Definition: routing.h:2991
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &pure_transits, const std::vector< int > &dependent_transits, const RoutingDimension *base_dimension, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension with transits depending on the cumuls of another dimension.
Definition: routing.h:498
std::vector< int64 > pre_travels
Definition: routing.h:2022
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:240
bool Check() override
This method is called to check the status of the limit.
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
Definition: routing.h:3192
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:241
Filter-based heuristic dedicated to routing.
Definition: routing.h:3065
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2288
bool IsVarSynced(int index) const
bool RoutesToAssignment(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices, bool close_routes, Assignment *const assignment) const
Fills an assignment from a specification of the routes of the vehicles.
std::function< int64(int64, int64)> IndexEvaluator2
int64 transit_evaluator_class
Definition: routing.h:297
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:791
Definition: routing.h:2148
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &transits, const RoutingDimension *base_dimension, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
As above, but pure_transits are taken to be zero evaluators.
@ PICKUP_AND_DELIVERY_NO_ORDER
Any precedence is accepted.
Definition: routing.h:231
int vehicle_class
Definition: routing.h:359
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:378
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3582
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1146
int num_chain_tasks
Definition: routing.h:1950
int64 GetTransitValueFromClass(int64 from_index, int64 to_index, int64 vehicle_class) const
Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicl...
Definition: routing.h:2367
Definition: routing.h:2319
static const char kRemoveValues[]
Definition: routing.h:1936
bool DistanceDuration(Tasks *tasks)
Propagates distance_duration constraints, if any.
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1333
Assignment *const assignment_
Definition: routing.h:3045
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
@ TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added a...
Definition: routing.h:776
Definition: routing.h:323
void Reset()
Definition: routing.h:2892
const std::vector< IntVar * > & Nexts() const
Returns all next variables of the model, such that Nexts(i) is the next variable of the node correspo...
Definition: routing.h:1188
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, std::vector< int64 > node_visit_transits)
Deprecated, sets pre_travel(i, j) = node_visit_transit[i].
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:3553
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2383
void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor, int64 quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2716
const std::vector< int64 > & GetTouchedPathStarts() const
Definition: routing.h:3757
const IntContainer & IntVarContainer() const
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1266
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
bool AddMatrixDimension(std::vector< std::vector< int64 > > values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for...
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1150
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
void ArrangeIndices(std::vector< int64 > *indices)
void CloseModelWithParameters(const RoutingSearchParameters &search_parameters)
Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing...
std::string DebugString() const override
int64 span_max
Definition: routing.h:1961
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:242
friend class RoutingModelInspector
Definition: routing.h:2846
std::string DebugString() const override
Definition: routing.h:3495
Definition: routing.h:2882
int64 Value() const
void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex(int64 index, int64 max_cardinality, F f) const
Calls f for each variable index of indices in the same disjunctions as the node corresponding to the ...
Definition: routing.h:627
std::vector< std::pair< int64, int64 > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
const std::vector< std::pair< int, int > > & GetPickupIndexPairs(int64 node_index) const
Returns pairs for which the node is a pickup; the first element of each pair is the index in the pick...
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:466
int GetVisitType(int64 index) const
int64 second_node
Definition: routing.h:2638
std::function< int64(int64)> RoutingTransitCallback1
Definition: routing_types.h:41
Christofides addition heuristic.
Definition: routing.h:3709
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
int Type(int vehicle) const
Definition: routing.h:2890
int GetVehicleOfType(int type) const
Definition: routing.h:2905
IntVar * Var() const
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:377
void SetValue(int64 v)
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:274
void InitialPropagate() override
This method performs the initial propagation of the constraint.
Definition: routing.h:272
@ kRelax
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3760
int64 number_of_rejects() const
Definition: routing.h:3000
absl::StrongVector< DimensionIndex, int64 > dimension_evaluator_classes
dimension_evaluators[d]->Run(from, to) is the transit value of arc from->to for a dimension d.
Definition: routing.h:345
~CheapestAdditionFilteredHeuristic() override
Definition: routing.h:3451
~GlobalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:3210
void OnSynchronize(const Assignment *delta) override
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
Definition: routing.h:1200
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model)
int RegisterPositiveTransitCallback(TransitCallback2 callback)
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:3034
void AppendLightWeightDimensionFilters(const PathState *path_state, const std::vector< RoutingDimension * > &dimensions, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
virtual std::string DebugString() const
Definition: routing.h:3002
void AppendTasksFromPath(const std::vector< int64 > &path, const TravelBounds &travel_bounds, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
int StartNewRouteWithBestVehicleOfType(int type, int64 before_node, int64 after_node)
Finds the best available vehicle of type "type" to start a new route to serve the arc before_node-->a...
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
int64 Zero()
NOLINT.
void SetSoftSpanUpperBoundForVehicle(SimpleBoundCosts::BoundCost bound_cost, int vehicle)
If the span of vehicle on this dimension is larger than bound, the cost will be increased by cost * (...
Definition: routing.h:2688
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:327
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1248
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
Definition: routing.h:2636
IntVar * FixedTransitVar(int64 index) const
Definition: routing.h:2376
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
bool AddDimensionWithVehicleTransitAndCapacity(const std::vector< int > &evaluator_indices, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
CheapestAdditionFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
const std::vector< int64 > & vehicle_span_cost_coefficients() const
Definition: routing.h:2666
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3586
const RoutingModel::TransitCallback1 & GetUnaryTransitEvaluator(int vehicle) const
Returns the unary callback evaluating the transit value between two node indices for a given vehicle.
Definition: routing.h:2444
const std::vector< IntVar * > & VehicleVars() const
Returns all vehicle variables of the model, such that VehicleVars(i) is the vehicle variable of the n...
Definition: routing.h:1191
std::function< int64(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
Definition: routing.h:2626
Class to arrange indices by by their distance and their angles from the depot.
Definition: routing.h:2858
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:3008
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
@ PICKUP_AND_DELIVERY_LIFO
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:233
std::function< std::vector< operations_research::IntVar * >(RoutingModel *)> GetTabuVarsCallback
Sets the callback returning the variable to use for the Tabu Search metaheuristic.
Definition: routing.h:1356
BoundCost bound_cost(int element) const
Definition: routing.h:2326
int NumTypes() const
Definition: routing.h:368
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:655
Definition: routing.h:212
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
Definition: routing.h:745
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:362
friend class RoutingDimension
Definition: routing.h:1924
static const char kLightElement[]
Constraint types.
Definition: routing.h:1934
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:415
bool SolveModelWithSat(const RoutingModel &model, const RoutingSearchParameters &search_parameters, const Assignment *initial_solution, Assignment *solution)
Attempts to solve the model using the cp-sat solver.
void SetValue(const IntVar *const var, int64 value)
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
Routing model visitor.
Definition: routing.h:1931
static const int64 kUnassigned
Definition: routing.h:3745
~SequentialSavingsFilteredHeuristic() override
Definition: routing.h:3648
int64 cost_coefficient
Definition: routing.h:298
std::function< bool(int64, int64, int64)> VariableValueComparator
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2385
void ResetSolution()
Resets the data members for a new solution.
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio) are considered as insertion positions during in...
Definition: routing.h:3196
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
A search monitor is a simple set of callbacks to monitor all search events.
RoutingIndexPair IndexPair
Definition: routing.h:246
@ ROUTING_FAIL
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:221
int64 GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2654
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
int GetPath(int64 node) const
Definition: routing.h:3754
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:3077
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:564
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
~ChristofidesFilteredHeuristic() override
Definition: routing.h:3714
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:560
const RoutingModel::TransitCallback2 & transit_evaluator(int vehicle) const
Returns the callback evaluating the transit value between two node indices for a given vehicle.
Definition: routing.h:2437
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:265
~RoutingFilteredHeuristic() override
Definition: routing.h:3069
std::vector< bool > is_preemptible
Definition: routing.h:1957
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
Definition: routing.h:3186
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2699
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:682
void SetArcCostEvaluatorOfAllVehicles(int evaluator_index)
Sets the cost function of the model such that the cost of a segment of a route between node 'from' an...
Status status() const
Returns the current status of the routing model.
Definition: routing.h:1030
int position_of_last_type_on_vehicle_up_to_visit
Position of the last node of policy TYPE_ON_VEHICLE_UP_TO_VISIT visited on the route.
Definition: routing.h:2176
A structure to hold tasks described by their features.
Definition: routing.h:1949
int GetCompatibleVehicleOfType(int type, std::function< bool(int)> vehicle_is_compatible)
@ PICKUP_AND_DELIVERY_FIFO
Deliveries must be performed in the same order as pickups.
Definition: routing.h:235
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
Definition: routing.h:3511
std::vector< int64 > max_travels
Definition: routing.h:2021
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:3414
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
@ kAccept
int64 GetArcCostForClass(int64 from_index, int64 to_index, int64 cost_class_index) const
Returns the cost of the segment between two nodes for a given cost class.
int64 offset
Definition: routing.h:2639
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
bool TypeCurrentlyOnRoute(int type, int pos) const
Returns true iff there's at least one instance of the given type on the route when scanning the route...
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
Definition: routing.h:3103
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:325
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2662
virtual void SetVehicleIndex(int64 node, int vehicle)
Definition: routing.h:3091
Definition: routing.h:3641
CPFeasibilityFilter(RoutingModel *routing_model)
void AppendEvaluatedPositionsAfter(int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, std::vector< ValuedPosition > *valued_positions)
Helper method to the ComputeEvaluatorSortedPositions* methods.
bool TypeOccursOnRoute(int type) const
Returns true iff any occurrence of the given type was seen on the route, i.e.
const std::vector< int > & GetPairIndicesOfType(int type) const
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const
Returns the transition value for a given pair of nodes (as var index); this value is the one taken by...
int VehicleIndex(int index) const
Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/en...
Definition: routing.h:1177
Status
Status of the search.
Definition: routing.h:215
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1219
std::pair< int64, int64 > ValuedPosition
Definition: routing.h:3113
std::vector< int64 > end_max
Definition: routing.h:1956
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1959
friend void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:3030
~RoutingDimension()
int64 span_min
Definition: routing.h:1960
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
Definition: routing.h:2019
bool HasHardTypeIncompatibilities() const
Returns true if any hard (resp.
Definition: routing.h:810
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).
void AddTemporalTypeIncompatibility(int type1, int type2)
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1261
void InitialPropagate() override
This method performs the initial propagation of the constraint.
std::string DebugString() const override
Definition: routing.h:3212
~RoutingModel()
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2608
@ TYPE_ON_VEHICLE_UP_TO_VISIT
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
Definition: routing.h:771
int64 GetLastPossibleLessOrEqualValueForNode(int64 index, int64 max_value) const
Returns the largest value outside the forbidden intervals of node 'index' that is less than or equal ...
Definition: routing.h:2416
virtual ~TypeRegulationsChecker()
Definition: routing.h:2151
~CPFeasibilityFilter() override
Definition: routing.h:3815
Assignment *const BuildSolution()
Builds a solution.
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
void AddLocalSearchFilter(LocalSearchFilter *filter)
Adds a custom local search filter to the list of filters used to speed up local search by pruning unf...
Definition: routing.h:1157
Definition: routing.h:3114
A BaseObject is the root of all reversibly allocated objects.
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2612
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
Definition: routing.h:3567
IntVar * SlackVar(int64 index) const
Definition: routing.h:2377
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:3016
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size)
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:547
int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert, int64 insert_after, int64 insert_before, int vehicle) const
Returns the cost of inserting 'node_to_insert' between 'insert_after' and 'insert_before' on the 'veh...
absl::StrongVector< DimensionIndex, int64 > dimension_end_cumuls_max
Definition: routing.h:341
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2226
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64 > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
bool AddConstantDimensionWithSlack(int64 value, int64 capacity, int64 slack_max, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is t...
void AddSoftSameVehicleConstraint(const std::vector< int64 > &indices, int64 cost)
Adds a soft contraint to force a set of variable indices to be on the same vehicle.
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:956
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
Definition: routing.h:2966
void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration, int vehicle)
With breaks supposed to be consecutive, this forces the distance between breaks of size at least mini...
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
Definition: routing.h:3189
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, const RoutingSearchParameters &parameters, bool propagate_own_objective_value, bool filter_objective_cost, bool can_use_lp=true)
absl::StrongVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:339
Manager for any NodeIndex <-> variable index conversion.
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1256
int NumTypes() const
Definition: routing.h:2888
Local Search Filters are used for fast neighbor pruning.
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1335
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
const Assignment * BuildSolutionFromRoutes(const std::function< int64(int64)> &next_accessor)
Builds a solution starting from the routes formed by the next accessor.
int64 GetNext(int64 node) const
Definition: routing.h:3747
int64 GetFirstPossibleGreaterOrEqualValueForNode(int64 index, int64 min_value) const
Returns the smallest value outside the forbidden intervals of node 'index' that is greater than or eq...
Definition: routing.h:2397
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:347
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
IntVar * TransitVar(int64 index) const
Definition: routing.h:2375
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1318
std::unique_ptr< VehicleTypeCurator > vehicle_type_curator_
Definition: routing.h:3603
absl::Time AbsoluteSolverDeadline() const
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:3039
ChristofidesFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
const std::vector< IntVar * > & transits() const
Definition: routing.h:2384
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
Struct used to sort and store vehicles by their type.
Definition: routing.h:357
const E & Element(const V *const var) const
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
void InitializeCheck(int vehicle, const std::function< int64(int64)> &next_accessor)
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:229
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
Definition: routing.h:2884
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:239
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:3090
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
Definition: routing.h:3812
int64 GetHomogeneousCost(int64 from_index, int64 to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
Definition: routing.h:1224
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
Checker for type requirements.
Definition: routing.h:2224
int64 first_node
Definition: routing.h:2637
int64 global_span_cost_coefficient() const
Definition: routing.h:2670
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:892
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
Generic filter-based heuristic applied to IntVars.
Definition: routing.h:2986
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
const std::vector< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2432
std::string DebugString() const override
Definition: routing.h:3670
bool HasSoftSpanUpperBounds() const
Definition: routing.h:2696
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
~BasePathFilter() override
Definition: routing.h:3739
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
int64 Value(int index) const
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:407
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:931
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:411
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2317
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:2050
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1212
void AssignmentToRoutes(const Assignment &assignment, std::vector< std::vector< int64 >> *const routes) const
Converts the solution in the given assignment to routes for all vehicles.
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:646
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:3539
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64 fixed_cost)
Definition: routing.h:2917
int Rank(int64 node) const
Definition: routing.h:3755
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
RoutingCostClassIndex CostClassIndex
Definition: routing.h:237
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1205
TypeRegulationsChecker(const RoutingModel &model)
bool operator<(const StartEndValue &other) const
Definition: routing.h:3118
int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const
Same as above except that it returns default_value instead of 0 when penalty is not well defined (def...
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.
static const char kLightElement2[]
Definition: routing.h:1935
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Definition: routing.h:3664
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:3447
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
bool add_unperformed_entries
If true, entries are created for making the nodes/pairs unperformed, and when the cost of making a no...
Definition: routing.h:3201
@ TYPE_ADDED_TO_VEHICLE
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:763
virtual void BuildRoutesFromSavings()=0
~LocalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:3420
A DecisionBuilder is responsible for creating the search tree.
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:951
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
Definition: routing.h:2374
const RoutingModel & model_
Definition: routing.h:2200
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenAddingType(int type) const
Returns the set of requirement alternatives when adding the given type.
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:334
bool AddDimensionDependentDimensionWithVehicleCapacity(int transit, const RoutingDimension *base_dimension, int64 slack_max, int64 vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
Homogeneous versions of the functions above.
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
double max_memory_usage_bytes
The number of neighbors considered for each node is also adapted so that the stored Savings don't use...
Definition: routing.h:3547
RoutingIndexPairs IndexPairs
Definition: routing.h:247
RoutingModel::VisitTypePolicy VisitTypePolicy
Definition: routing.h:2158
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1345
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2360
int Type(int vehicle) const
Definition: routing.h:370
@ ROUTING_NOT_SOLVED
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:217
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1174
std::string DebugOutputAssignment(const Assignment &solution_assignment, const std::string &dimension_to_print) const
Print some debugging information about an assignment, including the feasible intervals of the CumulVa...
std::string DebugString() const override
Definition: routing.h:2053
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:855
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1324
std::vector< int64 > start_min
Definition: routing.h:1951
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model)
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
virtual bool FinalizeCheck() const
Definition: routing.h:2198
std::pair< StartEndValue, int > Seed
Definition: routing.h:3123
void Post() override
This method is called when the constraint is processed by the solver.
IntVarLocalSearchFilter * MakeCumulBoundsPropagatorFilter(const RoutingDimension &dimension)
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:296
~CheapestInsertionFilteredHeuristic() override
Definition: routing.h:3110
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1258
absl::StrongVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:342
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
Definition: routing.h:3574
std::string DebugString() const override
Definition: routing.h:3518
const std::vector< int64 > & vehicle_span_upper_bounds() const
Definition: routing.h:2658
~SavingsFilteredHeuristic() override
bool ApplyLocksToAllVehicles(const std::vector< std::vector< int64 >> &locks, bool close_routes)
Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for rout...
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
Definition: routing.h:761
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1273
@ ROUTING_SUCCESS
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:219
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
void SetVisitType(int64 index, int type, VisitTypePolicy type_policy)
int num_type_removed_from_vehicle
Number of ADDED_TYPE_REMOVED_FROM_VEHICLE (effectively removing a type from the route) and TYPE_SIMUL...
Definition: routing.h:2171
RoutingModel(const RoutingIndexManager &index_manager, const RoutingModelParameters &parameters)
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
Definition: routing_types.h:44
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
Interval variables are often used in scheduling.
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:619
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
Assignment * MutablePreAssignment()
Definition: routing.h:1055
std::pair< int64, int64 > Saving
Definition: routing.h:3564
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2642
bool HasPickupToDeliveryLimits() const
int RegisterTransitCallback(TransitCallback2 callback)
std::vector< int64 > duration_min
Definition: routing.h:1953
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
std::string DebugString() const override
Definition: routing.h:3422
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:45
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
Definition: routing.h:3488
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2388
virtual void OnInitializeCheck()
Definition: routing.h:2194
bool AddDimensionDependentDimensionWithVehicleCapacity(int pure_transit, int dependent_transit, const RoutingDimension *base_dimension, int64 slack_max, int64 vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
std::vector< int64 > start_max
Definition: routing.h:1952
int end_equivalence_class
Definition: routing.h:335
std::vector< int64 > duration_max
Definition: routing.h:1954
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the set of same-vehicle requirement alternatives for the given type.
int64 GetGlobalOptimizerOffset() const
Definition: routing.h:2674
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:864
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulOptimizers() const
Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed.
Definition: routing.h:556
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
std::vector< int > type_index_of_vehicle
Definition: routing.h:375
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:651
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
A constraint is the main modeling object.
Definition: routing.h:3662
RoutingModel * model() const
Definition: routing.h:3073
std::string DebugString() const override
Definition: routing.h:3716
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
~TypeIncompatibilityChecker() override
Definition: routing.h:2212
void InitializePriorityQueue(std::vector< std::vector< StartEndValue > > *start_end_distances_per_node, Queue *priority_queue)
Initializes the priority_queue by inserting the best entry corresponding to each node,...
std::vector< std::vector< int64 > > GetRoutesFromAssignment(const Assignment &assignment)
Converts the solution in the given assignment to routes for all vehicles.
Solver Class.
~ComparatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3517
virtual bool HasRegulationsToCheck() const =0
Definition: routing.h:3184
void OnSynchronize(const Assignment *delta) override
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
std::vector< int64 > post_travels
Definition: routing.h:2023
GlobalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, LocalSearchFilterManager *filter_manager, GlobalCheapestInsertionParameters parameters)
Takes ownership of evaluators.
DecisionBuilder * MakeSetValuesFromTargets(Solver *solver, std::vector< IntVar * > variables, std::vector< int64 > targets)
A decision builder which tries to assign values to variables as close as possible to target values fi...
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:813
int vehicle_to_class(int vehicle) const
Definition: routing.h:2455
CostClass(int evaluator_index)
Definition: routing.h:310
SimpleBoundCosts(const SimpleBoundCosts &)=delete
~ParallelSavingsFilteredHeuristic() override
Definition: routing.h:3669
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenRemovingType(int type) const
Returns the set of requirement alternatives when removing the given type.
RangeIntToIntFunction * transit
Definition: routing.h:264
const Assignment * PackCumulsOfOptimizerDimensionsFromAssignment(const Assignment *original_assignment, absl::Duration duration_limit)
For every dimension in the model with an optimizer in local/global_dimension_optimizers_,...
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
int vehicle
Definition: routing.h:3116
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2645
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
Definition: routing.h:3544
std::vector< int64 > end_min
Definition: routing.h:1955
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:1054
Checker for type incompatibilities.
Definition: routing.h:2208
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:738
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:934
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2451
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1170
void MakePartiallyPerformedPairsUnperformed()
Make all partially performed pickup and delivery pairs unperformed.
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
void Clear()
Definition: routing.h:1963
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2650
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
std::string DebugString() const override
Definition: routing.h:3816
Generic path-based filter class.
Definition: routing.h:3736
std::vector< std::vector< StartEndValue > > ComputeStartEndDistanceForVehicles(const std::vector< int > &vehicles)
Computes and returns the distance of each uninserted node to every vehicle in "vehicles" as a std::ve...
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
absl::StrongVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:338
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1239
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
void AddRequiredTypeAlternativesWhenRemovingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
The following requirements apply when visiting dependent nodes that remove their type from the route,...
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
@ ADDED_TYPE_REMOVED_FROM_VEHICLE
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:768
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:943
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1268
int64 Start(int vehicle) const
Model inspection.
Definition: routing.h:1168
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1210
void AddIntervalToAssignment(IntervalVar *const interval)
void AddSameVehicleRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported,...
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:3019
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
void SetQuadraticCostSoftSpanUpperBoundForVehicle(SimpleBoundCosts::BoundCost bound_cost, int vehicle)
If the span of vehicle on this dimension is larger than bound, the cost will be increased by cost * (...
Definition: routing.h:2706
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
std::vector< int64 > min_travels
Definition: routing.h:2020
std::string DebugString() const override
Definition: routing.h:3649
virtual ~SweepArranger()
Definition: routing.h:2861
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
Definition: routing.h:3541
const std::vector< int > & GetSingleNodesOfType(int type) const
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2323
~IntVarFilteredDecisionBuilder() override
Definition: routing.h:2971
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
void SetMaximumNumberOfActiveVehicles(int max_active_vehicles)
Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an emp...
Definition: routing.h:888
@ ROUTING_INVALID
Model, model parameters or flags are not valid.
Definition: routing.h:225
int64 number_of_rejects() const
int num_type_added_to_vehicle
Number of TYPE_ADDED_TO_VEHICLE and TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED node type policies seen on ...
Definition: routing.h:2165
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
SavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
int64 number_of_decisions() const
Returns statistics from its underlying heuristic.
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:734
bool IsDisabled() const
Definition: routing.h:3756
~TypeRequirementChecker() override
Definition: routing.h:2228
static const DisjunctionIndex kNoDisjunction
Constant used to express the "no disjunction" index, returned when a node does not appear in any disj...
Definition: routing.h:387
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1315
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:938
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2356
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
The base class for all local search operators.
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3601
const RoutingDimension * dimension
Definition: routing.h:299
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:391
Definition: routing.h:358
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:3075
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:3182
void Post() override
This method is called when the constraint is processed by the solver.
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
virtual void ResetVehicleIndices()
Definition: routing.h:3092
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
Definition: routing.h:596
VisitTypePolicy GetVisitTypePolicy(int64 index) const
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
Definition: routing.h:2161
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:314
void AddRequiredTypeAlternativesWhenAddingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_T...
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:3041
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Definition: routing.h:3643
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:308
DisjunctionIndex AddDisjunction(const std::vector< int64 > &indices, int64 penalty=kNoPenalty, int64 max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
bool ChainSpanMinDynamic(Tasks *tasks)
Computes a lower bound of the span of the chain, taking into account only the first nonchain task.
friend class RoutingModelInspector
Definition: routing.h:1925
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
int64 cost
Definition: routing.h:2321
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
RoutingDimensionIndex DimensionIndex
Definition: routing.h:238
int64 fixed_cost
Definition: routing.h:360
int NumPaths() const
Definition: routing.h:3752
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(GlobalDimensionCumulOptimizer *optimizer, bool filter_objective_cost)
SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index, int64 min_value, int64 max_value) const
Returns allowed intervals for a given node in a given interval.
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2719
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:3550
bool AddVectorDimension(std::vector< int64 > values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; ...
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(RoutingModel *routing_model)
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:3170
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:263
bool ChainSpanMin(Tasks *tasks)
Propagates a lower bound of the chain span, end[num_chain_tasks] - start[0], to span_min.
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1942
void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3578
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
@ ROUTING_FAIL_TIMEOUT
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:223
void SetSectors(int sectors)
Definition: routing.h:2863
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
RoutingFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
std::function< int64(int64, int64)> RoutingTransitCallback2
Definition: routing_types.h:42
std::vector< std::vector< std::pair< int64, int64 > > > GetCumulBounds(const Assignment &solution_assignment, const RoutingDimension &dimension)
Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maxi...
Base class of all search limits.
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:383
int64 GetArcCostForVehicle(int64 from_index, int64 to_index, int64 vehicle) const
Returns the cost of the transit arc between two nodes for a given vehicle.
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2382
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1331
bool HasTemporalTypeRequirements() const
Definition: routing.h:858
void SetAssignmentFromOtherModelAssignment(Assignment *target_assignment, const RoutingModel *source_model, const Assignment *source_assignment)
Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variab...
int64 distance
Definition: routing.h:3115
friend class SavingsFilteredHeuristicTestPeer
Definition: routing.h:3638
int GetNumberOfVisitTypes() const
Definition: routing.h:789
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2597
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
absl::StrongVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:340
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2999
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
BoundCost & bound_cost(int element)
Definition: routing.h:2325
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2678
int64 Start(int i) const
Definition: routing.h:3753
int Size()
Definition: routing.h:2327
std::function< int64(int64)> penalty_evaluator_
Definition: routing.h:3171
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1958
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
int64 bound
Definition: routing.h:2320
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1197
IntVarLocalSearchFilter * MakeMaxActiveVehiclesFilter(const RoutingModel &routing_model)
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
~EvaluatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3494
A Decision represents a choice point in the search tree.