OR-Tools  9.1
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"
193 
194 namespace operations_research {
195 
196 class GlobalDimensionCumulOptimizer;
197 class LocalDimensionCumulOptimizer;
198 class LocalSearchPhaseParameters;
199 #ifndef SWIG
200 class IndexNeighborFinder;
201 class IntVarFilteredDecisionBuilder;
202 #endif
203 class RoutingDimension;
204 #ifndef SWIG
206 class SweepArranger;
207 #endif
208 
210  public:
212  enum Status {
223  };
224 
233  };
234  typedef RoutingCostClassIndex CostClassIndex;
235  typedef RoutingDimensionIndex DimensionIndex;
236  typedef RoutingDisjunctionIndex DisjunctionIndex;
237  typedef RoutingVehicleClassIndex VehicleClassIndex;
240 
241 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
242 #if !defined(SWIG)
245 #endif // SWIG
246 
247 #if !defined(SWIG)
248  struct StateDependentTransit {
263  };
264  typedef std::function<StateDependentTransit(int64_t, int64_t)>
266 #endif // SWIG
267 
268 #if !defined(SWIG)
269  struct CostClass {
272 
287 
293  struct DimensionCost {
297  bool operator<(const DimensionCost& cost) const {
298  if (transit_evaluator_class != cost.transit_evaluator_class) {
299  return transit_evaluator_class < cost.transit_evaluator_class;
300  }
301  return cost_coefficient < cost.cost_coefficient;
302  }
303  };
304  std::vector<DimensionCost>
306 
309 
311  static bool LessThan(const CostClass& a, const CostClass& b) {
312  if (a.evaluator_index != b.evaluator_index) {
313  return a.evaluator_index < b.evaluator_index;
314  }
315  return a.dimension_transit_evaluator_class_and_cost_coefficient <
316  b.dimension_transit_evaluator_class_and_cost_coefficient;
317  }
318  };
319 
320  struct VehicleClass {
324  int64_t fixed_cost;
329  // TODO(user): Find equivalent start/end nodes wrt dimensions and
330  // callbacks.
345 
347  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
348  };
349 #endif // defined(SWIG)
350 
357  int64_t fixed_cost;
358 
359  bool operator<(const VehicleClassEntry& other) const {
360  return std::tie(fixed_cost, vehicle_class) <
361  std::tie(other.fixed_cost, other.vehicle_class);
362  }
363  };
364 
365  int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
366 
367  int Type(int vehicle) const {
368  DCHECK_LT(vehicle, type_index_of_vehicle.size());
369  return type_index_of_vehicle[vehicle];
370  }
371 
372  std::vector<int> type_index_of_vehicle;
373  // clang-format off
374  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
375  std::vector<std::deque<int> > vehicles_per_vehicle_class;
376  // clang-format on
377  };
378 
379 #ifndef SWIG
380  class ResourceGroup {
391  public:
393  class Attributes {
394  public:
395  Attributes();
397 
398  const Domain& start_domain() const { return start_domain_; }
399  const Domain& end_domain() const { return end_domain_; }
400 
401  private:
405  Domain start_domain_;
407  Domain end_domain_;
408  };
409 
411  class Resource {
412  public:
414  const RoutingDimension* dimension) const;
415 
416  private:
417  explicit Resource(const RoutingModel* model) : model_(model) {}
418 
419  void SetDimensionAttributes(Attributes attributes,
420  const RoutingDimension* dimension);
421  const Attributes& GetDefaultAttributes() const;
422 
423  const RoutingModel* const model_;
424  absl::flat_hash_map<DimensionIndex, Attributes> dimension_attributes_;
425 
426  friend class ResourceGroup;
427  };
428 
429  explicit ResourceGroup(const RoutingModel* model) : model_(model) {}
430 
433  void AddResource(Attributes attributes, const RoutingDimension* dimension);
434 
435  const std::vector<Resource>& GetResources() const { return resources_; }
436  const absl::flat_hash_set<DimensionIndex>& GetAffectedDimensionIndices()
437  const {
438  return affected_dimension_indices_;
439  }
440  int Size() const { return resources_.size(); }
441 
442  private:
443  const RoutingModel* const model_;
444  std::vector<Resource> resources_;
446  absl::flat_hash_set<DimensionIndex> affected_dimension_indices_;
447  };
448 #endif // SWIG
449 
451  static const int64_t kNoPenalty;
452 
456 
460 
464  explicit RoutingModel(const RoutingIndexManager& index_manager);
465  RoutingModel(const RoutingIndexManager& index_manager,
467  ~RoutingModel();
468 
470  int RegisterUnaryTransitVector(std::vector<int64_t> values);
473 
475  std::vector<std::vector<int64_t> /*needed_for_swig*/> values);
478 
480  const TransitCallback2& TransitCallback(int callback_index) const {
481  CHECK_LT(callback_index, transit_evaluators_.size());
482  return transit_evaluators_[callback_index];
483  }
484  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
485  CHECK_LT(callback_index, unary_transit_evaluators_.size());
486  return unary_transit_evaluators_[callback_index];
487  }
489  int callback_index) const {
490  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
491  return state_dependent_transit_evaluators_[callback_index];
492  }
493 
495 
507 
516  bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity,
517  bool fix_start_cumul_to_zero, const std::string& name);
519  const std::vector<int>& evaluator_indices, int64_t slack_max,
520  int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
521  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max,
522  std::vector<int64_t> vehicle_capacities,
523  bool fix_start_cumul_to_zero,
524  const std::string& name);
526  const std::vector<int>& evaluator_indices, int64_t slack_max,
527  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
528  const std::string& name);
537  std::pair<int, bool> AddConstantDimensionWithSlack(
538  int64_t value, int64_t capacity, int64_t slack_max,
539  bool fix_start_cumul_to_zero, const std::string& name);
540  std::pair<int, bool> AddConstantDimension(int64_t value, int64_t capacity,
541  bool fix_start_cumul_to_zero,
542  const std::string& name) {
544  fix_start_cumul_to_zero, name);
545  }
555  std::pair<int, bool> AddVectorDimension(std::vector<int64_t> values,
556  int64_t capacity,
557  bool fix_start_cumul_to_zero,
558  const std::string& name);
568  std::pair<int, bool> AddMatrixDimension(
569  std::vector<std::vector<int64_t> /*needed_for_swig*/> values,
570  int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
578  const std::vector<int>& pure_transits,
579  const std::vector<int>& dependent_transits,
580  const RoutingDimension* base_dimension, int64_t slack_max,
581  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
582  const std::string& name) {
583  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
584  pure_transits, dependent_transits, base_dimension, slack_max,
585  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
586  }
587 
590  const std::vector<int>& transits, const RoutingDimension* base_dimension,
591  int64_t slack_max, std::vector<int64_t> vehicle_capacities,
592  bool fix_start_cumul_to_zero, const std::string& name);
595  int transit, const RoutingDimension* base_dimension, int64_t slack_max,
596  int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
597  const std::string& name);
599  int pure_transit, int dependent_transit,
600  const RoutingDimension* base_dimension, int64_t slack_max,
601  int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
602  const std::string& name);
603 
606  const std::function<int64_t(int64_t)>& f, int64_t domain_start,
607  int64_t domain_end);
608 
619  std::vector<IntVar*> spans,
620  std::vector<IntVar*> total_slacks);
621 
623  // TODO(user): rename.
624  std::vector<std::string> GetAllDimensionNames() const;
626  const std::vector<RoutingDimension*>& GetDimensions() const {
627  return dimensions_.get();
628  }
630  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
631  // clang-format off
634  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
636  return global_dimension_optimizers_;
637  }
638  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
640  return global_dimension_mp_optimizers_;
641  }
642  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
644  return local_dimension_optimizers_;
645  }
646  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
648  return local_dimension_mp_optimizers_;
649  }
650  // clang-format on
651 
655  const RoutingDimension& dimension) const;
657  const RoutingDimension& dimension) const;
659  const RoutingDimension& dimension) const;
661  const RoutingDimension& dimension) const;
662 
664  bool HasDimension(const std::string& dimension_name) const;
667  const std::string& dimension_name) const;
671  const std::string& dimension_name) const;
676  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
677  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
678  primary_constrained_dimension_ = dimension_name;
679  }
681  const std::string& GetPrimaryConstrainedDimension() const {
682  return primary_constrained_dimension_;
683  }
684 
685 #ifndef SWIG
686  ResourceGroup* const AddResourceGroup();
687  // clang-format off
688  const std::vector<std::unique_ptr<ResourceGroup> >& GetResourceGroups()
689  const {
690  return resource_groups_;
691  }
692 #endif // SWIG
693  // clang-format on
696  const std::vector<int>& GetDimensionResourceGroupIndices(
697  const RoutingDimension* dimension) const;
698 
715  DisjunctionIndex AddDisjunction(const std::vector<int64_t>& indices,
716  int64_t penalty = kNoPenalty,
717  int64_t max_cardinality = 1);
719  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
720  int64_t index) const {
721  return index_to_disjunctions_[index];
722  }
726  template <typename F>
728  int64_t index, int64_t max_cardinality, F f) const {
729  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
730  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
731  for (const int64_t d_index : disjunctions_[disjunction].indices) {
732  f(d_index);
733  }
734  }
735  }
736  }
737 #if !defined(SWIGPYTHON)
738  const std::vector<int64_t>& GetDisjunctionNodeIndices(
741  DisjunctionIndex index) const {
742  return disjunctions_[index].indices;
743  }
744 #endif // !defined(SWIGPYTHON)
747  return disjunctions_[index].value.penalty;
748  }
752  return disjunctions_[index].value.max_cardinality;
753  }
755  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
760  std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions() const;
767 
771  void AddSoftSameVehicleConstraint(const std::vector<int64_t>& indices,
772  int64_t cost);
773 
778  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
779  int64_t index);
780 
782  bool IsVehicleAllowedForIndex(int vehicle, int64_t index) {
783  return allowed_vehicles_[index].empty() ||
784  allowed_vehicles_[index].find(vehicle) !=
785  allowed_vehicles_[index].end();
786  }
787 
802  // TODO(user): Remove this when model introspection detects linked nodes.
803  void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
807  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
808  DisjunctionIndex delivery_disjunction);
809  // clang-format off
813  const std::vector<std::pair<int, int> >&
814  GetPickupIndexPairs(int64_t node_index) const;
816  const std::vector<std::pair<int, int> >&
817  GetDeliveryIndexPairs(int64_t node_index) const;
818  // clang-format on
819 
824  int vehicle);
826  int vehicle) const;
829 
830  int GetNumOfSingletonNodes() const;
831 
832 #ifndef SWIG
833  const IndexPairs& GetPickupAndDeliveryPairs() const {
835  return pickup_delivery_pairs_;
836  }
837  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
839  return pickup_delivery_disjunctions_;
840  }
846  DCHECK(closed_);
847  return implicit_pickup_delivery_pairs_without_alternatives_;
848  }
849 #endif // SWIG
850  enum VisitTypePolicy {
877  };
878  // TODO(user): Support multiple visit types per node?
879  void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy);
880  int GetVisitType(int64_t index) const;
881  const std::vector<int>& GetSingleNodesOfType(int type) const;
882  const std::vector<int>& GetPairIndicesOfType(int type) const;
886  // TODO(user): Reconsider the logic and potentially remove the need to
888  void CloseVisitTypes();
889  int GetNumberOfVisitTypes() const { return num_visit_types_; }
890 #ifndef SWIG
891  const std::vector<std::vector<int>>& GetTopologicallySortedVisitTypes()
892  const {
893  DCHECK(closed_);
894  return topologically_sorted_visit_types_;
895  }
896 #endif // SWIG
897  void AddHardTypeIncompatibility(int type1, int type2);
902  void AddTemporalTypeIncompatibility(int type1, int type2);
904  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
905  int type) const;
906  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
907  int type) const;
911  return has_hard_type_incompatibilities_;
912  }
914  return has_temporal_type_incompatibilities_;
915  }
927  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
933  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
940  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
941  // clang-format off
944  const std::vector<absl::flat_hash_set<int> >&
947  const std::vector<absl::flat_hash_set<int> >&
950  const std::vector<absl::flat_hash_set<int> >&
952  // clang-format on
956  return has_same_vehicle_type_requirements_;
957  }
959  return has_temporal_type_requirements_;
960  }
961 
964  bool HasTypeRegulations() const {
968  }
969 
974  int64_t UnperformedPenalty(int64_t var_index) const;
978  int64_t UnperformedPenaltyOrValue(int64_t default_value,
979  int64_t var_index) const;
983  int64_t GetDepot() const;
984 
989  void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
990  max_active_vehicles_ = max_active_vehicles;
991  }
993  int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
997  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
999  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
1002  void SetFixedCostOfAllVehicles(int64_t cost);
1004  void SetFixedCostOfVehicle(int64_t cost, int vehicle);
1008  int64_t GetFixedCostOfVehicle(int vehicle) const;
1009 
1025  void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor,
1026  int64_t quadratic_cost_factor);
1028  void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor,
1029  int64_t quadratic_cost_factor,
1030  int vehicle);
1031 
1032  const std::vector<int64_t>& GetAmortizedLinearCostFactorOfVehicles() const {
1033  return linear_cost_factor_of_vehicle_;
1034  }
1035  const std::vector<int64_t>& GetAmortizedQuadraticCostFactorOfVehicles()
1036  const {
1037  return quadratic_cost_factor_of_vehicle_;
1038  }
1039 
1040  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
1041  DCHECK_LT(vehicle, vehicles_);
1042  consider_empty_route_costs_[vehicle] = consider_costs;
1043  }
1044 
1045  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
1046  DCHECK_LT(vehicle, vehicles_);
1047  return consider_empty_route_costs_[vehicle];
1048  }
1049 
1052 #ifndef SWIG
1054  return first_solution_evaluator_;
1055  }
1056 #endif
1059  first_solution_evaluator_ = std::move(evaluator);
1060  }
1063  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
1065  void AddSearchMonitor(SearchMonitor* const monitor);
1069  void AddAtSolutionCallback(std::function<void()> callback);
1074  void AddVariableMinimizedByFinalizer(IntVar* var);
1077  void AddVariableMaximizedByFinalizer(IntVar* var);
1080  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64_t cost);
1083  void AddVariableTargetToFinalizer(IntVar* var, int64_t target);
1090  void CloseModel();
1094  const RoutingSearchParameters& search_parameters);
1101  const Assignment* Solve(const Assignment* assignment = nullptr);
1109  const Assignment* SolveWithParameters(
1110  const RoutingSearchParameters& search_parameters,
1111  std::vector<const Assignment*>* solutions = nullptr);
1114  const Assignment* SolveFromAssignmentWithParameters(
1115  const Assignment* assignment,
1116  const RoutingSearchParameters& search_parameters,
1117  std::vector<const Assignment*>* solutions = nullptr);
1120  const Assignment* SolveFromAssignmentsWithParameters(
1121  const std::vector<const Assignment*>& assignments,
1122  const RoutingSearchParameters& search_parameters,
1123  std::vector<const Assignment*>* solutions = nullptr);
1130  Assignment* target_assignment, const RoutingModel* source_model,
1131  const Assignment* source_assignment);
1137  // TODO(user): Add support for non-homogeneous costs and disjunctions.
1138  int64_t ComputeLowerBound();
1140  Status status() const { return status_; }
1149  IntVar* ApplyLocks(const std::vector<int64_t>& locks);
1158  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64_t>>& locks,
1159  bool close_routes);
1164  const Assignment* const PreAssignment() const { return preassignment_; }
1165  Assignment* MutablePreAssignment() { return preassignment_; }
1169  bool WriteAssignment(const std::string& file_name) const;
1173  Assignment* ReadAssignment(const std::string& file_name);
1176  Assignment* RestoreAssignment(const Assignment& solution);
1183  const std::vector<std::vector<int64_t>>& routes,
1184  bool ignore_inactive_indices);
1201  bool RoutesToAssignment(const std::vector<std::vector<int64_t>>& routes,
1202  bool ignore_inactive_indices, bool close_routes,
1203  Assignment* const assignment) const;
1207  void AssignmentToRoutes(
1208  const Assignment& assignment,
1209  std::vector<std::vector<int64_t>>* const routes) const;
1214 #ifndef SWIG
1215  std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1216  const Assignment& assignment);
1217 #endif
1218  Assignment* CompactAssignment(const Assignment& assignment) const;
1239  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1241  void AddToAssignment(IntVar* const var);
1254  const Assignment* original_assignment, absl::Duration duration_limit);
1255 #ifndef SWIG
1256  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1259  SweepArranger* sweep_arranger() const;
1260 #endif
1261  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1267  CHECK(filter != nullptr);
1268  if (closed_) {
1269  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1270  }
1271  extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1272  extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1273  }
1274 
1277  int64_t Start(int vehicle) const { return starts_[vehicle]; }
1279  int64_t End(int vehicle) const { return ends_[vehicle]; }
1281  bool IsStart(int64_t index) const;
1283  bool IsEnd(int64_t index) const { return index >= Size(); }
1286  int VehicleIndex(int64_t index) const { return index_to_vehicle_[index]; }
1290  int64_t Next(const Assignment& assignment, int64_t index) const;
1292  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1293 
1294 #if !defined(SWIGPYTHON)
1295  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1300  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1301 #endif
1302  IntVar* NextVar(int64_t index) const { return nexts_[index]; }
1305  IntVar* ActiveVar(int64_t index) const { return active_[index]; }
1309  IntVar* ActiveVehicleVar(int vehicle) const {
1310  return vehicle_active_[vehicle];
1311  }
1314  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1315  return vehicle_costs_considered_[vehicle];
1316  }
1319  IntVar* VehicleVar(int64_t index) const { return vehicle_vars_[index]; }
1321  IntVar* CostVar() const { return cost_; }
1322 
1325  int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1326  int64_t vehicle) const;
1329  return costs_are_homogeneous_across_vehicles_;
1330  }
1333  int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const {
1334  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1335  }
1338  int64_t GetArcCostForFirstSolution(int64_t from_index,
1339  int64_t to_index) const;
1346  int64_t GetArcCostForClass(int64_t from_index, int64_t to_index,
1347  int64_t /*CostClassIndex*/ cost_class_index) const;
1350  DCHECK(closed_);
1351  DCHECK_GE(vehicle, 0);
1352  DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1353  DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1354  return cost_class_index_of_vehicle_[vehicle];
1355  }
1358  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1359  DCHECK(closed_);
1360  if (cost_class_index == kCostClassIndexOfZeroCost) {
1361  return has_vehicle_with_zero_cost_class_;
1362  }
1363  return cost_class_index < cost_classes_.size();
1364  }
1366  int GetCostClassesCount() const { return cost_classes_.size(); }
1369  return std::max(0, GetCostClassesCount() - 1);
1370  }
1372  DCHECK(closed_);
1373  return vehicle_class_index_of_vehicle_[vehicle];
1374  }
1378  DCHECK(closed_);
1379  const RoutingModel::VehicleTypeContainer& vehicle_type_container =
1381  if (vehicle_class.value() >= GetVehicleClassesCount() ||
1382  vehicle_type_container.vehicles_per_vehicle_class[vehicle_class.value()]
1383  .empty()) {
1384  return -1;
1385  }
1386  return vehicle_type_container
1388  .front();
1389  }
1391  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1393  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1394  DCHECK(closed_);
1395  return same_vehicle_groups_[same_vehicle_group_[node]];
1396  }
1397 
1399  DCHECK(closed_);
1400  return vehicle_type_container_;
1401  }
1402 
1421  bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1426  std::string DebugOutputAssignment(
1427  const Assignment& solution_assignment,
1428  const std::string& dimension_to_print) const;
1434 #ifndef SWIG
1435  std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1436  const Assignment& solution_assignment, const RoutingDimension& dimension);
1437 #endif
1438  Solver* solver() const { return solver_.get(); }
1441 
1443  bool CheckLimit() {
1444  DCHECK(limit_ != nullptr);
1445  return limit_->Check();
1446  }
1447 
1449  absl::Duration RemainingTime() const {
1450  DCHECK(limit_ != nullptr);
1451  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1452  }
1453 
1456  int nodes() const { return nodes_; }
1458  int vehicles() const { return vehicles_; }
1460  int64_t Size() const { return nodes_ + vehicles_ - start_end_count_; }
1461 
1465  const RoutingSearchParameters& search_parameters) const;
1467  const RoutingSearchParameters& search_parameters) const;
1471  return automatic_first_solution_strategy_;
1472  }
1473 
1475  bool IsMatchingModel() const;
1476 
1477 #ifndef SWIG
1478  using GetTabuVarsCallback =
1481  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1482 
1483  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1484 #endif // SWIG
1485 
1487  // TODO(user): Find a way to test and restrict the access at the same time.
1500  const RoutingDimension* dimension,
1501  std::function<int64_t(int64_t)> initializer);
1502 #ifndef SWIG
1503  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1508  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1509  std::vector<IntVar*> variables);
1510 #endif
1511  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1525  const RoutingDimension* dimension);
1526 
1527  private:
1529  enum RoutingLocalSearchOperator {
1530  RELOCATE = 0,
1531  RELOCATE_PAIR,
1532  LIGHT_RELOCATE_PAIR,
1533  RELOCATE_NEIGHBORS,
1534  EXCHANGE,
1535  EXCHANGE_PAIR,
1536  CROSS,
1537  CROSS_EXCHANGE,
1538  TWO_OPT,
1539  OR_OPT,
1540  GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1541  LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1542  GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1543  LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1544  RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1545  GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1546  LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1547  RELOCATE_EXPENSIVE_CHAIN,
1548  LIN_KERNIGHAN,
1549  TSP_OPT,
1550  MAKE_ACTIVE,
1551  RELOCATE_AND_MAKE_ACTIVE,
1552  MAKE_ACTIVE_AND_RELOCATE,
1553  MAKE_INACTIVE,
1554  MAKE_CHAIN_INACTIVE,
1555  SWAP_ACTIVE,
1556  EXTENDED_SWAP_ACTIVE,
1557  NODE_PAIR_SWAP,
1558  PATH_LNS,
1559  FULL_PATH_LNS,
1560  TSP_LNS,
1561  INACTIVE_LNS,
1562  EXCHANGE_RELOCATE_PAIR,
1563  RELOCATE_SUBTRIP,
1564  EXCHANGE_SUBTRIP,
1565  LOCAL_SEARCH_OPERATOR_COUNTER
1566  };
1567 
1571  template <typename T>
1572  struct ValuedNodes {
1573  std::vector<int64_t> indices;
1574  T value;
1575  };
1576  struct DisjunctionValues {
1577  int64_t penalty;
1578  int64_t max_cardinality;
1579  };
1580  typedef ValuedNodes<DisjunctionValues> Disjunction;
1581 
1584  struct CostCacheElement {
1590  int index;
1591  CostClassIndex cost_class_index;
1592  int64_t cost;
1593  };
1594 
1596  void Initialize();
1597  void AddNoCycleConstraintInternal();
1598  bool AddDimensionWithCapacityInternal(
1599  const std::vector<int>& evaluator_indices, int64_t slack_max,
1600  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1601  const std::string& name);
1602  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1603  const std::vector<int>& pure_transits,
1604  const std::vector<int>& dependent_transits,
1605  const RoutingDimension* base_dimension, int64_t slack_max,
1606  std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1607  const std::string& name);
1608  bool InitializeDimensionInternal(
1609  const std::vector<int>& evaluator_indices,
1610  const std::vector<int>& state_dependent_evaluator_indices,
1611  int64_t slack_max, bool fix_start_cumul_to_zero,
1612  RoutingDimension* dimension);
1613  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1614 
1642  void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1643 
1644  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1645  void ComputeVehicleClasses();
1653  void ComputeVehicleTypes();
1663  void FinalizeVisitTypes();
1664  // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_.
1665  void TopologicallySortVisitTypes();
1666  int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index,
1667  CostClassIndex cost_class_index) const;
1668  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1669  int node_index,
1670  std::vector<IntVar*>* cost_elements);
1671  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1672  std::vector<IntVar*>* cost_elements);
1673  Assignment* DoRestoreAssignment();
1674  static const CostClassIndex kCostClassIndexOfZeroCost;
1675  int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle) const {
1676  DCHECK_LT(0, vehicles_);
1677  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1678  : kCostClassIndexOfZeroCost)
1679  .value();
1680  }
1681  int64_t GetDimensionTransitCostSum(int64_t i, int64_t j,
1682  const CostClass& cost_class) const;
1684  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1686  void AddPickupAndDeliverySetsInternal(const std::vector<int64_t>& pickups,
1687  const std::vector<int64_t>& deliveries);
1690  IntVar* CreateSameVehicleCost(int vehicle_index);
1693  int FindNextActive(int index, const std::vector<int64_t>& indices) const;
1694 
1697  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1698  int vehicle) const;
1706  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1707  Assignment* compact_assignment) const;
1708 
1709  void QuietCloseModel();
1710  void QuietCloseModelWithParameters(
1711  const RoutingSearchParameters& parameters) {
1712  if (!closed_) {
1714  }
1715  }
1716 
1718  bool SolveMatchingModel(Assignment* assignment,
1719  const RoutingSearchParameters& parameters);
1720 #ifndef SWIG
1721  bool AppendAssignmentIfFeasible(
1723  const Assignment& assignment,
1724  std::vector<std::unique_ptr<Assignment>>* assignments);
1725 #endif
1726  void LogSolution(const RoutingSearchParameters& parameters,
1728  const std::string& description, int64_t solution_cost,
1729  int64_t start_time_ms);
1732  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1733  bool check_compact_assignment) const;
1738  std::string FindErrorInSearchParametersForModel(
1739  const RoutingSearchParameters& search_parameters) const;
1741  void SetupSearch(const RoutingSearchParameters& search_parameters);
1743  // TODO(user): Document each auxiliary method.
1744  Assignment* GetOrCreateAssignment();
1745  Assignment* GetOrCreateTmpAssignment();
1746  RegularLimit* GetOrCreateLimit();
1747  RegularLimit* GetOrCreateLocalSearchLimit();
1748  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1749  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1750  LocalSearchOperator* CreateInsertionOperator();
1751  LocalSearchOperator* CreateMakeInactiveOperator();
1752  template <class T>
1753  LocalSearchOperator* CreateCPOperator(const T& operator_factory) {
1754  return operator_factory(solver_.get(), nexts_,
1756  ? std::vector<IntVar*>()
1757  : vehicle_vars_,
1758  vehicle_start_class_callback_);
1759  }
1760  template <class T>
1761  LocalSearchOperator* CreateCPOperator() {
1762  return CreateCPOperator(absl::bind_front(MakeLocalSearchOperator<T>));
1763  }
1764  template <class T, class Arg>
1765  LocalSearchOperator* CreateOperator(const Arg& arg) {
1766  return solver_->RevAlloc(new T(nexts_,
1768  ? std::vector<IntVar*>()
1769  : vehicle_vars_,
1770  vehicle_start_class_callback_, arg));
1771  }
1772  template <class T>
1773  LocalSearchOperator* CreatePairOperator() {
1774  return CreateOperator<T>(pickup_delivery_pairs_);
1775  }
1776  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1777  LocalSearchOperator* ConcatenateOperators(
1778  const RoutingSearchParameters& search_parameters,
1779  const std::vector<LocalSearchOperator*>& operators) const;
1780  LocalSearchOperator* GetNeighborhoodOperators(
1781  const RoutingSearchParameters& search_parameters) const;
1782  std::vector<LocalSearchFilterManager::FilterEvent>
1783  GetOrCreateLocalSearchFilters(const RoutingSearchParameters& parameters,
1784  bool filter_cost = true);
1785  LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1786  const RoutingSearchParameters& parameters);
1787  std::vector<LocalSearchFilterManager::FilterEvent>
1788  GetOrCreateFeasibilityFilters(const RoutingSearchParameters& parameters);
1789  LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1790  const RoutingSearchParameters& parameters);
1791  LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1792  const RoutingSearchParameters& parameters);
1793  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1794  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1795  void CreateFirstSolutionDecisionBuilders(
1796  const RoutingSearchParameters& search_parameters);
1797  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1798  const RoutingSearchParameters& search_parameters) const;
1799  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1800  const RoutingSearchParameters& parameters) const;
1801  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1802  const RoutingSearchParameters& search_parameters);
1803  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1804  const RoutingSearchParameters& search_parameters);
1805  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1806  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1807  void SetupAssignmentCollector(
1808  const RoutingSearchParameters& search_parameters);
1809  void SetupTrace(const RoutingSearchParameters& search_parameters);
1810  void SetupImprovementLimit(const RoutingSearchParameters& search_parameters);
1811  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1812  bool UsesLightPropagation(
1813  const RoutingSearchParameters& search_parameters) const;
1814  GetTabuVarsCallback tabu_var_callback_;
1815 
1816  // Detects implicit pickup delivery pairs. These pairs are
1817  // non-pickup/delivery pairs for which there exists a unary dimension such
1818  // that the demand d of the implicit pickup is positive and the demand of the
1819  // implicit delivery is equal to -d.
1820  void DetectImplicitPickupAndDeliveries();
1821 
1822  int GetVehicleStartClass(int64_t start) const;
1823 
1824  void InitSameVehicleGroups(int number_of_groups) {
1825  same_vehicle_group_.assign(Size(), 0);
1826  same_vehicle_groups_.assign(number_of_groups, {});
1827  }
1828  void SetSameVehicleGroup(int index, int group) {
1829  same_vehicle_group_[index] = group;
1830  same_vehicle_groups_[group].push_back(index);
1831  }
1832 
1834  std::unique_ptr<Solver> solver_;
1835  int nodes_;
1836  int vehicles_;
1837  int max_active_vehicles_;
1838  Constraint* no_cycle_constraint_ = nullptr;
1840  std::vector<IntVar*> nexts_;
1841  std::vector<IntVar*> vehicle_vars_;
1842  std::vector<IntVar*> active_;
1843  // The following vectors are indexed by vehicle index.
1844  std::vector<IntVar*> vehicle_active_;
1845  std::vector<IntVar*> vehicle_costs_considered_;
1850  std::vector<IntVar*> is_bound_to_end_;
1851  mutable RevSwitch is_bound_to_end_ct_added_;
1853  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1859  // clang-format off
1860  std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1863  dimension_resource_group_indices_;
1864 
1868  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1869  global_dimension_optimizers_;
1870  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1871  global_dimension_mp_optimizers_;
1872  absl::StrongVector<DimensionIndex, int> global_optimizer_index_;
1873  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1874  local_dimension_optimizers_;
1875  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1876  local_dimension_mp_optimizers_;
1877  // clang-format off
1878  absl::StrongVector<DimensionIndex, int> local_optimizer_index_;
1879  std::string primary_constrained_dimension_;
1881  IntVar* cost_ = nullptr;
1882  std::vector<int> vehicle_to_transit_cost_;
1883  std::vector<int64_t> fixed_cost_of_vehicle_;
1884  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1885  bool has_vehicle_with_zero_cost_class_;
1886  std::vector<int64_t> linear_cost_factor_of_vehicle_;
1887  std::vector<int64_t> quadratic_cost_factor_of_vehicle_;
1888  bool vehicle_amortized_cost_factors_set_;
1899  std::vector<bool> consider_empty_route_costs_;
1900 #ifndef SWIG
1902 #endif // SWIG
1903  bool costs_are_homogeneous_across_vehicles_;
1904  bool cache_callbacks_;
1905  mutable std::vector<CostCacheElement> cost_cache_;
1906  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1907 #ifndef SWIG
1909 #endif // SWIG
1910  VehicleTypeContainer vehicle_type_container_;
1911  std::function<int(int64_t)> vehicle_start_class_callback_;
1914  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1916  std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
1918 #ifndef SWIG
1919  std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1920 #endif // SWIG
1921  IndexPairs pickup_delivery_pairs_;
1923  IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
1924  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1925  pickup_delivery_disjunctions_;
1926  // clang-format off
1927  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1928  // vector of pairs {pair_index, pickup_index} such that
1929  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1930  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1931  // Same as above for deliveries.
1932  std::vector<std::vector<std::pair<int, int> > >
1933  index_to_delivery_index_pairs_;
1934  // clang-format on
1935  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1936  // Same vehicle group to which a node belongs.
1937  std::vector<int> same_vehicle_group_;
1938  // Same vehicle node groups.
1939  std::vector<std::vector<int>> same_vehicle_groups_;
1940  // Node visit types
1941  // Variable index to visit type index.
1942  std::vector<int> index_to_visit_type_;
1943  // Variable index to VisitTypePolicy.
1944  std::vector<VisitTypePolicy> index_to_type_policy_;
1945  // clang-format off
1946  std::vector<std::vector<int> > single_nodes_of_type_;
1947  std::vector<std::vector<int> > pair_indices_of_type_;
1948 
1949  std::vector<absl::flat_hash_set<int> >
1950  hard_incompatible_types_per_type_index_;
1951  bool has_hard_type_incompatibilities_;
1952  std::vector<absl::flat_hash_set<int> >
1953  temporal_incompatible_types_per_type_index_;
1954  bool has_temporal_type_incompatibilities_;
1955 
1956  std::vector<std::vector<absl::flat_hash_set<int> > >
1957  same_vehicle_required_type_alternatives_per_type_index_;
1958  bool has_same_vehicle_type_requirements_;
1959  std::vector<std::vector<absl::flat_hash_set<int> > >
1960  required_type_alternatives_when_adding_type_index_;
1961  std::vector<std::vector<absl::flat_hash_set<int> > >
1962  required_type_alternatives_when_removing_type_index_;
1963  bool has_temporal_type_requirements_;
1964  absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
1965  trivially_infeasible_visit_types_to_policies_;
1966 
1967  // Visit types sorted topologically based on required-->dependent requirement
1968  // arcs between the types (if the requirement/dependency graph is acyclic).
1969  // Visit types of the same topological level are sorted in each sub-vector
1970  // by decreasing requirement "tightness", computed as the pair of the two
1971  // following criteria:
1972  //
1973  // 1) How highly *dependent* this type is, determined by
1974  // (total number of required alternative sets for that type)
1975  // / (average number of types in the required alternative sets)
1976  // 2) How highly *required* this type t is, computed as
1977  // SUM_{S required set containing t} ( 1 / |S| ),
1978  // i.e. the sum of reverse number of elements of all required sets
1979  // containing the type t.
1980  //
1981  // The higher these two numbers, the tighter the type is wrt requirements.
1982  std::vector<std::vector<int> > topologically_sorted_visit_types_;
1983  // clang-format on
1984  int num_visit_types_;
1985  // Two indices are equivalent if they correspond to the same node (as given
1986  // to the constructors taking a RoutingIndexManager).
1987  std::vector<int> index_to_equivalence_class_;
1988  std::vector<int> index_to_vehicle_;
1989  std::vector<int64_t> starts_;
1990  std::vector<int64_t> ends_;
1991  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1992  // anymore.
1993  RoutingIndexManager manager_;
1994  int start_end_count_;
1995  // Model status
1996  bool closed_ = false;
1997  Status status_ = ROUTING_NOT_SOLVED;
1998  bool enable_deep_serialization_ = true;
1999 
2000  // Search data
2001  std::vector<DecisionBuilder*> first_solution_decision_builders_;
2002  std::vector<IntVarFilteredDecisionBuilder*>
2003  first_solution_filtered_decision_builders_;
2004  Solver::IndexEvaluator2 first_solution_evaluator_;
2005  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
2007  std::vector<LocalSearchOperator*> local_search_operators_;
2008  std::vector<SearchMonitor*> monitors_;
2009  SolutionCollector* collect_assignments_ = nullptr;
2010  SolutionCollector* collect_one_assignment_ = nullptr;
2011  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
2012  DecisionBuilder* solve_db_ = nullptr;
2013  DecisionBuilder* improve_db_ = nullptr;
2014  DecisionBuilder* restore_assignment_ = nullptr;
2015  DecisionBuilder* restore_tmp_assignment_ = nullptr;
2016  Assignment* assignment_ = nullptr;
2017  Assignment* preassignment_ = nullptr;
2018  Assignment* tmp_assignment_ = nullptr;
2019  std::vector<IntVar*> extra_vars_;
2020  std::vector<IntervalVar*> extra_intervals_;
2021  std::vector<LocalSearchOperator*> extra_operators_;
2022  LocalSearchFilterManager* local_search_filter_manager_ = nullptr;
2023  LocalSearchFilterManager* feasibility_filter_manager_ = nullptr;
2024  LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr;
2025  std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
2026 #ifndef SWIG
2027  std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_cost_pairs_;
2028  std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_target_pairs_;
2029  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
2030  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
2031  std::unique_ptr<SweepArranger> sweep_arranger_;
2032 #endif
2033 
2034  RegularLimit* limit_ = nullptr;
2035  RegularLimit* ls_limit_ = nullptr;
2036  RegularLimit* lns_limit_ = nullptr;
2037  RegularLimit* first_solution_lns_limit_ = nullptr;
2038 
2039  typedef std::pair<int64_t, int64_t> CacheKey;
2040  typedef absl::flat_hash_map<CacheKey, int64_t> TransitCallbackCache;
2041  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
2042  StateDependentTransitCallbackCache;
2043 
2044  std::vector<TransitCallback1> unary_transit_evaluators_;
2045  std::vector<TransitCallback2> transit_evaluators_;
2046  // The following vector stores a boolean per transit_evaluator_, indicating
2047  // whether the transits are all positive.
2048  // is_transit_evaluator_positive_ will be set to true only when registering a
2049  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
2050  // The actual positivity of the transit values will only be checked in debug
2051  // mode, when calling RegisterPositiveTransitCallback().
2052  // Therefore, RegisterPositiveTransitCallback() should only be called when the
2053  // transits are known to be positive, as the positivity of a callback will
2054  // allow some improvements in the solver, but will entail in errors if the
2055  // transits are falsely assumed positive.
2056  std::vector<bool> is_transit_evaluator_positive_;
2057  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
2058  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
2059  state_dependent_transit_evaluators_cache_;
2060 
2061  friend class RoutingDimension;
2064 
2066 };
2067 
2070  public:
2072  static const char kLightElement[];
2073  static const char kLightElement2[];
2074  static const char kRemoveValues[];
2075 };
2076 
2077 #if !defined(SWIG)
2078 class DisjunctivePropagator {
2081  public:
2087  struct Tasks {
2089  std::vector<int64_t> start_min;
2090  std::vector<int64_t> start_max;
2091  std::vector<int64_t> duration_min;
2092  std::vector<int64_t> duration_max;
2093  std::vector<int64_t> end_min;
2094  std::vector<int64_t> end_max;
2095  std::vector<bool> is_preemptible;
2096  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
2097  std::vector<std::pair<int64_t, int64_t>> distance_duration;
2098  int64_t span_min = 0;
2099  int64_t span_max = kint64max;
2100 
2101  void Clear() {
2102  start_min.clear();
2103  start_max.clear();
2104  duration_min.clear();
2105  duration_max.clear();
2106  end_min.clear();
2107  end_max.clear();
2108  is_preemptible.clear();
2109  forbidden_intervals.clear();
2110  distance_duration.clear();
2111  span_min = 0;
2112  span_max = kint64max;
2113  num_chain_tasks = 0;
2114  }
2115  };
2116 
2119  bool Propagate(Tasks* tasks);
2120 
2122  bool Precedences(Tasks* tasks);
2125  bool MirrorTasks(Tasks* tasks);
2127  bool EdgeFinding(Tasks* tasks);
2130  bool DetectablePrecedencesWithChain(Tasks* tasks);
2132  bool ForbiddenIntervals(Tasks* tasks);
2134  bool DistanceDuration(Tasks* tasks);
2137  bool ChainSpanMin(Tasks* tasks);
2142  bool ChainSpanMinDynamic(Tasks* tasks);
2143 
2144  private:
2147  sat::ThetaLambdaTree<int64_t> theta_lambda_tree_;
2149  std::vector<int> tasks_by_start_min_;
2150  std::vector<int> tasks_by_end_max_;
2151  std::vector<int> event_of_task_;
2152  std::vector<int> nonchain_tasks_by_start_max_;
2154  std::vector<int64_t> total_duration_before_;
2155 };
2156 
2158  std::vector<int64_t> min_travels;
2159  std::vector<int64_t> max_travels;
2160  std::vector<int64_t> pre_travels;
2161  std::vector<int64_t> post_travels;
2162 };
2163 
2164 void AppendTasksFromPath(const std::vector<int64_t>& path,
2165  const TravelBounds& travel_bounds,
2166  const RoutingDimension& dimension,
2168 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
2170 void FillPathEvaluation(const std::vector<int64_t>& path,
2171  const RoutingModel::TransitCallback2& evaluator,
2172  std::vector<int64_t>* values);
2173 void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64_t>& path,
2174  const RoutingDimension& dimension,
2175  TravelBounds* travel_bounds);
2176 #endif // !defined(SWIG)
2177 
2189  public:
2190  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
2191  std::string DebugString() const override {
2192  return "GlobalVehicleBreaksConstraint";
2193  }
2194 
2195  void Post() override;
2196  void InitialPropagate() override;
2197 
2198  private:
2199  void PropagateNode(int node);
2200  void PropagateVehicle(int vehicle);
2201  void PropagateMaxBreakDistance(int vehicle);
2202 
2203  const RoutingModel* model_;
2204  const RoutingDimension* const dimension_;
2205  std::vector<Demon*> vehicle_demons_;
2206  std::vector<int64_t> path_;
2207 
2212  void FillPartialPathOfVehicle(int vehicle);
2213  void FillPathTravels(const std::vector<int64_t>& path);
2214 
2225  class TaskTranslator {
2226  public:
2227  TaskTranslator(IntVar* start, int64_t before_start, int64_t after_start)
2228  : start_(start),
2229  before_start_(before_start),
2230  after_start_(after_start) {}
2231  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2232  TaskTranslator() {}
2233 
2234  void SetStartMin(int64_t value) {
2235  if (start_ != nullptr) {
2236  start_->SetMin(CapAdd(before_start_, value));
2237  } else if (interval_ != nullptr) {
2238  interval_->SetStartMin(value);
2239  }
2240  }
2241  void SetStartMax(int64_t value) {
2242  if (start_ != nullptr) {
2243  start_->SetMax(CapAdd(before_start_, value));
2244  } else if (interval_ != nullptr) {
2245  interval_->SetStartMax(value);
2246  }
2247  }
2248  void SetDurationMin(int64_t value) {
2249  if (interval_ != nullptr) {
2250  interval_->SetDurationMin(value);
2251  }
2252  }
2253  void SetEndMin(int64_t value) {
2254  if (start_ != nullptr) {
2255  start_->SetMin(CapSub(value, after_start_));
2256  } else if (interval_ != nullptr) {
2257  interval_->SetEndMin(value);
2258  }
2259  }
2260  void SetEndMax(int64_t value) {
2261  if (start_ != nullptr) {
2262  start_->SetMax(CapSub(value, after_start_));
2263  } else if (interval_ != nullptr) {
2264  interval_->SetEndMax(value);
2265  }
2266  }
2267 
2268  private:
2269  IntVar* start_ = nullptr;
2270  int64_t before_start_;
2271  int64_t after_start_;
2272  IntervalVar* interval_ = nullptr;
2273  };
2274 
2276  std::vector<TaskTranslator> task_translators_;
2277 
2279  DisjunctivePropagator disjunctive_propagator_;
2280  DisjunctivePropagator::Tasks tasks_;
2281 
2283  TravelBounds travel_bounds_;
2284 };
2285 
2287  public:
2288  explicit TypeRegulationsChecker(const RoutingModel& model);
2290 
2291  bool CheckVehicle(int vehicle,
2292  const std::function<int64_t(int64_t)>& next_accessor);
2293 
2294  protected:
2295 #ifndef SWIG
2297 #endif // SWIG
2298 
2315  };
2316 
2321  bool TypeOccursOnRoute(int type) const;
2328  bool TypeCurrentlyOnRoute(int type, int pos) const;
2329 
2330  void InitializeCheck(int vehicle,
2331  const std::function<int64_t(int64_t)>& next_accessor);
2332  virtual void OnInitializeCheck() {}
2333  virtual bool HasRegulationsToCheck() const = 0;
2334  virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2335  int pos) = 0;
2336  virtual bool FinalizeCheck() const { return true; }
2337 
2339 
2340  private:
2341  std::vector<TypePolicyOccurrence> occurrences_of_type_;
2342  std::vector<int64_t> current_route_visits_;
2343 };
2344 
2347  public:
2349  bool check_hard_incompatibilities);
2351 
2352  private:
2353  bool HasRegulationsToCheck() const override;
2354  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2358  bool check_hard_incompatibilities_;
2359 };
2360 
2363  public:
2367 
2368  private:
2369  bool HasRegulationsToCheck() const override;
2370  void OnInitializeCheck() override {
2371  types_with_same_vehicle_requirements_on_route_.clear();
2372  }
2373  // clang-format off
2376  bool CheckRequiredTypesCurrentlyOnRoute(
2377  const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2378  int pos);
2379  // clang-format on
2380  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2381  bool FinalizeCheck() const override;
2382 
2383  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2384 };
2385 
2427  public:
2428  explicit TypeRegulationsConstraint(const RoutingModel& model);
2429 
2430  void Post() override;
2431  void InitialPropagate() override;
2432 
2433  private:
2434  void PropagateNodeRegulations(int node);
2435  void CheckRegulationsOnVehicle(int vehicle);
2436 
2437  const RoutingModel& model_;
2438  TypeIncompatibilityChecker incompatibility_checker_;
2439  TypeRequirementChecker requirement_checker_;
2440  std::vector<Demon*> vehicle_demons_;
2441 };
2442 #if !defined SWIG
2443 class SimpleBoundCosts {
2456  public:
2457  struct BoundCost {
2458  int64_t bound;
2459  int64_t cost;
2460  };
2461  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2462  : bound_costs_(num_bounds, default_bound_cost) {}
2463  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2464  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2465  int Size() { return bound_costs_.size(); }
2466  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
2467  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
2468 
2469  private:
2470  std::vector<BoundCost> bound_costs_;
2471 };
2472 #endif // !defined SWIG
2473 
2491 // TODO(user): Break constraints need to know the service time of nodes
2495  public:
2498  RoutingModel* model() const { return model_; }
2502  int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2503  int64_t vehicle) const;
2506  int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index,
2507  int64_t vehicle_class) const {
2508  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2509  to_index);
2510  }
2513  IntVar* CumulVar(int64_t index) const { return cumuls_[index]; }
2514  IntVar* TransitVar(int64_t index) const { return transits_[index]; }
2515  IntVar* FixedTransitVar(int64_t index) const {
2516  return fixed_transits_[index];
2517  }
2518  IntVar* SlackVar(int64_t index) const { return slacks_[index]; }
2519 
2520 #if !defined(SWIGPYTHON)
2521  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2524  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2525  const std::vector<IntVar*>& transits() const { return transits_; }
2526  const std::vector<IntVar*>& slacks() const { return slacks_; }
2527 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2528  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2530  return forbidden_intervals_;
2531  }
2533  SortedDisjointIntervalList GetAllowedIntervalsInRange(
2534  int64_t index, int64_t min_value, int64_t max_value) const;
2538  int64_t min_value) const {
2539  DCHECK_LT(index, forbidden_intervals_.size());
2541  forbidden_intervals_[index];
2542  const auto first_forbidden_interval_it =
2543  forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2544  if (first_forbidden_interval_it != forbidden_intervals.end() &&
2545  min_value >= first_forbidden_interval_it->start) {
2547  return CapAdd(first_forbidden_interval_it->end, 1);
2548  }
2550  return min_value;
2551  }
2557  int64_t max_value) const {
2558  DCHECK_LT(index, forbidden_intervals_.size());
2560  forbidden_intervals_[index];
2561  const auto last_forbidden_interval_it =
2562  forbidden_intervals.LastIntervalLessOrEqual(max_value);
2563  if (last_forbidden_interval_it != forbidden_intervals.end() &&
2564  max_value <= last_forbidden_interval_it->end) {
2566  return CapSub(last_forbidden_interval_it->start, 1);
2567  }
2569  return max_value;
2570  }
2572  const std::vector<int64_t>& vehicle_capacities() const {
2573  return vehicle_capacities_;
2574  }
2578  return model_->TransitCallback(
2579  class_evaluators_[vehicle_to_class_[vehicle]]);
2580  }
2581 
2585  RoutingVehicleClassIndex vehicle_class) const {
2586  const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2587  DCHECK_NE(vehicle, -1);
2588  return transit_evaluator(vehicle);
2589  }
2590 
2595  int vehicle) const {
2596  return model_->UnaryTransitCallbackOrNull(
2597  class_evaluators_[vehicle_to_class_[vehicle]]);
2598  }
2601  bool AreVehicleTransitsPositive(int vehicle) const {
2602  return model()->is_transit_evaluator_positive_
2603  [class_evaluators_[vehicle_to_class_[vehicle]]];
2604  }
2605  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2606 #endif
2607 #endif
2608  void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle);
2612  void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle);
2627 
2628 #ifndef SWIG
2634  const PiecewiseLinearFunction& cost);
2637  bool HasCumulVarPiecewiseLinearCost(int64_t index) const;
2641  int64_t index) const;
2642 #endif
2643 
2652  void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound,
2653  int64_t coefficient);
2656  bool HasCumulVarSoftUpperBound(int64_t index) const;
2660  int64_t GetCumulVarSoftUpperBound(int64_t index) const;
2664  int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const;
2665 
2675  void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound,
2676  int64_t coefficient);
2679  bool HasCumulVarSoftLowerBound(int64_t index) const;
2683  int64_t GetCumulVarSoftLowerBound(int64_t index) const;
2687  int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const;
2703  // TODO(user): Remove if !defined when routing.i is repaired.
2704 #if !defined(SWIGPYTHON)
2705  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2706  int pre_travel_evaluator,
2707  int post_travel_evaluator);
2708 #endif // !defined(SWIGPYTHON)
2709 
2711  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2712  std::vector<int64_t> node_visit_transits);
2713 
2718  void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration,
2719  int vehicle);
2722  void InitializeBreaks();
2724  bool HasBreakConstraints() const;
2725 #if !defined(SWIGPYTHON)
2729  std::vector<IntervalVar*> breaks, int vehicle,
2730  std::vector<int64_t> node_visit_transits,
2731  std::function<int64_t(int64_t, int64_t)> delays);
2732 
2734  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2735  int vehicle) const;
2738  // clang-format off
2739  const std::vector<std::pair<int64_t, int64_t> >&
2740  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2741  // clang-format on
2742 #endif
2743  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2744  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2745 
2747  const RoutingDimension* base_dimension() const { return base_dimension_; }
2755  int64_t ShortestTransitionSlack(int64_t node) const;
2756 
2758  const std::string& name() const { return name_; }
2759 
2761 #ifndef SWIG
2763  return path_precedence_graph_;
2764  }
2765 #endif // SWIG
2766 
2776  typedef std::function<int64_t(int, int)> PickupToDeliveryLimitFunction;
2777 
2779  PickupToDeliveryLimitFunction limit_function, int pair_index);
2780 
2781  bool HasPickupToDeliveryLimits() const;
2782 #ifndef SWIG
2783  int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2784  int delivery) const;
2785 
2787  int64_t first_node;
2788  int64_t second_node;
2789  int64_t offset;
2790  };
2791 
2793  node_precedences_.push_back(precedence);
2794  }
2795  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2796  return node_precedences_;
2797  }
2798 #endif // SWIG
2799 
2800  void AddNodePrecedence(int64_t first_node, int64_t second_node,
2801  int64_t offset) {
2802  AddNodePrecedence({first_node, second_node, offset});
2803  }
2804 
2805  int64_t GetSpanUpperBoundForVehicle(int vehicle) const {
2806  return vehicle_span_upper_bounds_[vehicle];
2807  }
2808 #ifndef SWIG
2809  const std::vector<int64_t>& vehicle_span_upper_bounds() const {
2810  return vehicle_span_upper_bounds_;
2811  }
2812 #endif // SWIG
2813  int64_t GetSpanCostCoefficientForVehicle(int vehicle) const {
2814  return vehicle_span_cost_coefficients_[vehicle];
2815  }
2816 #ifndef SWIG
2818  RoutingVehicleClassIndex vehicle_class) const {
2819  const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2820  DCHECK_NE(vehicle, -1);
2821  return GetSpanCostCoefficientForVehicle(vehicle);
2822  }
2823 #endif // SWIG
2824 #ifndef SWIG
2825  const std::vector<int64_t>& vehicle_span_cost_coefficients() const {
2826  return vehicle_span_cost_coefficients_;
2827  }
2828 #endif // SWIG
2830  return global_span_cost_coefficient_;
2831  }
2832 
2833  int64_t GetGlobalOptimizerOffset() const {
2834  DCHECK_GE(global_optimizer_offset_, 0);
2835  return global_optimizer_offset_;
2836  }
2837  int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2838  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2839  return 0;
2840  }
2841  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2842  return local_optimizer_offset_for_vehicle_[vehicle];
2843  }
2844 #if !defined SWIG
2848  int vehicle) {
2849  if (!HasSoftSpanUpperBounds()) {
2850  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2851  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2852  }
2853  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2854  }
2855  bool HasSoftSpanUpperBounds() const {
2856  return vehicle_soft_span_upper_bound_ != nullptr;
2857  }
2859  int vehicle) const {
2861  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2862  }
2866  SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2868  vehicle_quadratic_cost_soft_span_upper_bound_ =
2869  absl::make_unique<SimpleBoundCosts>(
2870  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2871  }
2872  vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2873  bound_cost;
2874  }
2876  return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2877  }
2879  int vehicle) const {
2881  return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2882  }
2883 #endif
2884 
2885  private:
2886  struct SoftBound {
2887  IntVar* var;
2888  int64_t bound;
2889  int64_t coefficient;
2890  };
2891 
2892  struct PiecewiseLinearCost {
2893  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2894  IntVar* var;
2895  std::unique_ptr<PiecewiseLinearFunction> cost;
2896  };
2897 
2898  class SelfBased {};
2899  RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2900  const std::string& name,
2901  const RoutingDimension* base_dimension);
2902  RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2903  const std::string& name, SelfBased);
2904  void Initialize(const std::vector<int>& transit_evaluators,
2905  const std::vector<int>& state_dependent_transit_evaluators,
2906  int64_t slack_max);
2907  void InitializeCumuls();
2908  void InitializeTransits(
2909  const std::vector<int>& transit_evaluators,
2910  const std::vector<int>& state_dependent_transit_evaluators,
2911  int64_t slack_max);
2912  void InitializeTransitVariables(int64_t slack_max);
2914  void SetupCumulVarSoftUpperBoundCosts(
2915  std::vector<IntVar*>* cost_elements) const;
2917  void SetupCumulVarSoftLowerBoundCosts(
2918  std::vector<IntVar*>* cost_elements) const;
2919  void SetupCumulVarPiecewiseLinearCosts(
2920  std::vector<IntVar*>* cost_elements) const;
2923  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2924  void SetupSlackAndDependentTransitCosts() const;
2926  void CloseModel(bool use_light_propagation);
2927 
2928  void SetOffsetForGlobalOptimizer(int64_t offset) {
2929  global_optimizer_offset_ = std::max(Zero(), offset);
2930  }
2932  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64_t> offsets) {
2934  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2935  [](int64_t offset) { return std::max(Zero(), offset); });
2936  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2937  }
2938 
2939  std::vector<IntVar*> cumuls_;
2940  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2941  std::vector<IntVar*> capacity_vars_;
2942  const std::vector<int64_t> vehicle_capacities_;
2943  std::vector<IntVar*> transits_;
2944  std::vector<IntVar*> fixed_transits_;
2947  std::vector<int> class_evaluators_;
2948  std::vector<int64_t> vehicle_to_class_;
2949 #ifndef SWIG
2950  ReverseArcListGraph<int, int> path_precedence_graph_;
2951 #endif
2952  // For every {first_node, second_node, offset} element in node_precedences_,
2953  // if both first_node and second_node are performed, then
2954  // cumuls_[second_node] must be greater than (or equal to)
2955  // cumuls_[first_node] + offset.
2956  std::vector<NodePrecedence> node_precedences_;
2957 
2958  // The transits of a dimension may depend on its cumuls or the cumuls of
2959  // another dimension. There can be no cycles, except for self loops, a
2960  // typical example for this is a time dimension.
2961  const RoutingDimension* const base_dimension_;
2962 
2963  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2964  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2965  // class.
2966  std::vector<int> state_dependent_class_evaluators_;
2967  std::vector<int64_t> state_dependent_vehicle_to_class_;
2968 
2969  // For each pickup/delivery pair_index for which limits have been set,
2970  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2971  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2972  std::vector<PickupToDeliveryLimitFunction>
2973  pickup_to_delivery_limits_per_pair_index_;
2974 
2975  // Used if some vehicle has breaks in this dimension, typically time.
2976  bool break_constraints_are_initialized_ = false;
2977  // clang-format off
2978  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2979  std::vector<std::vector<std::pair<int64_t, int64_t> > >
2980  vehicle_break_distance_duration_;
2981  // clang-format on
2982  // For each vehicle, stores the part of travel that is made directly
2983  // after (before) the departure (arrival) node of the travel.
2984  // These parts of the travel are non-interruptible, in particular by a break.
2985  std::vector<int> vehicle_pre_travel_evaluators_;
2986  std::vector<int> vehicle_post_travel_evaluators_;
2987 
2988  std::vector<IntVar*> slacks_;
2989  std::vector<IntVar*> dependent_transits_;
2990  std::vector<int64_t> vehicle_span_upper_bounds_;
2991  int64_t global_span_cost_coefficient_;
2992  std::vector<int64_t> vehicle_span_cost_coefficients_;
2993  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2994  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2995  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2996  RoutingModel* const model_;
2997  const std::string name_;
2998  int64_t global_optimizer_offset_;
2999  std::vector<int64_t> local_optimizer_offset_for_vehicle_;
3001  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
3002  std::unique_ptr<SimpleBoundCosts>
3003  vehicle_quadratic_cost_soft_span_upper_bound_;
3004  friend class RoutingModel;
3006  friend void AppendDimensionCumulFilters(
3007  const std::vector<RoutingDimension*>& dimensions,
3008  const RoutingSearchParameters& parameters, bool filter_objective_cost,
3009  std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3010 
3012 };
3013 
3017  std::vector<IntVar*> variables,
3018  std::vector<int64_t> targets);
3019 
3025  const RoutingSearchParameters& search_parameters,
3026  const Assignment* initial_solution,
3027  Assignment* solution);
3028 
3029 #if !defined(SWIG)
3031  const RoutingModel& routing_model, const RoutingDimension& dimension);
3032 #endif
3033 
3034 } // namespace operations_research
3035 #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:3200
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
Definition: routing.cc:1874
#define CHECK(condition)
Definition: base/logging.h:491
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:238
Status
Status of the search.
Definition: routing.h:212
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:2594
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:891
void Post() override
This method is called when the constraint is processed by the solver.
Definition: routing.cc:6045
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:6292
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
Definition: routing.cc:1755
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:444
int64_t bound
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1440
int64_t CapSub(int64_t x, int64_t y)
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
Definition: routing.cc:915
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:868
int64_t GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Definition: routing.cc:3183
std::vector< int64_t > post_travels
Definition: routing.h:2161
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:3788
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:2776
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64_t index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
Definition: routing.cc:6227
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1449
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
Definition: routing.h:436
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2461
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:1818
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:2817
TypeRegulationsConstraint(const RoutingModel &model)
Definition: routing.cc:6012
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:2726
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:3466
RoutingCostClassIndex CostClassIndex
Definition: routing.h:234
int64_t GetCumulVarSoftUpperBound(int64_t index) const
Returns the soft upper bound of a cumul variable for a given variable index.
Definition: routing.cc:6284
TypeRegulationsChecker(const RoutingModel &model)
Definition: routing.cc:5820
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2523
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:3484
Definition: routing.h:355
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1210
void SetSpanCostCoefficientForAllVehicles(int64_t coefficient)
Definition: routing.cc:6192
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
Definition: routing.h:845
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
Definition: routing.cc:6539
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:755
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:3357
bool HasCumulVarPiecewiseLinearCost(int64_t index) const
Returns true if a piecewise linear cost has been set for a given variable index.
Definition: routing.cc:6222
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
Definition: routing.cc:3682
int vehicle_class
Definition: routing.h:356
int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2837
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:488
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
Definition: routing.cc:2037
Manager for any NodeIndex <-> variable index conversion.
bool operator<(const DimensionCost &cost) const
Definition: routing.h:297
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:6494
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:968
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:359
ResourceGroup(const RoutingModel *model)
Definition: routing.h:429
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64_t index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:719
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
Definition: routing.cc:6484
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:1319
const std::vector< int > & GetPairIndicesOfType(int type) const
Definition: routing.cc:3643
void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy)
Definition: routing.cc:3624
BoundCost & bound_cost(int element)
Definition: routing.h:2463
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:955
bool IsVehicleAllowedForIndex(int vehicle, int64_t index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:782
std::pair< int, bool > AddConstantDimension(int64_t value, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:540
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1358
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:335
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1321
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:6184
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:342
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:6344
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:6153
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
Definition: routing.cc:5159
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:1256
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:3495
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
Definition: routing.cc:4571
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:740
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:676
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
Definition: routing.cc:5059
int64_t global_span_cost_coefficient() const
Definition: routing.h:2829
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2524
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2498
int64_t GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:746
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:3802
int RegisterTransitMatrix(std::vector< std::vector< int64_t > > values)
Definition: routing.cc:855
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:1930
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:1738
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
Definition: routing.h:688
#define LOG(severity)
Definition: base/logging.h:416
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:484
GRBmodel * model
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
Definition: routing.cc:2631
Checker for type incompatibilities.
Definition: routing.h:2346
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:5139
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:220
A constraint is the main modeling object.
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2494
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1279
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
Definition: routing.cc:5519
std::vector< int64_t > pre_travels
Definition: routing.h:2160
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
Definition: routing.cc:1868
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:1140
absl::StrongVector< DimensionIndex, int64_t > dimension_capacities
Definition: routing.h:339
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
Definition: routing.cc:1246
int64_t coefficient
int64_t GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2805
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:337
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:1333
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:1053
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:635
IntVar * FixedTransitVar(int64_t index) const
Definition: routing.h:2515
int64_t Zero()
NOLINT.
const std::vector< IntVar * > & transits() const
Definition: routing.h:2525
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:834
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:2584
void FillPathEvaluation(const std::vector< int64_t > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64_t > *values)
Definition: routing.cc:5810
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2762
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2455
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:344
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:577
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:216
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:3231
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
Definition: routing.cc:6553
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:2825
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:910
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
Definition: routing.h:1309
Deliveries must be performed in the same order as pickups.
Definition: routing.h:232
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:3529
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:218
#define CHECK_LT(val1, val2)
Definition: base/logging.h:701
Interval variables are often used in scheduling.
static const char kLightElement[]
Constraint types.
Definition: routing.h:2072
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
Definition: routing.cc:5173
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:643
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:1300
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2792
int RegisterTransitCallback(TransitCallback2 callback)
Definition: routing.cc:882
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
Definition: routing.cc:1888
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:2660
int64_t GetCumulVarSoftLowerBound(int64_t index) const
Returns the soft lower bound of a cumul variable for a given variable index.
Definition: routing.cc:6336
const std::vector< int64_t > & vehicle_span_upper_bounds() const
Definition: routing.h:2809
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
Definition: routing.cc:3654
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:2506
int64_t ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
Definition: routing.cc:2913
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:169
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:2513
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:1456
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:3740
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
Definition: routing.h:871
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:1040
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:1856
const std::vector< Resource > & GetResources() const
Definition: routing.h:435
int RegisterUnaryTransitVector(std::vector< int64_t > values)
Registers 'callback' and returns its index.
Definition: routing.cc:836
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
Definition: routing.cc:2655
double upper_bound
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2758
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1393
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64_t >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
Definition: routing.cc:3344
VisitTypePolicy GetVisitTypePolicy(int64_t index) const
Definition: routing.cc:3648
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:3062
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
Definition: routing.h:338
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
Definition: routing.cc:3689
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
Definition: routing.cc:1189
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1314
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:939
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:3474
static const int64_t kint64max
const int WARNING
Definition: log_severity.h:31
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2364
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Definition: routing.cc:847
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:2314
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:3771
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:230
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:1045
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
Definition: routing.cc:874
RoutingDimensionIndex DimensionIndex
Definition: routing.h:235
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
Definition: routing.cc:3209
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1222
std::vector< int64_t > min_travels
Definition: routing.h:2158
void AddIntervalToAssignment(IntervalVar *const interval)
Definition: routing.cc:5177
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
Definition: routing.cc:1883
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64_t index)
Sets the vehicles which can visit a given node.
Definition: routing.cc:1809
#define DCHECK_NE(val1, val2)
Definition: base/logging.h:887
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:2362
int64_t GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2813
A Resource sets attributes (costs/constraints) for a set of dimensions.
Definition: routing.h:411
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64_t node_index) const
Same as above for deliveries.
Definition: routing.cc:1862
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:214
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:993
bool IsStart(int64_t index) const
Returns true if 'index' represents the first node of a route.
Definition: routing.cc:3452
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:1297
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:681
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:3175
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:3057
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:3778
std::function< StateDependentTransit(int64_t, int64_t)> VariableIndexEvaluator2
Definition: routing.h:265
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1328
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:1177
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:2215
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
Definition: routing.h:861
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2529
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:6279
void AddTemporalTypeIncompatibility(int type1, int type2)
Definition: routing.cc:3672
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
Definition: routing.cc:1470
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:1375
Assignment * MutablePreAssignment()
Definition: routing.h:1165
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2601
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1391
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:1377
int64_t fixed_cost
Definition: routing.h:357
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:2847
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:1058
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:5152
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:236
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:226
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:2650
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2747
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:455
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:727
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:2188
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:2309
CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1349
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:1481
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
Definition: routing.cc:1234
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const
Definition: routing.h:1371
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1366
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:1018
The class IntVar is a subset of IntExpr.
bool CheckVehicle(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
Definition: routing.cc:5823
#define DCHECK_GE(val1, val2)
Definition: base/logging.h:890
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:863
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:375
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:2577
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
Definition: routing.h:390
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:1029
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:3697
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2858
static const int64_t kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:451
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:331
bool HasCumulVarSoftLowerBound(int64_t index) const
Returns true if a soft lower bound has been set for a given variable index.
Definition: routing.cc:6331
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1398
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:2080
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:1164
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:293
IntVar * ApplyLocks(const std::vector< int64_t > &locks)
Applies a lock chain to the next search.
Definition: routing.cc:3148
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:647
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:2800
size_type size() const
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2526
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:6147
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:3391
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:1367
RoutingIndexPairs IndexPairs
Definition: routing.h:244
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:262
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:459
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:3876
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1470
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:374
#define DCHECK(condition)
Definition: base/logging.h:885
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:2537
BoundCost bound_cost(int element) const
Definition: routing.h:2464
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:6533
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
Definition: routing.cc:6511
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:1368
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.cc:500
int vehicle_to_class(int vehicle) const
Definition: routing.h:2605
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1458
RoutingIndexPair IndexPair
Definition: routing.h:243
void SetFixedCostOfVehicle(int64_t cost, int vehicle)
Sets the fixed cost of one vehicle route.
Definition: routing.cc:1361
void AddResource(Attributes attributes, const RoutingDimension *dimension)
Add a Resource with the given attributes for the corresponding dimension.
Definition: routing.cc:1313
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:958
Model, model parameters or flags are not valid.
Definition: routing.h:222
const Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
Definition: routing.cc:1282
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:989
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:838
ResourceGroup *const AddResourceGroup()
Definition: routing.cc:1308
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:6198
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:709
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2795
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:3763
std::vector< std::pair< int64_t, int64_t > > distance_duration
Definition: routing.h:2097
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:239
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2426
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.
const int64_t limit_
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:324
void SetFixedCostOfAllVehicles(int64_t cost)
Sets the fixed cost of all vehicle routes.
Definition: routing.cc:1350
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:305
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
Definition: routing.cc:1261
int64_t GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
Definition: routing.cc:1934
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:6321
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:1797
Struct used to sort and store vehicles by their type.
Definition: routing.h:354
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:2303
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:913
const std::vector< int > & GetSingleNodesOfType(int type) const
Definition: routing.cc:3638
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:876
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:5898
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2875
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.cc:504
IntVar * SlackVar(int64_t index) const
Definition: routing.h:2518
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:271
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:1286
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:1336
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:6517
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:311
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
Definition: routing.cc:3663
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:322
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:6203
int64_t GetGlobalOptimizerOffset() const
Definition: routing.h:2833
bool TypeOccursOnRoute(int type) const
Returns true iff any occurrence of the given type was seen on the route, i.e.
Definition: routing.cc:5892
SatParameters parameters
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:626
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1460
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
Definition: routing.cc:6498
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:2865
int GetVisitType(int64_t index) const
Definition: routing.cc:3633
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:2096
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:1356
RoutingModel::VisitTypePolicy VisitTypePolicy
Definition: routing.h:2296
IntVar * var
Definition: expr_array.cc:1874
int RegisterPositiveTransitCallback(TransitCallback2 callback)
Definition: routing.cc:908
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:1035
bool HasTemporalTypeRequirements() const
Definition: routing.h:958
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:480
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:1038
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:260
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:3719
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:2733
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1283
A structure to hold tasks described by their features.
Definition: routing.h:2087
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:1443
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
Definition: routing.cc:3191
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:237
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:1266
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
Definition: routing.cc:3456
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
Definition: routing.cc:5905
void InitialPropagate() override
This method performs the initial propagation of the constraint.
Definition: routing.cc:6060
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:3169
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
Definition: routing.cc:5163
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:949
const std::vector< int > & GetDimensionResourceGroupIndices(const RoutingDimension *dimension) const
Returns the indices of resource groups for this dimension.
Definition: routing.cc:1328
std::vector< int64_t > max_travels
Definition: routing.h:2159
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:1721
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:6455
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:6269
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2572
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:2875
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:1823
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:2556
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:964
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:1198
const std::vector< int64_t > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:1032
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:5867
double distance
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_max
Definition: routing.h:336
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2878
IntVar * ActiveVar(int64_t index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1306
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
Definition: routing.cc:1343
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:889
IntVar * TransitVar(int64_t index) const
Definition: routing.h:2514
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:29
std::string DebugString() const override
Definition: routing.h:2191
int64_t Start(int vehicle) const
Model inspection.
Definition: routing.h:1277
int64_t a
int64_t UnperformedPenalty(int64_t var_index) const
Get the "unperformed" penalty of a node.
Definition: routing.cc:3784
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulMPOptimizers() const
Definition: routing.h:639
int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:751