OR-Tools  9.2
routing.h
Go to the documentation of this file.
1 // Copyright 2010-2021 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 <algorithm>
161 #include <deque>
162 #include <functional>
163 #include <memory>
164 #include <set>
165 #include <string>
166 #include <tuple>
167 #include <utility>
168 #include <vector>
169 
170 #include "absl/container/flat_hash_map.h"
171 #include "absl/container/flat_hash_set.h"
172 #include "absl/functional/bind_front.h"
173 #include "absl/memory/memory.h"
174 #include "absl/time/time.h"
175 #include "ortools/base/int_type.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
179 #include "ortools/base/map_util.h"
187 #include "ortools/graph/graph.h"
188 #include "ortools/sat/theta_tree.h"
189 #include "ortools/util/bitset.h"
194 
195 namespace operations_research {
196 
197 class GlobalDimensionCumulOptimizer;
198 class LocalDimensionCumulOptimizer;
199 class LocalSearchPhaseParameters;
200 #ifndef SWIG
201 class IndexNeighborFinder;
202 class IntVarFilteredDecisionBuilder;
203 #endif
204 class RoutingDimension;
205 #ifndef SWIG
207 class SweepArranger;
208 #endif
209 
211  public:
213  enum Status {
224  };
225 
234  };
235  typedef RoutingCostClassIndex CostClassIndex;
236  typedef RoutingDimensionIndex DimensionIndex;
237  typedef RoutingDisjunctionIndex DisjunctionIndex;
238  typedef RoutingVehicleClassIndex VehicleClassIndex;
241 
242 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
243 #if !defined(SWIG)
246 #endif // SWIG
247 
248 #if !defined(SWIG)
249  struct StateDependentTransit {
264  };
265  typedef std::function<StateDependentTransit(int64_t, int64_t)>
267 #endif // SWIG
268 
269 #if !defined(SWIG)
270  struct CostClass {
273 
288 
294  struct DimensionCost {
298  bool operator<(const DimensionCost& cost) const {
299  if (transit_evaluator_class != cost.transit_evaluator_class) {
300  return transit_evaluator_class < cost.transit_evaluator_class;
301  }
302  return cost_coefficient < cost.cost_coefficient;
303  }
304  };
305  std::vector<DimensionCost>
307 
310 
312  static bool LessThan(const CostClass& a, const CostClass& b) {
313  if (a.evaluator_index != b.evaluator_index) {
314  return a.evaluator_index < b.evaluator_index;
315  }
316  return a.dimension_transit_evaluator_class_and_cost_coefficient <
317  b.dimension_transit_evaluator_class_and_cost_coefficient;
318  }
319  };
320 
321  struct VehicleClass {
325  int64_t fixed_cost;
332  // TODO(user): Find equivalent start/end nodes wrt dimensions and
333  // callbacks.
350 
352  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
353  };
354 #endif // defined(SWIG)
355 
362  int64_t fixed_cost;
363 
364  bool operator<(const VehicleClassEntry& other) const {
365  return std::tie(fixed_cost, vehicle_class) <
366  std::tie(other.fixed_cost, other.vehicle_class);
367  }
368  };
369 
370  int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
371 
372  int Type(int vehicle) const {
373  DCHECK_LT(vehicle, type_index_of_vehicle.size());
374  return type_index_of_vehicle[vehicle];
375  }
376 
377  std::vector<int> type_index_of_vehicle;
378  // clang-format off
379  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
380  std::vector<std::deque<int> > vehicles_per_vehicle_class;
381  // clang-format on
382  };
383 
396  public:
398  class Attributes {
399  public:
400  Attributes();
402 
403  const Domain& start_domain() const { return start_domain_; }
404  const Domain& end_domain() const { return end_domain_; }
405 
406  private:
410  Domain start_domain_;
412  Domain end_domain_;
413  };
414 
416  class Resource {
417  public:
419  const RoutingDimension* dimension) const;
420 
421  private:
422  explicit Resource(const RoutingModel* model) : model_(model) {}
423 
424  void SetDimensionAttributes(ResourceGroup::Attributes attributes,
425  const RoutingDimension* dimension);
426  const ResourceGroup::Attributes& GetDefaultAttributes() const;
427 
428  const RoutingModel* const model_;
429  absl::flat_hash_map<DimensionIndex, ResourceGroup::Attributes>
430  dimension_attributes_;
431 
432  friend class ResourceGroup;
433  };
434 
436  : model_(model), vehicle_requires_resource_(model->vehicles(), false) {}
437 
440  int AddResource(Attributes attributes, const RoutingDimension* dimension);
441 
445  void NotifyVehicleRequiresAResource(int vehicle);
446 
447  const std::vector<int>& GetVehiclesRequiringAResource() const {
448  return vehicles_requiring_resource_;
449  }
450 
451  bool VehicleRequiresAResource(int vehicle) const {
452  return vehicle_requires_resource_[vehicle];
453  }
454 
455  const std::vector<Resource>& GetResources() const { return resources_; }
456  const Resource& GetResource(int resource_index) const {
457  DCHECK_LT(resource_index, resources_.size());
458  return resources_[resource_index];
459  }
460  const absl::flat_hash_set<DimensionIndex>& GetAffectedDimensionIndices()
461  const {
462  return affected_dimension_indices_;
463  }
464  int Size() const { return resources_.size(); }
465 
466  private:
467  const RoutingModel* const model_;
468  std::vector<Resource> resources_;
469  std::vector<bool> vehicle_requires_resource_;
470  std::vector<int> vehicles_requiring_resource_;
472  absl::flat_hash_set<DimensionIndex> affected_dimension_indices_;
473  };
474 
476  static const int64_t kNoPenalty;
477 
481 
485 
489  explicit RoutingModel(const RoutingIndexManager& index_manager);
490  RoutingModel(const RoutingIndexManager& index_manager,
492  ~RoutingModel();
493 
495  int RegisterUnaryTransitVector(std::vector<int64_t> values);
498 
500  std::vector<std::vector<int64_t> /*needed_for_swig*/> values);
503 
505  const TransitCallback2& TransitCallback(int callback_index) const {
506  CHECK_LT(callback_index, transit_evaluators_.size());
507  return transit_evaluators_[callback_index];
508  }
509  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
510  CHECK_LT(callback_index, unary_transit_evaluators_.size());
511  return unary_transit_evaluators_[callback_index];
512  }
514  int callback_index) const {
515  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
516  return state_dependent_transit_evaluators_[callback_index];
517  }
518 
520 
532 
541  bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity,
542  bool fix_start_cumul_to_zero, const std::string& name);
544  const std::vector<int>& evaluator_indices, int64_t slack_max,
545  int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
546  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max,
547  std::vector<int64_t> vehicle_capacities,
548  bool fix_start_cumul_to_zero,
549  const std::string& name);
551  const std::vector<int>& evaluator_indices, int64_t slack_max,
552  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
553  const std::string& name);
562  std::pair<int, bool> AddConstantDimensionWithSlack(
563  int64_t value, int64_t capacity, int64_t slack_max,
564  bool fix_start_cumul_to_zero, const std::string& name);
565  std::pair<int, bool> AddConstantDimension(int64_t value, int64_t capacity,
566  bool fix_start_cumul_to_zero,
567  const std::string& name) {
569  fix_start_cumul_to_zero, name);
570  }
580  std::pair<int, bool> AddVectorDimension(std::vector<int64_t> values,
581  int64_t capacity,
582  bool fix_start_cumul_to_zero,
583  const std::string& name);
593  std::pair<int, bool> AddMatrixDimension(
594  std::vector<std::vector<int64_t> /*needed_for_swig*/> values,
595  int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
603  const std::vector<int>& pure_transits,
604  const std::vector<int>& dependent_transits,
605  const RoutingDimension* base_dimension, int64_t slack_max,
606  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
607  const std::string& name) {
608  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
609  pure_transits, dependent_transits, base_dimension, slack_max,
610  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
611  }
612 
615  const std::vector<int>& transits, const RoutingDimension* base_dimension,
616  int64_t slack_max, std::vector<int64_t> vehicle_capacities,
617  bool fix_start_cumul_to_zero, const std::string& name);
620  int transit, const RoutingDimension* base_dimension, int64_t slack_max,
621  int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
622  const std::string& name);
624  int pure_transit, int dependent_transit,
625  const RoutingDimension* base_dimension, int64_t slack_max,
626  int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
627  const std::string& name);
628 
631  const std::function<int64_t(int64_t)>& f, int64_t domain_start,
632  int64_t domain_end);
633 
644  std::vector<IntVar*> spans,
645  std::vector<IntVar*> total_slacks);
646 
648  // TODO(user): rename.
649  std::vector<std::string> GetAllDimensionNames() const;
651  const std::vector<RoutingDimension*>& GetDimensions() const {
652  return dimensions_.get();
653  }
655  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
656  // clang-format off
659  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
661  return global_dimension_optimizers_;
662  }
663  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
665  return global_dimension_mp_optimizers_;
666  }
667  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
669  return local_dimension_optimizers_;
670  }
671  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
673  return local_dimension_mp_optimizers_;
674  }
675  // clang-format on
676 
680  const RoutingDimension& dimension) const;
682  const RoutingDimension& dimension) const;
684  const RoutingDimension& dimension) const;
686  const RoutingDimension& dimension) const;
687 
689  bool HasDimension(const std::string& dimension_name) const;
692  const std::string& dimension_name) const;
696  const std::string& dimension_name) const;
701  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
702  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
703  primary_constrained_dimension_ = dimension_name;
704  }
706  const std::string& GetPrimaryConstrainedDimension() const {
707  return primary_constrained_dimension_;
708  }
709 
712  int AddResourceGroup();
713  // clang-format off
714  const std::vector<std::unique_ptr<ResourceGroup> >& GetResourceGroups()
715  const {
716  return resource_groups_;
717  }
718  // clang-format on
719  ResourceGroup* GetResourceGroup(int rg_index) const {
720  DCHECK_LT(rg_index, resource_groups_.size());
721  return resource_groups_[rg_index].get();
722  }
723 
726  const std::vector<int>& GetDimensionResourceGroupIndices(
727  const RoutingDimension* dimension) const;
728 
731  int GetDimensionResourceGroupIndex(const RoutingDimension* dimension) const {
732  DCHECK_EQ(GetDimensionResourceGroupIndices(dimension).size(), 1);
733  return GetDimensionResourceGroupIndices(dimension)[0];
734  }
735 
752  DisjunctionIndex AddDisjunction(const std::vector<int64_t>& indices,
753  int64_t penalty = kNoPenalty,
754  int64_t max_cardinality = 1);
756  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
757  int64_t index) const {
758  return index_to_disjunctions_[index];
759  }
763  template <typename F>
765  int64_t index, int64_t max_cardinality, F f) const {
766  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
767  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
768  for (const int64_t d_index : disjunctions_[disjunction].indices) {
769  f(d_index);
770  }
771  }
772  }
773  }
774 #if !defined(SWIGPYTHON)
775  const std::vector<int64_t>& GetDisjunctionNodeIndices(
778  DisjunctionIndex index) const {
779  return disjunctions_[index].indices;
780  }
781 #endif // !defined(SWIGPYTHON)
784  return disjunctions_[index].value.penalty;
785  }
789  return disjunctions_[index].value.max_cardinality;
790  }
792  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
795  bool HasMandatoryDisjunctions() const;
803  std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions() const;
810 
814  void AddSoftSameVehicleConstraint(const std::vector<int64_t>& indices,
815  int64_t cost);
816 
821  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
822  int64_t index);
823 
825  bool IsVehicleAllowedForIndex(int vehicle, int64_t index) {
826  return allowed_vehicles_[index].empty() ||
827  allowed_vehicles_[index].find(vehicle) !=
828  allowed_vehicles_[index].end();
829  }
830 
845  // TODO(user): Remove this when model introspection detects linked nodes.
846  void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
850  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
851  DisjunctionIndex delivery_disjunction);
852  // clang-format off
856  const std::vector<std::pair<int, int> >&
857  GetPickupIndexPairs(int64_t node_index) const;
859  const std::vector<std::pair<int, int> >&
860  GetDeliveryIndexPairs(int64_t node_index) const;
861  // clang-format on
862 
867  int vehicle);
869  int vehicle) const;
872 
873  int GetNumOfSingletonNodes() const;
874 
875 #ifndef SWIG
876  const IndexPairs& GetPickupAndDeliveryPairs() const {
878  return pickup_delivery_pairs_;
879  }
880  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
882  return pickup_delivery_disjunctions_;
883  }
889  DCHECK(closed_);
890  return implicit_pickup_delivery_pairs_without_alternatives_;
891  }
892 #endif // SWIG
893  enum VisitTypePolicy {
920  };
921  // TODO(user): Support multiple visit types per node?
922  void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy);
923  int GetVisitType(int64_t index) const;
924  const std::vector<int>& GetSingleNodesOfType(int type) const;
925  const std::vector<int>& GetPairIndicesOfType(int type) const;
929  // TODO(user): Reconsider the logic and potentially remove the need to
931  void CloseVisitTypes();
932  int GetNumberOfVisitTypes() const { return num_visit_types_; }
933 #ifndef SWIG
934  const std::vector<std::vector<int>>& GetTopologicallySortedVisitTypes()
935  const {
936  DCHECK(closed_);
937  return topologically_sorted_visit_types_;
938  }
939 #endif // SWIG
940  void AddHardTypeIncompatibility(int type1, int type2);
945  void AddTemporalTypeIncompatibility(int type1, int type2);
947  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
948  int type) const;
949  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
950  int type) const;
954  return has_hard_type_incompatibilities_;
955  }
957  return has_temporal_type_incompatibilities_;
958  }
970  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
976  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
983  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
984  // clang-format off
987  const std::vector<absl::flat_hash_set<int> >&
990  const std::vector<absl::flat_hash_set<int> >&
993  const std::vector<absl::flat_hash_set<int> >&
995  // clang-format on
999  return has_same_vehicle_type_requirements_;
1000  }
1002  return has_temporal_type_requirements_;
1003  }
1004 
1007  bool HasTypeRegulations() const {
1011  }
1012 
1017  int64_t UnperformedPenalty(int64_t var_index) const;
1021  int64_t UnperformedPenaltyOrValue(int64_t default_value,
1022  int64_t var_index) const;
1026  int64_t GetDepot() const;
1027 
1032  void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
1033  max_active_vehicles_ = max_active_vehicles;
1034  }
1036  int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
1040  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
1042  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
1045  void SetFixedCostOfAllVehicles(int64_t cost);
1047  void SetFixedCostOfVehicle(int64_t cost, int vehicle);
1051  int64_t GetFixedCostOfVehicle(int vehicle) const;
1052 
1068  void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor,
1069  int64_t quadratic_cost_factor);
1071  void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor,
1072  int64_t quadratic_cost_factor,
1073  int vehicle);
1074 
1075  const std::vector<int64_t>& GetAmortizedLinearCostFactorOfVehicles() const {
1076  return linear_cost_factor_of_vehicle_;
1077  }
1078  const std::vector<int64_t>& GetAmortizedQuadraticCostFactorOfVehicles()
1079  const {
1080  return quadratic_cost_factor_of_vehicle_;
1081  }
1082 
1083  void SetVehicleUsedWhenEmpty(bool is_used, int vehicle) {
1084  DCHECK_LT(vehicle, vehicles_);
1085  vehicle_used_when_empty_[vehicle] = is_used;
1086  }
1087 
1088  bool IsVehicleUsedWhenEmpty(int vehicle) const {
1089  DCHECK_LT(vehicle, vehicles_);
1090  return vehicle_used_when_empty_[vehicle];
1091  }
1092 
1095 #ifndef SWIG
1097  return first_solution_evaluator_;
1098  }
1099 #endif
1102  first_solution_evaluator_ = std::move(evaluator);
1103  }
1106  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
1108  void AddSearchMonitor(SearchMonitor* const monitor);
1112  void AddAtSolutionCallback(std::function<void()> callback);
1117  void AddVariableMinimizedByFinalizer(IntVar* var);
1120  void AddVariableMaximizedByFinalizer(IntVar* var);
1123  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64_t cost);
1126  void AddVariableTargetToFinalizer(IntVar* var, int64_t target);
1133  void CloseModel();
1137  const RoutingSearchParameters& search_parameters);
1144  const Assignment* Solve(const Assignment* assignment = nullptr);
1152  const Assignment* SolveWithParameters(
1153  const RoutingSearchParameters& search_parameters,
1154  std::vector<const Assignment*>* solutions = nullptr);
1157  const Assignment* SolveFromAssignmentWithParameters(
1158  const Assignment* assignment,
1159  const RoutingSearchParameters& search_parameters,
1160  std::vector<const Assignment*>* solutions = nullptr);
1163  const Assignment* SolveFromAssignmentsWithParameters(
1164  const std::vector<const Assignment*>& assignments,
1165  const RoutingSearchParameters& search_parameters,
1166  std::vector<const Assignment*>* solutions = nullptr);
1173  Assignment* target_assignment, const RoutingModel* source_model,
1174  const Assignment* source_assignment);
1180  // TODO(user): Add support for non-homogeneous costs and disjunctions.
1181  int64_t ComputeLowerBound();
1183  Status status() const { return status_; }
1192  IntVar* ApplyLocks(const std::vector<int64_t>& locks);
1201  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64_t>>& locks,
1202  bool close_routes);
1207  const Assignment* const PreAssignment() const { return preassignment_; }
1208  Assignment* MutablePreAssignment() { return preassignment_; }
1212  bool WriteAssignment(const std::string& file_name) const;
1216  Assignment* ReadAssignment(const std::string& file_name);
1219  Assignment* RestoreAssignment(const Assignment& solution);
1226  const std::vector<std::vector<int64_t>>& routes,
1227  bool ignore_inactive_indices);
1244  bool RoutesToAssignment(const std::vector<std::vector<int64_t>>& routes,
1245  bool ignore_inactive_indices, bool close_routes,
1246  Assignment* const assignment) const;
1250  void AssignmentToRoutes(
1251  const Assignment& assignment,
1252  std::vector<std::vector<int64_t>>* const routes) const;
1257 #ifndef SWIG
1258  std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1259  const Assignment& assignment);
1260 #endif
1261  Assignment* CompactAssignment(const Assignment& assignment) const;
1282  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1284  void AddToAssignment(IntVar* const var);
1297  const Assignment* original_assignment, absl::Duration duration_limit);
1298 #ifndef SWIG
1299  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1302  SweepArranger* sweep_arranger() const;
1303 #endif
1304  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1310  CHECK(filter != nullptr);
1311  if (closed_) {
1312  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1313  }
1314  extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1315  extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1316  }
1317 
1320  int64_t Start(int vehicle) const { return starts_[vehicle]; }
1322  int64_t End(int vehicle) const { return ends_[vehicle]; }
1324  bool IsStart(int64_t index) const;
1326  bool IsEnd(int64_t index) const { return index >= Size(); }
1329  int VehicleIndex(int64_t index) const { return index_to_vehicle_[index]; }
1333  int64_t Next(const Assignment& assignment, int64_t index) const;
1335  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1336 
1337 #if !defined(SWIGPYTHON)
1338  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1343  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1347  const std::vector<IntVar*>& ResourceVars(int resource_group) const {
1348  return resource_vars_[resource_group];
1349  }
1350 #endif
1351  IntVar* NextVar(int64_t index) const { return nexts_[index]; }
1354  IntVar* ActiveVar(int64_t index) const { return active_[index]; }
1358  IntVar* ActiveVehicleVar(int vehicle) const {
1359  return vehicle_active_[vehicle];
1360  }
1364  IntVar* VehicleRouteConsideredVar(int vehicle) const {
1365  return vehicle_route_considered_[vehicle];
1366  }
1369  IntVar* VehicleVar(int64_t index) const { return vehicle_vars_[index]; }
1373  IntVar* ResourceVar(int vehicle, int resource_group) const {
1374  DCHECK_LT(resource_group, resource_vars_.size());
1375  DCHECK_LT(vehicle, resource_vars_[resource_group].size());
1376  return resource_vars_[resource_group][vehicle];
1377  }
1379  IntVar* CostVar() const { return cost_; }
1380 
1383  int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1384  int64_t vehicle) const;
1387  return costs_are_homogeneous_across_vehicles_;
1388  }
1391  int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const {
1392  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1393  }
1396  int64_t GetArcCostForFirstSolution(int64_t from_index,
1397  int64_t to_index) const;
1404  int64_t GetArcCostForClass(int64_t from_index, int64_t to_index,
1405  int64_t /*CostClassIndex*/ cost_class_index) const;
1408  DCHECK(closed_);
1409  DCHECK_GE(vehicle, 0);
1410  DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1411  DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1412  return cost_class_index_of_vehicle_[vehicle];
1413  }
1416  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1417  DCHECK(closed_);
1418  if (cost_class_index == kCostClassIndexOfZeroCost) {
1419  return has_vehicle_with_zero_cost_class_;
1420  }
1421  return cost_class_index < cost_classes_.size();
1422  }
1424  int GetCostClassesCount() const { return cost_classes_.size(); }
1427  return std::max(0, GetCostClassesCount() - 1);
1428  }
1430  DCHECK(closed_);
1431  return vehicle_class_index_of_vehicle_[vehicle];
1432  }
1436  DCHECK(closed_);
1437  const RoutingModel::VehicleTypeContainer& vehicle_type_container =
1439  if (vehicle_class.value() >= GetVehicleClassesCount() ||
1440  vehicle_type_container.vehicles_per_vehicle_class[vehicle_class.value()]
1441  .empty()) {
1442  return -1;
1443  }
1444  return vehicle_type_container
1446  .front();
1447  }
1449  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1451  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1452  DCHECK(closed_);
1453  return same_vehicle_groups_[same_vehicle_group_[node]];
1454  }
1455 
1457  DCHECK(closed_);
1458  return vehicle_type_container_;
1459  }
1460 
1479  bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1484  std::string DebugOutputAssignment(
1485  const Assignment& solution_assignment,
1486  const std::string& dimension_to_print) const;
1492 #ifndef SWIG
1493  std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1494  const Assignment& solution_assignment, const RoutingDimension& dimension);
1495 #endif
1496  Solver* solver() const { return solver_.get(); }
1499 
1501  bool CheckLimit() {
1502  DCHECK(limit_ != nullptr);
1503  return limit_->Check();
1504  }
1505 
1507  absl::Duration RemainingTime() const {
1508  DCHECK(limit_ != nullptr);
1509  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1510  }
1511 
1514  int nodes() const { return nodes_; }
1516  int vehicles() const { return vehicles_; }
1518  int64_t Size() const { return nodes_ + vehicles_ - start_end_count_; }
1519 
1523  const RoutingSearchParameters& search_parameters) const;
1525  const RoutingSearchParameters& search_parameters) const;
1529  return automatic_first_solution_strategy_;
1530  }
1531 
1533  bool IsMatchingModel() const;
1534 
1535 #ifndef SWIG
1536  using GetTabuVarsCallback =
1539  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1540 
1541  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1542 #endif // SWIG
1543 
1545  // TODO(user): Find a way to test and restrict the access at the same time.
1558  const RoutingDimension* dimension,
1559  std::function<int64_t(int64_t)> initializer);
1560 #ifndef SWIG
1561  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1566  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1567  std::vector<IntVar*> variables);
1568  // Read access to currently registered search monitors.
1569  const std::vector<SearchMonitor*>& GetSearchMonitors() const {
1570  return monitors_;
1571  }
1572 #endif
1573  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1587  const RoutingDimension* dimension);
1588 
1589  private:
1591  enum RoutingLocalSearchOperator {
1592  RELOCATE = 0,
1593  RELOCATE_PAIR,
1594  LIGHT_RELOCATE_PAIR,
1595  RELOCATE_NEIGHBORS,
1596  EXCHANGE,
1597  EXCHANGE_PAIR,
1598  CROSS,
1599  CROSS_EXCHANGE,
1600  TWO_OPT,
1601  OR_OPT,
1602  GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1603  LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1604  GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1605  LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1606  RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1607  GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1608  LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1609  RELOCATE_EXPENSIVE_CHAIN,
1610  LIN_KERNIGHAN,
1611  TSP_OPT,
1612  MAKE_ACTIVE,
1613  RELOCATE_AND_MAKE_ACTIVE,
1614  MAKE_ACTIVE_AND_RELOCATE,
1615  MAKE_INACTIVE,
1616  MAKE_CHAIN_INACTIVE,
1617  SWAP_ACTIVE,
1618  EXTENDED_SWAP_ACTIVE,
1619  NODE_PAIR_SWAP,
1620  PATH_LNS,
1621  FULL_PATH_LNS,
1622  TSP_LNS,
1623  INACTIVE_LNS,
1624  EXCHANGE_RELOCATE_PAIR,
1625  RELOCATE_SUBTRIP,
1626  EXCHANGE_SUBTRIP,
1627  LOCAL_SEARCH_OPERATOR_COUNTER
1628  };
1629 
1633  template <typename T>
1634  struct ValuedNodes {
1635  std::vector<int64_t> indices;
1636  T value;
1637  };
1638  struct DisjunctionValues {
1639  int64_t penalty;
1640  int64_t max_cardinality;
1641  };
1642  typedef ValuedNodes<DisjunctionValues> Disjunction;
1643 
1646  struct CostCacheElement {
1652  int index;
1653  CostClassIndex cost_class_index;
1654  int64_t cost;
1655  };
1656 
1658  void Initialize();
1659  void AddNoCycleConstraintInternal();
1660  bool AddDimensionWithCapacityInternal(
1661  const std::vector<int>& evaluator_indices, int64_t slack_max,
1662  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1663  const std::string& name);
1664  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1665  const std::vector<int>& pure_transits,
1666  const std::vector<int>& dependent_transits,
1667  const RoutingDimension* base_dimension, int64_t slack_max,
1668  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1669  const std::string& name);
1670  bool InitializeDimensionInternal(
1671  const std::vector<int>& evaluator_indices,
1672  const std::vector<int>& state_dependent_evaluator_indices,
1673  int64_t slack_max, bool fix_start_cumul_to_zero,
1674  RoutingDimension* dimension);
1675  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1676 
1704  void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1705 
1706  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1707  void ComputeVehicleClasses();
1715  void ComputeVehicleTypes();
1725  void FinalizeVisitTypes();
1726  // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_.
1727  void TopologicallySortVisitTypes();
1728  int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index,
1729  CostClassIndex cost_class_index) const;
1730  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1731  int node_index,
1732  std::vector<IntVar*>* cost_elements);
1733  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1734  std::vector<IntVar*>* cost_elements);
1735  Assignment* DoRestoreAssignment();
1736  static const CostClassIndex kCostClassIndexOfZeroCost;
1737  int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle) const {
1738  DCHECK_LT(0, vehicles_);
1739  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1740  : kCostClassIndexOfZeroCost)
1741  .value();
1742  }
1743  int64_t GetDimensionTransitCostSum(int64_t i, int64_t j,
1744  const CostClass& cost_class) const;
1746  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1748  void AddPickupAndDeliverySetsInternal(const std::vector<int64_t>& pickups,
1749  const std::vector<int64_t>& deliveries);
1752  IntVar* CreateSameVehicleCost(int vehicle_index);
1755  int FindNextActive(int index, const std::vector<int64_t>& indices) const;
1756 
1759  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1760  int vehicle) const;
1768  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1769  Assignment* compact_assignment) const;
1770 
1771  void QuietCloseModel();
1772  void QuietCloseModelWithParameters(
1773  const RoutingSearchParameters& parameters) {
1774  if (!closed_) {
1776  }
1777  }
1778 
1780  bool SolveMatchingModel(Assignment* assignment,
1781  const RoutingSearchParameters& parameters);
1782 #ifndef SWIG
1783  bool AppendAssignmentIfFeasible(
1785  const Assignment& assignment,
1786  std::vector<std::unique_ptr<Assignment>>* assignments);
1787 #endif
1788  void LogSolution(const RoutingSearchParameters& parameters,
1790  const std::string& description, int64_t solution_cost,
1791  int64_t start_time_ms);
1794  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1795  bool check_compact_assignment) const;
1800  std::string FindErrorInSearchParametersForModel(
1801  const RoutingSearchParameters& search_parameters) const;
1803  void SetupSearch(const RoutingSearchParameters& search_parameters);
1805  // TODO(user): Document each auxiliary method.
1806  Assignment* GetOrCreateAssignment();
1807  Assignment* GetOrCreateTmpAssignment();
1808  RegularLimit* GetOrCreateLimit();
1809  RegularLimit* GetOrCreateLocalSearchLimit();
1810  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1811  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1812  LocalSearchOperator* CreateInsertionOperator();
1813  LocalSearchOperator* CreateMakeInactiveOperator();
1814  template <class T>
1815  LocalSearchOperator* CreateCPOperator(const T& operator_factory) {
1816  return operator_factory(solver_.get(), nexts_,
1818  ? std::vector<IntVar*>()
1819  : vehicle_vars_,
1820  vehicle_start_class_callback_);
1821  }
1822  template <class T>
1823  LocalSearchOperator* CreateCPOperator() {
1824  return CreateCPOperator(MakeLocalSearchOperator<T>);
1825  }
1826  template <class T, class Arg>
1827  LocalSearchOperator* CreateOperator(const Arg& arg) {
1828  return solver_->RevAlloc(new T(nexts_,
1830  ? std::vector<IntVar*>()
1831  : vehicle_vars_,
1832  vehicle_start_class_callback_, arg));
1833  }
1834  template <class T>
1835  LocalSearchOperator* CreatePairOperator() {
1836  return CreateOperator<T>(pickup_delivery_pairs_);
1837  }
1838  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1839  LocalSearchOperator* ConcatenateOperators(
1840  const RoutingSearchParameters& search_parameters,
1841  const std::vector<LocalSearchOperator*>& operators) const;
1842  LocalSearchOperator* GetNeighborhoodOperators(
1843  const RoutingSearchParameters& search_parameters) const;
1844  std::vector<LocalSearchFilterManager::FilterEvent>
1845  GetOrCreateLocalSearchFilters(const RoutingSearchParameters& parameters,
1846  bool filter_cost = true);
1847  LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1848  const RoutingSearchParameters& parameters);
1849  std::vector<LocalSearchFilterManager::FilterEvent>
1850  GetOrCreateFeasibilityFilters(const RoutingSearchParameters& parameters);
1851  LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1852  const RoutingSearchParameters& parameters);
1853  LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1854  const RoutingSearchParameters& parameters);
1855  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1856  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1857  void CreateFirstSolutionDecisionBuilders(
1858  const RoutingSearchParameters& search_parameters);
1859  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1860  const RoutingSearchParameters& search_parameters) const;
1861  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1862  const RoutingSearchParameters& parameters) const;
1863  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1864  const RoutingSearchParameters& search_parameters);
1865  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1866  const RoutingSearchParameters& search_parameters);
1867  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1868  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1869  void SetupAssignmentCollector(
1870  const RoutingSearchParameters& search_parameters);
1871  void SetupTrace(const RoutingSearchParameters& search_parameters);
1872  void SetupImprovementLimit(const RoutingSearchParameters& search_parameters);
1873  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1874  bool UsesLightPropagation(
1875  const RoutingSearchParameters& search_parameters) const;
1876  GetTabuVarsCallback tabu_var_callback_;
1877 
1878  // Detects implicit pickup delivery pairs. These pairs are
1879  // non-pickup/delivery pairs for which there exists a unary dimension such
1880  // that the demand d of the implicit pickup is positive and the demand of the
1881  // implicit delivery is equal to -d.
1882  void DetectImplicitPickupAndDeliveries();
1883 
1884  int GetVehicleStartClass(int64_t start) const;
1885 
1886  void InitSameVehicleGroups(int number_of_groups) {
1887  same_vehicle_group_.assign(Size(), 0);
1888  same_vehicle_groups_.assign(number_of_groups, {});
1889  }
1890  void SetSameVehicleGroup(int index, int group) {
1891  same_vehicle_group_[index] = group;
1892  same_vehicle_groups_[group].push_back(index);
1893  }
1894 
1896  std::unique_ptr<Solver> solver_;
1897  int nodes_;
1898  int vehicles_;
1899  int max_active_vehicles_;
1900  Constraint* no_cycle_constraint_ = nullptr;
1902  std::vector<IntVar*> nexts_;
1903  std::vector<IntVar*> vehicle_vars_;
1904  std::vector<IntVar*> active_;
1907  // clang-format off
1908  std::vector<std::vector<IntVar*> > resource_vars_;
1909  // clang-format on
1910  // The following vectors are indexed by vehicle index.
1911  std::vector<IntVar*> vehicle_active_;
1912  std::vector<IntVar*> vehicle_route_considered_;
1917  std::vector<IntVar*> is_bound_to_end_;
1918  mutable RevSwitch is_bound_to_end_ct_added_;
1920  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1926  // clang-format off
1927  std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1930  dimension_resource_group_indices_;
1931 
1935  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1936  global_dimension_optimizers_;
1937  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1938  global_dimension_mp_optimizers_;
1939  absl::StrongVector<DimensionIndex, int> global_optimizer_index_;
1940  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1941  local_dimension_optimizers_;
1942  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1943  local_dimension_mp_optimizers_;
1944  // clang-format off
1945  absl::StrongVector<DimensionIndex, int> local_optimizer_index_;
1946  std::string primary_constrained_dimension_;
1948  IntVar* cost_ = nullptr;
1949  std::vector<int> vehicle_to_transit_cost_;
1950  std::vector<int64_t> fixed_cost_of_vehicle_;
1951  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1952  bool has_vehicle_with_zero_cost_class_;
1953  std::vector<int64_t> linear_cost_factor_of_vehicle_;
1954  std::vector<int64_t> quadratic_cost_factor_of_vehicle_;
1955  bool vehicle_amortized_cost_factors_set_;
1967  std::vector<bool> vehicle_used_when_empty_;
1968 #ifndef SWIG
1970 #endif // SWIG
1971  bool costs_are_homogeneous_across_vehicles_;
1972  bool cache_callbacks_;
1973  mutable std::vector<CostCacheElement> cost_cache_;
1974  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1975 #ifndef SWIG
1977 #endif // SWIG
1978  VehicleTypeContainer vehicle_type_container_;
1979  std::function<int(int64_t)> vehicle_start_class_callback_;
1982  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1984  std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
1986 #ifndef SWIG
1987  std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1988 #endif // SWIG
1989  IndexPairs pickup_delivery_pairs_;
1991  IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
1992  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1993  pickup_delivery_disjunctions_;
1994  // clang-format off
1995  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1996  // vector of pairs {pair_index, pickup_index} such that
1997  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1998  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1999  // Same as above for deliveries.
2000  std::vector<std::vector<std::pair<int, int> > >
2001  index_to_delivery_index_pairs_;
2002  // clang-format on
2003  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
2004  // Same vehicle group to which a node belongs.
2005  std::vector<int> same_vehicle_group_;
2006  // Same vehicle node groups.
2007  std::vector<std::vector<int>> same_vehicle_groups_;
2008  // Node visit types
2009  // Variable index to visit type index.
2010  std::vector<int> index_to_visit_type_;
2011  // Variable index to VisitTypePolicy.
2012  std::vector<VisitTypePolicy> index_to_type_policy_;
2013  // clang-format off
2014  std::vector<std::vector<int> > single_nodes_of_type_;
2015  std::vector<std::vector<int> > pair_indices_of_type_;
2016 
2017  std::vector<absl::flat_hash_set<int> >
2018  hard_incompatible_types_per_type_index_;
2019  bool has_hard_type_incompatibilities_;
2020  std::vector<absl::flat_hash_set<int> >
2021  temporal_incompatible_types_per_type_index_;
2022  bool has_temporal_type_incompatibilities_;
2023 
2024  std::vector<std::vector<absl::flat_hash_set<int> > >
2025  same_vehicle_required_type_alternatives_per_type_index_;
2026  bool has_same_vehicle_type_requirements_;
2027  std::vector<std::vector<absl::flat_hash_set<int> > >
2028  required_type_alternatives_when_adding_type_index_;
2029  std::vector<std::vector<absl::flat_hash_set<int> > >
2030  required_type_alternatives_when_removing_type_index_;
2031  bool has_temporal_type_requirements_;
2032  absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
2033  trivially_infeasible_visit_types_to_policies_;
2034 
2035  // Visit types sorted topologically based on required-->dependent requirement
2036  // arcs between the types (if the requirement/dependency graph is acyclic).
2037  // Visit types of the same topological level are sorted in each sub-vector
2038  // by decreasing requirement "tightness", computed as the pair of the two
2039  // following criteria:
2040  //
2041  // 1) How highly *dependent* this type is, determined by
2042  // (total number of required alternative sets for that type)
2043  // / (average number of types in the required alternative sets)
2044  // 2) How highly *required* this type t is, computed as
2045  // SUM_{S required set containing t} ( 1 / |S| ),
2046  // i.e. the sum of reverse number of elements of all required sets
2047  // containing the type t.
2048  //
2049  // The higher these two numbers, the tighter the type is wrt requirements.
2050  std::vector<std::vector<int> > topologically_sorted_visit_types_;
2051  // clang-format on
2052  int num_visit_types_;
2053  // Two indices are equivalent if they correspond to the same node (as given
2054  // to the constructors taking a RoutingIndexManager).
2055  std::vector<int> index_to_equivalence_class_;
2056  std::vector<int> index_to_vehicle_;
2057  std::vector<int64_t> starts_;
2058  std::vector<int64_t> ends_;
2059  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
2060  // anymore.
2061  RoutingIndexManager manager_;
2062  int start_end_count_;
2063  // Model status
2064  bool closed_ = false;
2065  Status status_ = ROUTING_NOT_SOLVED;
2066  bool enable_deep_serialization_ = true;
2067 
2068  // Search data
2069  std::vector<DecisionBuilder*> first_solution_decision_builders_;
2070  std::vector<IntVarFilteredDecisionBuilder*>
2071  first_solution_filtered_decision_builders_;
2072  Solver::IndexEvaluator2 first_solution_evaluator_;
2073  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
2075  std::vector<LocalSearchOperator*> local_search_operators_;
2076  std::vector<SearchMonitor*> monitors_;
2077  SolutionCollector* collect_assignments_ = nullptr;
2078  SolutionCollector* collect_one_assignment_ = nullptr;
2079  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
2080  DecisionBuilder* solve_db_ = nullptr;
2081  DecisionBuilder* improve_db_ = nullptr;
2082  DecisionBuilder* restore_assignment_ = nullptr;
2083  DecisionBuilder* restore_tmp_assignment_ = nullptr;
2084  Assignment* assignment_ = nullptr;
2085  Assignment* preassignment_ = nullptr;
2086  Assignment* tmp_assignment_ = nullptr;
2087  std::vector<IntVar*> extra_vars_;
2088  std::vector<IntervalVar*> extra_intervals_;
2089  std::vector<LocalSearchOperator*> extra_operators_;
2090  LocalSearchFilterManager* local_search_filter_manager_ = nullptr;
2091  LocalSearchFilterManager* feasibility_filter_manager_ = nullptr;
2092  LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr;
2093  std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
2094 #ifndef SWIG
2095  std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_cost_pairs_;
2096  std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_target_pairs_;
2097  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
2098  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
2099  std::unique_ptr<SweepArranger> sweep_arranger_;
2100 #endif
2101 
2102  RegularLimit* limit_ = nullptr;
2103  RegularLimit* ls_limit_ = nullptr;
2104  RegularLimit* lns_limit_ = nullptr;
2105  RegularLimit* first_solution_lns_limit_ = nullptr;
2106 
2107  typedef std::pair<int64_t, int64_t> CacheKey;
2108  typedef absl::flat_hash_map<CacheKey, int64_t> TransitCallbackCache;
2109  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
2110  StateDependentTransitCallbackCache;
2111 
2112  std::vector<TransitCallback1> unary_transit_evaluators_;
2113  std::vector<TransitCallback2> transit_evaluators_;
2114  // The following vector stores a boolean per transit_evaluator_, indicating
2115  // whether the transits are all positive.
2116  // is_transit_evaluator_positive_ will be set to true only when registering a
2117  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
2118  // The actual positivity of the transit values will only be checked in debug
2119  // mode, when calling RegisterPositiveTransitCallback().
2120  // Therefore, RegisterPositiveTransitCallback() should only be called when the
2121  // transits are known to be positive, as the positivity of a callback will
2122  // allow some improvements in the solver, but will entail in errors if the
2123  // transits are falsely assumed positive.
2124  std::vector<bool> is_transit_evaluator_positive_;
2125  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
2126  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
2127  state_dependent_transit_evaluators_cache_;
2128 
2129  friend class RoutingDimension;
2132 
2134 };
2135 
2138  public:
2140  static const char kLightElement[];
2141  static const char kLightElement2[];
2142  static const char kRemoveValues[];
2143 };
2144 
2145 #if !defined(SWIG)
2146 class DisjunctivePropagator {
2149  public:
2155  struct Tasks {
2157  std::vector<int64_t> start_min;
2158  std::vector<int64_t> start_max;
2159  std::vector<int64_t> duration_min;
2160  std::vector<int64_t> duration_max;
2161  std::vector<int64_t> end_min;
2162  std::vector<int64_t> end_max;
2163  std::vector<bool> is_preemptible;
2164  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
2165  std::vector<std::pair<int64_t, int64_t>> distance_duration;
2166  int64_t span_min = 0;
2167  int64_t span_max = kint64max;
2168 
2169  void Clear() {
2170  start_min.clear();
2171  start_max.clear();
2172  duration_min.clear();
2173  duration_max.clear();
2174  end_min.clear();
2175  end_max.clear();
2176  is_preemptible.clear();
2177  forbidden_intervals.clear();
2178  distance_duration.clear();
2179  span_min = 0;
2180  span_max = kint64max;
2181  num_chain_tasks = 0;
2182  }
2183  };
2184 
2187  bool Propagate(Tasks* tasks);
2188 
2190  bool Precedences(Tasks* tasks);
2193  bool MirrorTasks(Tasks* tasks);
2195  bool EdgeFinding(Tasks* tasks);
2198  bool DetectablePrecedencesWithChain(Tasks* tasks);
2200  bool ForbiddenIntervals(Tasks* tasks);
2202  bool DistanceDuration(Tasks* tasks);
2205  bool ChainSpanMin(Tasks* tasks);
2210  bool ChainSpanMinDynamic(Tasks* tasks);
2211 
2212  private:
2215  sat::ThetaLambdaTree<int64_t> theta_lambda_tree_;
2217  std::vector<int> tasks_by_start_min_;
2218  std::vector<int> tasks_by_end_max_;
2219  std::vector<int> event_of_task_;
2220  std::vector<int> nonchain_tasks_by_start_max_;
2222  std::vector<int64_t> total_duration_before_;
2223 };
2224 
2226  std::vector<int64_t> min_travels;
2227  std::vector<int64_t> max_travels;
2228  std::vector<int64_t> pre_travels;
2229  std::vector<int64_t> post_travels;
2230 };
2231 
2232 void AppendTasksFromPath(const std::vector<int64_t>& path,
2233  const TravelBounds& travel_bounds,
2234  const RoutingDimension& dimension,
2236 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
2238 void FillPathEvaluation(const std::vector<int64_t>& path,
2239  const RoutingModel::TransitCallback2& evaluator,
2240  std::vector<int64_t>* values);
2241 void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64_t>& path,
2242  const RoutingDimension& dimension,
2243  TravelBounds* travel_bounds);
2244 #endif // !defined(SWIG)
2245 
2257  public:
2258  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
2259  std::string DebugString() const override {
2260  return "GlobalVehicleBreaksConstraint";
2261  }
2262 
2263  void Post() override;
2264  void InitialPropagate() override;
2265 
2266  private:
2267  void PropagateNode(int node);
2268  void PropagateVehicle(int vehicle);
2269  void PropagateMaxBreakDistance(int vehicle);
2270 
2271  const RoutingModel* model_;
2272  const RoutingDimension* const dimension_;
2273  std::vector<Demon*> vehicle_demons_;
2274  std::vector<int64_t> path_;
2275 
2280  void FillPartialPathOfVehicle(int vehicle);
2281  void FillPathTravels(const std::vector<int64_t>& path);
2282 
2293  class TaskTranslator {
2294  public:
2295  TaskTranslator(IntVar* start, int64_t before_start, int64_t after_start)
2296  : start_(start),
2297  before_start_(before_start),
2298  after_start_(after_start) {}
2299  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2300  TaskTranslator() {}
2301 
2302  void SetStartMin(int64_t value) {
2303  if (start_ != nullptr) {
2304  start_->SetMin(CapAdd(before_start_, value));
2305  } else if (interval_ != nullptr) {
2306  interval_->SetStartMin(value);
2307  }
2308  }
2309  void SetStartMax(int64_t value) {
2310  if (start_ != nullptr) {
2311  start_->SetMax(CapAdd(before_start_, value));
2312  } else if (interval_ != nullptr) {
2313  interval_->SetStartMax(value);
2314  }
2315  }
2316  void SetDurationMin(int64_t value) {
2317  if (interval_ != nullptr) {
2318  interval_->SetDurationMin(value);
2319  }
2320  }
2321  void SetEndMin(int64_t value) {
2322  if (start_ != nullptr) {
2323  start_->SetMin(CapSub(value, after_start_));
2324  } else if (interval_ != nullptr) {
2325  interval_->SetEndMin(value);
2326  }
2327  }
2328  void SetEndMax(int64_t value) {
2329  if (start_ != nullptr) {
2330  start_->SetMax(CapSub(value, after_start_));
2331  } else if (interval_ != nullptr) {
2332  interval_->SetEndMax(value);
2333  }
2334  }
2335 
2336  private:
2337  IntVar* start_ = nullptr;
2338  int64_t before_start_;
2339  int64_t after_start_;
2340  IntervalVar* interval_ = nullptr;
2341  };
2342 
2344  std::vector<TaskTranslator> task_translators_;
2345 
2347  DisjunctivePropagator disjunctive_propagator_;
2348  DisjunctivePropagator::Tasks tasks_;
2349 
2351  TravelBounds travel_bounds_;
2352 };
2353 
2355  public:
2356  explicit TypeRegulationsChecker(const RoutingModel& model);
2358 
2359  bool CheckVehicle(int vehicle,
2360  const std::function<int64_t(int64_t)>& next_accessor);
2361 
2362  protected:
2363 #ifndef SWIG
2365 #endif // SWIG
2366 
2383  };
2384 
2389  bool TypeOccursOnRoute(int type) const;
2396  bool TypeCurrentlyOnRoute(int type, int pos) const;
2397 
2398  void InitializeCheck(int vehicle,
2399  const std::function<int64_t(int64_t)>& next_accessor);
2400  virtual void OnInitializeCheck() {}
2401  virtual bool HasRegulationsToCheck() const = 0;
2402  virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2403  int pos) = 0;
2404  virtual bool FinalizeCheck() const { return true; }
2405 
2407 
2408  private:
2409  std::vector<TypePolicyOccurrence> occurrences_of_type_;
2410  std::vector<int64_t> current_route_visits_;
2411 };
2412 
2415  public:
2417  bool check_hard_incompatibilities);
2419 
2420  private:
2421  bool HasRegulationsToCheck() const override;
2422  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2426  bool check_hard_incompatibilities_;
2427 };
2428 
2431  public:
2435 
2436  private:
2437  bool HasRegulationsToCheck() const override;
2438  void OnInitializeCheck() override {
2439  types_with_same_vehicle_requirements_on_route_.clear();
2440  }
2441  // clang-format off
2444  bool CheckRequiredTypesCurrentlyOnRoute(
2445  const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2446  int pos);
2447  // clang-format on
2448  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2449  bool FinalizeCheck() const override;
2450 
2451  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2452 };
2453 
2495  public:
2496  explicit TypeRegulationsConstraint(const RoutingModel& model);
2497 
2498  void Post() override;
2499  void InitialPropagate() override;
2500 
2501  private:
2502  void PropagateNodeRegulations(int node);
2503  void CheckRegulationsOnVehicle(int vehicle);
2504 
2505  const RoutingModel& model_;
2506  TypeIncompatibilityChecker incompatibility_checker_;
2507  TypeRequirementChecker requirement_checker_;
2508  std::vector<Demon*> vehicle_demons_;
2509 };
2510 #if !defined SWIG
2511 class SimpleBoundCosts {
2524  public:
2525  struct BoundCost {
2526  int64_t bound;
2527  int64_t cost;
2528  };
2529  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2530  : bound_costs_(num_bounds, default_bound_cost) {}
2531  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2532  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2533  int Size() { return bound_costs_.size(); }
2534  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
2535  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
2536 
2537  private:
2538  std::vector<BoundCost> bound_costs_;
2539 };
2540 #endif // !defined SWIG
2541 
2559 // TODO(user): Break constraints need to know the service time of nodes
2563  public:
2566  RoutingModel* model() const { return model_; }
2570  int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2571  int64_t vehicle) const;
2574  int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index,
2575  int64_t vehicle_class) const {
2576  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2577  to_index);
2578  }
2581  IntVar* CumulVar(int64_t index) const { return cumuls_[index]; }
2582  IntVar* TransitVar(int64_t index) const { return transits_[index]; }
2583  IntVar* FixedTransitVar(int64_t index) const {
2584  return fixed_transits_[index];
2585  }
2586  IntVar* SlackVar(int64_t index) const { return slacks_[index]; }
2587 
2588 #if !defined(SWIGPYTHON)
2589  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2592  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2593  const std::vector<IntVar*>& transits() const { return transits_; }
2594  const std::vector<IntVar*>& slacks() const { return slacks_; }
2595 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2596  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2598  return forbidden_intervals_;
2599  }
2601  SortedDisjointIntervalList GetAllowedIntervalsInRange(
2602  int64_t index, int64_t min_value, int64_t max_value) const;
2606  int64_t min_value) const {
2607  DCHECK_LT(index, forbidden_intervals_.size());
2609  forbidden_intervals_[index];
2610  const auto first_forbidden_interval_it =
2611  forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2612  if (first_forbidden_interval_it != forbidden_intervals.end() &&
2613  min_value >= first_forbidden_interval_it->start) {
2615  return CapAdd(first_forbidden_interval_it->end, 1);
2616  }
2618  return min_value;
2619  }
2625  int64_t max_value) const {
2626  DCHECK_LT(index, forbidden_intervals_.size());
2628  forbidden_intervals_[index];
2629  const auto last_forbidden_interval_it =
2630  forbidden_intervals.LastIntervalLessOrEqual(max_value);
2631  if (last_forbidden_interval_it != forbidden_intervals.end() &&
2632  max_value <= last_forbidden_interval_it->end) {
2634  return CapSub(last_forbidden_interval_it->start, 1);
2635  }
2637  return max_value;
2638  }
2640  const std::vector<int64_t>& vehicle_capacities() const {
2641  return vehicle_capacities_;
2642  }
2646  return model_->TransitCallback(
2647  class_evaluators_[vehicle_to_class_[vehicle]]);
2648  }
2649 
2653  RoutingVehicleClassIndex vehicle_class) const {
2654  const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2655  DCHECK_NE(vehicle, -1);
2656  return transit_evaluator(vehicle);
2657  }
2658 
2663  int vehicle) const {
2664  return model_->UnaryTransitCallbackOrNull(
2665  class_evaluators_[vehicle_to_class_[vehicle]]);
2666  }
2669  bool AreVehicleTransitsPositive(int vehicle) const {
2670  return model()->is_transit_evaluator_positive_
2671  [class_evaluators_[vehicle_to_class_[vehicle]]];
2672  }
2673  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2674 #endif
2675 #endif
2676  void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle);
2680  void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle);
2695 
2696 #ifndef SWIG
2702  const PiecewiseLinearFunction& cost);
2705  bool HasCumulVarPiecewiseLinearCost(int64_t index) const;
2709  int64_t index) const;
2710 #endif
2711 
2720  void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound,
2721  int64_t coefficient);
2724  bool HasCumulVarSoftUpperBound(int64_t index) const;
2728  int64_t GetCumulVarSoftUpperBound(int64_t index) const;
2732  int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const;
2733 
2743  void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound,
2744  int64_t coefficient);
2747  bool HasCumulVarSoftLowerBound(int64_t index) const;
2751  int64_t GetCumulVarSoftLowerBound(int64_t index) const;
2755  int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const;
2771  // TODO(user): Remove if !defined when routing.i is repaired.
2772 #if !defined(SWIGPYTHON)
2773  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2774  int pre_travel_evaluator,
2775  int post_travel_evaluator);
2776 #endif // !defined(SWIGPYTHON)
2777 
2779  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2780  std::vector<int64_t> node_visit_transits);
2781 
2786  void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration,
2787  int vehicle);
2790  void InitializeBreaks();
2792  bool HasBreakConstraints() const;
2793 #if !defined(SWIGPYTHON)
2797  std::vector<IntervalVar*> breaks, int vehicle,
2798  std::vector<int64_t> node_visit_transits,
2799  std::function<int64_t(int64_t, int64_t)> delays);
2800 
2802  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2803  int vehicle) const;
2806  // clang-format off
2807  const std::vector<std::pair<int64_t, int64_t> >&
2808  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2809  // clang-format on
2810 #endif
2811  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2812  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2813 
2815  const RoutingDimension* base_dimension() const { return base_dimension_; }
2823  int64_t ShortestTransitionSlack(int64_t node) const;
2824 
2826  const std::string& name() const { return name_; }
2827 
2829 #ifndef SWIG
2831  return path_precedence_graph_;
2832  }
2833 #endif // SWIG
2834 
2844  typedef std::function<int64_t(int, int)> PickupToDeliveryLimitFunction;
2845 
2847  PickupToDeliveryLimitFunction limit_function, int pair_index);
2848 
2849  bool HasPickupToDeliveryLimits() const;
2850 #ifndef SWIG
2851  int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2852  int delivery) const;
2853 
2855  int64_t first_node;
2856  int64_t second_node;
2857  int64_t offset;
2858  };
2859 
2861  node_precedences_.push_back(precedence);
2862  }
2863  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2864  return node_precedences_;
2865  }
2866 #endif // SWIG
2867 
2868  void AddNodePrecedence(int64_t first_node, int64_t second_node,
2869  int64_t offset) {
2870  AddNodePrecedence({first_node, second_node, offset});
2871  }
2872 
2873  int64_t GetSpanUpperBoundForVehicle(int vehicle) const {
2874  return vehicle_span_upper_bounds_[vehicle];
2875  }
2876 #ifndef SWIG
2877  const std::vector<int64_t>& vehicle_span_upper_bounds() const {
2878  return vehicle_span_upper_bounds_;
2879  }
2880 #endif // SWIG
2881  int64_t GetSpanCostCoefficientForVehicle(int vehicle) const {
2882  return vehicle_span_cost_coefficients_[vehicle];
2883  }
2884 #ifndef SWIG
2886  RoutingVehicleClassIndex vehicle_class) const {
2887  const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2888  DCHECK_NE(vehicle, -1);
2889  return GetSpanCostCoefficientForVehicle(vehicle);
2890  }
2891 #endif // SWIG
2892 #ifndef SWIG
2893  const std::vector<int64_t>& vehicle_span_cost_coefficients() const {
2894  return vehicle_span_cost_coefficients_;
2895  }
2896 #endif // SWIG
2898  return global_span_cost_coefficient_;
2899  }
2900 
2901  int64_t GetGlobalOptimizerOffset() const {
2902  DCHECK_GE(global_optimizer_offset_, 0);
2903  return global_optimizer_offset_;
2904  }
2905  int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2906  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2907  return 0;
2908  }
2909  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2910  return local_optimizer_offset_for_vehicle_[vehicle];
2911  }
2912 #if !defined SWIG
2916  int vehicle) {
2917  if (!HasSoftSpanUpperBounds()) {
2918  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2919  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2920  }
2921  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2922  }
2923  bool HasSoftSpanUpperBounds() const {
2924  return vehicle_soft_span_upper_bound_ != nullptr;
2925  }
2927  int vehicle) const {
2929  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2930  }
2934  SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2936  vehicle_quadratic_cost_soft_span_upper_bound_ =
2937  absl::make_unique<SimpleBoundCosts>(
2938  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2939  }
2940  vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2941  bound_cost;
2942  }
2944  return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2945  }
2947  int vehicle) const {
2949  return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2950  }
2951 #endif
2952 
2953  private:
2954  struct SoftBound {
2955  IntVar* var;
2956  int64_t bound;
2957  int64_t coefficient;
2958  };
2959 
2960  struct PiecewiseLinearCost {
2961  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2962  IntVar* var;
2963  std::unique_ptr<PiecewiseLinearFunction> cost;
2964  };
2965 
2966  class SelfBased {};
2967  RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2968  const std::string& name,
2969  const RoutingDimension* base_dimension);
2970  RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2971  const std::string& name, SelfBased);
2972  void Initialize(const std::vector<int>& transit_evaluators,
2973  const std::vector<int>& state_dependent_transit_evaluators,
2974  int64_t slack_max);
2975  void InitializeCumuls();
2976  void InitializeTransits(
2977  const std::vector<int>& transit_evaluators,
2978  const std::vector<int>& state_dependent_transit_evaluators,
2979  int64_t slack_max);
2980  void InitializeTransitVariables(int64_t slack_max);
2982  void SetupCumulVarSoftUpperBoundCosts(
2983  std::vector<IntVar*>* cost_elements) const;
2985  void SetupCumulVarSoftLowerBoundCosts(
2986  std::vector<IntVar*>* cost_elements) const;
2987  void SetupCumulVarPiecewiseLinearCosts(
2988  std::vector<IntVar*>* cost_elements) const;
2991  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2992  void SetupSlackAndDependentTransitCosts() const;
2994  void CloseModel(bool use_light_propagation);
2995 
2996  void SetOffsetForGlobalOptimizer(int64_t offset) {
2997  global_optimizer_offset_ = std::max(Zero(), offset);
2998  }
3000  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64_t> offsets) {
3002  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
3003  [](int64_t offset) { return std::max(Zero(), offset); });
3004  local_optimizer_offset_for_vehicle_ = std::move(offsets);
3005  }
3006 
3007  std::vector<IntVar*> cumuls_;
3008  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
3009  std::vector<IntVar*> capacity_vars_;
3010  const std::vector<int64_t> vehicle_capacities_;
3011  std::vector<IntVar*> transits_;
3012  std::vector<IntVar*> fixed_transits_;
3015  std::vector<int> class_evaluators_;
3016  std::vector<int64_t> vehicle_to_class_;
3017 #ifndef SWIG
3018  ReverseArcListGraph<int, int> path_precedence_graph_;
3019 #endif
3020  // For every {first_node, second_node, offset} element in node_precedences_,
3021  // if both first_node and second_node are performed, then
3022  // cumuls_[second_node] must be greater than (or equal to)
3023  // cumuls_[first_node] + offset.
3024  std::vector<NodePrecedence> node_precedences_;
3025 
3026  // The transits of a dimension may depend on its cumuls or the cumuls of
3027  // another dimension. There can be no cycles, except for self loops, a
3028  // typical example for this is a time dimension.
3029  const RoutingDimension* const base_dimension_;
3030 
3031  // Values in state_dependent_class_evaluators_ correspond to the evaluators
3032  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
3033  // class.
3034  std::vector<int> state_dependent_class_evaluators_;
3035  std::vector<int64_t> state_dependent_vehicle_to_class_;
3036 
3037  // For each pickup/delivery pair_index for which limits have been set,
3038  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
3039  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
3040  std::vector<PickupToDeliveryLimitFunction>
3041  pickup_to_delivery_limits_per_pair_index_;
3042 
3043  // Used if some vehicle has breaks in this dimension, typically time.
3044  bool break_constraints_are_initialized_ = false;
3045  // clang-format off
3046  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
3047  std::vector<std::vector<std::pair<int64_t, int64_t> > >
3048  vehicle_break_distance_duration_;
3049  // clang-format on
3050  // For each vehicle, stores the part of travel that is made directly
3051  // after (before) the departure (arrival) node of the travel.
3052  // These parts of the travel are non-interruptible, in particular by a break.
3053  std::vector<int> vehicle_pre_travel_evaluators_;
3054  std::vector<int> vehicle_post_travel_evaluators_;
3055 
3056  std::vector<IntVar*> slacks_;
3057  std::vector<IntVar*> dependent_transits_;
3058  std::vector<int64_t> vehicle_span_upper_bounds_;
3059  int64_t global_span_cost_coefficient_;
3060  std::vector<int64_t> vehicle_span_cost_coefficients_;
3061  std::vector<SoftBound> cumul_var_soft_upper_bound_;
3062  std::vector<SoftBound> cumul_var_soft_lower_bound_;
3063  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
3064  RoutingModel* const model_;
3065  const std::string name_;
3066  int64_t global_optimizer_offset_;
3067  std::vector<int64_t> local_optimizer_offset_for_vehicle_;
3069  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
3070  std::unique_ptr<SimpleBoundCosts>
3071  vehicle_quadratic_cost_soft_span_upper_bound_;
3072  friend class RoutingModel;
3074  friend void AppendDimensionCumulFilters(
3075  const std::vector<RoutingDimension*>& dimensions,
3076  const RoutingSearchParameters& parameters, bool filter_objective_cost,
3077  std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3078 
3080 };
3081 
3085  std::vector<IntVar*> variables,
3086  std::vector<int64_t> targets);
3087 
3093  const RoutingSearchParameters& search_parameters,
3094  const Assignment* initial_solution,
3095  Assignment* solution);
3096 
3097 #if !defined(SWIG)
3099  const RoutingModel& routing_model, const RoutingDimension& dimension);
3100 
3101 // A decision builder that monitors solutions, and tries to fix dimension
3102 // variables whose route did not change in the candidate solution.
3103 // Dimension variables are Cumul, Slack and break variables of all dimensions.
3104 // The user must make sure that those variables will be always be fixed at
3105 // solution, typically by composing another DecisionBuilder after this one.
3106 // If this DecisionBuilder returns a non-nullptr value at some node of the
3107 // search tree, it will always return nullptr in the subtree of that node.
3108 // Moreover, the decision will be a simultaneous assignment of the dimension
3109 // variables of unchanged routes on the left branch, and an empty decision on
3110 // the right branch.
3112  RoutingModel* model);
3113 #endif
3114 
3115 } // namespace operations_research
3116 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
Definition: routing.cc:3675
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
Definition: routing.cc:2084
bool VehicleRequiresAResource(int vehicle) const
Definition: routing.h:451
#define CHECK(condition)
Definition: base/logging.h:495
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:239
Status
Status of the search.
Definition: routing.h:213
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:2662
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:934
void Post() override
This method is called when the constraint is processed by the solver.
Definition: routing.cc:6581
int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
Definition: routing.cc:6828
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
Definition: routing.cc:1965
const Assignment * PackCumulsOfOptimizerDimensionsFromAssignment(const Assignment *original_assignment, absl::Duration duration_limit)
For every dimension in the model with an optimizer in local/global_dimension_optimizers_,...
Definition: routing.cc:607
int64_t bound
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1498
int64_t CapSub(int64_t x, int64_t y)
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
Definition: routing.cc:1091
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:911
std::vector< int > required_resource_group_indices
Sorted set of resource groups for which the vehicle requires a resource.
Definition: routing.h:349
int64_t GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Definition: routing.cc:3658
std::vector< int64_t > post_travels
Definition: routing.h:2229
int64_t UnperformedPenaltyOrValue(int64_t default_value, int64_t var_index) const
Same as above except that it returns default_value instead of 0 when penalty is not well defined (def...
Definition: routing.cc:4263
std::function< int64_t(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
Definition: routing.h:2844
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64_t index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
Definition: routing.cc:6763
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1507
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
Definition: routing.h:460
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2529
void AddPickupAndDelivery(int64_t pickup, int64_t delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
Definition: routing.cc:2028
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
int64_t GetSpanCostCoefficientForVehicleClass(RoutingVehicleClassIndex vehicle_class) const
Definition: routing.h:2885
TypeRegulationsConstraint(const RoutingModel &model)
Definition: routing.cc:6548
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Same as above, except that if assignment is not null, it will be used as the initial solution.
Definition: routing.cc:3201
int64_t Next(const Assignment &assignment, int64_t index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
Definition: routing.cc:3941
RoutingCostClassIndex CostClassIndex
Definition: routing.h:235
int64_t GetCumulVarSoftUpperBound(int64_t index) const
Returns the soft upper bound of a cumul variable for a given variable index.
Definition: routing.cc:6820
TypeRegulationsChecker(const RoutingModel &model)
Definition: routing.cc:6356
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2591
int64_t GetArcCostForClass(int64_t from_index, int64_t to_index, int64_t cost_class_index) const
Returns the cost of the segment between two nodes for a given cost class.
Definition: routing.cc:3959
Definition: routing.h:360
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1386
void SetSpanCostCoefficientForAllVehicles(int64_t coefficient)
Definition: routing.cc:6728
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
Definition: routing.h:888
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
Definition: routing.cc:7075
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:792
void AssignmentToRoutes(const Assignment &assignment, std::vector< std::vector< int64_t >> *const routes) const
Converts the solution in the given assignment to routes for all vehicles.
Definition: routing.cc:3832
bool HasCumulVarPiecewiseLinearCost(int64_t index) const
Returns true if a piecewise linear cost has been set for a given variable index.
Definition: routing.cc:6758
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
Definition: routing.cc:4157
int vehicle_class
Definition: routing.h:361
int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2905
ResourceGroup * GetResourceGroup(int rg_index) const
Definition: routing.h:719
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:513
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
Definition: routing.cc:2247
Manager for any NodeIndex <-> variable index conversion.
bool operator<(const DimensionCost &cost) const
Definition: routing.h:298
int64_t ShortestTransitionSlack(int64_t node) const
It makes sense to use the function only for self-dependent dimension.
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
Definition: routing.cc:7030
bool AddDimensionWithVehicleTransitAndCapacity(const std::vector< int > &evaluator_indices, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.cc:1144
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:364
ResourceGroup(const RoutingModel *model)
Definition: routing.h:435
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64_t index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:756
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
Definition: routing.cc:7020
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:46
IntVar * VehicleVar(int64_t index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1369
const std::vector< int > & GetPairIndicesOfType(int type) const
Definition: routing.cc:4118
void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy)
Definition: routing.cc:4099
BoundCost & bound_cost(int element)
Definition: routing.h:2531
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:998
bool IsVehicleAllowedForIndex(int vehicle, int64_t index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:825
int AddResourceGroup()
Adds a resource group to the routing model.
Definition: routing.cc:1484
std::pair< int, bool > AddConstantDimension(int64_t value, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:565
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1416
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:338
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1379
const std::string name
void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
Definition: routing.cc:6720
absl::StrongVector< DimensionIndex, int64_t > dimension_evaluator_classes
dimension_evaluators[d]->Run(from, to) is the transit value of arc from->to for a dimension d.
Definition: routing.h:345
int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
Definition: routing.cc:6880
SortedDisjointIntervalList GetAllowedIntervalsInRange(int64_t index, int64_t min_value, int64_t max_value) const
Returns allowed intervals for a given node in a given interval.
Definition: routing.cc:6689
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
Definition: routing.cc:5695
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
Definition: routing.cc:1432
friend void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
int64_t GetArcCostForFirstSolution(int64_t from_index, int64_t to_index) const
Returns the cost of the arc in the context of the first solution strategy.
Definition: routing.cc:3970
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
Definition: routing.cc:5048
const std::vector< int64_t > & GetDisjunctionNodeIndices(DisjunctionIndex index) const
Returns the variable indices of the nodes in the disjunction of index 'index'.
Definition: routing.h:777
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:701
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
Definition: routing.cc:5595
int64_t global_span_cost_coefficient() const
Definition: routing.h:2897
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2592
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2566
int64_t GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:783
MPCallback * callback
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...
Definition: routing.cc:4277
int RegisterTransitMatrix(std::vector< std::vector< int64_t > > values)
Definition: routing.cc:1031
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
Definition: routing.cc:2140
std::vector< std::pair< int64_t, int64_t > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
Definition: routing.cc:1948
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
int AddResource(Attributes attributes, const RoutingDimension *dimension)
Adds a Resource with the given attributes for the corresponding dimension.
Definition: routing.cc:1489
DecisionBuilder * MakeRestoreDimensionValuesForUnchangedRoutes(RoutingModel *model)
Definition: routing.cc:3100
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
Definition: routing.h:714
#define LOG(severity)
Definition: base/logging.h:420
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:509
GRBmodel * model
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
Definition: routing.cc:3106
Checker for type incompatibilities.
Definition: routing.h:2414
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
bool ChainSpanMin(Tasks *tasks)
Propagates a lower bound of the chain span, end[num_chain_tasks] - start[0], to span_min.
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64_t cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
Definition: routing.cc:5675
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:221
A constraint is the main modeling object.
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2562
bool HasMandatoryDisjunctions() const
Returns true if the model contains mandatory disjunctions (ones with kNoPenalty as penalty).
Definition: routing.cc:1933
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1322
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
Definition: routing.cc:6055
std::vector< int64_t > pre_travels
Definition: routing.h:2228
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
Definition: routing.cc:2078
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
Status status() const
Returns the current status of the routing model.
Definition: routing.h:1183
absl::StrongVector< DimensionIndex, int64_t > dimension_capacities
Definition: routing.h:342
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
Definition: routing.cc:1422
int64_t coefficient
int64_t GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2873
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_min
Definition: routing.h:340
int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
Definition: routing.h:1391
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:1096
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulOptimizers() const
Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed.
Definition: routing.h:660
IntVar * FixedTransitVar(int64_t index) const
Definition: routing.h:2583
int64_t Zero()
NOLINT.
const std::vector< IntVar * > & transits() const
Definition: routing.h:2593
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:877
A DecisionBuilder is responsible for creating the search tree.
const RoutingModel::TransitCallback2 & class_transit_evaluator(RoutingVehicleClassIndex vehicle_class) const
Returns the callback evaluating the transit value between two node indices for a given vehicle class.
Definition: routing.h:2652
void FillPathEvaluation(const std::vector< int64_t > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64_t > *values)
Definition: routing.cc:6346
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2830
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2523
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:347
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &pure_transits, const std::vector< int > &dependent_transits, const RoutingDimension *base_dimension, int64_t slack_max, std::vector< int64_t > 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:602
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:217
bool RoutesToAssignment(const std::vector< std::vector< int64_t >> &routes, bool ignore_inactive_indices, bool close_routes, Assignment *const assignment) const
Fills an assignment from a specification of the routes of the vehicles.
Definition: routing.cc:3706
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
Definition: routing.cc:7089
int64_t b
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64_t > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
const std::vector< int64_t > & vehicle_span_cost_coefficients() const
Definition: routing.h:2893
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:953
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
Definition: routing.h:1358
Deliveries must be performed in the same order as pickups.
Definition: routing.h:233
bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
Definition: routing.cc:4004
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:219
#define CHECK_LT(val1, val2)
Definition: base/logging.h:705
Interval variables are often used in scheduling.
static const char kLightElement[]
Constraint types.
Definition: routing.h:2140
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
Definition: routing.cc:5709
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:668
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:1343
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2860
int RegisterTransitCallback(TransitCallback2 callback)
Definition: routing.cc:1058
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
Definition: routing.cc:2098
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
Definition: routing.cc:3135
int64_t GetCumulVarSoftLowerBound(int64_t index) const
Returns the soft lower bound of a cumul variable for a given variable index.
Definition: routing.cc:6872
const std::vector< IntVar * > & ResourceVars(int resource_group) const
Returns vehicle resource variables for a given resource group, such that ResourceVars(r_g)[v] is the ...
Definition: routing.h:1347
const std::vector< int64_t > & vehicle_span_upper_bounds() const
Definition: routing.h:2877
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
Definition: routing.cc:4129
int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index, int64_t 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:2574
int64_t ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
Definition: routing.cc:3388
DecisionBuilder * MakeSetValuesFromTargets(Solver *solver, std::vector< IntVar * > variables, std::vector< int64_t > targets)
A decision builder which tries to assign values to variables as close as possible to target values fi...
Definition: routing.cc:170
IntVar * CumulVar(int64_t index) const
Get the cumul, transit and slack variables for the given node (given as int64_t var index).
Definition: routing.h:2581
int GetDimensionResourceGroupIndex(const RoutingDimension *dimension) const
Returns the index of the resource group attached to the dimension.
Definition: routing.h:731
int64_t max
Definition: alldiff_cst.cc:140
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1514
void AddRequiredTypeAlternativesWhenRemovingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
The following requirements apply when visiting dependent nodes that remove their type from the route,...
Definition: routing.cc:4215
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
Definition: routing.h:914
const std::vector< std::pair< int, int > > & GetPickupIndexPairs(int64_t node_index) const
Returns pairs for which the node is a pickup; the first element of each pair is the index in the pick...
Definition: routing.cc:2066
const std::vector< Resource > & GetResources() const
Definition: routing.h:455
int RegisterUnaryTransitVector(std::vector< int64_t > values)
Registers 'callback' and returns its index.
Definition: routing.cc:1012
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
Definition: routing.cc:3130
double upper_bound
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2826
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1451
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64_t >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
Definition: routing.cc:3819
VisitTypePolicy GetVisitTypePolicy(int64_t index) const
Definition: routing.cc:4123
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
Definition: routing.cc:3537
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
Definition: routing.h:341
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
Definition: routing.cc:4164
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
Definition: routing.cc:1365
bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
Definition: routing.cc:1115
const Resource & GetResource(int resource_index) const
Definition: routing.h:456
int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index, int64_t vehicle) const
Returns the cost of the transit arc between two nodes for a given vehicle.
Definition: routing.cc:3949
static const int64_t kint64max
const int WARNING
Definition: log_severity.h:31
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2432
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Definition: routing.cc:1023
void NotifyVehicleRequiresAResource(int vehicle)
Notifies that the given vehicle index requires a resource from this group if the vehicle is used (i....
Definition: routing.cc:1506
int64_t CapAdd(int64_t x, int64_t y)
bool SolveModelWithSat(const RoutingModel &model, const RoutingSearchParameters &search_parameters, const Assignment *initial_solution, Assignment *solution)
Attempts to solve the model using the cp-sat solver.
int position_of_last_type_on_vehicle_up_to_visit
Position of the last node of policy TYPE_ON_VEHICLE_UP_TO_VISIT visited on the route.
Definition: routing.h:2382
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenAddingType(int type) const
Returns the set of requirement alternatives when adding the given type.
Definition: routing.cc:4246
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:231
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
Definition: routing.cc:1050
RoutingDimensionIndex DimensionIndex
Definition: routing.h:236
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
Definition: routing.cc:3684
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1398
std::vector< int64_t > min_travels
Definition: routing.h:2226
void AddIntervalToAssignment(IntervalVar *const interval)
Definition: routing.cc:5713
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
Definition: routing.cc:2093
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64_t index)
Sets the vehicles which can visit a given node.
Definition: routing.cc:2019
void SetVehicleUsedWhenEmpty(bool is_used, int vehicle)
Definition: routing.h:1083
#define DCHECK_NE(val1, val2)
Definition: base/logging.h:891
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
Checker for type requirements.
Definition: routing.h:2430
int64_t GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2881
A Resource sets attributes (costs/constraints) for a set of dimensions.
Definition: routing.h:416
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64_t node_index) const
Same as above for deliveries.
Definition: routing.cc:2072
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:215
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:1036
std::vector< int > dimensions
bool IsStart(int64_t index) const
Returns true if 'index' represents the first node of a route.
Definition: routing.cc:3927
double lower_bound
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:1340
This class represents a sorted list of disjoint, closed intervals.
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
Definition: routing.h:706
int64_t GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
Definition: routing.cc:3650
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
Definition: routing.cc:3532
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenRemovingType(int type) const
Returns the set of requirement alternatives when removing the given type.
Definition: routing.cc:4253
std::function< StateDependentTransit(int64_t, int64_t)> VariableIndexEvaluator2
Definition: routing.h:266
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1386
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
Creates a cached StateDependentTransit from an std::function.
Definition: routing.cc:1353
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...
Definition: routing.cc:2425
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
Definition: routing.h:904
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2597
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
bool HasCumulVarSoftUpperBound(int64_t index) const
Returns true if a soft upper bound has been set for a given variable index.
Definition: routing.cc:6815
void AddTemporalTypeIncompatibility(int type1, int type2)
Definition: routing.cc:4147
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
Definition: routing.cc:1655
void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor, int64_t quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
Definition: routing.cc:1560
Assignment * MutablePreAssignment()
Definition: routing.h:1208
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2669
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1449
int GetVehicleOfClass(VehicleClassIndex vehicle_class) const
Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class.
Definition: routing.h:1435
int64_t fixed_cost
Definition: routing.h:362
int64_t capacity
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:2915
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:1101
const std::vector< SearchMonitor * > & GetSearchMonitors() const
Definition: routing.h:1569
void AddVariableTargetToFinalizer(IntVar *var, int64_t target)
Add a variable to set the closest possible to the target value in the solution finalizer.
Definition: routing.cc:5688
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:237
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:227
int index
Definition: pack.cc:509
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
Definition: routing.cc:3125
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2815
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:480
void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex(int64_t index, int64_t 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:764
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:2256
An Assignment is a variable -> domains mapping, used to report solutions to the user.
int num_type_removed_from_vehicle
Number of ADDED_TYPE_REMOVED_FROM_VEHICLE (effectively removing a type from the route) and TYPE_SIMUL...
Definition: routing.h:2377
CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1407
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:1539
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1410
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const
Definition: routing.h:1429
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1424
A BaseObject is the root of all reversibly allocated objects.
std::function< int64_t(int64_t, int64_t)> RoutingTransitCallback2
Definition: routing_types.h:43
std::pair< int, bool > AddConstantDimensionWithSlack(int64_t value, int64_t capacity, int64_t 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...
Definition: routing.cc:1194
The class IntVar is a subset of IntExpr.
bool CheckVehicle(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
Definition: routing.cc:6359
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:894
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:906
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:380
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:2645
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
Definition: routing.h:395
std::pair< int, bool > AddVectorDimension(std::vector< int64_t > values, int64_t 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; ...
Definition: routing.cc:1205
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,...
Definition: routing.cc:4172
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2926
bool IsVehicleUsedWhenEmpty(int vehicle) const
Definition: routing.h:1088
static const int64_t kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:476
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:334
bool HasCumulVarSoftLowerBound(int64_t index) const
Returns true if a soft lower bound has been set for a given variable index.
Definition: routing.cc:6867
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1456
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:2148
bool DistanceDuration(Tasks *tasks)
Propagates distance_duration constraints, if any.
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:1207
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:294
IntVar * ApplyLocks(const std::vector< int64_t > &locks)
Applies a lock chain to the next search.
Definition: routing.cc:3623
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:672
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
void AddNodePrecedence(int64_t first_node, int64_t second_node, int64_t offset)
Definition: routing.h:2868
size_type size() const
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2594
int64_t cost
int64_t GetTransitValue(int64_t from_index, int64_t to_index, int64_t vehicle) const
Returns the transition value for a given pair of nodes (as var index); this value is the one taken by...
Definition: routing.cc:6683
std::vector< std::vector< int64_t > > GetRoutesFromAssignment(const Assignment &assignment)
Converts the solution in the given assignment to routes for all vehicles.
Definition: routing.cc:3866
virtual bool HasRegulationsToCheck() const =0
void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor, int64_t quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
Definition: routing.cc:1552
RoutingIndexPairs IndexPairs
Definition: routing.h:245
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:263
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:484
std::vector< std::vector< std::pair< int64_t, int64_t > > > GetCumulBounds(const Assignment &solution_assignment, const RoutingDimension &dimension)
Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maxi...
Definition: routing.cc:4351
bool used_when_empty
Whether or not the vehicle is used when empty.
Definition: routing.h:327
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1528
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:379
#define DCHECK(condition)
Definition: base/logging.h:889
int64_t GetFirstPossibleGreaterOrEqualValueForNode(int64_t index, int64_t min_value) const
Returns the smallest value outside the forbidden intervals of node 'index' that is greater than or eq...
Definition: routing.h:2605
BoundCost bound_cost(int element) const
Definition: routing.h:2532
const std::vector< std::pair< int64_t, int64_t > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
Definition: routing.cc:7069
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
Definition: routing.cc:7047
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
We call domain any subset of Int64 = [kint64min, kint64max].
std::function< int64_t(int64_t)> RoutingTransitCallback1
Definition: routing_types.h:42
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1426
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.cc:676
int vehicle_to_class(int vehicle) const
Definition: routing.h:2673
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1516
RoutingIndexPair IndexPair
Definition: routing.h:244
void SetFixedCostOfVehicle(int64_t cost, int vehicle)
Sets the fixed cost of one vehicle route.
Definition: routing.cc:1546
const std::vector< int > & GetVehiclesRequiringAResource() const
Definition: routing.h:447
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.cc:1134
Model, model parameters or flags are not valid.
Definition: routing.h:223
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:890
const ResourceGroup::Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
Definition: routing.cc:1458
void SetMaximumNumberOfActiveVehicles(int max_active_vehicles)
Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an emp...
Definition: routing.h:1032
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:881
void SetGlobalSpanCostCoefficient(int64_t coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
Definition: routing.cc:6734
void InitialPropagate() override
This method performs the initial propagation of the constraint.
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
Definition: routing.cc:885
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2863
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the set of same-vehicle requirement alternatives for the given type.
Definition: routing.cc:4238
std::vector< std::pair< int64_t, int64_t > > distance_duration
Definition: routing.h:2165
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:240
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2494
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64_t(int64_t)> initializer)
The next few members are in the public section only for testing purposes.
bool HasMaxCardinalityConstrainedDisjunctions() const
Returns true if the model contains at least one disjunction which is constrained by its max_cardinali...
Definition: routing.cc:1940
const int64_t limit_
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:325
void SetFixedCostOfAllVehicles(int64_t cost)
Sets the fixed cost of all vehicle routes.
Definition: routing.cc:1535
void Post() override
This method is called when the constraint is processed by the solver.
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:306
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
Definition: routing.cc:1437
int64_t GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
Definition: routing.cc:2144
void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound, int64_t coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
Definition: routing.cc:6857
void AddSoftSameVehicleConstraint(const std::vector< int64_t > &indices, int64_t cost)
Adds a soft constraint to force a set of variable indices to be on the same vehicle.
Definition: routing.cc:2007
Struct used to sort and store vehicles by their type.
Definition: routing.h:359
int num_type_added_to_vehicle
Number of TYPE_ADDED_TO_VEHICLE and TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED node type policies seen on ...
Definition: routing.h:2371
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:956
const std::vector< int > & GetSingleNodesOfType(int type) const
Definition: routing.cc:4113
The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added a...
Definition: routing.h:919
bool TypeCurrentlyOnRoute(int type, int pos) const
Returns true iff there's at least one instance of the given type on the route when scanning the route...
Definition: routing.cc:6434
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2943
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.cc:680
IntVar * SlackVar(int64_t index) const
Definition: routing.h:2586
Collection of objects used to extend the Constraint Solver library.
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:272
int VehicleIndex(int64_t 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:1329
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...
Definition: routing.cc:1521
void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration, int vehicle)
With breaks supposed to be consecutive, this forces the distance between breaks of size at least mini...
Definition: routing.cc:7053
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:312
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
Definition: routing.cc:4138
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:323
void SetCumulVarPiecewiseLinearCost(int64_t index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
Definition: routing.cc:6739
int64_t GetGlobalOptimizerOffset() const
Definition: routing.h:2901
bool TypeOccursOnRoute(int type) const
Returns true iff any occurrence of the given type was seen on the route, i.e.
Definition: routing.cc:6428
SatParameters parameters
IntVar * VehicleRouteConsideredVar(int vehicle) const
Returns the variable specifying whether or not the given vehicle route is considered for costs and co...
Definition: routing.h:1364
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int vehicle_class
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:651
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1518
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
Definition: routing.cc:7034
void SetQuadraticCostSoftSpanUpperBoundForVehicle(SimpleBoundCosts::BoundCost bound_cost, int vehicle)
If the span of vehicle on this dimension is larger than bound, the cost will be increased by cost * (...
Definition: routing.h:2933
int GetVisitType(int64_t index) const
Definition: routing.cc:4108
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:2164
int64_t GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
Definition: routing.cc:1541
RoutingModel::VisitTypePolicy VisitTypePolicy
Definition: routing.h:2364
IntVar * var
Definition: expr_array.cc:1874
int RegisterPositiveTransitCallback(TransitCallback2 callback)
Definition: routing.cc:1084
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:1078
bool HasTemporalTypeRequirements() const
Definition: routing.h:1001
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:505
std::pair< int, bool > AddMatrixDimension(std::vector< std::vector< int64_t > > values, int64_t 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...
Definition: routing.cc:1214
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:261
void AddRequiredTypeAlternativesWhenAddingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_T...
Definition: routing.cc:4194
const Assignment * SolveFromAssignmentsWithParameters(const std::vector< const Assignment * > &assignments, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Same as above but will try all assignments in order as first solutions until one succeeds.
Definition: routing.cc:3208
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1326
A structure to hold tasks described by their features.
Definition: routing.h:2155
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
Definition: routing_flow.cc:55
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1501
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
Definition: routing.cc:3666
bool ChainSpanMinDynamic(Tasks *tasks)
Computes a lower bound of the span of the chain, taking into account only the first nonchain task.
void AppendTasksFromPath(const std::vector< int64_t > &path, const TravelBounds &travel_bounds, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:238
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:1309
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
Definition: routing.cc:3931
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
Definition: routing.cc:6441
void InitialPropagate() override
This method performs the initial propagation of the constraint.
Definition: routing.cc:6596
bool ApplyLocksToAllVehicles(const std::vector< std::vector< int64_t >> &locks, bool close_routes)
Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for rout...
Definition: routing.cc:3644
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
Definition: routing.cc:5699
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.cc:1125
const std::vector< int > & GetDimensionResourceGroupIndices(const RoutingDimension *dimension) const
Returns the indices of resource groups for this dimension.
Definition: routing.cc:1513
std::vector< int64_t > max_travels
Definition: routing.h:2227
Local Search Filters are used for fast neighbor pruning.
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
DisjunctionIndex AddDisjunction(const std::vector< int64_t > &indices, int64_t penalty=kNoPenalty, int64_t max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
Definition: routing.cc:1917
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
Definition: routing.cc:6991
void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound, int64_t coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
Definition: routing.cc:6805
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2640
int64_t value
IntervalVar * interval
Definition: resource.cc:100
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...
Definition: routing.cc:3350
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
Definition: routing.cc:2033
int64_t GetLastPossibleLessOrEqualValueForNode(int64_t index, int64_t max_value) const
Returns the largest value outside the forbidden intervals of node 'index' that is less than or equal ...
Definition: routing.h:2624
std::pair< std::vector< int64_t >, std::vector< int64_t > > RoutingIndexPair
Definition: routing_types.h:45
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:1007
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
Definition: routing.cc:1374
const std::vector< int64_t > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:1075
Class to arrange indices by by their distance and their angles from the depot.
void InitializeCheck(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
Definition: routing.cc:6403
double distance
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_max
Definition: routing.h:339
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2946
IntVar * ActiveVar(int64_t index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1355
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
Definition: routing.cc:1528
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:893
IntVar * TransitVar(int64_t index) const
Definition: routing.h:2582
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:29
std::string DebugString() const override
Definition: routing.h:2259
int64_t Start(int vehicle) const
Model inspection.
Definition: routing.h:1320
int64_t a
IntVar * ResourceVar(int vehicle, int resource_group) const
Returns the resource variable for the given vehicle index in the given resource group.
Definition: routing.h:1373
int64_t UnperformedPenalty(int64_t var_index) const
Get the "unperformed" penalty of a node.
Definition: routing.cc:4259
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulMPOptimizers() const
Definition: routing.h:664
int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:788