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"
184 #include "ortools/glop/lp_solver.h"
185 #include "ortools/glop/parameters.pb.h"
186 #include "ortools/graph/graph.h"
187 #include "ortools/lp_data/lp_data.h"
188 #include "ortools/lp_data/lp_types.h"
189 #include "ortools/sat/theta_tree.h"
190 #include "ortools/util/range_query_function.h"
191 #include "ortools/util/sorted_interval_list.h"
192 
193 namespace operations_research {
194 
195 class IntVarFilteredDecisionBuilder;
196 class LocalSearchOperator;
197 class RoutingDimension;
198 #ifndef SWIG
199 using util::ReverseArcListGraph;
200 class SweepArranger;
201 #endif
202 struct SweepIndex;
203 
205  public:
207  enum Status {
218  };
219 
228  };
229  typedef RoutingCostClassIndex CostClassIndex;
230  typedef RoutingDimensionIndex DimensionIndex;
231  typedef RoutingDisjunctionIndex DisjunctionIndex;
232  typedef RoutingVehicleClassIndex VehicleClassIndex;
235 
236 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
237 #if !defined(SWIG)
240 #endif // SWIG
241 
242 #if !defined(SWIG)
243  struct StateDependentTransit {
256  RangeIntToIntFunction* transit;
257  RangeMinMaxIndexFunction* transit_plus_identity;
258  };
259  typedef std::function<StateDependentTransit(int64, int64)>
261 #endif // SWIG
262 
263 #if !defined(SWIG)
264  struct CostClass {
267 
282 
288  struct DimensionCost {
292  bool operator<(const DimensionCost& cost) const {
295  }
296  return cost_coefficient < cost.cost_coefficient;
297  }
298  };
299  std::vector<DimensionCost>
301 
304 
306  static bool LessThan(const CostClass& a, const CostClass& b) {
307  if (a.evaluator_index != b.evaluator_index) {
308  return a.evaluator_index < b.evaluator_index;
309  }
312  }
313  };
314 
315  struct VehicleClass {
319  int64 fixed_cost;
324  // TODO(user): Find equivalent start/end nodes wrt dimensions and
325  // callbacks.
330  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_min;
331  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_max;
332  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_min;
333  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_max;
334  gtl::ITIVector<DimensionIndex, int64> dimension_capacities;
337  gtl::ITIVector<DimensionIndex, int64> dimension_evaluator_classes;
340 
342  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
343  };
344 #endif // defined(SWIG)
345 
347  static const int64 kNoPenalty;
348 
352 
356 
360  explicit RoutingModel(const RoutingIndexManager& index_manager);
361  RoutingModel(const RoutingIndexManager& index_manager,
362  const RoutingModelParameters& parameters);
363  ~RoutingModel();
364 
371  const TransitCallback2& TransitCallback(int callback_index) const {
372  CHECK_LT(callback_index, transit_evaluators_.size());
373  return transit_evaluators_[callback_index];
374  }
375  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
376  CHECK_LT(callback_index, unary_transit_evaluators_.size());
377  return unary_transit_evaluators_[callback_index];
378  }
380  int callback_index) const {
381  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
382  return state_dependent_transit_evaluators_[callback_index];
383  }
384 
386 
398 
407  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
408  bool fix_start_cumul_to_zero, const std::string& name);
410  const std::vector<int>& evaluator_indices, int64 slack_max,
411  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
412  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
413  std::vector<int64> vehicle_capacities,
414  bool fix_start_cumul_to_zero,
415  const std::string& name);
417  const std::vector<int>& evaluator_indices, int64 slack_max,
418  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
419  const std::string& name);
426  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
427  int64 slack_max,
428  bool fix_start_cumul_to_zero,
429  const std::string& name);
430  bool AddConstantDimension(int64 value, int64 capacity,
431  bool fix_start_cumul_to_zero,
432  const std::string& name) {
433  return AddConstantDimensionWithSlack(value, capacity, 0,
434  fix_start_cumul_to_zero, name);
435  }
443  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
444  bool fix_start_cumul_to_zero,
445  const std::string& name);
453  bool AddMatrixDimension(std::vector<std::vector<int64>> values,
454  int64 capacity, bool fix_start_cumul_to_zero,
455  const std::string& name);
463  const std::vector<int>& pure_transits,
464  const std::vector<int>& dependent_transits,
465  const RoutingDimension* base_dimension, int64 slack_max,
466  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
467  const std::string& name) {
468  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
469  pure_transits, dependent_transits, base_dimension, slack_max,
470  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
471  }
474  const std::vector<int>& transits, const RoutingDimension* base_dimension,
475  int64 slack_max, std::vector<int64> vehicle_capacities,
476  bool fix_start_cumul_to_zero, const std::string& name);
479  int transit, const RoutingDimension* base_dimension, int64 slack_max,
480  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
481  const std::string& name);
483  int pure_transit, int dependent_transit,
484  const RoutingDimension* base_dimension, int64 slack_max,
485  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
486  const std::string& name);
487 
490  const std::function<int64(int64)>& f, int64 domain_start,
491  int64 domain_end);
492 
503  std::vector<IntVar*> spans,
504  std::vector<IntVar*> total_slacks);
505 
507  // TODO(user): rename.
508  std::vector<::std::string> GetAllDimensionNames() const;
510  const std::vector<RoutingDimension*>& GetDimensions() const {
511  return dimensions_.get();
512  }
514  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
517  const std::vector<RoutingDimension*>& GetDimensionsForGlobalCumulOptimizers()
518  const {
519  return dimensions_for_global_optimizer_;
520  }
521  const std::vector<RoutingDimension*>& GetDimensionsForLocalCumulOptimizers()
522  const {
523  return dimensions_for_local_optimizer_;
524  }
526  bool HasDimension(const std::string& dimension_name) const;
529  const std::string& dimension_name) const;
533  const std::string& dimension_name) const;
538  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
539  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
540  primary_constrained_dimension_ = dimension_name;
541  }
544  const std::string& GetPrimaryConstrainedDimension() const {
545  return primary_constrained_dimension_;
546  }
563  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
564  int64 penalty = kNoPenalty,
565  int64 max_cardinality = 1);
567  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
568  int64 index) const {
569  return index_to_disjunctions_[index];
570  }
574  template <typename F>
576  int64 index, int64 max_cardinality, F f) const {
577  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
578  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
579  for (const int64 d_index : disjunctions_[disjunction].indices) {
580  f(d_index);
581  }
582  }
583  }
584  }
585 #if !defined(SWIGPYTHON)
586  const std::vector<int64>& GetDisjunctionIndices(
589  DisjunctionIndex index) const {
590  return disjunctions_[index].indices;
591  }
592 #endif // !defined(SWIGPYTHON)
593  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
595  return disjunctions_[index].value.penalty;
596  }
600  return disjunctions_[index].value.max_cardinality;
601  }
603  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
608  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
615 
619  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
620  int64 cost);
621 
626  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
627  int64 index);
628 
630  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
631  return allowed_vehicles_[index].empty() ||
632  allowed_vehicles_[index].find(vehicle) !=
633  allowed_vehicles_[index].end();
634  }
635 
650  // TODO(user): Remove this when model introspection detects linked nodes.
651  void AddPickupAndDelivery(int64 pickup, int64 delivery);
655  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
656  DisjunctionIndex delivery_disjunction);
657  // clang-format off
661  const std::vector<std::pair<int, int> >&
662  GetPickupIndexPairs(int64 node_index) const;
664  const std::vector<std::pair<int, int> >&
665  GetDeliveryIndexPairs(int64 node_index) const;
666  // clang-format on
667 
672  int vehicle);
674  int vehicle) const;
677 
678  int GetNumOfSingletonNodes() const;
679 
680 #ifndef SWIG
681  const IndexPairs& GetPickupAndDeliveryPairs() const {
683  return pickup_delivery_pairs_;
684  }
685  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
687  return pickup_delivery_disjunctions_;
688  }
689 #endif // SWIG
690  // TODO(user): Support multiple visit types per node?
706  void SetVisitType(int64 index, int type);
707  int GetVisitType(int64 index) const;
710  // TODO(user): Reconsider the logic and potentially remove the need to
712  void CloseVisitTypes();
713  int GetNumberOfVisitTypes() const { return num_visit_types_; }
718  void AddHardTypeIncompatibility(int type1, int type2);
719  void AddTemporalTypeIncompatibility(int type1, int type2);
721  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
722  int type) const;
723  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
724  int type) const;
728  return has_hard_type_incompatibilities_;
729  }
731  return has_temporal_type_incompatibilities_;
732  }
744  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
749  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
750  // clang-format off
753  const std::vector<absl::flat_hash_set<int> >&
755  const std::vector<absl::flat_hash_set<int> >&
757  // clang-format on
761  return has_same_vehicle_type_requirements_;
762  }
764  return has_temporal_type_requirements_;
765  }
766 
769  bool HasTypeRegulations() const {
773  }
774 
779  int64 UnperformedPenalty(int64 var_index) const;
783  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
787  int64 GetDepot() const;
788 
792  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
794  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
797  void SetFixedCostOfAllVehicles(int64 cost);
799  void SetFixedCostOfVehicle(int64 cost, int vehicle);
803  int64 GetFixedCostOfVehicle(int vehicle) const;
804 
820  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
821  int64 quadratic_cost_factor);
823  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
824  int64 quadratic_cost_factor,
825  int vehicle);
826 
827  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
828  return linear_cost_factor_of_vehicle_;
829  }
830  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
831  return quadratic_cost_factor_of_vehicle_;
832  }
833 
834  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
835  DCHECK_LT(vehicle, vehicles_);
836  consider_empty_route_costs_[vehicle] = consider_costs;
837  }
838 
839  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
840  DCHECK_LT(vehicle, vehicles_);
841  return consider_empty_route_costs_[vehicle];
842  }
843 
846 #ifndef SWIG
848  return first_solution_evaluator_;
849  }
850 #endif
853  first_solution_evaluator_ = std::move(evaluator);
854  }
857  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
859  void AddSearchMonitor(SearchMonitor* const monitor);
863  void AddAtSolutionCallback(std::function<void()> callback);
868  void AddVariableMinimizedByFinalizer(IntVar* var);
871  void AddVariableMaximizedByFinalizer(IntVar* var);
874  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost);
877  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
884  void CloseModel();
888  const RoutingSearchParameters& search_parameters);
895  const Assignment* Solve(const Assignment* assignment = nullptr);
903  const Assignment* SolveWithParameters(
904  const RoutingSearchParameters& search_parameters,
905  std::vector<const Assignment*>* solutions = nullptr);
906  const Assignment* SolveFromAssignmentWithParameters(
907  const Assignment* assignment,
908  const RoutingSearchParameters& search_parameters,
909  std::vector<const Assignment*>* solutions = nullptr);
916  Assignment* target_assignment, const RoutingModel* source_model,
917  const Assignment* source_assignment);
923  // TODO(user): Add support for non-homogeneous costs and disjunctions.
924  int64 ComputeLowerBound();
926  Status status() const { return status_; }
935  IntVar* ApplyLocks(const std::vector<int64>& locks);
944  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
945  bool close_routes);
950  const Assignment* const PreAssignment() const { return preassignment_; }
951  Assignment* MutablePreAssignment() { return preassignment_; }
955  bool WriteAssignment(const std::string& file_name) const;
959  Assignment* ReadAssignment(const std::string& file_name);
962  Assignment* RestoreAssignment(const Assignment& solution);
969  const std::vector<std::vector<int64>>& routes,
970  bool ignore_inactive_indices);
987  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
988  bool ignore_inactive_indices, bool close_routes,
989  Assignment* const assignment) const;
993  void AssignmentToRoutes(const Assignment& assignment,
994  std::vector<std::vector<int64>>* const routes) const;
1012  Assignment* CompactAssignment(const Assignment& assignment) const;
1016  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1018  void AddToAssignment(IntVar* const var);
1019  void AddIntervalToAssignment(IntervalVar* const interval);
1030  const Assignment* original_assignment, absl::Duration duration_limit);
1031 #ifndef SWIG
1032  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1034  sweep_arranger_.reset(sweep_arranger);
1035  }
1037  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1038 #endif
1039  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1045  CHECK(filter != nullptr);
1046  if (closed_) {
1047  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1048  }
1049  extra_filters_.push_back(filter);
1050  }
1051 
1054  int64 Start(int vehicle) const { return starts_[vehicle]; }
1056  int64 End(int vehicle) const { return ends_[vehicle]; }
1058  bool IsStart(int64 index) const;
1060  bool IsEnd(int64 index) const { return index >= Size(); }
1063  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1067  int64 Next(const Assignment& assignment, int64 index) const;
1069  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1070 
1071 #if !defined(SWIGPYTHON)
1072  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1077  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1078 #endif
1079  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1082  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1086  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1087  return vehicle_costs_considered_[vehicle];
1088  }
1091  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1093  IntVar* CostVar() const { return cost_; }
1094 
1097  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1098  int64 vehicle) const;
1101  return costs_are_homogeneous_across_vehicles_;
1102  }
1105  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1106  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1107  }
1110  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1117  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1118  int64 /*CostClassIndex*/ cost_class_index) const;
1121  DCHECK(closed_);
1122  return cost_class_index_of_vehicle_[vehicle];
1123  }
1126  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1127  DCHECK(closed_);
1128  if (cost_class_index == kCostClassIndexOfZeroCost) {
1129  return has_vehicle_with_zero_cost_class_;
1130  }
1131  return cost_class_index < cost_classes_.size();
1132  }
1134  int GetCostClassesCount() const { return cost_classes_.size(); }
1137  return std::max(0, GetCostClassesCount() - 1);
1138  }
1140  DCHECK(closed_);
1141  return vehicle_class_index_of_vehicle_[vehicle];
1142  }
1144  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1146  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1147  DCHECK(closed_);
1148  return same_vehicle_groups_[same_vehicle_group_[node]];
1149  }
1168  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1173  std::string DebugOutputAssignment(
1174  const Assignment& solution_assignment,
1175  const std::string& dimension_to_print) const;
1176 
1179  Solver* solver() const { return solver_.get(); }
1180 
1182  bool CheckLimit() {
1183  DCHECK(limit_ != nullptr);
1184  return limit_->Check();
1185  }
1186 
1188  absl::Duration RemainingTime() const {
1189  DCHECK(limit_ != nullptr);
1190  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1191  }
1192 
1195  int nodes() const { return nodes_; }
1197  int vehicles() const { return vehicles_; }
1199  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1200 
1204  const RoutingSearchParameters& search_parameters) const;
1206  const RoutingSearchParameters& search_parameters) const;
1207 
1209  bool IsMatchingModel() const;
1210 
1211 #ifndef SWIG
1212  using GetTabuVarsCallback =
1215  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1216 
1217  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1218 #endif // SWIG
1219 
1221  // TODO(user): Find a way to test and restrict the access at the same time.
1234  const RoutingDimension* dimension,
1235  std::function<int64(int64)> initializer);
1236 #ifndef SWIG
1237  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1242  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1243  std::vector<IntVar*> variables);
1244 #endif
1245  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1259  const RoutingDimension* dimension);
1260 
1261  private:
1263  enum RoutingLocalSearchOperator {
1264  RELOCATE = 0,
1265  RELOCATE_PAIR,
1266  LIGHT_RELOCATE_PAIR,
1267  RELOCATE_NEIGHBORS,
1268  EXCHANGE,
1269  EXCHANGE_PAIR,
1270  CROSS,
1271  CROSS_EXCHANGE,
1272  TWO_OPT,
1273  OR_OPT,
1274  RELOCATE_EXPENSIVE_CHAIN,
1275  LIN_KERNIGHAN,
1276  TSP_OPT,
1277  MAKE_ACTIVE,
1278  RELOCATE_AND_MAKE_ACTIVE,
1279  MAKE_ACTIVE_AND_RELOCATE,
1280  MAKE_INACTIVE,
1281  MAKE_CHAIN_INACTIVE,
1282  SWAP_ACTIVE,
1283  EXTENDED_SWAP_ACTIVE,
1284  NODE_PAIR_SWAP,
1285  PATH_LNS,
1286  FULL_PATH_LNS,
1287  TSP_LNS,
1288  INACTIVE_LNS,
1289  EXCHANGE_RELOCATE_PAIR,
1290  RELOCATE_SUBTRIP,
1291  EXCHANGE_SUBTRIP,
1292  LOCAL_SEARCH_OPERATOR_COUNTER
1293  };
1294 
1298  template <typename T>
1299  struct ValuedNodes {
1300  std::vector<int64> indices;
1301  T value;
1302  };
1303  struct DisjunctionValues {
1304  int64 penalty;
1305  int64 max_cardinality;
1306  };
1307  typedef ValuedNodes<DisjunctionValues> Disjunction;
1308 
1311  struct CostCacheElement {
1316  int index;
1317  CostClassIndex cost_class_index;
1318  int64 cost;
1319  };
1320 
1322  void Initialize();
1323  void AddNoCycleConstraintInternal();
1324  bool AddDimensionWithCapacityInternal(
1325  const std::vector<int>& evaluator_indices, int64 slack_max,
1326  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1327  const std::string& name);
1328  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1329  const std::vector<int>& pure_transits,
1330  const std::vector<int>& dependent_transits,
1331  const RoutingDimension* base_dimension, int64 slack_max,
1332  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1333  const std::string& name);
1334  bool InitializeDimensionInternal(
1335  const std::vector<int>& evaluator_indices,
1336  const std::vector<int>& state_dependent_evaluator_indices,
1337  int64 slack_max, bool fix_start_cumul_to_zero,
1338  RoutingDimension* dimension);
1339  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1340 
1367  void StoreDimensionsForDimensionCumulOptimizers();
1368 
1369  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1370  void ComputeVehicleClasses();
1371  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1372  CostClassIndex cost_class_index) const;
1373  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1374  int node_index,
1375  std::vector<IntVar*>* cost_elements);
1376  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1377  std::vector<IntVar*>* cost_elements);
1378  Assignment* DoRestoreAssignment();
1379  static const CostClassIndex kCostClassIndexOfZeroCost;
1380  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1381  DCHECK_LT(0, vehicles_);
1382  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1383  : kCostClassIndexOfZeroCost)
1384  .value();
1385  }
1386  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1387  const CostClass& cost_class) const;
1389  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1391  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1392  const std::vector<int64>& deliveries);
1395  IntVar* CreateSameVehicleCost(int vehicle_index);
1398  int FindNextActive(int index, const std::vector<int64>& indices) const;
1399 
1402  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1403  int vehicle) const;
1411  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1412  Assignment* compact_assignment) const;
1413 
1414  void QuietCloseModel();
1415  void QuietCloseModelWithParameters(
1416  const RoutingSearchParameters& parameters) {
1417  if (!closed_) {
1418  CloseModelWithParameters(parameters);
1419  }
1420  }
1421 
1423  bool SolveMatchingModel(Assignment* assignment);
1424 #ifndef SWIG
1425  bool AppendAssignmentIfFeasible(
1427  const Assignment& assignment,
1428  std::vector<std::unique_ptr<Assignment>>* assignments);
1429 #endif
1430  void LogSolution(const RoutingSearchParameters& parameters,
1432  const std::string& description, int64 solution_cost,
1433  int64 start_time_ms);
1436  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1437  bool check_compact_assignment) const;
1442  std::string FindErrorInSearchParametersForModel(
1443  const RoutingSearchParameters& search_parameters) const;
1445  void SetupSearch(const RoutingSearchParameters& search_parameters);
1447  // TODO(user): Document each auxiliary method.
1448  Assignment* GetOrCreateAssignment();
1449  Assignment* GetOrCreateTmpAssignment();
1450  RegularLimit* GetOrCreateLimit();
1451  RegularLimit* GetOrCreateLocalSearchLimit();
1452  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1453  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1454  LocalSearchOperator* CreateInsertionOperator();
1455  LocalSearchOperator* CreateMakeInactiveOperator();
1456  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1457  LocalSearchOperator* GetNeighborhoodOperators(
1458  const RoutingSearchParameters& search_parameters) const;
1459  const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters();
1460  const std::vector<LocalSearchFilter*>& GetOrCreateFeasibilityFilters();
1461  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1462  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1463  void CreateFirstSolutionDecisionBuilders(
1464  const RoutingSearchParameters& search_parameters);
1465  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1466  const RoutingSearchParameters& search_parameters) const;
1467  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1468  const RoutingSearchParameters& parameters) const;
1469  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1470  const RoutingSearchParameters& search_parameters);
1471  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1472  const RoutingSearchParameters& search_parameters);
1473  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1474  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1475  void SetupAssignmentCollector(
1476  const RoutingSearchParameters& search_parameters);
1477  void SetupTrace(const RoutingSearchParameters& search_parameters);
1478  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1479  bool UsesLightPropagation(
1480  const RoutingSearchParameters& search_parameters) const;
1481  GetTabuVarsCallback tabu_var_callback_;
1482 
1483  int GetVehicleStartClass(int64 start) const;
1484 
1485  void InitSameVehicleGroups(int number_of_groups) {
1486  same_vehicle_group_.assign(Size(), 0);
1487  same_vehicle_groups_.assign(number_of_groups, {});
1488  }
1489  void SetSameVehicleGroup(int index, int group) {
1490  same_vehicle_group_[index] = group;
1491  same_vehicle_groups_[group].push_back(index);
1492  }
1493 
1495  std::unique_ptr<Solver> solver_;
1496  int nodes_;
1497  int vehicles_;
1498  Constraint* no_cycle_constraint_ = nullptr;
1500  std::vector<IntVar*> nexts_;
1501  std::vector<IntVar*> vehicle_vars_;
1502  std::vector<IntVar*> active_;
1503  std::vector<IntVar*> vehicle_costs_considered_;
1508  std::vector<IntVar*> is_bound_to_end_;
1509  mutable RevSwitch is_bound_to_end_ct_added_;
1511  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1512  gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1513  std::vector<RoutingDimension*> dimensions_for_global_optimizer_;
1514  std::vector<RoutingDimension*> dimensions_for_local_optimizer_;
1515  std::string primary_constrained_dimension_;
1517  IntVar* cost_ = nullptr;
1518  std::vector<int> vehicle_to_transit_cost_;
1519  std::vector<int64> fixed_cost_of_vehicle_;
1520  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1521  bool has_vehicle_with_zero_cost_class_;
1522  std::vector<int64> linear_cost_factor_of_vehicle_;
1523  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1524  bool vehicle_amortized_cost_factors_set_;
1535  std::vector<bool> consider_empty_route_costs_;
1536 #ifndef SWIG
1537  gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1538 #endif // SWIG
1539  bool costs_are_homogeneous_across_vehicles_;
1540  bool cache_callbacks_;
1541  mutable std::vector<CostCacheElement> cost_cache_;
1542  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1543 #ifndef SWIG
1544  gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1545 #endif // SWIG
1546  std::function<int(int64)> vehicle_start_class_callback_;
1548  gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1549  std::vector<std::vector<DisjunctionIndex>> index_to_disjunctions_;
1551  std::vector<ValuedNodes<int64>> same_vehicle_costs_;
1553 #ifndef SWIG
1554  std::vector<std::unordered_set<int>> allowed_vehicles_;
1555 #endif // SWIG
1556  IndexPairs pickup_delivery_pairs_;
1558  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>
1559  pickup_delivery_disjunctions_;
1560  // clang-format off
1561  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1562  // vector of pairs {pair_index, pickup_index} such that
1563  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1564  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1565  // Same as above for deliveries.
1566  std::vector<std::vector<std::pair<int, int> > >
1567  index_to_delivery_index_pairs_;
1568  // clang-format on
1569  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1570  // Same vehicle group to which a node belongs.
1571  std::vector<int> same_vehicle_group_;
1572  // Same vehicle node groups.
1573  std::vector<std::vector<int>> same_vehicle_groups_;
1574  // Node visit types
1575  // Variable index to visit type index.
1576  std::vector<int> index_to_visit_type_;
1577  // clang-format off
1578  std::vector<absl::flat_hash_set<int> >
1579  hard_incompatible_types_per_type_index_;
1580  bool has_hard_type_incompatibilities_;
1581  std::vector<absl::flat_hash_set<int> >
1582  temporal_incompatible_types_per_type_index_;
1583  bool has_temporal_type_incompatibilities_;
1584 
1585  std::vector<std::vector<absl::flat_hash_set<int> > >
1586  same_vehicle_required_type_alternatives_per_type_index_;
1587  bool has_same_vehicle_type_requirements_;
1588  std::vector<std::vector<absl::flat_hash_set<int> > >
1589  temporal_required_type_alternatives_per_type_index_;
1590  bool has_temporal_type_requirements_;
1591  absl::flat_hash_set<int> trivially_infeasible_visit_types_;
1592  // clang-format on
1593  int num_visit_types_;
1594  // Two indices are equivalent if they correspond to the same node (as given
1595  // to the constructors taking a RoutingIndexManager).
1596  std::vector<int> index_to_equivalence_class_;
1597  std::vector<int> index_to_vehicle_;
1598  std::vector<int64> starts_;
1599  std::vector<int64> ends_;
1600  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1601  // anymore.
1602  RoutingIndexManager manager_;
1603  int start_end_count_;
1604  // Model status
1605  bool closed_ = false;
1606  Status status_ = ROUTING_NOT_SOLVED;
1607  bool enable_deep_serialization_ = true;
1608 
1609  // Search data
1610  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1611  std::vector<IntVarFilteredDecisionBuilder*>
1612  first_solution_filtered_decision_builders_;
1613  Solver::IndexEvaluator2 first_solution_evaluator_;
1614  std::vector<LocalSearchOperator*> local_search_operators_;
1615  std::vector<SearchMonitor*> monitors_;
1616  SolutionCollector* collect_assignments_ = nullptr;
1617  SolutionCollector* collect_one_assignment_ = nullptr;
1618  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1619  DecisionBuilder* solve_db_ = nullptr;
1620  DecisionBuilder* improve_db_ = nullptr;
1621  DecisionBuilder* restore_assignment_ = nullptr;
1622  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1623  Assignment* assignment_ = nullptr;
1624  Assignment* preassignment_ = nullptr;
1625  Assignment* tmp_assignment_ = nullptr;
1626  std::vector<IntVar*> extra_vars_;
1627  std::vector<IntervalVar*> extra_intervals_;
1628  std::vector<LocalSearchOperator*> extra_operators_;
1629  std::vector<LocalSearchFilter*> filters_;
1630  std::vector<LocalSearchFilter*> feasibility_filters_;
1631  std::vector<LocalSearchFilter*> extra_filters_;
1632 #ifndef SWIG
1633  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1634  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1635  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1636  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1637  std::unique_ptr<SweepArranger> sweep_arranger_;
1638 #endif
1639 
1640  RegularLimit* limit_ = nullptr;
1641  RegularLimit* ls_limit_ = nullptr;
1642  RegularLimit* lns_limit_ = nullptr;
1643  RegularLimit* first_solution_lns_limit_ = nullptr;
1644 
1645  typedef std::pair<int64, int64> CacheKey;
1646  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1647  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1648  StateDependentTransitCallbackCache;
1649 
1650  std::vector<TransitCallback1> unary_transit_evaluators_;
1651  std::vector<TransitCallback2> transit_evaluators_;
1652  // The following vector stores a boolean per transit_evaluator_, indicating
1653  // whether the transits are all positive.
1654  // is_transit_evaluator_positive_ will be set to true only when registering a
1655  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1656  // The actual positivity of the transit values will only be checked in debug
1657  // mode, when calling RegisterPositiveTransitCallback().
1658  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1659  // transits are known to be positive, as the positivity of a callback will
1660  // allow some improvements in the solver, but will entail in errors if the
1661  // transits are falsely assumed positive.
1662  std::vector<bool> is_transit_evaluator_positive_;
1663  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1664  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1665  state_dependent_transit_evaluators_cache_;
1666 
1667  friend class RoutingDimension;
1669 
1670  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1671 };
1672 
1675  public:
1677  static const char kLightElement[];
1678  static const char kLightElement2[];
1679  static const char kRemoveValues[];
1680 };
1681 
1682 #if !defined(SWIG)
1683 class DisjunctivePropagator {
1686  public:
1692  struct Tasks {
1694  std::vector<int64> start_min;
1695  std::vector<int64> start_max;
1696  std::vector<int64> duration_min;
1697  std::vector<int64> duration_max;
1698  std::vector<int64> end_min;
1699  std::vector<int64> end_max;
1700  std::vector<bool> is_preemptible;
1701  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1702  std::vector<std::pair<int64, int64>> distance_duration;
1703 
1704  void Clear() {
1705  start_min.clear();
1706  start_max.clear();
1707  duration_min.clear();
1708  duration_max.clear();
1709  end_min.clear();
1710  end_max.clear();
1711  is_preemptible.clear();
1712  forbidden_intervals.clear();
1713  distance_duration.clear();
1714  }
1715  };
1716 
1719  bool Propagate(Tasks* tasks);
1720 
1722  bool Precedences(Tasks* tasks);
1725  bool MirrorTasks(Tasks* tasks);
1727  bool EdgeFinding(Tasks* tasks);
1730  bool DetectablePrecedencesWithChain(Tasks* tasks);
1732  bool ForbiddenIntervals(Tasks* tasks);
1733  bool DistanceDuration(Tasks* tasks);
1734 
1735  private:
1738  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1740  std::vector<int> tasks_by_start_min_;
1741  std::vector<int> tasks_by_end_max_;
1742  std::vector<int> event_of_task_;
1743  std::vector<int> nonchain_tasks_by_start_max_;
1744 };
1745 
1746 void AppendTasksFromPath(const std::vector<int64>& path,
1747  const std::vector<int64>& min_travels,
1748  const std::vector<int64>& max_travels,
1749  const std::vector<int64>& pre_travels,
1750  const std::vector<int64>& post_travels,
1751  const RoutingDimension& dimension,
1752  DisjunctivePropagator::Tasks* tasks);
1753 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
1754  DisjunctivePropagator::Tasks* tasks);
1755 void FillPathEvaluation(const std::vector<int64>& path,
1756  const RoutingModel::TransitCallback2& evaluator,
1757  std::vector<int64>* values);
1758 #endif // !defined(SWIG)
1759 
1771  public:
1772  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
1773 
1774  void Post() override;
1775  void InitialPropagate() override;
1776 
1777  private:
1778  void PropagateNode(int node);
1779  void PropagateVehicle(int vehicle);
1780  void PropagateMaxBreakDistance(int vehicle);
1781 
1782  const RoutingModel* model_;
1783  const RoutingDimension* const dimension_;
1784  std::vector<Demon*> vehicle_demons_;
1785  std::vector<int64> path_;
1786 
1791  void FillPartialPathOfVehicle(int vehicle);
1792  void FillPathTravels(const std::vector<int64>& path);
1793 
1804  class TaskTranslator {
1805  public:
1806  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
1807  : start_(start),
1808  before_start_(before_start),
1809  after_start_(after_start) {}
1810  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
1811  TaskTranslator() {}
1812 
1813  void SetStartMin(int64 value) {
1814  if (start_ != nullptr) {
1815  start_->SetMin(CapAdd(before_start_, value));
1816  } else if (interval_ != nullptr) {
1817  interval_->SetStartMin(value);
1818  }
1819  }
1820  void SetStartMax(int64 value) {
1821  if (start_ != nullptr) {
1822  start_->SetMax(CapAdd(before_start_, value));
1823  } else if (interval_ != nullptr) {
1824  interval_->SetStartMax(value);
1825  }
1826  }
1827  void SetDurationMin(int64 value) {
1828  if (interval_ != nullptr) {
1829  interval_->SetDurationMin(value);
1830  }
1831  }
1832  void SetEndMin(int64 value) {
1833  if (start_ != nullptr) {
1834  start_->SetMin(CapSub(value, after_start_));
1835  } else if (interval_ != nullptr) {
1836  interval_->SetEndMin(value);
1837  }
1838  }
1839  void SetEndMax(int64 value) {
1840  if (start_ != nullptr) {
1841  start_->SetMax(CapSub(value, after_start_));
1842  } else if (interval_ != nullptr) {
1843  interval_->SetEndMax(value);
1844  }
1845  }
1846 
1847  private:
1848  IntVar* start_ = nullptr;
1849  int64 before_start_;
1850  int64 after_start_;
1851  IntervalVar* interval_ = nullptr;
1852  };
1853 
1855  std::vector<TaskTranslator> task_translators_;
1856 
1858  DisjunctivePropagator disjunctive_propagator_;
1860 
1862  std::vector<int64> min_travel_;
1863  std::vector<int64> max_travel_;
1864  std::vector<int64> pre_travel_;
1865  std::vector<int64> post_travel_;
1866 };
1867 
1869  public:
1870  explicit TypeRegulationsChecker(const RoutingModel& model);
1872 
1873  bool CheckVehicle(int vehicle,
1874  const std::function<int64(int64)>& next_accessor);
1875 
1876  protected:
1878  struct NodeCount {
1880  int pickup = 0;
1881  int delivery = 0;
1882  };
1883 
1886  int GetNonDeliveryCount(int type) const;
1888  int GetNonDeliveredCount(int type) const;
1889 
1890  virtual bool HasRegulationsToCheck() const = 0;
1891  virtual void InitializeCheck() {}
1892  virtual bool CheckTypeRegulations(int type) = 0;
1893  virtual bool FinalizeCheck() const { return true; }
1894 
1896 
1897  private:
1898  std::vector<PickupDeliveryStatus> pickup_delivery_status_of_node_;
1899  std::vector<NodeCount> counts_of_type_;
1900 };
1901 
1904  public:
1906  bool check_hard_incompatibilities);
1908 
1909  private:
1910  bool HasRegulationsToCheck() const override;
1911  bool CheckTypeRegulations(int type) override;
1915  bool check_hard_incompatibilities_;
1916 };
1917 
1920  public:
1921  explicit TypeRequirementChecker(const RoutingModel& model)
1922  : TypeRegulationsChecker(model) {}
1924 
1925  private:
1926  bool HasRegulationsToCheck() const override;
1927  void InitializeCheck() override {
1928  types_with_same_vehicle_requirements_on_route_.clear();
1929  }
1930  bool CheckTypeRegulations(int type) override;
1931  bool FinalizeCheck() const override;
1932 
1933  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
1934 };
1935 
1956  public:
1957  explicit TypeRegulationsConstraint(const RoutingModel& model);
1958 
1959  void Post() override;
1960  void InitialPropagate() override;
1961 
1962  private:
1963  void PropagateNodeRegulations(int node);
1964  void CheckRegulationsOnVehicle(int vehicle);
1965 
1966  const RoutingModel& model_;
1967  TypeIncompatibilityChecker incompatibility_checker_;
1968  TypeRequirementChecker requirement_checker_;
1969  std::vector<Demon*> vehicle_demons_;
1970 };
1971 #if !defined SWIG
1972 class SimpleBoundCosts {
1985  public:
1986  struct BoundCost {
1987  int64 bound;
1988  int64 cost;
1989  };
1990  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
1991  : bound_costs_(num_bounds, default_bound_cost) {}
1992  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
1993  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
1994  int Size() { return bound_costs_.size(); }
1995  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
1996  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
1997 
1998  private:
1999  std::vector<BoundCost> bound_costs_;
2000 };
2001 #endif // !defined SWIG
2002 
2020 // TODO(user): Break constraints need to know the service time of nodes
2024  public:
2027  RoutingModel* model() const { return model_; }
2031  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2034  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2035  int64 vehicle_class) const {
2036  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2037  to_index);
2038  }
2041  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2042  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2043  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2044  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2045 
2046 #if !defined(SWIGPYTHON)
2047  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2050  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2051  const std::vector<IntVar*>& transits() const { return transits_; }
2052  const std::vector<IntVar*>& slacks() const { return slacks_; }
2053 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2054  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2056  return forbidden_intervals_;
2057  }
2059  const std::vector<int64>& vehicle_capacities() const {
2060  return vehicle_capacities_;
2061  }
2065  return model_->TransitCallback(
2066  class_evaluators_[vehicle_to_class_[vehicle]]);
2067  }
2072  int vehicle) const {
2073  return model_->UnaryTransitCallbackOrNull(
2074  class_evaluators_[vehicle_to_class_[vehicle]]);
2075  }
2078  bool AreVehicleTransitsPositive(int vehicle) const {
2079  return model()->is_transit_evaluator_positive_
2080  [class_evaluators_[vehicle_to_class_[vehicle]]];
2081  }
2082  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2083 #endif
2084 #endif
2085  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2089  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2096  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2103  void SetGlobalSpanCostCoefficient(int64 coefficient);
2104 
2105 #ifndef SWIG
2106  void SetCumulVarPiecewiseLinearCost(int64 index,
2111  const PiecewiseLinearFunction& cost);
2114  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2117  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2118  int64 index) const;
2119 #endif
2120 
2129  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2130  int64 coefficient);
2133  bool HasCumulVarSoftUpperBound(int64 index) const;
2137  int64 GetCumulVarSoftUpperBound(int64 index) const;
2141  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2142 
2155  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2156  int64 coefficient);
2159  bool HasCumulVarSoftLowerBound(int64 index) const;
2163  int64 GetCumulVarSoftLowerBound(int64 index) const;
2167  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2183  // TODO(user): Remove if !defined when routing.i is repaired.
2184 #if !defined(SWIGPYTHON)
2185  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2186  int pre_travel_evaluator,
2187  int post_travel_evaluator);
2188 #endif // !defined(SWIGPYTHON)
2189 
2191  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2192  std::vector<int64> node_visit_transits);
2193 
2198  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2199  int vehicle);
2202  void InitializeBreaks();
2204  bool HasBreakConstraints() const;
2205 #if !defined(SWIGPYTHON)
2209  std::vector<IntervalVar*> breaks, int vehicle,
2210  std::vector<int64> node_visit_transits,
2211  std::function<int64(int64, int64)> group_delays);
2212 
2214  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2215  int vehicle) const;
2218  // clang-format off
2219  const std::vector<std::pair<int64, int64> >&
2220  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2221  // clang-format on
2222 #endif
2223  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2224  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2225 
2227  const RoutingDimension* base_dimension() const { return base_dimension_; }
2235  int64 ShortestTransitionSlack(int64 node) const;
2236 
2238  const std::string& name() const { return name_; }
2239 
2241 #ifndef SWIG
2242  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2243  return path_precedence_graph_;
2244  }
2245 #endif // SWIG
2246 
2256  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2257 
2259  PickupToDeliveryLimitFunction limit_function, int pair_index);
2260 
2261  bool HasPickupToDeliveryLimits() const;
2262 #ifndef SWIG
2263  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2264  int delivery) const;
2265 
2267  int64 first_node;
2269  int64 offset;
2270  };
2271 
2273  node_precedences_.push_back(precedence);
2274  }
2275  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2276  return node_precedences_;
2277  }
2278 #endif // SWIG
2279 
2280  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2281  AddNodePrecedence({first_node, second_node, offset});
2282  }
2283 
2284  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2285  return vehicle_span_upper_bounds_[vehicle];
2286  }
2287 #ifndef SWIG
2288  const std::vector<int64>& vehicle_span_upper_bounds() const {
2289  return vehicle_span_upper_bounds_;
2290  }
2291 #endif // SWIG
2292  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2293  return vehicle_span_cost_coefficients_[vehicle];
2294  }
2295 #ifndef SWIG
2296  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2297  return vehicle_span_cost_coefficients_;
2298  }
2299 #endif // SWIG
2301  return global_span_cost_coefficient_;
2302  }
2303 
2305  DCHECK_GE(global_optimizer_offset_, 0);
2306  return global_optimizer_offset_;
2307  }
2308  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2309  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2310  return 0;
2311  }
2312  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2313  return local_optimizer_offset_for_vehicle_[vehicle];
2314  }
2315 #if !defined SWIG
2319  int vehicle) {
2320  if (!HasSoftSpanUpperBounds()) {
2321  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2322  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2323  }
2324  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2325  }
2326  bool HasSoftSpanUpperBounds() const {
2327  return vehicle_soft_span_upper_bound_ != nullptr;
2328  }
2330  int vehicle) const {
2331  DCHECK(HasSoftSpanUpperBounds());
2332  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2333  }
2334 #endif
2335 
2336  private:
2337  struct SoftBound {
2338  IntVar* var;
2339  int64 bound;
2340  int64 coefficient;
2341  };
2342 
2343  struct PiecewiseLinearCost {
2344  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2345  IntVar* var;
2346  std::unique_ptr<PiecewiseLinearFunction> cost;
2347  };
2348 
2349  class SelfBased {};
2350  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2351  const std::string& name,
2352  const RoutingDimension* base_dimension);
2353  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2354  const std::string& name, SelfBased);
2355  void Initialize(const std::vector<int>& transit_evaluators,
2356  const std::vector<int>& state_dependent_transit_evaluators,
2357  int64 slack_max);
2358  void InitializeCumuls();
2359  void InitializeTransits(
2360  const std::vector<int>& transit_evaluators,
2361  const std::vector<int>& state_dependent_transit_evaluators,
2362  int64 slack_max);
2363  void InitializeTransitVariables(int64 slack_max);
2365  void SetupCumulVarSoftUpperBoundCosts(
2366  std::vector<IntVar*>* cost_elements) const;
2368  void SetupCumulVarSoftLowerBoundCosts(
2369  std::vector<IntVar*>* cost_elements) const;
2370  void SetupCumulVarPiecewiseLinearCosts(
2371  std::vector<IntVar*>* cost_elements) const;
2374  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2375  void SetupSlackAndDependentTransitCosts() const;
2377  void CloseModel(bool use_light_propagation);
2378 
2379  void SetOffsetForGlobalOptimizer(int64 offset) {
2380  global_optimizer_offset_ = std::max(Zero(), offset);
2381  }
2383  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2385  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2386  [](int64 offset) { return std::max(Zero(), offset); });
2387  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2388  }
2389 
2390  std::vector<IntVar*> cumuls_;
2391  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2392  std::vector<IntVar*> capacity_vars_;
2393  const std::vector<int64> vehicle_capacities_;
2394  std::vector<IntVar*> transits_;
2395  std::vector<IntVar*> fixed_transits_;
2398  std::vector<int> class_evaluators_;
2399  std::vector<int64> vehicle_to_class_;
2400 #ifndef SWIG
2401  ReverseArcListGraph<int, int> path_precedence_graph_;
2402 #endif
2403  // For every {first_node, second_node, offset} element in node_precedences_,
2404  // if both first_node and second_node are performed, then
2405  // cumuls_[second_node] must be greater than (or equal to)
2406  // cumuls_[first_node] + offset.
2407  std::vector<NodePrecedence> node_precedences_;
2408 
2409  // The transits of a dimension may depend on its cumuls or the cumuls of
2410  // another dimension. There can be no cycles, except for self loops, a
2411  // typical example for this is a time dimension.
2412  const RoutingDimension* const base_dimension_;
2413 
2414  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2415  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2416  // class.
2417  std::vector<int> state_dependent_class_evaluators_;
2418  std::vector<int64> state_dependent_vehicle_to_class_;
2419 
2420  // For each pickup/delivery pair_index for which limits have been set,
2421  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2422  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2423  std::vector<PickupToDeliveryLimitFunction>
2424  pickup_to_delivery_limits_per_pair_index_;
2425 
2426  // Used if some vehicle has breaks in this dimension, typically time.
2427  bool break_constraints_are_initialized_ = false;
2428  // clang-format off
2429  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2430  std::vector<std::vector<std::pair<int64, int64> > >
2431  vehicle_break_distance_duration_;
2432  // clang-format on
2433  // For each vehicle, stores the part of travel that is made directly
2434  // after (before) the departure (arrival) node of the travel.
2435  // These parts of the travel are non-interruptible, in particular by a break.
2436  std::vector<int> vehicle_pre_travel_evaluators_;
2437  std::vector<int> vehicle_post_travel_evaluators_;
2438 
2439  std::vector<IntVar*> slacks_;
2440  std::vector<IntVar*> dependent_transits_;
2441  std::vector<int64> vehicle_span_upper_bounds_;
2442  int64 global_span_cost_coefficient_;
2443  std::vector<int64> vehicle_span_cost_coefficients_;
2444  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2445  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2446  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2447  RoutingModel* const model_;
2448  const std::string name_;
2449  int64 global_optimizer_offset_;
2450  std::vector<int64> local_optimizer_offset_for_vehicle_;
2452  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2453  friend class RoutingModel;
2455 
2456  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2457 };
2458 
2459 #ifndef SWIG
2460 class SweepArranger {
2463  public:
2464  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2465  virtual ~SweepArranger() {}
2466  void ArrangeIndices(std::vector<int64>* indices);
2467  void SetSectors(int sectors) { sectors_ = sectors; }
2468 
2469  private:
2470  std::vector<int> coordinates_;
2471  int sectors_;
2472 
2473  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2474 };
2475 #endif
2476 
2479 DecisionBuilder* MakeSetValuesFromTargets(Solver* solver,
2480  std::vector<IntVar*> variables,
2481  std::vector<int64> targets);
2482 
2494 
2496 // TODO(user): Eventually move this to the core CP solver library
2499  public:
2501  const std::vector<IntVar*>& vars,
2502  const std::vector<LocalSearchFilter*>& filters);
2504  Decision* Next(Solver* solver) override;
2506  virtual bool BuildSolution() = 0;
2509  int64 number_of_decisions() const { return number_of_decisions_; }
2510  int64 number_of_rejects() const { return number_of_rejects_; }
2511 
2512  protected:
2514  virtual bool InitializeSolution() { return true; }
2518  bool Commit();
2520  virtual bool StopSearch() { return false; }
2523  void SetValue(int64 index, int64 value) {
2524  if (!is_in_delta_[index]) {
2525  delta_->FastAdd(vars_[index])->SetValue(value);
2526  delta_indices_.push_back(index);
2527  is_in_delta_[index] = true;
2528  } else {
2529  delta_->SetValue(vars_[index], value);
2530  }
2531  }
2534  int64 Value(int64 index) const {
2535  return assignment_->IntVarContainer().Element(index).Value();
2536  }
2538  bool Contains(int64 index) const {
2539  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
2540  }
2543  int Size() const { return vars_.size(); }
2545  IntVar* Var(int64 index) const { return vars_[index]; }
2546 
2547  private:
2549  void SynchronizeFilters();
2552  bool FilterAccept();
2553 
2554  const std::vector<IntVar*> vars_;
2555  Assignment* const assignment_;
2556  Assignment* const delta_;
2557  std::vector<int> delta_indices_;
2558  std::vector<bool> is_in_delta_;
2559  Assignment* const empty_;
2560  LocalSearchFilterManager filter_manager_;
2562  int64 number_of_decisions_;
2563  int64 number_of_rejects_;
2564 };
2565 
2568  public:
2570  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
2572  RoutingModel* model() const { return model_; }
2574  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
2576  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
2579  void MakeDisjunctionNodesUnperformed(int64 node);
2582 
2583  protected:
2584  bool StopSearch() override { return model_->CheckLimit(); }
2585 
2586  private:
2588  bool InitializeSolution() override;
2589 
2590  RoutingModel* const model_;
2591  std::vector<int64> start_chain_ends_;
2592  std::vector<int64> end_chain_starts_;
2593 };
2594 
2597  public:
2600  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2601  std::function<int64(int64)> penalty_evaluator,
2602  const std::vector<LocalSearchFilter*>& filters);
2604 
2605  protected:
2606  typedef std::pair<int64, int64> ValuedPosition;
2607  struct StartEndValue {
2608  int64 distance;
2609  int vehicle;
2610 
2611  bool operator<(const StartEndValue& other) const {
2612  return std::tie(distance, vehicle) <
2613  std::tie(other.distance, other.vehicle);
2614  }
2615  };
2616  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
2617 
2623  // clang-format off
2624  std::vector<std::vector<StartEndValue> >
2625  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
2626 
2631  template <class Queue>
2633  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
2634  Queue* priority_queue);
2635  // clang-format on
2636 
2641  void InsertBetween(int64 node, int64 predecessor, int64 successor);
2647  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
2648  std::vector<ValuedPosition>* valued_positions);
2651  int64 GetUnperformedValue(int64 node_to_insert) const;
2652 
2653  std::function<int64(int64, int64, int64)> evaluator_;
2654  std::function<int64(int64)> penalty_evaluator_;
2655 };
2656 
2666  public:
2669  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2670  std::function<int64(int64)> penalty_evaluator,
2671  const std::vector<LocalSearchFilter*>& filters, bool is_sequential,
2672  double farthest_seeds_ratio, double neighbors_ratio);
2674  bool BuildSolution() override;
2675  std::string DebugString() const override {
2676  return "GlobalCheapestInsertionFilteredDecisionBuilder";
2677  }
2678 
2679  private:
2680  class PairEntry;
2681  class NodeEntry;
2682  typedef absl::flat_hash_set<PairEntry*> PairEntries;
2683  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
2684 
2691  void InsertPairs();
2692 
2700  void InsertNodesOnRoutes(const std::vector<int>& nodes,
2701  const std::vector<int>& vehicles);
2702 
2708  void SequentialInsertNodes(const std::vector<int>& nodes);
2709 
2713  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
2714  std::vector<int>* used_vehicles,
2715  std::vector<int>* unused_vehicles);
2716 
2720  void InsertFarthestNodesAsSeeds();
2721 
2730  template <class Queue>
2731  int InsertSeedNode(
2732  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
2733  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
2734  // clang-format on
2735 
2738  void InitializePairPositions(
2739  AdjustablePriorityQueue<PairEntry>* priority_queue,
2740  std::vector<PairEntries>* pickup_to_entries,
2741  std::vector<PairEntries>* delivery_to_entries);
2744  void UpdatePairPositions(int vehicle, int64 insert_after,
2745  AdjustablePriorityQueue<PairEntry>* priority_queue,
2746  std::vector<PairEntries>* pickup_to_entries,
2747  std::vector<PairEntries>* delivery_to_entries) {
2748  UpdatePickupPositions(vehicle, insert_after, priority_queue,
2749  pickup_to_entries, delivery_to_entries);
2750  UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
2751  pickup_to_entries, delivery_to_entries);
2752  }
2755  void UpdatePickupPositions(int vehicle, int64 pickup_insert_after,
2756  AdjustablePriorityQueue<PairEntry>* priority_queue,
2757  std::vector<PairEntries>* pickup_to_entries,
2758  std::vector<PairEntries>* delivery_to_entries);
2761  void UpdateDeliveryPositions(
2762  int vehicle, int64 delivery_insert_after,
2763  AdjustablePriorityQueue<PairEntry>* priority_queue,
2764  std::vector<PairEntries>* pickup_to_entries,
2765  std::vector<PairEntries>* delivery_to_entries);
2768  void DeletePairEntry(PairEntry* entry,
2769  AdjustablePriorityQueue<PairEntry>* priority_queue,
2770  std::vector<PairEntries>* pickup_to_entries,
2771  std::vector<PairEntries>* delivery_to_entries);
2774  void InitializePositions(const std::vector<int>& nodes,
2775  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2776  std::vector<NodeEntries>* position_to_node_entries,
2777  const std::vector<int>& vehicles);
2780  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
2781  int64 insert_after,
2782  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2783  std::vector<NodeEntries>* node_entries);
2786  void DeleteNodeEntry(NodeEntry* entry,
2787  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2788  std::vector<NodeEntries>* node_entries);
2789 
2794  void AddNeighborForCostClass(int cost_class, int64 node_index,
2795  int64 neighbor_index, bool neighbor_is_pickup,
2796  bool neighbor_is_delivery);
2797 
2800  bool IsNeighborForCostClass(int cost_class, int64 node_index,
2801  int64 neighbor_index) const;
2802 
2804  const absl::flat_hash_set<int64>& GetPickupNeighborsOfNodeForCostClass(
2805  int cost_class, int64 node_index) {
2806  if (neighbors_ratio_ == 1) {
2807  return pickup_nodes_;
2808  }
2809  return node_index_to_pickup_neighbors_by_cost_class_[node_index]
2810  [cost_class];
2811  }
2812 
2814  const absl::flat_hash_set<int64>& GetDeliveryNeighborsOfNodeForCostClass(
2815  int cost_class, int64 node_index) {
2816  if (neighbors_ratio_ == 1) {
2817  return delivery_nodes_;
2818  }
2819  return node_index_to_delivery_neighbors_by_cost_class_[node_index]
2820  [cost_class];
2821  }
2822 
2823  const bool is_sequential_;
2824  const double farthest_seeds_ratio_;
2825  const double neighbors_ratio_;
2826 
2827  // clang-format off
2828  std::vector<std::vector<absl::flat_hash_set<int64> > >
2829  node_index_to_single_neighbors_by_cost_class_;
2830  std::vector<std::vector<absl::flat_hash_set<int64> > >
2831  node_index_to_pickup_neighbors_by_cost_class_;
2832  std::vector<std::vector<absl::flat_hash_set<int64> > >
2833  node_index_to_delivery_neighbors_by_cost_class_;
2834  // clang-format on
2835 
2839  absl::flat_hash_set<int64> pickup_nodes_;
2840  absl::flat_hash_set<int64> delivery_nodes_;
2841 };
2842 
2850  public:
2853  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2854  const std::vector<LocalSearchFilter*>& filters);
2856  bool BuildSolution() override;
2857  std::string DebugString() const override {
2858  return "LocalCheapestInsertionFilteredDecisionBuilder";
2859  }
2860 
2861  private:
2867  void ComputeEvaluatorSortedPositions(int64 node,
2868  std::vector<int64>* sorted_positions);
2873  void ComputeEvaluatorSortedPositionsOnRouteAfter(
2874  int64 node, int64 start, int64 next_after_start,
2875  std::vector<int64>* sorted_positions);
2876 };
2877 
2882  public:
2884  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
2886  bool BuildSolution() override;
2887 
2888  private:
2889  class PartialRoutesAndLargeVehicleIndicesFirst {
2890  public:
2891  explicit PartialRoutesAndLargeVehicleIndicesFirst(
2893  : builder_(builder) {}
2894  bool operator()(int vehicle1, int vehicle2) const;
2895 
2896  private:
2898  };
2900  template <typename Iterator>
2901  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
2902  Iterator end) const {
2903  const int size = model()->Size();
2904  std::vector<int64> nexts;
2905  for (Iterator it = start; it != end; ++it) {
2906  const int64 next = *it;
2907  if (next != node && (next >= size || !Contains(next))) {
2908  nexts.push_back(next);
2909  }
2910  }
2911  return nexts;
2912  }
2914  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
2915  virtual int64 FindTopSuccessor(int64 node,
2916  const std::vector<int64>& successors) = 0;
2917 };
2918 
2923  public:
2926  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
2927  const std::vector<LocalSearchFilter*>& filters);
2929  std::string DebugString() const override {
2930  return "EvaluatorCheapestAdditionFilteredDecisionBuilder";
2931  }
2932 
2933  private:
2935  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
2936  int64 FindTopSuccessor(int64 node,
2937  const std::vector<int64>& successors) override;
2938 
2939  std::function<int64(int64, int64)> evaluator_;
2940 };
2941 
2946  public:
2950  const std::vector<LocalSearchFilter*>& filters);
2952  std::string DebugString() const override {
2953  return "ComparatorCheapestAdditionFilteredDecisionBuilder";
2954  }
2955 
2956  private:
2958  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
2959  int64 FindTopSuccessor(int64 node,
2960  const std::vector<int64>& successors) override;
2961 
2962  Solver::VariableValueComparator comparator_;
2963 };
2964 
2974  public:
2978  double neighbors_ratio = 1.0;
2984  bool add_reverse_arcs = false;
2987  double arc_coefficient = 1.0;
2988  };
2989 
2992  SavingsParameters parameters,
2993  const std::vector<LocalSearchFilter*>& filters);
2995  bool BuildSolution() override;
2996 
2997  protected:
2998  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
2999 
3000  template <typename S>
3002 
3005  int64 fixed_cost;
3006 
3007  bool operator<(const VehicleClassEntry& other) const {
3008  return std::tie(fixed_cost, vehicle_class) <
3009  std::tie(other.fixed_cost, other.vehicle_class);
3010  }
3011  };
3012 
3013  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3014 
3015  virtual void BuildRoutesFromSavings() = 0;
3016 
3018  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3019  return saving.second / size_squared_;
3020  }
3022  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3023  return (saving.second % size_squared_) / Size();
3024  }
3026  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3027  return (saving.second % size_squared_) % Size();
3028  }
3030  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3031 
3041  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3042  int64 after_node);
3043 
3044  std::vector<int> type_index_of_vehicle_;
3045  // clang-format off
3046  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
3047  std::vector<std::deque<int> > vehicles_per_vehicle_class_;
3048  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3049  // clang-format on
3050 
3051  private:
3056  void AddSymetricArcsToAdjacencyLists(
3057  std::vector<std::vector<int64>>* adjacency_lists);
3058  // clang-format on
3059 
3066  void ComputeSavings();
3068  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3069  int after_node) const {
3070  return std::make_pair(saving, vehicle_type * size_squared_ +
3071  before_node * Size() + after_node);
3072  }
3073 
3081  void ComputeVehicleTypes();
3082 
3086  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3087 
3088  RoutingIndexManager* const manager_;
3089  const SavingsParameters savings_params_;
3090  int64 size_squared_;
3091 
3093 };
3094 
3097  public:
3100  SavingsParameters parameters,
3101  const std::vector<LocalSearchFilter*>& filters)
3102  : SavingsFilteredDecisionBuilder(model, manager, parameters, filters) {}
3104  std::string DebugString() const override {
3105  return "SequentialSavingsFilteredDecisionBuilder";
3106  }
3107 
3108  private:
3113  void BuildRoutesFromSavings() override;
3114  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3115 };
3116 
3119  public:
3122  SavingsParameters parameters,
3123  const std::vector<LocalSearchFilter*>& filters)
3124  : SavingsFilteredDecisionBuilder(model, manager, parameters, filters) {}
3126  std::string DebugString() const override {
3127  return "ParallelSavingsFilteredDecisionBuilder";
3128  }
3129 
3130  private:
3141  void BuildRoutesFromSavings() override;
3142 
3143  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3144 
3149  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3150  int64 after_node);
3151 
3153  std::vector<int64> first_node_on_route_;
3154  std::vector<int64> last_node_on_route_;
3158  std::vector<int> vehicle_of_first_or_last_node_;
3159 };
3160 
3164 
3167  public:
3169  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
3171  bool BuildSolution() override;
3172  std::string DebugString() const override {
3173  return "ChristofidesFilteredDecisionBuilder";
3174  }
3175 };
3176 
3181 bool SolveModelWithSat(const RoutingModel& model,
3182  const Assignment* initial_solution,
3183  Assignment* solution);
3184 
3186 
3188  public:
3189  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size,
3190  std::function<void(int64)> objective_callback);
3191  ~BasePathFilter() override {}
3192  bool Accept(Assignment* delta, Assignment* deltadelta) override;
3193  void OnSynchronize(const Assignment* delta) override;
3194 
3195  protected:
3196  static const int64 kUnassigned;
3197 
3198  int64 GetNext(int64 node) const {
3199  return (new_nexts_[node] == kUnassigned)
3200  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3201  : new_nexts_[node];
3202  }
3203  int NumPaths() const { return starts_.size(); }
3204  int64 Start(int i) const { return starts_[i]; }
3205  int GetPath(int64 node) const { return paths_[node]; }
3206  int Rank(int64 node) const { return ranks_[node]; }
3207  bool IsDisabled() const { return status_ == DISABLED; }
3208  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3209  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3210  }
3211 
3212  private:
3213  enum Status { UNKNOWN, ENABLED, DISABLED };
3214 
3215  virtual bool DisableFiltering() const { return false; }
3216  virtual void OnBeforeSynchronizePaths() {}
3217  virtual void OnAfterSynchronizePaths() {}
3218  virtual void OnSynchronizePathFromStart(int64 start) {}
3219  virtual void InitializeAcceptPath() {}
3220  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3221  int64 chain_end) = 0;
3222  virtual bool FinalizeAcceptPath(Assignment* delta) { return true; }
3224  void ComputePathStarts(std::vector<int64>* path_starts,
3225  std::vector<int>* index_to_path);
3226  bool HavePathsChanged();
3227  void SynchronizeFullAssignment();
3228  void UpdateAllRanks();
3229  void UpdatePathRanksFromStart(int start);
3230 
3231  std::vector<int64> node_path_starts_;
3232  std::vector<int64> starts_;
3233  std::vector<int> paths_;
3234  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3235  std::vector<int64> new_nexts_;
3236  std::vector<int> delta_touched_;
3237  SparseBitset<> touched_paths_;
3238  SparseBitset<> touched_path_nodes_;
3239  std::vector<int> ranks_;
3240 
3241  Status status_;
3242 };
3243 
3248 // TODO(user): Also call the solution finalizer on variables, with the
3254 // TODO(user): Avoid such false negatives.
3256  public:
3257  explicit CPFeasibilityFilter(const RoutingModel* routing_model);
3258  ~CPFeasibilityFilter() override {}
3259  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3260  bool Accept(Assignment* delta, Assignment* deltadelta) override;
3261  void OnSynchronize(const Assignment* delta) override;
3262 
3263  private:
3264  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3265 
3266  static const int64 kUnassigned;
3267  const RoutingModel* const model_;
3268  Solver* const solver_;
3269  Assignment* const assignment_;
3270  Assignment* const temp_assignment_;
3271  DecisionBuilder* const restore_;
3272 };
3273 
3274 #if !defined(SWIG)
3275 IntVarLocalSearchFilter* MakeNodeDisjunctionFilter(
3276  const RoutingModel& routing_model,
3277  std::function<void(int64)> objective_callback);
3278 IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter(
3279  const RoutingModel& routing_model,
3280  Solver::ObjectiveWatcher objective_callback);
3281 IntVarLocalSearchFilter* MakeTypeRegulationsFilter(
3282  const RoutingModel& routing_model);
3283 std::vector<IntVarLocalSearchFilter*> MakeCumulFilters(
3284  const RoutingDimension& dimension,
3285  Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost);
3286 IntVarLocalSearchFilter* MakePathCumulFilter(
3287  const RoutingDimension& dimension,
3288  Solver::ObjectiveWatcher objective_callback,
3289  bool propagate_own_objective_value, bool filter_objective_cost);
3290 IntVarLocalSearchFilter* MakeGlobalLPCumulFilter(
3291  const RoutingDimension& dimension,
3292  Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost);
3293 IntVarLocalSearchFilter* MakePickupDeliveryFilter(
3294  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3295  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3296 IntVarLocalSearchFilter* MakeVehicleVarFilter(
3297  const RoutingModel& routing_model);
3298 IntVarLocalSearchFilter* MakeVehicleBreaksFilter(
3299  const RoutingModel& routing_model, const RoutingDimension& dimension);
3300 IntVarLocalSearchFilter* MakeCPFeasibilityFilter(
3301  const RoutingModel* routing_model);
3302 #endif
3303 
3304 } // namespace operations_research
3305 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1182
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
const std::vector< IntVar * > & transits() const
Definition: routing.h:2051
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
void OnSynchronize(const Assignment *delta) override
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1195
int vehicle_to_class(int vehicle) const
Definition: routing.h:2082
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:330
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:430
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:331
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:288
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:630
std::vector< IntVarLocalSearchFilter * > MakeCumulFilters(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost)
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
static const char kLightElement[]
Constraint types.
Definition: routing.h:1677
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2280
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1120
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...
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:2664
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool propagate_own_objective_value, bool filter_objective_cost)
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
bool BuildSolution() override
Virtual method to redefine to build a solution.
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:727
int64 GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2284
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:510
bool Accept(Assignment *delta, Assignment *deltadelta) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:2984
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1060
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
Definition: routing.h:3018
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:567
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2050
int GetPath(int64 node) const
Definition: routing.h:3205
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2078
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost)
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
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:2064
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:1044
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:337
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
RoutingIndexPair IndexPair
Definition: routing.h:238
int Rank(int64 node) const
Definition: routing.h:3206
void AddIntervalToAssignment(IntervalVar *const interval)
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:2514
CheapestAdditionFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
GlobalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters, bool is_sequential, double farthest_seeds_ratio, double neighbors_ratio)
Takes ownership of evaluators.
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:950
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
Definition: routing.h:260
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2052
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:2520
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
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:2034
int GetNonDeliveryCount(int type) const
Returns the number of pickups and fixed nodes from counts_of_type_["type"].
int64 Start(int vehicle) const
Model inspection.
Definition: routing.h:1054
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
virtual bool CheckTypeRegulations(int type)=0
EvaluatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:682
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1685
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:2543
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
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,...
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2023
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2308
int GetNonDeliveredCount(int type) const
Same as above, but substracting the number of deliveries of "type".
void SetSectors(int sectors)
Definition: routing.h:2467
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2329
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:575
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:2973
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.
bool SolveModelWithSat(const RoutingModel &model, const Assignment *initial_solution, Assignment *solution)
Attempts to solve the model using the cp-sat solver.
std::function< int64(int64, int64)> RoutingTransitCallback2
Definition: routing_types.h:42
bool Accept(Assignment *delta, Assignment *deltadelta) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3208
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.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:538
void SetValue(const IntVar *const var, int64 value)
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
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.
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
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.
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1197
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.
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:2981
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2055
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:2574
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:462
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
Definition: routing.h:2041
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:839
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:2256
Filter-based decision builder dedicated to routing.
Definition: routing.h:2567
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:2534
int64 GetNext(int64 node) const
Definition: routing.h:3198
Checker for type requirements.
Definition: routing.h:1919
std::function< bool(int64, int64, int64)> VariableValueComparator
bool BuildSolution() override
Virtual method to redefine to build a solution.
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:334
RoutingCostClassIndex CostClassIndex
Definition: routing.h:229
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:1063
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:379
Status
Status of the search.
Definition: routing.h:207
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:2318
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:2071
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
RoutingIndexPairs IndexPairs
Definition: routing.h:239
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...
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,...
bool BuildSolution() override
Virtual method to redefine to build a solution.
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:827
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int64 global_span_cost_coefficient() const
Definition: routing.h:2300
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:234
bool operator<(const DimensionCost &cost) const
Definition: routing.h:292
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
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...
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:2978
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:1215
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:211
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
const Assignment * PackCumulsOfOptimizerDimensionsFromAssignment(const Assignment *original_assignment, absl::Duration duration_limit)
For every dimension in the model's dimensions_for_local/global_optimizer_, this method tries to pack ...
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:594
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:375
const std::vector< int64 > & vehicle_span_upper_bounds() const
Definition: routing.h:2288
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
ComparatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, Solver::VariableValueComparator comparator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:1955
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:2880
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor, int64 quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:326
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2509
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2238
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_max
Definition: routing.h:333
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
bool AddConstantDimensionWithSlack(int64 value, int64 capacity, int64 slack_max, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is t...
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:834
const IntContainer & IntVarContainer() const
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
bool HasTemporalTypeRequirements() const
Definition: routing.h:763
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...
void Post() override
This method is called when the constraint is processed by the solver.
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:255
std::function< int64(int64)> RoutingTransitCallback1
Definition: routing_types.h:41
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:215
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:221
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...
const std::vector< RoutingDimension * > & GetDimensionsForLocalCumulOptimizers() const
Definition: routing.h:521
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1056
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2049
Class to arrange indices by by their distance and their angles from the depot.
Definition: routing.h:2462
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
A structure to hold tasks described by their features.
Definition: routing.h:1692
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1093
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
Deliveries must be performed in the same order as pickups.
Definition: routing.h:227
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:232
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1100
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1144
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
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.
ParallelSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3120
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
IntVarFilteredDecisionBuilder(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< LocalSearchFilter * > &filters)
A DecisionBuilder is responsible for creating the search tree.
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:332
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:847
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1033
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:339
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1126
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...
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:317
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:266
const std::vector< RoutingDimension * > & GetDimensionsForGlobalCumulOptimizers() const
Returns dimensions_for_[global|local]_optimizer_ if the model has been closed, and empty vectors othe...
Definition: routing.h:517
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1701
BoundCost & bound_cost(int element)
Definition: routing.h:1992
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:2653
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc evalua...
Definition: routing.h:2921
Local Search Filters are used for fast neighbor pruning.
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1083
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2275
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2292
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; ...
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
bool BuildSolution() override
Virtual method to redefine to build a solution.
Status status() const
Returns the current status of the routing model.
Definition: routing.h:926
A constraint is the main modeling object.
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:225
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2027
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:1105
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:1984
Decision builders building a solution using local search filters to evaluate its feasibility.
Definition: routing.h:2498
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:306
const E & Element(const V *const var) const
RoutingFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
std::vector< std::pair< int64, int64 > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
IntVar * SlackVar(int64 index) const
Definition: routing.h:2044
IntVar * FixedTransitVar(int64 index) const
Definition: routing.h:2043
std::vector<::std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
TypeRegulationsChecker(const RoutingModel &model)
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:2545
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
int RegisterTransitCallback(TransitCallback2 callback)
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:2523
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...
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model, Solver::ObjectiveWatcher objective_callback)
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:213
Checker for type incompatibilities.
Definition: routing.h:1903
static const int64 kUnassigned
Definition: routing.h:3196
const std::vector< int64 > & vehicle_span_cost_coefficients() const
Definition: routing.h:2296
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:769
bool BuildSolution() override
Virtual method to redefine to build a solution.
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1188
int GetVisitType(int64 index) const
void ArrangeIndices(std::vector< int64 > *indices)
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model, std::function< void(int64)> objective_callback)
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
BoundCost bound_cost(int element) const
Definition: routing.h:1993
Manager for any NodeIndex <-> variable index conversion.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
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:1077
Model, model parameters or flags are not valid.
Definition: routing.h:217
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
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...
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:1770
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3048
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1086
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1037
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1146
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
Definition: routing.h:3255
void Post() override
This method is called when the constraint is processed by the solver.
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)
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
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.
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:233
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1199
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:603
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:1074
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:300
SequentialSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3098
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
A BaseObject is the root of all reversibly allocated objects.
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:2584
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size, std::function< void(int64)> objective_callback)
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
IntVar * TransitVar(int64 index) const
Definition: routing.h:2042
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...
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:351
void OnSynchronize(const Assignment *delta) override
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:1921
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:852
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)
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
std::function< void(int64)> ObjectiveWatcher
void AddTemporalTypeIncompatibility(int type1, int type2)
The class IntVar is a subset of IntExpr.
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:355
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
const std::vector< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2059
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:686
RoutingDimensionIndex DimensionIndex
Definition: routing.h:230
void InitialPropagate() override
This method performs the initial propagation of the constraint.
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:1990
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
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...
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1134
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1179
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:2576
CPFeasibilityFilter(const RoutingModel *routing_model)
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.
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Generic path-based filter class.
Definition: routing.h:3187
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:760
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1139
virtual bool HasRegulationsToCheck() const =0
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:347
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:209
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...
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type_
Definition: routing.h:3046
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1136
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:599
int RegisterPositiveTransitCallback(TransitCallback2 callback)
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:2538
const std::vector< absl::flat_hash_set< int > > & GetTemporalRequiredTypeAlternativesOfType(int type) const
ChristofidesFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
A Decision represents a choice point in the search tree.
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:45
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2272
Assignment * MutablePreAssignment()
Definition: routing.h:951
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3030
CheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
std::function< int64(int64, int64)> IndexEvaluator2
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty std::string if it is unset.
Definition: routing.h:544
Interval variables are often used in scheduling.
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...
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:257
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
TypeRegulationsConstraint(const RoutingModel &model)
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:231
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3022
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc compar...
Definition: routing.h:2944
void SetVisitType(int64 index, int type)
Set the node visit types and incompatibilities/requirements between the types (see below).
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:2848
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...
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:319
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:3007
bool Check() override
This method is called to check the status of the limit.
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:2987
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1091
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1702
std::vector< std::deque< int > > vehicles_per_vehicle_class_
Definition: routing.h:3047
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
Definition: routing_types.h:44
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2227
virtual bool BuildSolution()=0
Virtual method to redefine to build a solution.
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
LocalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:830
SavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:371
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:730
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
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...
std::string DebugString() const override
Definition: routing.h:3259
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2242
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3026
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.