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/hash/hash.h"
171 #include "absl/time/time.h"
172 #include "ortools/base/adjustable_priority_queue-inl.h"
173 #include "ortools/base/adjustable_priority_queue.h"
174 #include "ortools/base/commandlineflags.h"
175 #include "ortools/base/hash.h"
176 #include "ortools/base/int_type_indexed_vector.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
183 #include "ortools/constraint_solver/routing_parameters.pb.h"
185 #include "ortools/glop/lp_solver.h"
186 #include "ortools/glop/parameters.pb.h"
187 #include "ortools/graph/graph.h"
188 #include "ortools/lp_data/lp_data.h"
189 #include "ortools/lp_data/lp_types.h"
190 #include "ortools/sat/theta_tree.h"
191 #include "ortools/util/range_query_function.h"
192 #include "ortools/util/sorted_interval_list.h"
193 
194 namespace operations_research {
195 
196 class GlobalDimensionCumulOptimizer;
197 class IntVarFilteredDecisionBuilder;
198 class IntVarFilteredHeuristic;
199 class LocalDimensionCumulOptimizer;
200 class LocalSearchOperator;
201 class RoutingDimension;
202 #ifndef SWIG
203 using util::ReverseArcListGraph;
204 class SweepArranger;
205 #endif
206 struct SweepIndex;
207 
209  public:
211  enum Status {
222  };
223 
232  };
233  typedef RoutingCostClassIndex CostClassIndex;
234  typedef RoutingDimensionIndex DimensionIndex;
235  typedef RoutingDisjunctionIndex DisjunctionIndex;
236  typedef RoutingVehicleClassIndex VehicleClassIndex;
239 
240 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
241 #if !defined(SWIG)
244 #endif // SWIG
245 
246 #if !defined(SWIG)
247  struct StateDependentTransit {
260  RangeIntToIntFunction* transit;
261  RangeMinMaxIndexFunction* transit_plus_identity;
262  };
263  typedef std::function<StateDependentTransit(int64, int64)>
265 #endif // SWIG
266 
267 #if !defined(SWIG)
268  struct CostClass {
271 
286 
292  struct DimensionCost {
296  bool operator<(const DimensionCost& cost) const {
299  }
300  return cost_coefficient < cost.cost_coefficient;
301  }
302  };
303  std::vector<DimensionCost>
305 
308 
310  static bool LessThan(const CostClass& a, const CostClass& b) {
311  if (a.evaluator_index != b.evaluator_index) {
312  return a.evaluator_index < b.evaluator_index;
313  }
316  }
317  };
318 
319  struct VehicleClass {
323  int64 fixed_cost;
328  // TODO(user): Find equivalent start/end nodes wrt dimensions and
329  // callbacks.
334  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_min;
335  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_max;
336  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_min;
337  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_max;
338  gtl::ITIVector<DimensionIndex, int64> dimension_capacities;
341  gtl::ITIVector<DimensionIndex, int64> dimension_evaluator_classes;
344 
346  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
347  };
348 #endif // defined(SWIG)
349 
351  static const int64 kNoPenalty;
352 
356 
360 
364  explicit RoutingModel(const RoutingIndexManager& index_manager);
365  RoutingModel(const RoutingIndexManager& index_manager,
366  const RoutingModelParameters& parameters);
367  ~RoutingModel();
368 
375  const TransitCallback2& TransitCallback(int callback_index) const {
376  CHECK_LT(callback_index, transit_evaluators_.size());
377  return transit_evaluators_[callback_index];
378  }
379  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
380  CHECK_LT(callback_index, unary_transit_evaluators_.size());
381  return unary_transit_evaluators_[callback_index];
382  }
384  int callback_index) const {
385  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
386  return state_dependent_transit_evaluators_[callback_index];
387  }
388 
390 
402 
411  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
412  bool fix_start_cumul_to_zero, const std::string& name);
414  const std::vector<int>& evaluator_indices, int64 slack_max,
415  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
416  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
417  std::vector<int64> vehicle_capacities,
418  bool fix_start_cumul_to_zero,
419  const std::string& name);
421  const std::vector<int>& evaluator_indices, int64 slack_max,
422  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
423  const std::string& name);
430  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
431  int64 slack_max,
432  bool fix_start_cumul_to_zero,
433  const std::string& name);
434  bool AddConstantDimension(int64 value, int64 capacity,
435  bool fix_start_cumul_to_zero,
436  const std::string& name) {
437  return AddConstantDimensionWithSlack(value, capacity, 0,
438  fix_start_cumul_to_zero, name);
439  }
447  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
448  bool fix_start_cumul_to_zero,
449  const std::string& name);
457  bool AddMatrixDimension(std::vector<std::vector<int64>> values,
458  int64 capacity, bool fix_start_cumul_to_zero,
459  const std::string& name);
467  const std::vector<int>& pure_transits,
468  const std::vector<int>& dependent_transits,
469  const RoutingDimension* base_dimension, int64 slack_max,
470  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
471  const std::string& name) {
472  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
473  pure_transits, dependent_transits, base_dimension, slack_max,
474  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
475  }
478  const std::vector<int>& transits, const RoutingDimension* base_dimension,
479  int64 slack_max, std::vector<int64> vehicle_capacities,
480  bool fix_start_cumul_to_zero, const std::string& name);
483  int transit, const RoutingDimension* base_dimension, int64 slack_max,
484  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
485  const std::string& name);
487  int pure_transit, int dependent_transit,
488  const RoutingDimension* base_dimension, int64 slack_max,
489  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
490  const std::string& name);
491 
494  const std::function<int64(int64)>& f, int64 domain_start,
495  int64 domain_end);
496 
507  std::vector<IntVar*> spans,
508  std::vector<IntVar*> total_slacks);
509 
511  // TODO(user): rename.
512  std::vector<::std::string> GetAllDimensionNames() const;
514  const std::vector<RoutingDimension*>& GetDimensions() const {
515  return dimensions_.get();
516  }
518  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
519  // clang-format off
522  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
524  return global_dimension_optimizers_;
525  }
526  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
528  return local_dimension_optimizers_;
529  }
530  // clang-format on
531 
535  const RoutingDimension& dimension) const;
537  const RoutingDimension& dimension) const;
538 
540  bool HasDimension(const std::string& dimension_name) const;
543  const std::string& dimension_name) const;
547  const std::string& dimension_name) const;
552  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
553  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
554  primary_constrained_dimension_ = dimension_name;
555  }
558  const std::string& GetPrimaryConstrainedDimension() const {
559  return primary_constrained_dimension_;
560  }
577  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
578  int64 penalty = kNoPenalty,
579  int64 max_cardinality = 1);
581  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
582  int64 index) const {
583  return index_to_disjunctions_[index];
584  }
588  template <typename F>
590  int64 index, int64 max_cardinality, F f) const {
591  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
592  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
593  for (const int64 d_index : disjunctions_[disjunction].indices) {
594  f(d_index);
595  }
596  }
597  }
598  }
599 #if !defined(SWIGPYTHON)
600  const std::vector<int64>& GetDisjunctionIndices(
603  DisjunctionIndex index) const {
604  return disjunctions_[index].indices;
605  }
606 #endif // !defined(SWIGPYTHON)
607  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
609  return disjunctions_[index].value.penalty;
610  }
614  return disjunctions_[index].value.max_cardinality;
615  }
617  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
622  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
629 
633  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
634  int64 cost);
635 
640  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
641  int64 index);
642 
644  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
645  return allowed_vehicles_[index].empty() ||
646  allowed_vehicles_[index].find(vehicle) !=
647  allowed_vehicles_[index].end();
648  }
649 
664  // TODO(user): Remove this when model introspection detects linked nodes.
665  void AddPickupAndDelivery(int64 pickup, int64 delivery);
669  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
670  DisjunctionIndex delivery_disjunction);
671  // clang-format off
675  const std::vector<std::pair<int, int> >&
676  GetPickupIndexPairs(int64 node_index) const;
678  const std::vector<std::pair<int, int> >&
679  GetDeliveryIndexPairs(int64 node_index) const;
680  // clang-format on
681 
686  int vehicle);
688  int vehicle) const;
691 
692  int GetNumOfSingletonNodes() const;
693 
694 #ifndef SWIG
695  const IndexPairs& GetPickupAndDeliveryPairs() const {
697  return pickup_delivery_pairs_;
698  }
699  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
701  return pickup_delivery_disjunctions_;
702  }
703 #endif // SWIG
704  // TODO(user): Support multiple visit types per node?
720  void SetVisitType(int64 index, int type);
721  int GetVisitType(int64 index) const;
724  // TODO(user): Reconsider the logic and potentially remove the need to
726  void CloseVisitTypes();
727  int GetNumberOfVisitTypes() const { return num_visit_types_; }
732  void AddHardTypeIncompatibility(int type1, int type2);
733  void AddTemporalTypeIncompatibility(int type1, int type2);
735  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
736  int type) const;
737  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
738  int type) const;
742  return has_hard_type_incompatibilities_;
743  }
745  return has_temporal_type_incompatibilities_;
746  }
758  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
763  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
764  // clang-format off
767  const std::vector<absl::flat_hash_set<int> >&
769  const std::vector<absl::flat_hash_set<int> >&
771  // clang-format on
775  return has_same_vehicle_type_requirements_;
776  }
778  return has_temporal_type_requirements_;
779  }
780 
783  bool HasTypeRegulations() const {
787  }
788 
793  int64 UnperformedPenalty(int64 var_index) const;
797  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
801  int64 GetDepot() const;
802 
806  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
808  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
811  void SetFixedCostOfAllVehicles(int64 cost);
813  void SetFixedCostOfVehicle(int64 cost, int vehicle);
817  int64 GetFixedCostOfVehicle(int vehicle) const;
818 
834  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
835  int64 quadratic_cost_factor);
837  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
838  int64 quadratic_cost_factor,
839  int vehicle);
840 
841  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
842  return linear_cost_factor_of_vehicle_;
843  }
844  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
845  return quadratic_cost_factor_of_vehicle_;
846  }
847 
848  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
849  DCHECK_LT(vehicle, vehicles_);
850  consider_empty_route_costs_[vehicle] = consider_costs;
851  }
852 
853  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
854  DCHECK_LT(vehicle, vehicles_);
855  return consider_empty_route_costs_[vehicle];
856  }
857 
860 #ifndef SWIG
862  return first_solution_evaluator_;
863  }
864 #endif
867  first_solution_evaluator_ = std::move(evaluator);
868  }
871  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
873  void AddSearchMonitor(SearchMonitor* const monitor);
877  void AddAtSolutionCallback(std::function<void()> callback);
882  void AddVariableMinimizedByFinalizer(IntVar* var);
885  void AddVariableMaximizedByFinalizer(IntVar* var);
888  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost);
891  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
898  void CloseModel();
902  const RoutingSearchParameters& search_parameters);
909  const Assignment* Solve(const Assignment* assignment = nullptr);
917  const Assignment* SolveWithParameters(
918  const RoutingSearchParameters& search_parameters,
919  std::vector<const Assignment*>* solutions = nullptr);
920  const Assignment* SolveFromAssignmentWithParameters(
921  const Assignment* assignment,
922  const RoutingSearchParameters& search_parameters,
923  std::vector<const Assignment*>* solutions = nullptr);
930  Assignment* target_assignment, const RoutingModel* source_model,
931  const Assignment* source_assignment);
937  // TODO(user): Add support for non-homogeneous costs and disjunctions.
938  int64 ComputeLowerBound();
940  Status status() const { return status_; }
949  IntVar* ApplyLocks(const std::vector<int64>& locks);
958  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
959  bool close_routes);
964  const Assignment* const PreAssignment() const { return preassignment_; }
965  Assignment* MutablePreAssignment() { return preassignment_; }
969  bool WriteAssignment(const std::string& file_name) const;
973  Assignment* ReadAssignment(const std::string& file_name);
976  Assignment* RestoreAssignment(const Assignment& solution);
983  const std::vector<std::vector<int64>>& routes,
984  bool ignore_inactive_indices);
1001  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
1002  bool ignore_inactive_indices, bool close_routes,
1003  Assignment* const assignment) const;
1007  void AssignmentToRoutes(const Assignment& assignment,
1008  std::vector<std::vector<int64>>* const routes) const;
1026  Assignment* CompactAssignment(const Assignment& assignment) const;
1030  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1032  void AddToAssignment(IntVar* const var);
1033  void AddIntervalToAssignment(IntervalVar* const interval);
1045  const Assignment* original_assignment, absl::Duration duration_limit);
1046 #ifndef SWIG
1047  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1049  sweep_arranger_.reset(sweep_arranger);
1050  }
1052  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1053 #endif
1054  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1060  CHECK(filter != nullptr);
1061  if (closed_) {
1062  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1063  }
1064  extra_filters_.push_back(filter);
1065  }
1066 
1069  int64 Start(int vehicle) const { return starts_[vehicle]; }
1071  int64 End(int vehicle) const { return ends_[vehicle]; }
1073  bool IsStart(int64 index) const;
1075  bool IsEnd(int64 index) const { return index >= Size(); }
1078  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1082  int64 Next(const Assignment& assignment, int64 index) const;
1084  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1085 
1086 #if !defined(SWIGPYTHON)
1087  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1092  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1093 #endif
1094  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1097  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1101  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1102  return vehicle_costs_considered_[vehicle];
1103  }
1106  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1108  IntVar* CostVar() const { return cost_; }
1109 
1112  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1113  int64 vehicle) const;
1116  return costs_are_homogeneous_across_vehicles_;
1117  }
1120  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1121  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1122  }
1125  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1132  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1133  int64 /*CostClassIndex*/ cost_class_index) const;
1136  DCHECK(closed_);
1137  return cost_class_index_of_vehicle_[vehicle];
1138  }
1141  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1142  DCHECK(closed_);
1143  if (cost_class_index == kCostClassIndexOfZeroCost) {
1144  return has_vehicle_with_zero_cost_class_;
1145  }
1146  return cost_class_index < cost_classes_.size();
1147  }
1149  int GetCostClassesCount() const { return cost_classes_.size(); }
1152  return std::max(0, GetCostClassesCount() - 1);
1153  }
1155  DCHECK(closed_);
1156  return vehicle_class_index_of_vehicle_[vehicle];
1157  }
1159  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1161  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1162  DCHECK(closed_);
1163  return same_vehicle_groups_[same_vehicle_group_[node]];
1164  }
1183  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1188  std::string DebugOutputAssignment(
1189  const Assignment& solution_assignment,
1190  const std::string& dimension_to_print) const;
1191 
1194  Solver* solver() const { return solver_.get(); }
1195 
1197  bool CheckLimit() {
1198  DCHECK(limit_ != nullptr);
1199  return limit_->Check();
1200  }
1201 
1203  absl::Duration RemainingTime() const {
1204  DCHECK(limit_ != nullptr);
1205  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1206  }
1207 
1210  int nodes() const { return nodes_; }
1212  int vehicles() const { return vehicles_; }
1214  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1215 
1219  const RoutingSearchParameters& search_parameters) const;
1221  const RoutingSearchParameters& search_parameters) const;
1225  return automatic_first_solution_strategy_;
1226  }
1227 
1229  bool IsMatchingModel() const;
1230 
1231 #ifndef SWIG
1232  using GetTabuVarsCallback =
1235  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1236 
1237  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1238 #endif // SWIG
1239 
1241  // TODO(user): Find a way to test and restrict the access at the same time.
1254  const RoutingDimension* dimension,
1255  std::function<int64(int64)> initializer);
1256 #ifndef SWIG
1257  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1262  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1263  std::vector<IntVar*> variables);
1264 #endif
1265  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1279  const RoutingDimension* dimension);
1280 
1281  private:
1283  enum RoutingLocalSearchOperator {
1284  RELOCATE = 0,
1285  RELOCATE_PAIR,
1286  LIGHT_RELOCATE_PAIR,
1287  RELOCATE_NEIGHBORS,
1288  EXCHANGE,
1289  EXCHANGE_PAIR,
1290  CROSS,
1291  CROSS_EXCHANGE,
1292  TWO_OPT,
1293  OR_OPT,
1294  RELOCATE_EXPENSIVE_CHAIN,
1295  LIN_KERNIGHAN,
1296  TSP_OPT,
1297  MAKE_ACTIVE,
1298  RELOCATE_AND_MAKE_ACTIVE,
1299  MAKE_ACTIVE_AND_RELOCATE,
1300  MAKE_INACTIVE,
1301  MAKE_CHAIN_INACTIVE,
1302  SWAP_ACTIVE,
1303  EXTENDED_SWAP_ACTIVE,
1304  NODE_PAIR_SWAP,
1305  PATH_LNS,
1306  FULL_PATH_LNS,
1307  TSP_LNS,
1308  INACTIVE_LNS,
1309  EXCHANGE_RELOCATE_PAIR,
1310  RELOCATE_SUBTRIP,
1311  EXCHANGE_SUBTRIP,
1312  LOCAL_SEARCH_OPERATOR_COUNTER
1313  };
1314 
1318  template <typename T>
1319  struct ValuedNodes {
1320  std::vector<int64> indices;
1321  T value;
1322  };
1323  struct DisjunctionValues {
1324  int64 penalty;
1325  int64 max_cardinality;
1326  };
1327  typedef ValuedNodes<DisjunctionValues> Disjunction;
1328 
1331  struct CostCacheElement {
1336  int index;
1337  CostClassIndex cost_class_index;
1338  int64 cost;
1339  };
1340 
1342  void Initialize();
1343  void AddNoCycleConstraintInternal();
1344  bool AddDimensionWithCapacityInternal(
1345  const std::vector<int>& evaluator_indices, int64 slack_max,
1346  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1347  const std::string& name);
1348  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1349  const std::vector<int>& pure_transits,
1350  const std::vector<int>& dependent_transits,
1351  const RoutingDimension* base_dimension, int64 slack_max,
1352  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1353  const std::string& name);
1354  bool InitializeDimensionInternal(
1355  const std::vector<int>& evaluator_indices,
1356  const std::vector<int>& state_dependent_evaluator_indices,
1357  int64 slack_max, bool fix_start_cumul_to_zero,
1358  RoutingDimension* dimension);
1359  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1360 
1388  void StoreDimensionCumulOptimizers();
1389 
1390  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1391  void ComputeVehicleClasses();
1392  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1393  CostClassIndex cost_class_index) const;
1394  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1395  int node_index,
1396  std::vector<IntVar*>* cost_elements);
1397  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1398  std::vector<IntVar*>* cost_elements);
1399  Assignment* DoRestoreAssignment();
1400  static const CostClassIndex kCostClassIndexOfZeroCost;
1401  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1402  DCHECK_LT(0, vehicles_);
1403  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1404  : kCostClassIndexOfZeroCost)
1405  .value();
1406  }
1407  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1408  const CostClass& cost_class) const;
1410  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1412  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1413  const std::vector<int64>& deliveries);
1416  IntVar* CreateSameVehicleCost(int vehicle_index);
1419  int FindNextActive(int index, const std::vector<int64>& indices) const;
1420 
1423  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1424  int vehicle) const;
1432  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1433  Assignment* compact_assignment) const;
1434 
1435  void QuietCloseModel();
1436  void QuietCloseModelWithParameters(
1437  const RoutingSearchParameters& parameters) {
1438  if (!closed_) {
1439  CloseModelWithParameters(parameters);
1440  }
1441  }
1442 
1444  bool SolveMatchingModel(Assignment* assignment);
1445 #ifndef SWIG
1446  bool AppendAssignmentIfFeasible(
1448  const Assignment& assignment,
1449  std::vector<std::unique_ptr<Assignment>>* assignments);
1450 #endif
1451  void LogSolution(const RoutingSearchParameters& parameters,
1453  const std::string& description, int64 solution_cost,
1454  int64 start_time_ms);
1457  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1458  bool check_compact_assignment) const;
1463  std::string FindErrorInSearchParametersForModel(
1464  const RoutingSearchParameters& search_parameters) const;
1466  void SetupSearch(const RoutingSearchParameters& search_parameters);
1468  // TODO(user): Document each auxiliary method.
1469  Assignment* GetOrCreateAssignment();
1470  Assignment* GetOrCreateTmpAssignment();
1471  RegularLimit* GetOrCreateLimit();
1472  RegularLimit* GetOrCreateLocalSearchLimit();
1473  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1474  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1475  LocalSearchOperator* CreateInsertionOperator();
1476  LocalSearchOperator* CreateMakeInactiveOperator();
1477  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1478  LocalSearchOperator* GetNeighborhoodOperators(
1479  const RoutingSearchParameters& search_parameters) const;
1480  const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters();
1481  const std::vector<LocalSearchFilter*>& GetOrCreateFeasibilityFilters();
1482  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1483  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1484  void CreateFirstSolutionDecisionBuilders(
1485  const RoutingSearchParameters& search_parameters);
1486  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1487  const RoutingSearchParameters& search_parameters) const;
1488  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1489  const RoutingSearchParameters& parameters) const;
1490  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1491  const RoutingSearchParameters& search_parameters);
1492  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1493  const RoutingSearchParameters& search_parameters);
1494  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1495  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1496  void SetupAssignmentCollector(
1497  const RoutingSearchParameters& search_parameters);
1498  void SetupTrace(const RoutingSearchParameters& search_parameters);
1499  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1500  bool UsesLightPropagation(
1501  const RoutingSearchParameters& search_parameters) const;
1502  GetTabuVarsCallback tabu_var_callback_;
1503 
1504  int GetVehicleStartClass(int64 start) const;
1505 
1506  void InitSameVehicleGroups(int number_of_groups) {
1507  same_vehicle_group_.assign(Size(), 0);
1508  same_vehicle_groups_.assign(number_of_groups, {});
1509  }
1510  void SetSameVehicleGroup(int index, int group) {
1511  same_vehicle_group_[index] = group;
1512  same_vehicle_groups_[group].push_back(index);
1513  }
1514 
1516  std::unique_ptr<Solver> solver_;
1517  int nodes_;
1518  int vehicles_;
1519  Constraint* no_cycle_constraint_ = nullptr;
1521  std::vector<IntVar*> nexts_;
1522  std::vector<IntVar*> vehicle_vars_;
1523  std::vector<IntVar*> active_;
1524  std::vector<IntVar*> vehicle_costs_considered_;
1529  std::vector<IntVar*> is_bound_to_end_;
1530  mutable RevSwitch is_bound_to_end_ct_added_;
1532  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1533  gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1534  // clang-format off
1538  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1539  global_dimension_optimizers_;
1540  gtl::ITIVector<DimensionIndex, int> global_optimizer_index_;
1541  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1542  local_dimension_optimizers_;
1543  // clang-format off
1544  gtl::ITIVector<DimensionIndex, int> local_optimizer_index_;
1545  std::string primary_constrained_dimension_;
1547  IntVar* cost_ = nullptr;
1548  std::vector<int> vehicle_to_transit_cost_;
1549  std::vector<int64> fixed_cost_of_vehicle_;
1550  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1551  bool has_vehicle_with_zero_cost_class_;
1552  std::vector<int64> linear_cost_factor_of_vehicle_;
1553  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1554  bool vehicle_amortized_cost_factors_set_;
1565  std::vector<bool> consider_empty_route_costs_;
1566 #ifndef SWIG
1567  gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1568 #endif // SWIG
1569  bool costs_are_homogeneous_across_vehicles_;
1570  bool cache_callbacks_;
1571  mutable std::vector<CostCacheElement> cost_cache_;
1572  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1573 #ifndef SWIG
1574  gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1575 #endif // SWIG
1576  std::function<int(int64)> vehicle_start_class_callback_;
1578  gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1579  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1581  std::vector<ValuedNodes<int64> > same_vehicle_costs_;
1583 #ifndef SWIG
1584  std::vector<std::unordered_set<int>> allowed_vehicles_;
1585 #endif // SWIG
1586  IndexPairs pickup_delivery_pairs_;
1588  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1589  pickup_delivery_disjunctions_;
1590  // clang-format off
1591  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1592  // vector of pairs {pair_index, pickup_index} such that
1593  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1594  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1595  // Same as above for deliveries.
1596  std::vector<std::vector<std::pair<int, int> > >
1597  index_to_delivery_index_pairs_;
1598  // clang-format on
1599  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1600  // Same vehicle group to which a node belongs.
1601  std::vector<int> same_vehicle_group_;
1602  // Same vehicle node groups.
1603  std::vector<std::vector<int>> same_vehicle_groups_;
1604  // Node visit types
1605  // Variable index to visit type index.
1606  std::vector<int> index_to_visit_type_;
1607  // clang-format off
1608  std::vector<absl::flat_hash_set<int> >
1609  hard_incompatible_types_per_type_index_;
1610  bool has_hard_type_incompatibilities_;
1611  std::vector<absl::flat_hash_set<int> >
1612  temporal_incompatible_types_per_type_index_;
1613  bool has_temporal_type_incompatibilities_;
1614 
1615  std::vector<std::vector<absl::flat_hash_set<int> > >
1616  same_vehicle_required_type_alternatives_per_type_index_;
1617  bool has_same_vehicle_type_requirements_;
1618  std::vector<std::vector<absl::flat_hash_set<int> > >
1619  temporal_required_type_alternatives_per_type_index_;
1620  bool has_temporal_type_requirements_;
1621  absl::flat_hash_set<int> trivially_infeasible_visit_types_;
1622  // clang-format on
1623  int num_visit_types_;
1624  // Two indices are equivalent if they correspond to the same node (as given
1625  // to the constructors taking a RoutingIndexManager).
1626  std::vector<int> index_to_equivalence_class_;
1627  std::vector<int> index_to_vehicle_;
1628  std::vector<int64> starts_;
1629  std::vector<int64> ends_;
1630  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1631  // anymore.
1632  RoutingIndexManager manager_;
1633  int start_end_count_;
1634  // Model status
1635  bool closed_ = false;
1636  Status status_ = ROUTING_NOT_SOLVED;
1637  bool enable_deep_serialization_ = true;
1638 
1639  // Search data
1640  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1641  std::vector<IntVarFilteredDecisionBuilder*>
1642  first_solution_filtered_decision_builders_;
1643  Solver::IndexEvaluator2 first_solution_evaluator_;
1644  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
1646  std::vector<LocalSearchOperator*> local_search_operators_;
1647  std::vector<SearchMonitor*> monitors_;
1648  SolutionCollector* collect_assignments_ = nullptr;
1649  SolutionCollector* collect_one_assignment_ = nullptr;
1650  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1651  DecisionBuilder* solve_db_ = nullptr;
1652  DecisionBuilder* improve_db_ = nullptr;
1653  DecisionBuilder* restore_assignment_ = nullptr;
1654  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1655  Assignment* assignment_ = nullptr;
1656  Assignment* preassignment_ = nullptr;
1657  Assignment* tmp_assignment_ = nullptr;
1658  std::vector<IntVar*> extra_vars_;
1659  std::vector<IntervalVar*> extra_intervals_;
1660  std::vector<LocalSearchOperator*> extra_operators_;
1661  std::vector<LocalSearchFilter*> filters_;
1662  std::vector<LocalSearchFilter*> feasibility_filters_;
1663  std::vector<LocalSearchFilter*> extra_filters_;
1664 #ifndef SWIG
1665  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1666  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1667  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1668  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1669  std::unique_ptr<SweepArranger> sweep_arranger_;
1670 #endif
1671 
1672  RegularLimit* limit_ = nullptr;
1673  RegularLimit* ls_limit_ = nullptr;
1674  RegularLimit* lns_limit_ = nullptr;
1675  RegularLimit* first_solution_lns_limit_ = nullptr;
1676 
1677  typedef std::pair<int64, int64> CacheKey;
1678  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1679  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1680  StateDependentTransitCallbackCache;
1681 
1682  std::vector<TransitCallback1> unary_transit_evaluators_;
1683  std::vector<TransitCallback2> transit_evaluators_;
1684  // The following vector stores a boolean per transit_evaluator_, indicating
1685  // whether the transits are all positive.
1686  // is_transit_evaluator_positive_ will be set to true only when registering a
1687  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1688  // The actual positivity of the transit values will only be checked in debug
1689  // mode, when calling RegisterPositiveTransitCallback().
1690  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1691  // transits are known to be positive, as the positivity of a callback will
1692  // allow some improvements in the solver, but will entail in errors if the
1693  // transits are falsely assumed positive.
1694  std::vector<bool> is_transit_evaluator_positive_;
1695  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1696  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1697  state_dependent_transit_evaluators_cache_;
1698 
1699  friend class RoutingDimension;
1701 
1702  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1703 };
1704 
1707  public:
1709  static const char kLightElement[];
1710  static const char kLightElement2[];
1711  static const char kRemoveValues[];
1712 };
1713 
1714 #if !defined(SWIG)
1715 class DisjunctivePropagator {
1718  public:
1724  struct Tasks {
1726  std::vector<int64> start_min;
1727  std::vector<int64> start_max;
1728  std::vector<int64> duration_min;
1729  std::vector<int64> duration_max;
1730  std::vector<int64> end_min;
1731  std::vector<int64> end_max;
1732  std::vector<bool> is_preemptible;
1733  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1734  std::vector<std::pair<int64, int64>> distance_duration;
1735 
1736  void Clear() {
1737  start_min.clear();
1738  start_max.clear();
1739  duration_min.clear();
1740  duration_max.clear();
1741  end_min.clear();
1742  end_max.clear();
1743  is_preemptible.clear();
1744  forbidden_intervals.clear();
1745  distance_duration.clear();
1746  }
1747  };
1748 
1751  bool Propagate(Tasks* tasks);
1752 
1754  bool Precedences(Tasks* tasks);
1757  bool MirrorTasks(Tasks* tasks);
1759  bool EdgeFinding(Tasks* tasks);
1762  bool DetectablePrecedencesWithChain(Tasks* tasks);
1764  bool ForbiddenIntervals(Tasks* tasks);
1765  bool DistanceDuration(Tasks* tasks);
1766 
1767  private:
1770  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1772  std::vector<int> tasks_by_start_min_;
1773  std::vector<int> tasks_by_end_max_;
1774  std::vector<int> event_of_task_;
1775  std::vector<int> nonchain_tasks_by_start_max_;
1776 };
1777 
1778 void AppendTasksFromPath(const std::vector<int64>& path,
1779  const std::vector<int64>& min_travels,
1780  const std::vector<int64>& max_travels,
1781  const std::vector<int64>& pre_travels,
1782  const std::vector<int64>& post_travels,
1783  const RoutingDimension& dimension,
1784  DisjunctivePropagator::Tasks* tasks);
1785 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
1786  DisjunctivePropagator::Tasks* tasks);
1787 void FillPathEvaluation(const std::vector<int64>& path,
1788  const RoutingModel::TransitCallback2& evaluator,
1789  std::vector<int64>* values);
1790 #endif // !defined(SWIG)
1791 
1803  public:
1804  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
1805  std::string DebugString() const override {
1806  return "GlobalVehicleBreaksConstraint";
1807  }
1808 
1809  void Post() override;
1810  void InitialPropagate() override;
1811 
1812  private:
1813  void PropagateNode(int node);
1814  void PropagateVehicle(int vehicle);
1815  void PropagateMaxBreakDistance(int vehicle);
1816 
1817  const RoutingModel* model_;
1818  const RoutingDimension* const dimension_;
1819  std::vector<Demon*> vehicle_demons_;
1820  std::vector<int64> path_;
1821 
1826  void FillPartialPathOfVehicle(int vehicle);
1827  void FillPathTravels(const std::vector<int64>& path);
1828 
1839  class TaskTranslator {
1840  public:
1841  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
1842  : start_(start),
1843  before_start_(before_start),
1844  after_start_(after_start) {}
1845  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
1846  TaskTranslator() {}
1847 
1848  void SetStartMin(int64 value) {
1849  if (start_ != nullptr) {
1850  start_->SetMin(CapAdd(before_start_, value));
1851  } else if (interval_ != nullptr) {
1852  interval_->SetStartMin(value);
1853  }
1854  }
1855  void SetStartMax(int64 value) {
1856  if (start_ != nullptr) {
1857  start_->SetMax(CapAdd(before_start_, value));
1858  } else if (interval_ != nullptr) {
1859  interval_->SetStartMax(value);
1860  }
1861  }
1862  void SetDurationMin(int64 value) {
1863  if (interval_ != nullptr) {
1864  interval_->SetDurationMin(value);
1865  }
1866  }
1867  void SetEndMin(int64 value) {
1868  if (start_ != nullptr) {
1869  start_->SetMin(CapSub(value, after_start_));
1870  } else if (interval_ != nullptr) {
1871  interval_->SetEndMin(value);
1872  }
1873  }
1874  void SetEndMax(int64 value) {
1875  if (start_ != nullptr) {
1876  start_->SetMax(CapSub(value, after_start_));
1877  } else if (interval_ != nullptr) {
1878  interval_->SetEndMax(value);
1879  }
1880  }
1881 
1882  private:
1883  IntVar* start_ = nullptr;
1884  int64 before_start_;
1885  int64 after_start_;
1886  IntervalVar* interval_ = nullptr;
1887  };
1888 
1890  std::vector<TaskTranslator> task_translators_;
1891 
1893  DisjunctivePropagator disjunctive_propagator_;
1894  DisjunctivePropagator::Tasks tasks_;
1895 
1897  std::vector<int64> min_travel_;
1898  std::vector<int64> max_travel_;
1899  std::vector<int64> pre_travel_;
1900  std::vector<int64> post_travel_;
1901 };
1902 
1904  public:
1905  explicit TypeRegulationsChecker(const RoutingModel& model);
1907 
1908  bool CheckVehicle(int vehicle,
1909  const std::function<int64(int64)>& next_accessor);
1910 
1911  protected:
1913  struct NodeCount {
1915  int pickup = 0;
1916  int delivery = 0;
1917  };
1918 
1921  int GetNonDeliveryCount(int type) const;
1923  int GetNonDeliveredCount(int type) const;
1924 
1925  virtual bool HasRegulationsToCheck() const = 0;
1926  virtual void InitializeCheck() {}
1927  virtual bool CheckTypeRegulations(int type) = 0;
1928  virtual bool FinalizeCheck() const { return true; }
1929 
1931 
1932  private:
1933  std::vector<PickupDeliveryStatus> pickup_delivery_status_of_node_;
1934  std::vector<NodeCount> counts_of_type_;
1935 };
1936 
1939  public:
1941  bool check_hard_incompatibilities);
1943 
1944  private:
1945  bool HasRegulationsToCheck() const override;
1946  bool CheckTypeRegulations(int type) override;
1950  bool check_hard_incompatibilities_;
1951 };
1952 
1955  public:
1956  explicit TypeRequirementChecker(const RoutingModel& model)
1957  : TypeRegulationsChecker(model) {}
1959 
1960  private:
1961  bool HasRegulationsToCheck() const override;
1962  void InitializeCheck() override {
1963  types_with_same_vehicle_requirements_on_route_.clear();
1964  }
1965  bool CheckTypeRegulations(int type) override;
1966  bool FinalizeCheck() const override;
1967 
1968  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
1969 };
1970 
1991  public:
1992  explicit TypeRegulationsConstraint(const RoutingModel& model);
1993 
1994  void Post() override;
1995  void InitialPropagate() override;
1996 
1997  private:
1998  void PropagateNodeRegulations(int node);
1999  void CheckRegulationsOnVehicle(int vehicle);
2000 
2001  const RoutingModel& model_;
2002  TypeIncompatibilityChecker incompatibility_checker_;
2003  TypeRequirementChecker requirement_checker_;
2004  std::vector<Demon*> vehicle_demons_;
2005 };
2006 #if !defined SWIG
2007 class SimpleBoundCosts {
2020  public:
2021  struct BoundCost {
2022  int64 bound;
2023  int64 cost;
2024  };
2025  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2026  : bound_costs_(num_bounds, default_bound_cost) {}
2027  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2028  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2029  int Size() { return bound_costs_.size(); }
2030  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
2031  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
2032 
2033  private:
2034  std::vector<BoundCost> bound_costs_;
2035 };
2036 #endif // !defined SWIG
2037 
2055 // TODO(user): Break constraints need to know the service time of nodes
2059  public:
2062  RoutingModel* model() const { return model_; }
2066  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2069  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2070  int64 vehicle_class) const {
2071  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2072  to_index);
2073  }
2076  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2077  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2078  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2079  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2080 
2081 #if !defined(SWIGPYTHON)
2082  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2085  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2086  const std::vector<IntVar*>& transits() const { return transits_; }
2087  const std::vector<IntVar*>& slacks() const { return slacks_; }
2088 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2089  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2091  return forbidden_intervals_;
2092  }
2094  const std::vector<int64>& vehicle_capacities() const {
2095  return vehicle_capacities_;
2096  }
2100  return model_->TransitCallback(
2101  class_evaluators_[vehicle_to_class_[vehicle]]);
2102  }
2107  int vehicle) const {
2108  return model_->UnaryTransitCallbackOrNull(
2109  class_evaluators_[vehicle_to_class_[vehicle]]);
2110  }
2113  bool AreVehicleTransitsPositive(int vehicle) const {
2114  return model()->is_transit_evaluator_positive_
2115  [class_evaluators_[vehicle_to_class_[vehicle]]];
2116  }
2117  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2118 #endif
2119 #endif
2120  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2124  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2131  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2138  void SetGlobalSpanCostCoefficient(int64 coefficient);
2139 
2140 #ifndef SWIG
2141  void SetCumulVarPiecewiseLinearCost(int64 index,
2146  const PiecewiseLinearFunction& cost);
2149  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2152  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2153  int64 index) const;
2154 #endif
2155 
2164  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2165  int64 coefficient);
2168  bool HasCumulVarSoftUpperBound(int64 index) const;
2172  int64 GetCumulVarSoftUpperBound(int64 index) const;
2176  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2177 
2190  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2191  int64 coefficient);
2194  bool HasCumulVarSoftLowerBound(int64 index) const;
2198  int64 GetCumulVarSoftLowerBound(int64 index) const;
2202  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2218  // TODO(user): Remove if !defined when routing.i is repaired.
2219 #if !defined(SWIGPYTHON)
2220  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2221  int pre_travel_evaluator,
2222  int post_travel_evaluator);
2223 #endif // !defined(SWIGPYTHON)
2224 
2226  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2227  std::vector<int64> node_visit_transits);
2228 
2233  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2234  int vehicle);
2237  void InitializeBreaks();
2239  bool HasBreakConstraints() const;
2240 #if !defined(SWIGPYTHON)
2244  std::vector<IntervalVar*> breaks, int vehicle,
2245  std::vector<int64> node_visit_transits,
2246  std::function<int64(int64, int64)> group_delays);
2247 
2249  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2250  int vehicle) const;
2253  // clang-format off
2254  const std::vector<std::pair<int64, int64> >&
2255  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2256  // clang-format on
2257 #endif
2258  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2259  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2260 
2262  const RoutingDimension* base_dimension() const { return base_dimension_; }
2270  int64 ShortestTransitionSlack(int64 node) const;
2271 
2273  const std::string& name() const { return name_; }
2274 
2276 #ifndef SWIG
2277  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2278  return path_precedence_graph_;
2279  }
2280 #endif // SWIG
2281 
2291  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2292 
2294  PickupToDeliveryLimitFunction limit_function, int pair_index);
2295 
2296  bool HasPickupToDeliveryLimits() const;
2297 #ifndef SWIG
2298  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2299  int delivery) const;
2300 
2302  int64 first_node;
2304  int64 offset;
2305  };
2306 
2308  node_precedences_.push_back(precedence);
2309  }
2310  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2311  return node_precedences_;
2312  }
2313 #endif // SWIG
2314 
2315  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2316  AddNodePrecedence({first_node, second_node, offset});
2317  }
2318 
2319  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2320  return vehicle_span_upper_bounds_[vehicle];
2321  }
2322 #ifndef SWIG
2323  const std::vector<int64>& vehicle_span_upper_bounds() const {
2324  return vehicle_span_upper_bounds_;
2325  }
2326 #endif // SWIG
2327  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2328  return vehicle_span_cost_coefficients_[vehicle];
2329  }
2330 #ifndef SWIG
2331  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2332  return vehicle_span_cost_coefficients_;
2333  }
2334 #endif // SWIG
2336  return global_span_cost_coefficient_;
2337  }
2338 
2340  DCHECK_GE(global_optimizer_offset_, 0);
2341  return global_optimizer_offset_;
2342  }
2343  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2344  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2345  return 0;
2346  }
2347  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2348  return local_optimizer_offset_for_vehicle_[vehicle];
2349  }
2350 #if !defined SWIG
2354  int vehicle) {
2355  if (!HasSoftSpanUpperBounds()) {
2356  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2357  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2358  }
2359  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2360  }
2361  bool HasSoftSpanUpperBounds() const {
2362  return vehicle_soft_span_upper_bound_ != nullptr;
2363  }
2365  int vehicle) const {
2366  DCHECK(HasSoftSpanUpperBounds());
2367  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2368  }
2369 #endif
2370 
2371  private:
2372  struct SoftBound {
2373  IntVar* var;
2374  int64 bound;
2375  int64 coefficient;
2376  };
2377 
2378  struct PiecewiseLinearCost {
2379  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2380  IntVar* var;
2381  std::unique_ptr<PiecewiseLinearFunction> cost;
2382  };
2383 
2384  class SelfBased {};
2385  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2386  const std::string& name,
2387  const RoutingDimension* base_dimension);
2388  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2389  const std::string& name, SelfBased);
2390  void Initialize(const std::vector<int>& transit_evaluators,
2391  const std::vector<int>& state_dependent_transit_evaluators,
2392  int64 slack_max);
2393  void InitializeCumuls();
2394  void InitializeTransits(
2395  const std::vector<int>& transit_evaluators,
2396  const std::vector<int>& state_dependent_transit_evaluators,
2397  int64 slack_max);
2398  void InitializeTransitVariables(int64 slack_max);
2400  void SetupCumulVarSoftUpperBoundCosts(
2401  std::vector<IntVar*>* cost_elements) const;
2403  void SetupCumulVarSoftLowerBoundCosts(
2404  std::vector<IntVar*>* cost_elements) const;
2405  void SetupCumulVarPiecewiseLinearCosts(
2406  std::vector<IntVar*>* cost_elements) const;
2409  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2410  void SetupSlackAndDependentTransitCosts() const;
2412  void CloseModel(bool use_light_propagation);
2413 
2414  void SetOffsetForGlobalOptimizer(int64 offset) {
2415  global_optimizer_offset_ = std::max(Zero(), offset);
2416  }
2418  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2420  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2421  [](int64 offset) { return std::max(Zero(), offset); });
2422  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2423  }
2424 
2425  std::vector<IntVar*> cumuls_;
2426  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2427  std::vector<IntVar*> capacity_vars_;
2428  const std::vector<int64> vehicle_capacities_;
2429  std::vector<IntVar*> transits_;
2430  std::vector<IntVar*> fixed_transits_;
2433  std::vector<int> class_evaluators_;
2434  std::vector<int64> vehicle_to_class_;
2435 #ifndef SWIG
2436  ReverseArcListGraph<int, int> path_precedence_graph_;
2437 #endif
2438  // For every {first_node, second_node, offset} element in node_precedences_,
2439  // if both first_node and second_node are performed, then
2440  // cumuls_[second_node] must be greater than (or equal to)
2441  // cumuls_[first_node] + offset.
2442  std::vector<NodePrecedence> node_precedences_;
2443 
2444  // The transits of a dimension may depend on its cumuls or the cumuls of
2445  // another dimension. There can be no cycles, except for self loops, a
2446  // typical example for this is a time dimension.
2447  const RoutingDimension* const base_dimension_;
2448 
2449  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2450  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2451  // class.
2452  std::vector<int> state_dependent_class_evaluators_;
2453  std::vector<int64> state_dependent_vehicle_to_class_;
2454 
2455  // For each pickup/delivery pair_index for which limits have been set,
2456  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2457  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2458  std::vector<PickupToDeliveryLimitFunction>
2459  pickup_to_delivery_limits_per_pair_index_;
2460 
2461  // Used if some vehicle has breaks in this dimension, typically time.
2462  bool break_constraints_are_initialized_ = false;
2463  // clang-format off
2464  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2465  std::vector<std::vector<std::pair<int64, int64> > >
2466  vehicle_break_distance_duration_;
2467  // clang-format on
2468  // For each vehicle, stores the part of travel that is made directly
2469  // after (before) the departure (arrival) node of the travel.
2470  // These parts of the travel are non-interruptible, in particular by a break.
2471  std::vector<int> vehicle_pre_travel_evaluators_;
2472  std::vector<int> vehicle_post_travel_evaluators_;
2473 
2474  std::vector<IntVar*> slacks_;
2475  std::vector<IntVar*> dependent_transits_;
2476  std::vector<int64> vehicle_span_upper_bounds_;
2477  int64 global_span_cost_coefficient_;
2478  std::vector<int64> vehicle_span_cost_coefficients_;
2479  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2480  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2481  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2482  RoutingModel* const model_;
2483  const std::string name_;
2484  int64 global_optimizer_offset_;
2485  std::vector<int64> local_optimizer_offset_for_vehicle_;
2487  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2488  friend class RoutingModel;
2490 
2491  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2492 };
2493 
2494 #ifndef SWIG
2495 class SweepArranger {
2498  public:
2499  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2500  virtual ~SweepArranger() {}
2501  void ArrangeIndices(std::vector<int64>* indices);
2502  void SetSectors(int sectors) { sectors_ = sectors; }
2503 
2504  private:
2505  std::vector<int> coordinates_;
2506  int sectors_;
2507 
2508  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2509 };
2510 #endif
2511 
2514 DecisionBuilder* MakeSetValuesFromTargets(Solver* solver,
2515  std::vector<IntVar*> variables,
2516  std::vector<int64> targets);
2517 
2518 #ifndef SWIG
2519 
2533 // TODO(user): Eventually move this to the core CP solver library
2536  public:
2538  std::unique_ptr<IntVarFilteredHeuristic> heuristic);
2539 
2541 
2542  Decision* Next(Solver* solver) override;
2543 
2544  std::string DebugString() const override;
2545 
2547  int64 number_of_decisions() const;
2548  int64 number_of_rejects() const;
2549 
2550  private:
2551  const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
2552 };
2553 
2555 // TODO(user): Remove one level of indirection by getting rid of
2556 // IntVarFilteredHeuristic and putting everything in the
2557 // RoutingFilteredHeuristic?
2558 // In this case IntVarFilteredDecisionBuilder would also have to be renamed to
2559 // RoutingFilteredDecisionBuilder as it would no longer be generic.
2560 // TODO(user): Remove the inheritance from BaseObject as it's no longer
2561 // needed.
2563  public:
2564  IntVarFilteredHeuristic(Solver* solver, const std::vector<IntVar*>& vars,
2565  const std::vector<LocalSearchFilter*>& filters);
2566 
2568 
2571  Assignment* const BuildSolution();
2572 
2575  int64 number_of_decisions() const { return number_of_decisions_; }
2576  int64 number_of_rejects() const { return number_of_rejects_; }
2577 
2578  std::string DebugString() const override { return "IntVarFilteredHeuristic"; }
2579 
2580  protected:
2582  virtual bool InitializeSolution() { return true; }
2584  virtual bool BuildSolutionInternal() = 0;
2588  bool Commit();
2590  virtual bool StopSearch() { return false; }
2593  void SetValue(int64 index, int64 value) {
2594  if (!is_in_delta_[index]) {
2595  delta_->FastAdd(vars_[index])->SetValue(value);
2596  delta_indices_.push_back(index);
2597  is_in_delta_[index] = true;
2598  } else {
2599  delta_->SetValue(vars_[index], value);
2600  }
2601  }
2604  int64 Value(int64 index) const {
2605  return assignment_->IntVarContainer().Element(index).Value();
2606  }
2608  bool Contains(int64 index) const {
2609  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
2610  }
2613  int Size() const { return vars_.size(); }
2615  IntVar* Var(int64 index) const { return vars_[index]; }
2616 
2617  private:
2619  void SynchronizeFilters();
2622  bool FilterAccept();
2623 
2624  const std::vector<IntVar*> vars_;
2625  Assignment* const assignment_;
2626  Assignment* const delta_;
2627  std::vector<int> delta_indices_;
2628  std::vector<bool> is_in_delta_;
2629  Assignment* const empty_;
2630  LocalSearchFilterManager filter_manager_;
2632  int64 number_of_decisions_;
2633  int64 number_of_rejects_;
2634 };
2635 
2638  public:
2640  const std::vector<LocalSearchFilter*>& filters);
2642  RoutingModel* model() const { return model_; }
2644  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
2646  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
2649  void MakeDisjunctionNodesUnperformed(int64 node);
2652 
2653  protected:
2654  bool StopSearch() override { return model_->CheckLimit(); }
2655  virtual void SetVehicleIndex(int64 node, int vehicle) {}
2656  virtual void ResetVehicleIndices() {}
2657 
2658  private:
2660  bool InitializeSolution() override;
2661 
2662  RoutingModel* const model_;
2663  std::vector<int64> start_chain_ends_;
2664  std::vector<int64> end_chain_starts_;
2665 };
2666 
2668  public:
2671  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2672  std::function<int64(int64)> penalty_evaluator,
2673  const std::vector<LocalSearchFilter*>& filters);
2675 
2676  protected:
2677  typedef std::pair<int64, int64> ValuedPosition;
2678  struct StartEndValue {
2679  int64 distance;
2680  int vehicle;
2681 
2682  bool operator<(const StartEndValue& other) const {
2683  return std::tie(distance, vehicle) <
2684  std::tie(other.distance, other.vehicle);
2685  }
2686  };
2687  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
2688 
2694  // clang-format off
2695  std::vector<std::vector<StartEndValue> >
2696  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
2697 
2702  template <class Queue>
2704  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
2705  Queue* priority_queue);
2706  // clang-format on
2707 
2712  void InsertBetween(int64 node, int64 predecessor, int64 successor);
2718  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
2719  std::vector<ValuedPosition>* valued_positions);
2724  int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert,
2725  int64 insert_after,
2726  int64 insert_before,
2727  int vehicle) const;
2730  int64 GetUnperformedValue(int64 node_to_insert) const;
2731 
2732  std::function<int64(int64, int64, int64)> evaluator_;
2733  std::function<int64(int64)> penalty_evaluator_;
2734 };
2735 
2745  public:
2759  };
2760 
2763  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2764  std::function<int64(int64)> penalty_evaluator,
2765  const std::vector<LocalSearchFilter*>& filters,
2768  bool BuildSolutionInternal() override;
2769  std::string DebugString() const override {
2770  return "GlobalCheapestInsertionFilteredHeuristic";
2771  }
2772 
2773  private:
2774  class PairEntry;
2775  class NodeEntry;
2776  typedef absl::flat_hash_set<PairEntry*> PairEntries;
2777  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
2778 
2785  void InsertPairs();
2786 
2794  void InsertNodesOnRoutes(const std::vector<int>& nodes,
2795  const std::vector<int>& vehicles);
2796 
2802  void SequentialInsertNodes(const std::vector<int>& nodes);
2803 
2807  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
2808  std::vector<int>* used_vehicles,
2809  std::vector<int>* unused_vehicles);
2810 
2814  void InsertFarthestNodesAsSeeds();
2815 
2824  template <class Queue>
2825  int InsertSeedNode(
2826  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
2827  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
2828  // clang-format on
2829 
2832  void InitializePairPositions(
2833  AdjustablePriorityQueue<PairEntry>* priority_queue,
2834  std::vector<PairEntries>* pickup_to_entries,
2835  std::vector<PairEntries>* delivery_to_entries);
2841  void InitializeInsertionEntriesPerformingPair(
2842  int64 pickup, int64 delivery, int64 penalty,
2843  AdjustablePriorityQueue<PairEntry>* priority_queue,
2844  std::vector<PairEntries>* pickup_to_entries,
2845  std::vector<PairEntries>* delivery_to_entries);
2848  void UpdatePairPositions(int vehicle, int64 insert_after,
2849  AdjustablePriorityQueue<PairEntry>* priority_queue,
2850  std::vector<PairEntries>* pickup_to_entries,
2851  std::vector<PairEntries>* delivery_to_entries) {
2852  UpdatePickupPositions(vehicle, insert_after, priority_queue,
2853  pickup_to_entries, delivery_to_entries);
2854  UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
2855  pickup_to_entries, delivery_to_entries);
2856  }
2859  void UpdatePickupPositions(int vehicle, int64 pickup_insert_after,
2860  AdjustablePriorityQueue<PairEntry>* priority_queue,
2861  std::vector<PairEntries>* pickup_to_entries,
2862  std::vector<PairEntries>* delivery_to_entries);
2865  void UpdateDeliveryPositions(
2866  int vehicle, int64 delivery_insert_after,
2867  AdjustablePriorityQueue<PairEntry>* priority_queue,
2868  std::vector<PairEntries>* pickup_to_entries,
2869  std::vector<PairEntries>* delivery_to_entries);
2872  void DeletePairEntry(PairEntry* entry,
2873  AdjustablePriorityQueue<PairEntry>* priority_queue,
2874  std::vector<PairEntries>* pickup_to_entries,
2875  std::vector<PairEntries>* delivery_to_entries);
2878  void InitializePositions(const std::vector<int>& nodes,
2879  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2880  std::vector<NodeEntries>* position_to_node_entries,
2881  const std::vector<int>& vehicles);
2887  void InitializeInsertionEntriesPerformingNode(
2888  int64 node, int64 penalty, const std::vector<int>& vehicles,
2889  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2890  std::vector<NodeEntries>* position_to_node_entries);
2893  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
2894  int64 insert_after,
2895  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2896  std::vector<NodeEntries>* node_entries);
2899  void DeleteNodeEntry(NodeEntry* entry,
2900  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2901  std::vector<NodeEntries>* node_entries);
2902 
2907  void AddNeighborForCostClass(int cost_class, int64 node_index,
2908  int64 neighbor_index, bool neighbor_is_pickup,
2909  bool neighbor_is_delivery);
2910 
2913  bool IsNeighborForCostClass(int cost_class, int64 node_index,
2914  int64 neighbor_index) const;
2915 
2917  const std::vector<int64>& GetPickupNeighborsOfNodeForCostClass(
2918  int cost_class, int64 node_index) const {
2919  if (gci_params_.neighbors_ratio == 1) {
2920  return pickup_nodes_;
2921  }
2922  return node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
2923  ->PositionsSetAtLeastOnce();
2924  }
2925 
2927  const std::vector<int64>& GetDeliveryNeighborsOfNodeForCostClass(
2928  int cost_class, int64 node_index) const {
2929  if (gci_params_.neighbors_ratio == 1) {
2930  return delivery_nodes_;
2931  }
2932  return node_index_to_delivery_neighbors_by_cost_class_
2933  [node_index][cost_class]
2934  ->PositionsSetAtLeastOnce();
2935  }
2936 
2938  const std::vector<int64>& GetSingleNeighborsOfNodeForCostClass(
2939  int cost_class, int64 node_index) const {
2940  if (gci_params_.neighbors_ratio == 1) {
2941  return single_nodes_;
2942  }
2943  return node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]
2944  ->PositionsSetAtLeastOnce();
2945  }
2946 
2948  std::vector<const std::vector<int64>*> GetNeighborsOfNodeForCostClass(
2949  int cost_class, int64 node_index) const {
2950  return {&GetSingleNeighborsOfNodeForCostClass(cost_class, node_index),
2951  &GetPickupNeighborsOfNodeForCostClass(cost_class, node_index),
2952  &GetDeliveryNeighborsOfNodeForCostClass(cost_class, node_index)};
2953  }
2954 
2955  void ResetVehicleIndices() override {
2956  node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
2957  }
2958 
2959  void SetVehicleIndex(int64 node, int vehicle) override {
2960  DCHECK_LT(node, node_index_to_vehicle_.size());
2961  node_index_to_vehicle_[node] = vehicle;
2962  }
2963 
2966  bool CheckVehicleIndices() const;
2967 
2968  GlobalCheapestInsertionParameters gci_params_;
2970  std::vector<int> node_index_to_vehicle_;
2971 
2972  // clang-format off
2973  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
2974  node_index_to_single_neighbors_by_cost_class_;
2975  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
2976  node_index_to_pickup_neighbors_by_cost_class_;
2977  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
2978  node_index_to_delivery_neighbors_by_cost_class_;
2979  // clang-format on
2980 
2984  std::vector<int64> single_nodes_;
2985  std::vector<int64> pickup_nodes_;
2986  std::vector<int64> delivery_nodes_;
2987 };
2988 
2996  public:
2999  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3000  const std::vector<LocalSearchFilter*>& filters);
3002  bool BuildSolutionInternal() override;
3003  std::string DebugString() const override {
3004  return "LocalCheapestInsertionFilteredHeuristic";
3005  }
3006 
3007  private:
3013  void ComputeEvaluatorSortedPositions(int64 node,
3014  std::vector<int64>* sorted_positions);
3019  void ComputeEvaluatorSortedPositionsOnRouteAfter(
3020  int64 node, int64 start, int64 next_after_start,
3021  std::vector<int64>* sorted_positions);
3022 };
3023 
3027  public:
3029  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
3031  bool BuildSolutionInternal() override;
3032 
3033  private:
3034  class PartialRoutesAndLargeVehicleIndicesFirst {
3035  public:
3036  explicit PartialRoutesAndLargeVehicleIndicesFirst(
3037  const CheapestAdditionFilteredHeuristic& builder)
3038  : builder_(builder) {}
3039  bool operator()(int vehicle1, int vehicle2) const;
3040 
3041  private:
3042  const CheapestAdditionFilteredHeuristic& builder_;
3043  };
3045  template <typename Iterator>
3046  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
3047  Iterator end) const {
3048  const int size = model()->Size();
3049  std::vector<int64> nexts;
3050  for (Iterator it = start; it != end; ++it) {
3051  const int64 next = *it;
3052  if (next != node && (next >= size || !Contains(next))) {
3053  nexts.push_back(next);
3054  }
3055  }
3056  return nexts;
3057  }
3059  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
3060  virtual int64 FindTopSuccessor(int64 node,
3061  const std::vector<int64>& successors) = 0;
3062 };
3063 
3068  public:
3071  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
3072  const std::vector<LocalSearchFilter*>& filters);
3074  std::string DebugString() const override {
3075  return "EvaluatorCheapestAdditionFilteredHeuristic";
3076  }
3077 
3078  private:
3080  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3081  int64 FindTopSuccessor(int64 node,
3082  const std::vector<int64>& successors) override;
3083 
3084  std::function<int64(int64, int64)> evaluator_;
3085 };
3086 
3091  public:
3095  const std::vector<LocalSearchFilter*>& filters);
3097  std::string DebugString() const override {
3098  return "ComparatorCheapestAdditionFilteredHeuristic";
3099  }
3100 
3101  private:
3103  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3104  int64 FindTopSuccessor(int64 node,
3105  const std::vector<int64>& successors) override;
3106 
3107  Solver::VariableValueComparator comparator_;
3108 };
3109 
3119  public:
3123  double neighbors_ratio = 1.0;
3129  bool add_reverse_arcs = false;
3132  double arc_coefficient = 1.0;
3133  };
3134 
3136  SavingsParameters parameters,
3137  const std::vector<LocalSearchFilter*>& filters);
3138  ~SavingsFilteredHeuristic() override;
3139  bool BuildSolutionInternal() override;
3140 
3141  protected:
3142  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
3143 
3144  template <typename S>
3146 
3149  int64 fixed_cost;
3150 
3151  bool operator<(const VehicleClassEntry& other) const {
3152  return std::tie(fixed_cost, vehicle_class) <
3153  std::tie(other.fixed_cost, other.vehicle_class);
3154  }
3155  };
3156 
3157  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3158 
3159  virtual void BuildRoutesFromSavings() = 0;
3160 
3162  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3163  return saving.second / size_squared_;
3164  }
3166  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3167  return (saving.second % size_squared_) / Size();
3168  }
3170  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3171  return (saving.second % size_squared_) % Size();
3172  }
3174  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3175 
3185  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3186  int64 after_node);
3187 
3188  std::vector<int> type_index_of_vehicle_;
3189  // clang-format off
3190  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
3191  std::vector<std::deque<int> > vehicles_per_vehicle_class_;
3192  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3193  // clang-format on
3194 
3195  private:
3200  // clang-format off
3201  void AddSymmetricArcsToAdjacencyLists(
3202  std::vector<std::vector<int64> >* adjacency_lists);
3203  // clang-format on
3204 
3211  void ComputeSavings();
3213  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3214  int after_node) const {
3215  return std::make_pair(saving, vehicle_type * size_squared_ +
3216  before_node * Size() + after_node);
3217  }
3218 
3226  void ComputeVehicleTypes();
3227 
3231  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3232 
3233  RoutingIndexManager* const manager_;
3234  const SavingsParameters savings_params_;
3235  int64 size_squared_;
3236 
3238 };
3239 
3241  public:
3244  SavingsParameters parameters,
3245  const std::vector<LocalSearchFilter*>& filters)
3246  : SavingsFilteredHeuristic(model, manager, parameters, filters) {}
3248  std::string DebugString() const override {
3249  return "SequentialSavingsFilteredHeuristic";
3250  }
3251 
3252  private:
3257  void BuildRoutesFromSavings() override;
3258  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3259 };
3260 
3262  public:
3265  SavingsParameters parameters,
3266  const std::vector<LocalSearchFilter*>& filters)
3267  : SavingsFilteredHeuristic(model, manager, parameters, filters) {}
3269  std::string DebugString() const override {
3270  return "ParallelSavingsFilteredHeuristic";
3271  }
3272 
3273  private:
3284  void BuildRoutesFromSavings() override;
3285 
3286  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3287 
3292  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3293  int64 after_node);
3294 
3296  std::vector<int64> first_node_on_route_;
3297  std::vector<int64> last_node_on_route_;
3301  std::vector<int> vehicle_of_first_or_last_node_;
3302 };
3303 
3307 
3309  public:
3311  const std::vector<LocalSearchFilter*>& filters,
3312  bool use_minimum_matching);
3314  bool BuildSolutionInternal() override;
3315  std::string DebugString() const override {
3316  return "ChristofidesFilteredHeuristic";
3317  }
3318 
3319  private:
3320  const bool use_minimum_matching_;
3321 };
3322 #endif // SWIG
3323 
3328 bool SolveModelWithSat(const RoutingModel& model,
3329  const RoutingSearchParameters& search_parameters,
3330  const Assignment* initial_solution,
3331  Assignment* solution);
3332 
3334 
3336  public:
3337  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size);
3338  ~BasePathFilter() override {}
3339  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3340  int64 objective_min, int64 objective_max) override;
3341  void OnSynchronize(const Assignment* delta) override;
3342 
3343  protected:
3344  static const int64 kUnassigned;
3345 
3346  int64 GetNext(int64 node) const {
3347  return (new_nexts_[node] == kUnassigned)
3348  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3349  : new_nexts_[node];
3350  }
3351  int NumPaths() const { return starts_.size(); }
3352  int64 Start(int i) const { return starts_[i]; }
3353  int GetPath(int64 node) const { return paths_[node]; }
3354  int Rank(int64 node) const { return ranks_[node]; }
3355  bool IsDisabled() const { return status_ == DISABLED; }
3356  const std::vector<int64>& GetTouchedPathStarts() const {
3357  return touched_paths_.PositionsSetAtLeastOnce();
3358  }
3359  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3360  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3361  }
3362 
3363  private:
3364  enum Status { UNKNOWN, ENABLED, DISABLED };
3365 
3366  virtual bool DisableFiltering() const { return false; }
3367  virtual void OnBeforeSynchronizePaths() {}
3368  virtual void OnAfterSynchronizePaths() {}
3369  virtual void OnSynchronizePathFromStart(int64 start) {}
3370  virtual void InitializeAcceptPath() {}
3371  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3372  int64 chain_end) = 0;
3373  virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min,
3374  int64 objective_max,
3375  bool all_paths_accepted) {
3376  return true;
3377  }
3379  void ComputePathStarts(std::vector<int64>* path_starts,
3380  std::vector<int>* index_to_path);
3381  bool HavePathsChanged();
3382  void SynchronizeFullAssignment();
3383  void UpdateAllRanks();
3384  void UpdatePathRanksFromStart(int start);
3385 
3386  std::vector<int64> node_path_starts_;
3387  std::vector<int64> starts_;
3388  std::vector<int> paths_;
3389  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3390  std::vector<int64> new_nexts_;
3391  std::vector<int> delta_touched_;
3392  SparseBitset<> touched_paths_;
3393  SparseBitset<> touched_path_nodes_;
3394  std::vector<int> ranks_;
3395 
3396  Status status_;
3397 };
3398 
3403 // TODO(user): Also call the solution finalizer on variables, with the
3409 // TODO(user): Avoid such false negatives.
3411  public:
3412  explicit CPFeasibilityFilter(const RoutingModel* routing_model);
3413  ~CPFeasibilityFilter() override {}
3414  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3415  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3416  int64 objective_min, int64 objective_max) override;
3417  void OnSynchronize(const Assignment* delta) override;
3418 
3419  private:
3420  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3421 
3422  static const int64 kUnassigned;
3423  const RoutingModel* const model_;
3424  Solver* const solver_;
3425  Assignment* const assignment_;
3426  Assignment* const temp_assignment_;
3427  DecisionBuilder* const restore_;
3428 };
3429 
3430 #if !defined(SWIG)
3431 IntVarLocalSearchFilter* MakeNodeDisjunctionFilter(
3432  const RoutingModel& routing_model);
3433 IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter(
3434  const RoutingModel& routing_model);
3435 IntVarLocalSearchFilter* MakeTypeRegulationsFilter(
3436  const RoutingModel& routing_model);
3437 std::vector<IntVarLocalSearchFilter*> MakeCumulFilters(
3438  const RoutingDimension& dimension, bool filter_objective_cost);
3439 IntVarLocalSearchFilter* MakePathCumulFilter(const RoutingDimension& dimension,
3440  bool propagate_own_objective_value,
3441  bool filter_objective_cost);
3442 IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter(
3443  const RoutingDimension& dimension);
3444 IntVarLocalSearchFilter* MakeGlobalLPCumulFilter(
3445  GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost);
3446 IntVarLocalSearchFilter* MakePickupDeliveryFilter(
3447  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3448  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3449 IntVarLocalSearchFilter* MakeVehicleVarFilter(
3450  const RoutingModel& routing_model);
3451 IntVarLocalSearchFilter* MakeVehicleBreaksFilter(
3452  const RoutingModel& routing_model, const RoutingDimension& dimension);
3453 IntVarLocalSearchFilter* MakeCPFeasibilityFilter(
3454  const RoutingModel* routing_model);
3455 #endif
3456 
3457 } // namespace operations_research
3458 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
RoutingIndexPair IndexPair
Definition: routing.h:242
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:2582
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
std::string DebugString() const override
Definition: routing.h:3315
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
const IntContainer & IntVarContainer() const
Generic filter-based heuristic applied to IntVars.
Definition: routing.h:2562
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
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...
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
~ComparatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3096
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2315
std::vector<::std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
std::string DebugString() const override
Definition: routing.h:2578
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...
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
int64 first_node
Definition: routing.h:2302
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1135
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:2069
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:589
Any precedence is accepted.
Definition: routing.h:227
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
const std::vector< int64 > & vehicle_span_upper_bounds() const
Definition: routing.h:2323
const std::vector< int64 > & GetTouchedPathStarts() const
Definition: routing.h:3356
bool operator<(const StartEndValue &other) const
Definition: routing.h:2682
std::vector< int64 > start_max
Definition: routing.h:1727
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:379
bool HasPickupToDeliveryLimits() const
Definition: routing.h:1912
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1194
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; ...
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
int64 Value(int index) const
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:848
A BaseObject is the root of all reversibly allocated objects.
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2062
std::string DebugString() const override
Definition: routing.h:3414
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:783
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2277
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:261
std::pair< int64, int64 > ValuedPosition
Definition: routing.h:2677
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
void AddIntervalToAssignment(IntervalVar *const interval)
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
int vehicle_class
Definition: routing.h:3148
friend class RoutingDimension
Definition: routing.h:1699
std::vector< int > type_index_of_vehicle_
Definition: routing.h:3188
virtual ~SweepArranger()
Definition: routing.h:2500
std::function< int64(int64)> RoutingTransitCallback1
Definition: routing_types.h:41
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size)
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the sets of same-vehicle/temporal requirement alternatives for the given type.
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...
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:1078
int64 distance
Definition: routing.h:2679
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:359
std::string DebugString() const override
Definition: routing.h:3074
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:2644
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.
Definition: routing.h:208
int64 cost_coefficient
Definition: routing.h:294
void SetValue(const IntVar *const var, int64 value)
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< LocalSearchFilter * > &filters)
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1071
void InitialPropagate() override
This method performs the initial propagation of the constraint.
~CheapestInsertionFilteredHeuristic() override
Definition: routing.h:2674
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1154
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model)
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:1802
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
void Clear()
Definition: routing.h:1736
int64 number_of_decisions() const
Returns statistics from its underlying heuristic.
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1115
~GlobalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:2767
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:2590
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2085
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, bool propagate_own_objective_value, bool filter_objective_cost)
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:310
int64 Zero()
NOLINT.
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:237
Filter-based heuristic dedicated to routing.
Definition: routing.h:2637
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:523
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:338
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
std::function< int64(int64)> penalty_evaluator_
Definition: routing.h:2733
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:235
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
virtual void BuildRoutesFromSavings()=0
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
~TypeIncompatibilityChecker() override
Definition: routing.h:1942
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:608
bool IsVarSynced(int index) const
IntVar * SlackVar(int64 index) const
Definition: routing.h:2079
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:1990
static const int64 kUnassigned
Definition: routing.h:3344
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
Definition: routing.h:3145
RoutingCostClassIndex CostClassIndex
Definition: routing.h:233
RangeIntToIntFunction * transit
Definition: routing.h:260
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...
std::string DebugString() const override
Definition: routing.h:3003
A DecisionBuilder is responsible for creating the search tree.
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
void SetValue(int64 v)
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
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 AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
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:3126
Manager for any NodeIndex <-> variable index conversion.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:700
std::string DebugString() const override
Definition: routing.h:3097
const E & Element(const V *const var) const
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:259
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1075
int GetNumberOfVisitTypes() const
Definition: routing.h:727
absl::Time AbsoluteSolverDeadline() const
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:1956
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2327
ParallelSavingsFilteredHeuristic(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3263
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:343
bool HasTemporalTypeRequirements() const
Definition: routing.h:777
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...
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
~LocalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:3001
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
Definition: routing.h:2751
ChristofidesFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters, bool use_minimum_matching)
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:2106
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
int Rank(int64 node) const
Definition: routing.h:3354
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
int GetNonDeliveryCount(int type) const
Returns the number of pickups and fixed nodes from counts_of_type_["type"].
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
virtual bool HasRegulationsToCheck() const =0
IntVar * FixedTransitVar(int64 index) const
Definition: routing.h:2078
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2019
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1149
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:236
int delivery
Definition: routing.h:1916
~RoutingFilteredHeuristic() override
Definition: routing.h:2641
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:2654
BoundCost bound_cost(int element) const
Definition: routing.h:2028
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:2994
std::string DebugString() const override
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:3129
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
void AddTemporalTypeIncompatibility(int type1, int type2)
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 AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
Model, model parameters or flags are not valid.
Definition: routing.h:221
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:613
gtl::ITIVector< 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:341
std::pair< int64, int64 > Saving
Definition: routing.h:3142
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
int num_chain_tasks
Definition: routing.h:1725
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
Definition: routing.h:2076
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2025
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3192
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2343
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
std::string DebugString() const override
Definition: routing.h:3248
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:2754
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1733
CostClass(int evaluator_index)
Definition: routing.h:306
int64 second_node
Definition: routing.h:2303
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:2291
std::vector< int64 > start_min
Definition: routing.h:1726
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2273
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:2593
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
int64 fixed_cost
Definition: routing.h:3149
static const char kLightElement[]
Constraint types.
Definition: routing.h:1709
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3174
~IntVarFilteredDecisionBuilder() override
Definition: routing.h:2540
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:330
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
int GetPath(int64 node) const
Definition: routing.h:3353
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
virtual void ResetVehicleIndices()
Definition: routing.h:2656
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1212
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1098
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:215
int NumPaths() const
Definition: routing.h:3351
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
int64 GetGlobalOptimizerOffset() const
Definition: routing.h:2339
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
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:1089
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1052
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:213
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:2604
virtual ~TypeRegulationsChecker()
Definition: routing.h:1906
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.
static constexpr Value UNSET
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3166
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:334
~BasePathFilter() override
Definition: routing.h:3338
~ChristofidesFilteredHeuristic() override
Definition: routing.h:3313
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:964
The class IntVar is a subset of IntExpr.
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
Status
Status of the search.
Definition: routing.h:211
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
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:2099
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:3026
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
Definition: routing.h:264
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:238
GlobalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters, GlobalCheapestInsertionParameters parameters)
Takes ownership of evaluators.
Definition: routing.h:2301
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
TypeRegulationsChecker(const RoutingModel &model)
Definition: routing.h:1913
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:2732
int64 bound
Definition: routing.h:2022
A structure to hold tasks described by their features.
Definition: routing.h:1724
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
int GetNonDeliveredCount(int type) const
Same as above, but substracting the number of deliveries of "type".
A Decision represents a choice point in the search tree.
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)...
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...
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
Definition: routing.h:1903
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:321
bool IsDisabled() const
Definition: routing.h:3355
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:861
friend class RoutingModel
Definition: routing.h:2488
void InitialPropagate() override
This method performs the initial propagation of the constraint.
std::function< bool(int64, int64, int64)> VariableValueComparator
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type_
Definition: routing.h:3190
friend class SavingsFilteredHeuristicTestPeer
Definition: routing.h:3237
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
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...
Definition: routing.h:268
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
RoutingFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
bool Check() override
This method is called to check the status of the limit.
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:853
virtual bool FinalizeCheck() const
Definition: routing.h:1928
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
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...
const RoutingDimension * dimension
Definition: routing.h:295
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:229
Checker for type requirements.
Definition: routing.h:1954
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio) are considered as insertion positions during in...
Definition: routing.h:2758
void OnSynchronize(const Assignment *delta) override
int vehicle
Definition: routing.h:2680
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:375
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
int64 number_of_rejects() const
Definition: routing.h:2576
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
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:1059
Definition: routing.h:3120
virtual void InitializeCheck()
Definition: routing.h:1926
FirstSolutionStrategy_Value Value
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2575
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1214
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...
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
Definition: routing.h:3162
void OnSynchronize(const Assignment *delta) override
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:844
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
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...
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:2646
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
std::string DebugString() const override
Definition: routing.h:1805
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:2743
Assignment * MutablePreAssignment()
Definition: routing.h:965
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.
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:2027
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_max
Definition: routing.h:337
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
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.
std::vector< bool > is_preemptible
Definition: routing.h:1732
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.
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:617
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:2353
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
Class to arrange indices by by their distance and their angles from the depot.
Definition: routing.h:2497
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2058
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
static const char kLightElement2[]
Definition: routing.h:1710
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
bool HasSoftSpanUpperBounds() const
Definition: routing.h:2361
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3170
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1197
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:866
void SetVisitType(int64 index, int type)
Set the node visit types and incompatibilities/requirements between the types (see below).
~EvaluatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3073
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:3151
std::vector< int64 > duration_min
Definition: routing.h:1728
const RoutingModel & model_
Definition: routing.h:1930
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
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:466
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:323
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1106
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1048
Definition: routing.h:1912
IntVar * TransitVar(int64 index) const
Definition: routing.h:2077
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1717
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:514
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model)
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
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:1235
~ParallelSavingsFilteredHeuristic() override
Definition: routing.h:3268
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty std::string if it is unset.
Definition: routing.h:558
std::vector< int64 > duration_max
Definition: routing.h:1729
IntVarLocalSearchFilter * MakeCumulBoundsPropagatorFilter(const RoutingDimension &dimension)
SavingsFilteredHeuristic(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
RoutingDimensionIndex DimensionIndex
Definition: routing.h:234
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:434
std::vector< int64 > end_max
Definition: routing.h:1731
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:3118
const std::vector< IntVar * > & transits() const
Definition: routing.h:2086
CheapestAdditionFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1224
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_,...
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
int64 GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2319
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
Definition: routing_types.h:44
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:3132
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:225
Generic path-based filter class.
Definition: routing.h:3335
~TypeRequirementChecker() override
Definition: routing.h:1958
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
int64 global_span_cost_coefficient() const
Definition: routing.h:2335
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:45
Routing model visitor.
Definition: routing.h:1706
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1203
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:2615
int64 transit_evaluator_class
Definition: routing.h:293
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
Definition: routing.h:3410
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:841
Definition: routing.h:2746
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:355
std::vector< std::deque< int > > vehicles_per_vehicle_class_
Definition: routing.h:3191
virtual void SetVehicleIndex(int64 node, int vehicle)
Definition: routing.h:2655
int non_pickup_delivery
Definition: routing.h:1914
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1210
Definition: routing.h:3261
Definition: routing.h:1912
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:292
~CheapestAdditionFilteredHeuristic() override
Definition: routing.h:3030
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
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...
int64 offset
Definition: routing.h:2304
int GetVisitType(int64 index) const
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.
A constraint is the main modeling object.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:336
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
friend class RoutingModelInspector
Definition: routing.h:1700
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2262
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2113
RoutingModel * model() const
Definition: routing.h:2642
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:2613
PickupDeliveryStatus
Definition: routing.h:1912
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2084
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:217
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
int64 cost
Definition: routing.h:2023
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1734
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
Local Search Filters are used for fast neighbor pruning.
int RegisterPositiveTransitCallback(TransitCallback2 callback)
~RoutingDimension()
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)
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...
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:383
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:696
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:3123
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
int64 Start(int i) const
Definition: routing.h:3352
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...
TypeRegulationsConstraint(const RoutingModel &model)
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
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,...
Definition: routing.h:3147
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...
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2364
~SequentialSavingsFilteredHeuristic() override
Definition: routing.h:3247
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
const std::vector< int64 > & vehicle_span_cost_coefficients() const
Definition: routing.h:2331
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:270
void Post() override
This method is called when the constraint is processed by the solver.
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:351
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:219
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:527
Christofides addition heuristic.
Definition: routing.h:3308
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2310
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
std::string DebugString() const override
Definition: routing.h:2769
int pickup
Definition: routing.h:1915
RoutingIndexPairs IndexPairs
Definition: routing.h:243
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2087
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:552
friend class RoutingModelInspector
Definition: routing.h:2489
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1159
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
Definition: routing.h:2021
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
Definition: routing.h:2678
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...
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
~RoutingModel()
Checker for type incompatibilities.
Definition: routing.h:1938
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
CPFeasibilityFilter(const RoutingModel *routing_model)
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1108
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:2608
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
Definition: routing.h:2748
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:581
Solver Class.
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
int64 GetNext(int64 node) const
Definition: routing.h:3346
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:1092
void ArrangeIndices(std::vector< int64 > *indices)
void AppendTasksFromPath(const std::vector< int64 > &path, const std::vector< int64 > &min_travels, const std::vector< int64 > &max_travels, const std::vector< int64 > &pre_travels, const std::vector< int64 > &post_travels, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
Deliveries must be performed in the same order as pickups.
Definition: routing.h:231
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.
const std::vector< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2094
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3359
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...
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
Definition: routing.h:3089
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1141
SequentialSavingsFilteredHeuristic(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3242
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:1120
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:741
int64 number_of_rejects() const
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 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...
~CPFeasibilityFilter() override
Definition: routing.h:3413
const std::vector< absl::flat_hash_set< int > > & GetTemporalRequiredTypeAlternativesOfType(int type) const
std::function< int64(int64, int64)> IndexEvaluator2
FirstSolutionStrategy_Value
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
Definition: routing.h:3066
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:335
int64 Value() const
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:774
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1161
virtual bool CheckTypeRegulations(int type)=0
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1151
Interval variables are often used in scheduling.
int end_equivalence_class
Definition: routing.h:331
bool operator<(const DimensionCost &cost) const
Definition: routing.h:296
bool DistanceDuration(Tasks *tasks)
Assignment *const BuildSolution()
Builds a solution.
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:644
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(GlobalDimensionCumulOptimizer *optimizer, bool filter_objective_cost)
~SavingsFilteredHeuristic() override
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,...
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
int64 Start(int vehicle) const
Model inspection.
Definition: routing.h:1069
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2090
int vehicle_to_class(int vehicle) const
Definition: routing.h:2117
std::pair< StartEndValue, int > Seed
Definition: routing.h:2687
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
Definition: routing.h:2535
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
Definition: routing.h:2667
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
std::vector< int64 > end_min
Definition: routing.h:1730
std::function< int64(int64, int64)> RoutingTransitCallback2
Definition: routing_types.h:42
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
Definition: routing.h:319
void SetSectors(int sectors)
Definition: routing.h:2502
int RegisterTransitCallback(TransitCallback2 callback)
std::vector< IntVarLocalSearchFilter * > MakeCumulFilters(const RoutingDimension &dimension, bool filter_objective_cost)
~IntVarFilteredHeuristic() override
Definition: routing.h:2567
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1101
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:744
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:304
Status status() const
Returns the current status of the routing model.
Definition: routing.h:940
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
void Post() override
This method is called when the constraint is processed by the solver.
int Size()
Definition: routing.h:2029
void AddTemporalRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D temporally depends on type_R, any non-delivery node_D of type_D requires at least one non-d...
IntVar * Var() const
std::string DebugString() const override
Definition: routing.h:3269
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2307
Definition: routing.h:3240
static const char kRemoveValues[]
Definition: routing.h:1711