C++ Reference

C++ Reference: Routing

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"
176 #include "ortools/base/integral_types.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
179 #include "ortools/base/map_util.h"
180 #include "ortools/base/strong_vector.h"
187 #include "ortools/graph/graph.h"
188 #include "ortools/sat/theta_tree.h"
189 #include "ortools/util/piecewise_linear_function.h"
190 #include "ortools/util/range_query_function.h"
191 #include "ortools/util/saturated_arithmetic.h"
192 #include "ortools/util/sorted_interval_list.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
205 using util::ReverseArcListGraph;
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 {
261  RangeIntToIntFunction* transit;
262  RangeMinMaxIndexFunction* transit_plus_identity;
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 {
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  }
317  }
318  };
319 
320  struct VehicleClass {
324  int64_t fixed_cost;
329  // TODO(user): Find equivalent start/end nodes wrt dimensions and
330  // callbacks.
335  absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_min;
336  absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_max;
337  absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_min;
338  absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_max;
339  absl::StrongVector<DimensionIndex, int64_t> dimension_capacities;
342  absl::StrongVector<DimensionIndex, int64_t> dimension_evaluator_classes;
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();
396  Attributes(Domain start_domain, Domain end_domain);
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,
466  const RoutingModelParameters& parameters);
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) {
543  return AddConstantDimensionWithSlack(value, capacity, 0,
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)
745  int64_t GetDisjunctionPenalty(DisjunctionIndex index) const {
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;
883  VisitTypePolicy GetVisitTypePolicy(int64_t index) 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);
1242  void AddIntervalToAssignment(IntervalVar* const interval);
1254  const Assignment* original_assignment, absl::Duration duration_limit);
1255 #ifndef SWIG
1256  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1257  void SetSweepArranger(SweepArranger* sweep_arranger);
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  }
1377  int GetVehicleOfClass(VehicleClassIndex vehicle_class) const {
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
1387  .vehicles_per_vehicle_class[vehicle_class.value()]
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_) {
1713  CloseModelWithParameters(parameters);
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_;
1854  absl::StrongVector<DimensionIndex, RoutingDimension*> dimensions_;
1859  // clang-format off
1860  std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1862  absl::StrongVector<DimensionIndex, std::vector<int> >
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
1901  absl::StrongVector<CostClassIndex, CostClass> cost_classes_;
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
1908  absl::StrongVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1909 #endif // SWIG
1910  VehicleTypeContainer vehicle_type_container_;
1911  std::function<int(int64_t)> vehicle_start_class_callback_;
1913  absl::StrongVector<DisjunctionIndex, Disjunction> disjunctions_;
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 
2065  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
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:
2364  explicit TypeRequirementChecker(const RoutingModel& model)
2365  : TypeRegulationsChecker(model) {}
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());
2540  const SortedDisjointIntervalList& forbidden_intervals =
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());
2559  const SortedDisjointIntervalList& forbidden_intervals =
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);
2619  void SetSpanCostCoefficientForAllVehicles(int64_t coefficient);
2626  void SetGlobalSpanCostCoefficient(int64_t coefficient);
2627 
2628 #ifndef SWIG
2629  void SetCumulVarPiecewiseLinearCost(int64_t index,
2634  const PiecewiseLinearFunction& cost);
2637  bool HasCumulVarPiecewiseLinearCost(int64_t index) const;
2640  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
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
2762  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
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 {
2860  DCHECK(HasSoftSpanUpperBounds());
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 
3011  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
3012 };
3013 
3017  std::vector<IntVar*> variables,
3018  std::vector<int64_t> targets);
3019 
3024 bool SolveModelWithSat(const RoutingModel& model,
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_
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...
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
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.
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.
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1440
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.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
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
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...
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
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
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.
int64_t GetSpanCostCoefficientForVehicleClass(RoutingVehicleClassIndex vehicle_class) const
Definition: routing.h:2817
TypeRegulationsConstraint(const RoutingModel &model)
void AppendTasksFromPath(const std::vector< int64_t > &path, const TravelBounds &travel_bounds, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
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...
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.
TypeRegulationsChecker(const RoutingModel &model)
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.h:355
void SetSpanCostCoefficientForAllVehicles(int64_t coefficient)
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)
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.
bool HasCumulVarPiecewiseLinearCost(int64_t index) const
Returns true if a piecewise linear cost has been set for a given variable index.
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...
Manager for any NodeIndex <-> variable index conversion.
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
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.
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)
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...
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
void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy)
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::vector< std::vector< int64_t > > GetRoutesFromAssignment(const Assignment &assignment)
Converts the solution in the given assignment to routes for all vehicles.
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
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.
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
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.
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.
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.
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:459
friend void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
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_,...
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.
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)
int64_t global_span_cost_coefficient() const
Definition: routing.h:2829
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2524
const std::vector< int > & GetSingleNodesOfType(int type) const
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
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...
int RegisterTransitMatrix(std::vector< std::vector< int64_t > > values)
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
Definition: routing.h:688
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:484
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
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 ...
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
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
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1279
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.
std::vector< int64_t > pre_travels
Definition: routing.h:2160
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...
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64_t > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
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.
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.
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64_t >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
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
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.
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 "...
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64_t index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
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
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
Deliveries must be performed in the same order as pickups.
Definition: routing.h:232
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
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,...
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:218
Interval variables are often used in scheduling.
const std::vector< int > & GetDimensionResourceGroupIndices(const RoutingDimension *dimension) const
Returns the indices of resource groups for this dimension.
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
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
static const char kLightElement[]
Constraint types.
Definition: routing.h:2072
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2792
int RegisterTransitCallback(TransitCallback2 callback)
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
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
int64_t GetCumulVarSoftLowerBound(int64_t index) const
Returns the soft lower bound of a cumul variable for a given variable index.
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...
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
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
int64_t ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
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
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
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,...
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
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< Resource > & GetResources() const
Definition: routing.h:435
int RegisterUnaryTransitVector(std::vector< int64_t > values)
Registers 'callback' and returns its index.
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
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
Definition: routing.h:338
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.
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.
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2364
int RegisterUnaryTransitCallback(TransitCallback1 callback)
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
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:230
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:1045
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
RoutingDimensionIndex DimensionIndex
Definition: routing.h:235
std::vector< int64_t > min_travels
Definition: routing.h:2158
void AddIntervalToAssignment(IntervalVar *const interval)
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64_t index)
Sets the vehicles which can visit a given node.
IntVar * ApplyLocks(const std::vector< int64_t > &locks)
Applies a lock chain to the next search.
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
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
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
A Resource sets attributes (costs/constraints) for a set of dimensions.
Definition: routing.h:411
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:214
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:993
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...
bool IsStart(int64_t index) const
Returns true if 'index' represents the first node of a route.
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
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...
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
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...
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.
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
void AddTemporalTypeIncompatibility(int type1, int type2)
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.
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
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.
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...
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
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
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
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...
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
void AddVariableTargetToFinalizer(IntVar *var, int64_t target)
Add a variable to set the closest possible to the target value in the solution finalizer.
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:236
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:226
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2747
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
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
The class IntVar is a subset of IntExpr.
const std::vector< int > & GetPairIndicesOfType(int type) const
bool CheckVehicle(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
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
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.
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,...
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.
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
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
VisitTypePolicy GetVisitTypePolicy(int64_t index) const
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2526
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...
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)...
RoutingIndexPairs IndexPairs
Definition: routing.h:244
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:262
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
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
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64_t node_index) const
Same as above for deliveries.
BoundCost bound_cost(int element) const
Definition: routing.h:2464
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
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)
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.
void AddResource(Attributes attributes, const RoutingDimension *dimension)
Add a Resource with the given attributes for the corresponding dimension.
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenRemovingType(int type) const
Returns the set of requirement alternatives when removing the given type.
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)
Model, model parameters or flags are not valid.
Definition: routing.h:222
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
void SetGlobalSpanCostCoefficient(int64_t coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
void InitialPropagate() override
This method performs the initial propagation of the constraint.
ResourceGroup *const AddResourceGroup()
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2795
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
void FillPathEvaluation(const std::vector< int64_t > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64_t > *values)
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenAddingType(int type) const
Returns the set of requirement alternatives when adding the given type.
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
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.
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
int64_t GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
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.
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.
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
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...
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2875
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...
bool Check() override
This method is called to check the status of the limit.
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...
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,...
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.
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.
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
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
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.
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
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the set of same-vehicle requirement alternatives for the given type.
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,...
RoutingModel::VisitTypePolicy VisitTypePolicy
Definition: routing.h:2296
int RegisterPositiveTransitCallback(TransitCallback2 callback)
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:1035
bool HasTemporalTypeRequirements() const
Definition: routing.h:958
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
const std::vector< std::pair< int64_t, int64_t > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:480
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...
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.
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.
bool ChainSpanMinDynamic(Tasks *tasks)
Computes a lower bound of the span of the chain, taking into account only the first nonchain task.
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'.
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
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; ...
void InitialPropagate() override
This method performs the initial propagation of the constraint.
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...
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
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)
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.
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
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.
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2572
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
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...
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
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
const std::vector< int64_t > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:1032
void InitializeCheck(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
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.
IntVar * TransitVar(int64_t index) const
Definition: routing.h:2514
const Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
std::string DebugString() const override
Definition: routing.h:2191
int64_t Start(int vehicle) const
Model inspection.
Definition: routing.h:1277
int64_t UnperformedPenalty(int64_t var_index) const
Get the "unperformed" penalty of a node.
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