C++ Reference

C++ Reference: Routing

routing.h
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
68 // TODO(user): Add a section on costs (vehicle arc costs, span costs,
69 // disjunctions costs).
70 //
156 
157 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
158 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
159 
160 #include <cstddef>
161 #include <functional>
162 #include <memory>
163 #include <queue>
164 #include <string>
165 #include <utility>
166 #include <vector>
167 
168 #include "absl/container/flat_hash_map.h"
169 #include "absl/container/flat_hash_set.h"
170 #include "absl/hash/hash.h"
171 #include "absl/time/time.h"
172 #include "ortools/base/adjustable_priority_queue-inl.h"
173 #include "ortools/base/adjustable_priority_queue.h"
174 #include "ortools/base/commandlineflags.h"
175 #include "ortools/base/hash.h"
176 #include "ortools/base/int_type_indexed_vector.h"
177 #include "ortools/base/logging.h"
178 #include "ortools/base/macros.h"
182 #include "ortools/constraint_solver/routing_parameters.pb.h"
184 #include "ortools/glop/lp_solver.h"
185 #include "ortools/glop/parameters.pb.h"
186 #include "ortools/graph/graph.h"
187 #include "ortools/lp_data/lp_data.h"
188 #include "ortools/lp_data/lp_types.h"
189 #include "ortools/sat/theta_tree.h"
190 #include "ortools/util/range_query_function.h"
191 #include "ortools/util/sorted_interval_list.h"
192 
193 namespace operations_research {
194 
195 class GlobalDimensionCumulOptimizer;
196 class IntVarFilteredDecisionBuilder;
197 class LocalDimensionCumulOptimizer;
198 class LocalSearchOperator;
199 class RoutingDimension;
200 #ifndef SWIG
201 using util::ReverseArcListGraph;
202 class SweepArranger;
203 #endif
204 struct SweepIndex;
205 
207  public:
209  enum Status {
220  };
221 
230  };
231  typedef RoutingCostClassIndex CostClassIndex;
232  typedef RoutingDimensionIndex DimensionIndex;
233  typedef RoutingDisjunctionIndex DisjunctionIndex;
234  typedef RoutingVehicleClassIndex VehicleClassIndex;
237 
238 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
239 #if !defined(SWIG)
242 #endif // SWIG
243 
244 #if !defined(SWIG)
245  struct StateDependentTransit {
258  RangeIntToIntFunction* transit;
259  RangeMinMaxIndexFunction* transit_plus_identity;
260  };
261  typedef std::function<StateDependentTransit(int64, int64)>
263 #endif // SWIG
264 
265 #if !defined(SWIG)
266  struct CostClass {
269 
284 
290  struct DimensionCost {
294  bool operator<(const DimensionCost& cost) const {
297  }
298  return cost_coefficient < cost.cost_coefficient;
299  }
300  };
301  std::vector<DimensionCost>
303 
306 
308  static bool LessThan(const CostClass& a, const CostClass& b) {
309  if (a.evaluator_index != b.evaluator_index) {
310  return a.evaluator_index < b.evaluator_index;
311  }
314  }
315  };
316 
317  struct VehicleClass {
321  int64 fixed_cost;
326  // TODO(user): Find equivalent start/end nodes wrt dimensions and
327  // callbacks.
332  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_min;
333  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_max;
334  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_min;
335  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_max;
336  gtl::ITIVector<DimensionIndex, int64> dimension_capacities;
339  gtl::ITIVector<DimensionIndex, int64> dimension_evaluator_classes;
342 
344  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
345  };
346 #endif // defined(SWIG)
347 
349  static const int64 kNoPenalty;
350 
354 
358 
362  explicit RoutingModel(const RoutingIndexManager& index_manager);
363  RoutingModel(const RoutingIndexManager& index_manager,
364  const RoutingModelParameters& parameters);
365  ~RoutingModel();
366 
373  const TransitCallback2& TransitCallback(int callback_index) const {
374  CHECK_LT(callback_index, transit_evaluators_.size());
375  return transit_evaluators_[callback_index];
376  }
377  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
378  CHECK_LT(callback_index, unary_transit_evaluators_.size());
379  return unary_transit_evaluators_[callback_index];
380  }
382  int callback_index) const {
383  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
384  return state_dependent_transit_evaluators_[callback_index];
385  }
386 
388 
400 
409  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
410  bool fix_start_cumul_to_zero, const std::string& name);
412  const std::vector<int>& evaluator_indices, int64 slack_max,
413  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
414  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
415  std::vector<int64> vehicle_capacities,
416  bool fix_start_cumul_to_zero,
417  const std::string& name);
419  const std::vector<int>& evaluator_indices, int64 slack_max,
420  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
421  const std::string& name);
428  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
429  int64 slack_max,
430  bool fix_start_cumul_to_zero,
431  const std::string& name);
432  bool AddConstantDimension(int64 value, int64 capacity,
433  bool fix_start_cumul_to_zero,
434  const std::string& name) {
435  return AddConstantDimensionWithSlack(value, capacity, 0,
436  fix_start_cumul_to_zero, name);
437  }
445  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
446  bool fix_start_cumul_to_zero,
447  const std::string& name);
455  bool AddMatrixDimension(std::vector<std::vector<int64>> values,
456  int64 capacity, bool fix_start_cumul_to_zero,
457  const std::string& name);
465  const std::vector<int>& pure_transits,
466  const std::vector<int>& dependent_transits,
467  const RoutingDimension* base_dimension, int64 slack_max,
468  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
469  const std::string& name) {
470  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
471  pure_transits, dependent_transits, base_dimension, slack_max,
472  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
473  }
476  const std::vector<int>& transits, const RoutingDimension* base_dimension,
477  int64 slack_max, std::vector<int64> vehicle_capacities,
478  bool fix_start_cumul_to_zero, const std::string& name);
481  int transit, const RoutingDimension* base_dimension, int64 slack_max,
482  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
483  const std::string& name);
485  int pure_transit, int dependent_transit,
486  const RoutingDimension* base_dimension, int64 slack_max,
487  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
488  const std::string& name);
489 
492  const std::function<int64(int64)>& f, int64 domain_start,
493  int64 domain_end);
494 
505  std::vector<IntVar*> spans,
506  std::vector<IntVar*> total_slacks);
507 
509  // TODO(user): rename.
510  std::vector<::std::string> GetAllDimensionNames() const;
512  const std::vector<RoutingDimension*>& GetDimensions() const {
513  return dimensions_.get();
514  }
516  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
517  // clang-format off
520  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
522  return global_dimension_optimizers_;
523  }
524  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
526  return local_dimension_optimizers_;
527  }
528  // clang-format on
529 
533  const RoutingDimension& dimension) const;
535  const RoutingDimension& dimension) const;
536 
538  bool HasDimension(const std::string& dimension_name) const;
541  const std::string& dimension_name) const;
545  const std::string& dimension_name) const;
550  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
551  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
552  primary_constrained_dimension_ = dimension_name;
553  }
556  const std::string& GetPrimaryConstrainedDimension() const {
557  return primary_constrained_dimension_;
558  }
575  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
576  int64 penalty = kNoPenalty,
577  int64 max_cardinality = 1);
579  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
580  int64 index) const {
581  return index_to_disjunctions_[index];
582  }
586  template <typename F>
588  int64 index, int64 max_cardinality, F f) const {
589  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
590  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
591  for (const int64 d_index : disjunctions_[disjunction].indices) {
592  f(d_index);
593  }
594  }
595  }
596  }
597 #if !defined(SWIGPYTHON)
598  const std::vector<int64>& GetDisjunctionIndices(
601  DisjunctionIndex index) const {
602  return disjunctions_[index].indices;
603  }
604 #endif // !defined(SWIGPYTHON)
605  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
607  return disjunctions_[index].value.penalty;
608  }
612  return disjunctions_[index].value.max_cardinality;
613  }
615  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
620  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
627 
631  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
632  int64 cost);
633 
638  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
639  int64 index);
640 
642  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
643  return allowed_vehicles_[index].empty() ||
644  allowed_vehicles_[index].find(vehicle) !=
645  allowed_vehicles_[index].end();
646  }
647 
662  // TODO(user): Remove this when model introspection detects linked nodes.
663  void AddPickupAndDelivery(int64 pickup, int64 delivery);
667  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
668  DisjunctionIndex delivery_disjunction);
669  // clang-format off
673  const std::vector<std::pair<int, int> >&
674  GetPickupIndexPairs(int64 node_index) const;
676  const std::vector<std::pair<int, int> >&
677  GetDeliveryIndexPairs(int64 node_index) const;
678  // clang-format on
679 
684  int vehicle);
686  int vehicle) const;
689 
690  int GetNumOfSingletonNodes() const;
691 
692 #ifndef SWIG
693  const IndexPairs& GetPickupAndDeliveryPairs() const {
695  return pickup_delivery_pairs_;
696  }
697  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
699  return pickup_delivery_disjunctions_;
700  }
701 #endif // SWIG
702  // TODO(user): Support multiple visit types per node?
718  void SetVisitType(int64 index, int type);
719  int GetVisitType(int64 index) const;
722  // TODO(user): Reconsider the logic and potentially remove the need to
724  void CloseVisitTypes();
725  int GetNumberOfVisitTypes() const { return num_visit_types_; }
730  void AddHardTypeIncompatibility(int type1, int type2);
731  void AddTemporalTypeIncompatibility(int type1, int type2);
733  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
734  int type) const;
735  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
736  int type) const;
740  return has_hard_type_incompatibilities_;
741  }
743  return has_temporal_type_incompatibilities_;
744  }
756  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
761  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
762  // clang-format off
765  const std::vector<absl::flat_hash_set<int> >&
767  const std::vector<absl::flat_hash_set<int> >&
769  // clang-format on
773  return has_same_vehicle_type_requirements_;
774  }
776  return has_temporal_type_requirements_;
777  }
778 
781  bool HasTypeRegulations() const {
785  }
786 
791  int64 UnperformedPenalty(int64 var_index) const;
795  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
799  int64 GetDepot() const;
800 
804  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
806  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
809  void SetFixedCostOfAllVehicles(int64 cost);
811  void SetFixedCostOfVehicle(int64 cost, int vehicle);
815  int64 GetFixedCostOfVehicle(int vehicle) const;
816 
832  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
833  int64 quadratic_cost_factor);
835  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
836  int64 quadratic_cost_factor,
837  int vehicle);
838 
839  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
840  return linear_cost_factor_of_vehicle_;
841  }
842  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
843  return quadratic_cost_factor_of_vehicle_;
844  }
845 
846  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
847  DCHECK_LT(vehicle, vehicles_);
848  consider_empty_route_costs_[vehicle] = consider_costs;
849  }
850 
851  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
852  DCHECK_LT(vehicle, vehicles_);
853  return consider_empty_route_costs_[vehicle];
854  }
855 
858 #ifndef SWIG
860  return first_solution_evaluator_;
861  }
862 #endif
865  first_solution_evaluator_ = std::move(evaluator);
866  }
869  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
871  void AddSearchMonitor(SearchMonitor* const monitor);
875  void AddAtSolutionCallback(std::function<void()> callback);
880  void AddVariableMinimizedByFinalizer(IntVar* var);
883  void AddVariableMaximizedByFinalizer(IntVar* var);
886  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost);
889  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
896  void CloseModel();
900  const RoutingSearchParameters& search_parameters);
907  const Assignment* Solve(const Assignment* assignment = nullptr);
915  const Assignment* SolveWithParameters(
916  const RoutingSearchParameters& search_parameters,
917  std::vector<const Assignment*>* solutions = nullptr);
918  const Assignment* SolveFromAssignmentWithParameters(
919  const Assignment* assignment,
920  const RoutingSearchParameters& search_parameters,
921  std::vector<const Assignment*>* solutions = nullptr);
928  Assignment* target_assignment, const RoutingModel* source_model,
929  const Assignment* source_assignment);
935  // TODO(user): Add support for non-homogeneous costs and disjunctions.
936  int64 ComputeLowerBound();
938  Status status() const { return status_; }
947  IntVar* ApplyLocks(const std::vector<int64>& locks);
956  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
957  bool close_routes);
962  const Assignment* const PreAssignment() const { return preassignment_; }
963  Assignment* MutablePreAssignment() { return preassignment_; }
967  bool WriteAssignment(const std::string& file_name) const;
971  Assignment* ReadAssignment(const std::string& file_name);
974  Assignment* RestoreAssignment(const Assignment& solution);
981  const std::vector<std::vector<int64>>& routes,
982  bool ignore_inactive_indices);
999  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
1000  bool ignore_inactive_indices, bool close_routes,
1001  Assignment* const assignment) const;
1005  void AssignmentToRoutes(const Assignment& assignment,
1006  std::vector<std::vector<int64>>* const routes) const;
1024  Assignment* CompactAssignment(const Assignment& assignment) const;
1028  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1030  void AddToAssignment(IntVar* const var);
1031  void AddIntervalToAssignment(IntervalVar* const interval);
1043  const Assignment* original_assignment, absl::Duration duration_limit);
1044 #ifndef SWIG
1045  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1047  sweep_arranger_.reset(sweep_arranger);
1048  }
1050  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1051 #endif
1052  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1058  CHECK(filter != nullptr);
1059  if (closed_) {
1060  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1061  }
1062  extra_filters_.push_back(filter);
1063  }
1064 
1067  int64 Start(int vehicle) const { return starts_[vehicle]; }
1069  int64 End(int vehicle) const { return ends_[vehicle]; }
1071  bool IsStart(int64 index) const;
1073  bool IsEnd(int64 index) const { return index >= Size(); }
1076  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1080  int64 Next(const Assignment& assignment, int64 index) const;
1082  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1083 
1084 #if !defined(SWIGPYTHON)
1085  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1090  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1091 #endif
1092  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1095  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1099  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1100  return vehicle_costs_considered_[vehicle];
1101  }
1104  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1106  IntVar* CostVar() const { return cost_; }
1107 
1110  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1111  int64 vehicle) const;
1114  return costs_are_homogeneous_across_vehicles_;
1115  }
1118  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1119  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1120  }
1123  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1130  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1131  int64 /*CostClassIndex*/ cost_class_index) const;
1134  DCHECK(closed_);
1135  return cost_class_index_of_vehicle_[vehicle];
1136  }
1139  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1140  DCHECK(closed_);
1141  if (cost_class_index == kCostClassIndexOfZeroCost) {
1142  return has_vehicle_with_zero_cost_class_;
1143  }
1144  return cost_class_index < cost_classes_.size();
1145  }
1147  int GetCostClassesCount() const { return cost_classes_.size(); }
1150  return std::max(0, GetCostClassesCount() - 1);
1151  }
1153  DCHECK(closed_);
1154  return vehicle_class_index_of_vehicle_[vehicle];
1155  }
1157  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1159  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1160  DCHECK(closed_);
1161  return same_vehicle_groups_[same_vehicle_group_[node]];
1162  }
1181  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1186  std::string DebugOutputAssignment(
1187  const Assignment& solution_assignment,
1188  const std::string& dimension_to_print) const;
1189 
1192  Solver* solver() const { return solver_.get(); }
1193 
1195  bool CheckLimit() {
1196  DCHECK(limit_ != nullptr);
1197  return limit_->Check();
1198  }
1199 
1201  absl::Duration RemainingTime() const {
1202  DCHECK(limit_ != nullptr);
1203  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1204  }
1205 
1208  int nodes() const { return nodes_; }
1210  int vehicles() const { return vehicles_; }
1212  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1213 
1217  const RoutingSearchParameters& search_parameters) const;
1219  const RoutingSearchParameters& search_parameters) const;
1220 
1222  bool IsMatchingModel() const;
1223 
1224 #ifndef SWIG
1225  using GetTabuVarsCallback =
1228  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1229 
1230  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1231 #endif // SWIG
1232 
1234  // TODO(user): Find a way to test and restrict the access at the same time.
1247  const RoutingDimension* dimension,
1248  std::function<int64(int64)> initializer);
1249 #ifndef SWIG
1250  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1255  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1256  std::vector<IntVar*> variables);
1257 #endif
1258  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1272  const RoutingDimension* dimension);
1273 
1274  private:
1276  enum RoutingLocalSearchOperator {
1277  RELOCATE = 0,
1278  RELOCATE_PAIR,
1279  LIGHT_RELOCATE_PAIR,
1280  RELOCATE_NEIGHBORS,
1281  EXCHANGE,
1282  EXCHANGE_PAIR,
1283  CROSS,
1284  CROSS_EXCHANGE,
1285  TWO_OPT,
1286  OR_OPT,
1287  RELOCATE_EXPENSIVE_CHAIN,
1288  LIN_KERNIGHAN,
1289  TSP_OPT,
1290  MAKE_ACTIVE,
1291  RELOCATE_AND_MAKE_ACTIVE,
1292  MAKE_ACTIVE_AND_RELOCATE,
1293  MAKE_INACTIVE,
1294  MAKE_CHAIN_INACTIVE,
1295  SWAP_ACTIVE,
1296  EXTENDED_SWAP_ACTIVE,
1297  NODE_PAIR_SWAP,
1298  PATH_LNS,
1299  FULL_PATH_LNS,
1300  TSP_LNS,
1301  INACTIVE_LNS,
1302  EXCHANGE_RELOCATE_PAIR,
1303  RELOCATE_SUBTRIP,
1304  EXCHANGE_SUBTRIP,
1305  LOCAL_SEARCH_OPERATOR_COUNTER
1306  };
1307 
1311  template <typename T>
1312  struct ValuedNodes {
1313  std::vector<int64> indices;
1314  T value;
1315  };
1316  struct DisjunctionValues {
1317  int64 penalty;
1318  int64 max_cardinality;
1319  };
1320  typedef ValuedNodes<DisjunctionValues> Disjunction;
1321 
1324  struct CostCacheElement {
1329  int index;
1330  CostClassIndex cost_class_index;
1331  int64 cost;
1332  };
1333 
1335  void Initialize();
1336  void AddNoCycleConstraintInternal();
1337  bool AddDimensionWithCapacityInternal(
1338  const std::vector<int>& evaluator_indices, int64 slack_max,
1339  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1340  const std::string& name);
1341  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1342  const std::vector<int>& pure_transits,
1343  const std::vector<int>& dependent_transits,
1344  const RoutingDimension* base_dimension, int64 slack_max,
1345  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1346  const std::string& name);
1347  bool InitializeDimensionInternal(
1348  const std::vector<int>& evaluator_indices,
1349  const std::vector<int>& state_dependent_evaluator_indices,
1350  int64 slack_max, bool fix_start_cumul_to_zero,
1351  RoutingDimension* dimension);
1352  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1353 
1381  void StoreDimensionCumulOptimizers();
1382 
1383  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1384  void ComputeVehicleClasses();
1385  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1386  CostClassIndex cost_class_index) const;
1387  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1388  int node_index,
1389  std::vector<IntVar*>* cost_elements);
1390  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1391  std::vector<IntVar*>* cost_elements);
1392  Assignment* DoRestoreAssignment();
1393  static const CostClassIndex kCostClassIndexOfZeroCost;
1394  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1395  DCHECK_LT(0, vehicles_);
1396  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1397  : kCostClassIndexOfZeroCost)
1398  .value();
1399  }
1400  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1401  const CostClass& cost_class) const;
1403  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1405  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1406  const std::vector<int64>& deliveries);
1409  IntVar* CreateSameVehicleCost(int vehicle_index);
1412  int FindNextActive(int index, const std::vector<int64>& indices) const;
1413 
1416  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1417  int vehicle) const;
1425  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1426  Assignment* compact_assignment) const;
1427 
1428  void QuietCloseModel();
1429  void QuietCloseModelWithParameters(
1430  const RoutingSearchParameters& parameters) {
1431  if (!closed_) {
1432  CloseModelWithParameters(parameters);
1433  }
1434  }
1435 
1437  bool SolveMatchingModel(Assignment* assignment);
1438 #ifndef SWIG
1439  bool AppendAssignmentIfFeasible(
1441  const Assignment& assignment,
1442  std::vector<std::unique_ptr<Assignment>>* assignments);
1443 #endif
1444  void LogSolution(const RoutingSearchParameters& parameters,
1446  const std::string& description, int64 solution_cost,
1447  int64 start_time_ms);
1450  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1451  bool check_compact_assignment) const;
1456  std::string FindErrorInSearchParametersForModel(
1457  const RoutingSearchParameters& search_parameters) const;
1459  void SetupSearch(const RoutingSearchParameters& search_parameters);
1461  // TODO(user): Document each auxiliary method.
1462  Assignment* GetOrCreateAssignment();
1463  Assignment* GetOrCreateTmpAssignment();
1464  RegularLimit* GetOrCreateLimit();
1465  RegularLimit* GetOrCreateLocalSearchLimit();
1466  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1467  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1468  LocalSearchOperator* CreateInsertionOperator();
1469  LocalSearchOperator* CreateMakeInactiveOperator();
1470  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1471  LocalSearchOperator* GetNeighborhoodOperators(
1472  const RoutingSearchParameters& search_parameters) const;
1473  const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters();
1474  const std::vector<LocalSearchFilter*>& GetOrCreateFeasibilityFilters();
1475  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1476  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1477  void CreateFirstSolutionDecisionBuilders(
1478  const RoutingSearchParameters& search_parameters);
1479  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1480  const RoutingSearchParameters& search_parameters) const;
1481  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1482  const RoutingSearchParameters& parameters) const;
1483  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1484  const RoutingSearchParameters& search_parameters);
1485  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1486  const RoutingSearchParameters& search_parameters);
1487  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1488  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1489  void SetupAssignmentCollector(
1490  const RoutingSearchParameters& search_parameters);
1491  void SetupTrace(const RoutingSearchParameters& search_parameters);
1492  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1493  bool UsesLightPropagation(
1494  const RoutingSearchParameters& search_parameters) const;
1495  GetTabuVarsCallback tabu_var_callback_;
1496 
1497  int GetVehicleStartClass(int64 start) const;
1498 
1499  void InitSameVehicleGroups(int number_of_groups) {
1500  same_vehicle_group_.assign(Size(), 0);
1501  same_vehicle_groups_.assign(number_of_groups, {});
1502  }
1503  void SetSameVehicleGroup(int index, int group) {
1504  same_vehicle_group_[index] = group;
1505  same_vehicle_groups_[group].push_back(index);
1506  }
1507 
1509  std::unique_ptr<Solver> solver_;
1510  int nodes_;
1511  int vehicles_;
1512  Constraint* no_cycle_constraint_ = nullptr;
1514  std::vector<IntVar*> nexts_;
1515  std::vector<IntVar*> vehicle_vars_;
1516  std::vector<IntVar*> active_;
1517  std::vector<IntVar*> vehicle_costs_considered_;
1522  std::vector<IntVar*> is_bound_to_end_;
1523  mutable RevSwitch is_bound_to_end_ct_added_;
1525  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1526  gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1527  // clang-format off
1531  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1532  global_dimension_optimizers_;
1533  gtl::ITIVector<DimensionIndex, int> global_optimizer_index_;
1534  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1535  local_dimension_optimizers_;
1536  // clang-format off
1537  gtl::ITIVector<DimensionIndex, int> local_optimizer_index_;
1538  std::string primary_constrained_dimension_;
1540  IntVar* cost_ = nullptr;
1541  std::vector<int> vehicle_to_transit_cost_;
1542  std::vector<int64> fixed_cost_of_vehicle_;
1543  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1544  bool has_vehicle_with_zero_cost_class_;
1545  std::vector<int64> linear_cost_factor_of_vehicle_;
1546  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1547  bool vehicle_amortized_cost_factors_set_;
1558  std::vector<bool> consider_empty_route_costs_;
1559 #ifndef SWIG
1560  gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1561 #endif // SWIG
1562  bool costs_are_homogeneous_across_vehicles_;
1563  bool cache_callbacks_;
1564  mutable std::vector<CostCacheElement> cost_cache_;
1565  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1566 #ifndef SWIG
1567  gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1568 #endif // SWIG
1569  std::function<int(int64)> vehicle_start_class_callback_;
1571  gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1572  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1574  std::vector<ValuedNodes<int64> > same_vehicle_costs_;
1576 #ifndef SWIG
1577  std::vector<std::unordered_set<int>> allowed_vehicles_;
1578 #endif // SWIG
1579  IndexPairs pickup_delivery_pairs_;
1581  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1582  pickup_delivery_disjunctions_;
1583  // clang-format off
1584  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1585  // vector of pairs {pair_index, pickup_index} such that
1586  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1587  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1588  // Same as above for deliveries.
1589  std::vector<std::vector<std::pair<int, int> > >
1590  index_to_delivery_index_pairs_;
1591  // clang-format on
1592  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1593  // Same vehicle group to which a node belongs.
1594  std::vector<int> same_vehicle_group_;
1595  // Same vehicle node groups.
1596  std::vector<std::vector<int>> same_vehicle_groups_;
1597  // Node visit types
1598  // Variable index to visit type index.
1599  std::vector<int> index_to_visit_type_;
1600  // clang-format off
1601  std::vector<absl::flat_hash_set<int> >
1602  hard_incompatible_types_per_type_index_;
1603  bool has_hard_type_incompatibilities_;
1604  std::vector<absl::flat_hash_set<int> >
1605  temporal_incompatible_types_per_type_index_;
1606  bool has_temporal_type_incompatibilities_;
1607 
1608  std::vector<std::vector<absl::flat_hash_set<int> > >
1609  same_vehicle_required_type_alternatives_per_type_index_;
1610  bool has_same_vehicle_type_requirements_;
1611  std::vector<std::vector<absl::flat_hash_set<int> > >
1612  temporal_required_type_alternatives_per_type_index_;
1613  bool has_temporal_type_requirements_;
1614  absl::flat_hash_set<int> trivially_infeasible_visit_types_;
1615  // clang-format on
1616  int num_visit_types_;
1617  // Two indices are equivalent if they correspond to the same node (as given
1618  // to the constructors taking a RoutingIndexManager).
1619  std::vector<int> index_to_equivalence_class_;
1620  std::vector<int> index_to_vehicle_;
1621  std::vector<int64> starts_;
1622  std::vector<int64> ends_;
1623  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1624  // anymore.
1625  RoutingIndexManager manager_;
1626  int start_end_count_;
1627  // Model status
1628  bool closed_ = false;
1629  Status status_ = ROUTING_NOT_SOLVED;
1630  bool enable_deep_serialization_ = true;
1631 
1632  // Search data
1633  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1634  std::vector<IntVarFilteredDecisionBuilder*>
1635  first_solution_filtered_decision_builders_;
1636  Solver::IndexEvaluator2 first_solution_evaluator_;
1637  std::vector<LocalSearchOperator*> local_search_operators_;
1638  std::vector<SearchMonitor*> monitors_;
1639  SolutionCollector* collect_assignments_ = nullptr;
1640  SolutionCollector* collect_one_assignment_ = nullptr;
1641  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1642  DecisionBuilder* solve_db_ = nullptr;
1643  DecisionBuilder* improve_db_ = nullptr;
1644  DecisionBuilder* restore_assignment_ = nullptr;
1645  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1646  Assignment* assignment_ = nullptr;
1647  Assignment* preassignment_ = nullptr;
1648  Assignment* tmp_assignment_ = nullptr;
1649  std::vector<IntVar*> extra_vars_;
1650  std::vector<IntervalVar*> extra_intervals_;
1651  std::vector<LocalSearchOperator*> extra_operators_;
1652  std::vector<LocalSearchFilter*> filters_;
1653  std::vector<LocalSearchFilter*> feasibility_filters_;
1654  std::vector<LocalSearchFilter*> extra_filters_;
1655 #ifndef SWIG
1656  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1657  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1658  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1659  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1660  std::unique_ptr<SweepArranger> sweep_arranger_;
1661 #endif
1662 
1663  RegularLimit* limit_ = nullptr;
1664  RegularLimit* ls_limit_ = nullptr;
1665  RegularLimit* lns_limit_ = nullptr;
1666  RegularLimit* first_solution_lns_limit_ = nullptr;
1667 
1668  typedef std::pair<int64, int64> CacheKey;
1669  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1670  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1671  StateDependentTransitCallbackCache;
1672 
1673  std::vector<TransitCallback1> unary_transit_evaluators_;
1674  std::vector<TransitCallback2> transit_evaluators_;
1675  // The following vector stores a boolean per transit_evaluator_, indicating
1676  // whether the transits are all positive.
1677  // is_transit_evaluator_positive_ will be set to true only when registering a
1678  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1679  // The actual positivity of the transit values will only be checked in debug
1680  // mode, when calling RegisterPositiveTransitCallback().
1681  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1682  // transits are known to be positive, as the positivity of a callback will
1683  // allow some improvements in the solver, but will entail in errors if the
1684  // transits are falsely assumed positive.
1685  std::vector<bool> is_transit_evaluator_positive_;
1686  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1687  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1688  state_dependent_transit_evaluators_cache_;
1689 
1690  friend class RoutingDimension;
1692 
1693  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1694 };
1695 
1698  public:
1700  static const char kLightElement[];
1701  static const char kLightElement2[];
1702  static const char kRemoveValues[];
1703 };
1704 
1705 #if !defined(SWIG)
1706 class DisjunctivePropagator {
1709  public:
1715  struct Tasks {
1717  std::vector<int64> start_min;
1718  std::vector<int64> start_max;
1719  std::vector<int64> duration_min;
1720  std::vector<int64> duration_max;
1721  std::vector<int64> end_min;
1722  std::vector<int64> end_max;
1723  std::vector<bool> is_preemptible;
1724  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1725  std::vector<std::pair<int64, int64>> distance_duration;
1726 
1727  void Clear() {
1728  start_min.clear();
1729  start_max.clear();
1730  duration_min.clear();
1731  duration_max.clear();
1732  end_min.clear();
1733  end_max.clear();
1734  is_preemptible.clear();
1735  forbidden_intervals.clear();
1736  distance_duration.clear();
1737  }
1738  };
1739 
1742  bool Propagate(Tasks* tasks);
1743 
1745  bool Precedences(Tasks* tasks);
1748  bool MirrorTasks(Tasks* tasks);
1750  bool EdgeFinding(Tasks* tasks);
1753  bool DetectablePrecedencesWithChain(Tasks* tasks);
1755  bool ForbiddenIntervals(Tasks* tasks);
1756  bool DistanceDuration(Tasks* tasks);
1757 
1758  private:
1761  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1763  std::vector<int> tasks_by_start_min_;
1764  std::vector<int> tasks_by_end_max_;
1765  std::vector<int> event_of_task_;
1766  std::vector<int> nonchain_tasks_by_start_max_;
1767 };
1768 
1769 void AppendTasksFromPath(const std::vector<int64>& path,
1770  const std::vector<int64>& min_travels,
1771  const std::vector<int64>& max_travels,
1772  const std::vector<int64>& pre_travels,
1773  const std::vector<int64>& post_travels,
1774  const RoutingDimension& dimension,
1775  DisjunctivePropagator::Tasks* tasks);
1776 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
1777  DisjunctivePropagator::Tasks* tasks);
1778 void FillPathEvaluation(const std::vector<int64>& path,
1779  const RoutingModel::TransitCallback2& evaluator,
1780  std::vector<int64>* values);
1781 #endif // !defined(SWIG)
1782 
1794  public:
1795  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
1796 
1797  void Post() override;
1798  void InitialPropagate() override;
1799 
1800  private:
1801  void PropagateNode(int node);
1802  void PropagateVehicle(int vehicle);
1803  void PropagateMaxBreakDistance(int vehicle);
1804 
1805  const RoutingModel* model_;
1806  const RoutingDimension* const dimension_;
1807  std::vector<Demon*> vehicle_demons_;
1808  std::vector<int64> path_;
1809 
1814  void FillPartialPathOfVehicle(int vehicle);
1815  void FillPathTravels(const std::vector<int64>& path);
1816 
1827  class TaskTranslator {
1828  public:
1829  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
1830  : start_(start),
1831  before_start_(before_start),
1832  after_start_(after_start) {}
1833  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
1834  TaskTranslator() {}
1835 
1836  void SetStartMin(int64 value) {
1837  if (start_ != nullptr) {
1838  start_->SetMin(CapAdd(before_start_, value));
1839  } else if (interval_ != nullptr) {
1840  interval_->SetStartMin(value);
1841  }
1842  }
1843  void SetStartMax(int64 value) {
1844  if (start_ != nullptr) {
1845  start_->SetMax(CapAdd(before_start_, value));
1846  } else if (interval_ != nullptr) {
1847  interval_->SetStartMax(value);
1848  }
1849  }
1850  void SetDurationMin(int64 value) {
1851  if (interval_ != nullptr) {
1852  interval_->SetDurationMin(value);
1853  }
1854  }
1855  void SetEndMin(int64 value) {
1856  if (start_ != nullptr) {
1857  start_->SetMin(CapSub(value, after_start_));
1858  } else if (interval_ != nullptr) {
1859  interval_->SetEndMin(value);
1860  }
1861  }
1862  void SetEndMax(int64 value) {
1863  if (start_ != nullptr) {
1864  start_->SetMax(CapSub(value, after_start_));
1865  } else if (interval_ != nullptr) {
1866  interval_->SetEndMax(value);
1867  }
1868  }
1869 
1870  private:
1871  IntVar* start_ = nullptr;
1872  int64 before_start_;
1873  int64 after_start_;
1874  IntervalVar* interval_ = nullptr;
1875  };
1876 
1878  std::vector<TaskTranslator> task_translators_;
1879 
1881  DisjunctivePropagator disjunctive_propagator_;
1883 
1885  std::vector<int64> min_travel_;
1886  std::vector<int64> max_travel_;
1887  std::vector<int64> pre_travel_;
1888  std::vector<int64> post_travel_;
1889 };
1890 
1892  public:
1893  explicit TypeRegulationsChecker(const RoutingModel& model);
1895 
1896  bool CheckVehicle(int vehicle,
1897  const std::function<int64(int64)>& next_accessor);
1898 
1899  protected:
1901  struct NodeCount {
1903  int pickup = 0;
1904  int delivery = 0;
1905  };
1906 
1909  int GetNonDeliveryCount(int type) const;
1911  int GetNonDeliveredCount(int type) const;
1912 
1913  virtual bool HasRegulationsToCheck() const = 0;
1914  virtual void InitializeCheck() {}
1915  virtual bool CheckTypeRegulations(int type) = 0;
1916  virtual bool FinalizeCheck() const { return true; }
1917 
1919 
1920  private:
1921  std::vector<PickupDeliveryStatus> pickup_delivery_status_of_node_;
1922  std::vector<NodeCount> counts_of_type_;
1923 };
1924 
1927  public:
1929  bool check_hard_incompatibilities);
1931 
1932  private:
1933  bool HasRegulationsToCheck() const override;
1934  bool CheckTypeRegulations(int type) override;
1938  bool check_hard_incompatibilities_;
1939 };
1940 
1943  public:
1944  explicit TypeRequirementChecker(const RoutingModel& model)
1945  : TypeRegulationsChecker(model) {}
1947 
1948  private:
1949  bool HasRegulationsToCheck() const override;
1950  void InitializeCheck() override {
1951  types_with_same_vehicle_requirements_on_route_.clear();
1952  }
1953  bool CheckTypeRegulations(int type) override;
1954  bool FinalizeCheck() const override;
1955 
1956  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
1957 };
1958 
1979  public:
1980  explicit TypeRegulationsConstraint(const RoutingModel& model);
1981 
1982  void Post() override;
1983  void InitialPropagate() override;
1984 
1985  private:
1986  void PropagateNodeRegulations(int node);
1987  void CheckRegulationsOnVehicle(int vehicle);
1988 
1989  const RoutingModel& model_;
1990  TypeIncompatibilityChecker incompatibility_checker_;
1991  TypeRequirementChecker requirement_checker_;
1992  std::vector<Demon*> vehicle_demons_;
1993 };
1994 #if !defined SWIG
1995 class SimpleBoundCosts {
2008  public:
2009  struct BoundCost {
2010  int64 bound;
2011  int64 cost;
2012  };
2013  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2014  : bound_costs_(num_bounds, default_bound_cost) {}
2015  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2016  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2017  int Size() { return bound_costs_.size(); }
2018  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
2019  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
2020 
2021  private:
2022  std::vector<BoundCost> bound_costs_;
2023 };
2024 #endif // !defined SWIG
2025 
2043 // TODO(user): Break constraints need to know the service time of nodes
2047  public:
2050  RoutingModel* model() const { return model_; }
2054  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2057  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2058  int64 vehicle_class) const {
2059  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2060  to_index);
2061  }
2064  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2065  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2066  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2067  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2068 
2069 #if !defined(SWIGPYTHON)
2070  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2073  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2074  const std::vector<IntVar*>& transits() const { return transits_; }
2075  const std::vector<IntVar*>& slacks() const { return slacks_; }
2076 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2077  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2079  return forbidden_intervals_;
2080  }
2082  const std::vector<int64>& vehicle_capacities() const {
2083  return vehicle_capacities_;
2084  }
2088  return model_->TransitCallback(
2089  class_evaluators_[vehicle_to_class_[vehicle]]);
2090  }
2095  int vehicle) const {
2096  return model_->UnaryTransitCallbackOrNull(
2097  class_evaluators_[vehicle_to_class_[vehicle]]);
2098  }
2101  bool AreVehicleTransitsPositive(int vehicle) const {
2102  return model()->is_transit_evaluator_positive_
2103  [class_evaluators_[vehicle_to_class_[vehicle]]];
2104  }
2105  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2106 #endif
2107 #endif
2108  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2112  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2119  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2126  void SetGlobalSpanCostCoefficient(int64 coefficient);
2127 
2128 #ifndef SWIG
2129  void SetCumulVarPiecewiseLinearCost(int64 index,
2134  const PiecewiseLinearFunction& cost);
2137  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2140  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2141  int64 index) const;
2142 #endif
2143 
2152  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2153  int64 coefficient);
2156  bool HasCumulVarSoftUpperBound(int64 index) const;
2160  int64 GetCumulVarSoftUpperBound(int64 index) const;
2164  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2165 
2178  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2179  int64 coefficient);
2182  bool HasCumulVarSoftLowerBound(int64 index) const;
2186  int64 GetCumulVarSoftLowerBound(int64 index) const;
2190  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2206  // TODO(user): Remove if !defined when routing.i is repaired.
2207 #if !defined(SWIGPYTHON)
2208  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2209  int pre_travel_evaluator,
2210  int post_travel_evaluator);
2211 #endif // !defined(SWIGPYTHON)
2212 
2214  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2215  std::vector<int64> node_visit_transits);
2216 
2221  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2222  int vehicle);
2225  void InitializeBreaks();
2227  bool HasBreakConstraints() const;
2228 #if !defined(SWIGPYTHON)
2232  std::vector<IntervalVar*> breaks, int vehicle,
2233  std::vector<int64> node_visit_transits,
2234  std::function<int64(int64, int64)> group_delays);
2235 
2237  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2238  int vehicle) const;
2241  // clang-format off
2242  const std::vector<std::pair<int64, int64> >&
2243  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2244  // clang-format on
2245 #endif
2246  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2247  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2248 
2250  const RoutingDimension* base_dimension() const { return base_dimension_; }
2258  int64 ShortestTransitionSlack(int64 node) const;
2259 
2261  const std::string& name() const { return name_; }
2262 
2264 #ifndef SWIG
2265  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2266  return path_precedence_graph_;
2267  }
2268 #endif // SWIG
2269 
2279  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2280 
2282  PickupToDeliveryLimitFunction limit_function, int pair_index);
2283 
2284  bool HasPickupToDeliveryLimits() const;
2285 #ifndef SWIG
2286  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2287  int delivery) const;
2288 
2290  int64 first_node;
2292  int64 offset;
2293  };
2294 
2296  node_precedences_.push_back(precedence);
2297  }
2298  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2299  return node_precedences_;
2300  }
2301 #endif // SWIG
2302 
2303  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2304  AddNodePrecedence({first_node, second_node, offset});
2305  }
2306 
2307  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2308  return vehicle_span_upper_bounds_[vehicle];
2309  }
2310 #ifndef SWIG
2311  const std::vector<int64>& vehicle_span_upper_bounds() const {
2312  return vehicle_span_upper_bounds_;
2313  }
2314 #endif // SWIG
2315  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2316  return vehicle_span_cost_coefficients_[vehicle];
2317  }
2318 #ifndef SWIG
2319  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2320  return vehicle_span_cost_coefficients_;
2321  }
2322 #endif // SWIG
2324  return global_span_cost_coefficient_;
2325  }
2326 
2328  DCHECK_GE(global_optimizer_offset_, 0);
2329  return global_optimizer_offset_;
2330  }
2331  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2332  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2333  return 0;
2334  }
2335  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2336  return local_optimizer_offset_for_vehicle_[vehicle];
2337  }
2338 #if !defined SWIG
2342  int vehicle) {
2343  if (!HasSoftSpanUpperBounds()) {
2344  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2345  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2346  }
2347  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2348  }
2349  bool HasSoftSpanUpperBounds() const {
2350  return vehicle_soft_span_upper_bound_ != nullptr;
2351  }
2353  int vehicle) const {
2354  DCHECK(HasSoftSpanUpperBounds());
2355  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2356  }
2357 #endif
2358 
2359  private:
2360  struct SoftBound {
2361  IntVar* var;
2362  int64 bound;
2363  int64 coefficient;
2364  };
2365 
2366  struct PiecewiseLinearCost {
2367  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2368  IntVar* var;
2369  std::unique_ptr<PiecewiseLinearFunction> cost;
2370  };
2371 
2372  class SelfBased {};
2373  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2374  const std::string& name,
2375  const RoutingDimension* base_dimension);
2376  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2377  const std::string& name, SelfBased);
2378  void Initialize(const std::vector<int>& transit_evaluators,
2379  const std::vector<int>& state_dependent_transit_evaluators,
2380  int64 slack_max);
2381  void InitializeCumuls();
2382  void InitializeTransits(
2383  const std::vector<int>& transit_evaluators,
2384  const std::vector<int>& state_dependent_transit_evaluators,
2385  int64 slack_max);
2386  void InitializeTransitVariables(int64 slack_max);
2388  void SetupCumulVarSoftUpperBoundCosts(
2389  std::vector<IntVar*>* cost_elements) const;
2391  void SetupCumulVarSoftLowerBoundCosts(
2392  std::vector<IntVar*>* cost_elements) const;
2393  void SetupCumulVarPiecewiseLinearCosts(
2394  std::vector<IntVar*>* cost_elements) const;
2397  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2398  void SetupSlackAndDependentTransitCosts() const;
2400  void CloseModel(bool use_light_propagation);
2401 
2402  void SetOffsetForGlobalOptimizer(int64 offset) {
2403  global_optimizer_offset_ = std::max(Zero(), offset);
2404  }
2406  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2408  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2409  [](int64 offset) { return std::max(Zero(), offset); });
2410  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2411  }
2412 
2413  std::vector<IntVar*> cumuls_;
2414  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2415  std::vector<IntVar*> capacity_vars_;
2416  const std::vector<int64> vehicle_capacities_;
2417  std::vector<IntVar*> transits_;
2418  std::vector<IntVar*> fixed_transits_;
2421  std::vector<int> class_evaluators_;
2422  std::vector<int64> vehicle_to_class_;
2423 #ifndef SWIG
2424  ReverseArcListGraph<int, int> path_precedence_graph_;
2425 #endif
2426  // For every {first_node, second_node, offset} element in node_precedences_,
2427  // if both first_node and second_node are performed, then
2428  // cumuls_[second_node] must be greater than (or equal to)
2429  // cumuls_[first_node] + offset.
2430  std::vector<NodePrecedence> node_precedences_;
2431 
2432  // The transits of a dimension may depend on its cumuls or the cumuls of
2433  // another dimension. There can be no cycles, except for self loops, a
2434  // typical example for this is a time dimension.
2435  const RoutingDimension* const base_dimension_;
2436 
2437  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2438  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2439  // class.
2440  std::vector<int> state_dependent_class_evaluators_;
2441  std::vector<int64> state_dependent_vehicle_to_class_;
2442 
2443  // For each pickup/delivery pair_index for which limits have been set,
2444  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2445  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2446  std::vector<PickupToDeliveryLimitFunction>
2447  pickup_to_delivery_limits_per_pair_index_;
2448 
2449  // Used if some vehicle has breaks in this dimension, typically time.
2450  bool break_constraints_are_initialized_ = false;
2451  // clang-format off
2452  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2453  std::vector<std::vector<std::pair<int64, int64> > >
2454  vehicle_break_distance_duration_;
2455  // clang-format on
2456  // For each vehicle, stores the part of travel that is made directly
2457  // after (before) the departure (arrival) node of the travel.
2458  // These parts of the travel are non-interruptible, in particular by a break.
2459  std::vector<int> vehicle_pre_travel_evaluators_;
2460  std::vector<int> vehicle_post_travel_evaluators_;
2461 
2462  std::vector<IntVar*> slacks_;
2463  std::vector<IntVar*> dependent_transits_;
2464  std::vector<int64> vehicle_span_upper_bounds_;
2465  int64 global_span_cost_coefficient_;
2466  std::vector<int64> vehicle_span_cost_coefficients_;
2467  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2468  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2469  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2470  RoutingModel* const model_;
2471  const std::string name_;
2472  int64 global_optimizer_offset_;
2473  std::vector<int64> local_optimizer_offset_for_vehicle_;
2475  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2476  friend class RoutingModel;
2478 
2479  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2480 };
2481 
2482 #ifndef SWIG
2483 class SweepArranger {
2486  public:
2487  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2488  virtual ~SweepArranger() {}
2489  void ArrangeIndices(std::vector<int64>* indices);
2490  void SetSectors(int sectors) { sectors_ = sectors; }
2491 
2492  private:
2493  std::vector<int> coordinates_;
2494  int sectors_;
2495 
2496  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2497 };
2498 #endif
2499 
2502 DecisionBuilder* MakeSetValuesFromTargets(Solver* solver,
2503  std::vector<IntVar*> variables,
2504  std::vector<int64> targets);
2505 
2517 
2519 // TODO(user): Eventually move this to the core CP solver library
2522  public:
2524  const std::vector<IntVar*>& vars,
2525  const std::vector<LocalSearchFilter*>& filters);
2527  Decision* Next(Solver* solver) override;
2529  virtual bool BuildSolution() = 0;
2532  int64 number_of_decisions() const { return number_of_decisions_; }
2533  int64 number_of_rejects() const { return number_of_rejects_; }
2534 
2535  protected:
2537  virtual bool InitializeSolution() { return true; }
2541  bool Commit();
2543  virtual bool StopSearch() { return false; }
2546  void SetValue(int64 index, int64 value) {
2547  if (!is_in_delta_[index]) {
2548  delta_->FastAdd(vars_[index])->SetValue(value);
2549  delta_indices_.push_back(index);
2550  is_in_delta_[index] = true;
2551  } else {
2552  delta_->SetValue(vars_[index], value);
2553  }
2554  }
2557  int64 Value(int64 index) const {
2558  return assignment_->IntVarContainer().Element(index).Value();
2559  }
2561  bool Contains(int64 index) const {
2562  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
2563  }
2566  int Size() const { return vars_.size(); }
2568  IntVar* Var(int64 index) const { return vars_[index]; }
2569 
2570  private:
2572  void SynchronizeFilters();
2575  bool FilterAccept();
2576 
2577  const std::vector<IntVar*> vars_;
2578  Assignment* const assignment_;
2579  Assignment* const delta_;
2580  std::vector<int> delta_indices_;
2581  std::vector<bool> is_in_delta_;
2582  Assignment* const empty_;
2583  LocalSearchFilterManager filter_manager_;
2585  int64 number_of_decisions_;
2586  int64 number_of_rejects_;
2587 };
2588 
2591  public:
2593  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
2595  RoutingModel* model() const { return model_; }
2597  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
2599  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
2602  void MakeDisjunctionNodesUnperformed(int64 node);
2605 
2606  protected:
2607  bool StopSearch() override { return model_->CheckLimit(); }
2608 
2609  private:
2611  bool InitializeSolution() override;
2612 
2613  RoutingModel* const model_;
2614  std::vector<int64> start_chain_ends_;
2615  std::vector<int64> end_chain_starts_;
2616 };
2617 
2620  public:
2623  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2624  std::function<int64(int64)> penalty_evaluator,
2625  const std::vector<LocalSearchFilter*>& filters);
2627 
2628  protected:
2629  typedef std::pair<int64, int64> ValuedPosition;
2630  struct StartEndValue {
2631  int64 distance;
2632  int vehicle;
2633 
2634  bool operator<(const StartEndValue& other) const {
2635  return std::tie(distance, vehicle) <
2636  std::tie(other.distance, other.vehicle);
2637  }
2638  };
2639  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
2640 
2646  // clang-format off
2647  std::vector<std::vector<StartEndValue> >
2648  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
2649 
2654  template <class Queue>
2656  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
2657  Queue* priority_queue);
2658  // clang-format on
2659 
2664  void InsertBetween(int64 node, int64 predecessor, int64 successor);
2670  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
2671  std::vector<ValuedPosition>* valued_positions);
2674  int64 GetUnperformedValue(int64 node_to_insert) const;
2675 
2676  std::function<int64(int64, int64, int64)> evaluator_;
2677  std::function<int64(int64)> penalty_evaluator_;
2678 };
2679 
2689  public:
2692  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2693  std::function<int64(int64)> penalty_evaluator,
2694  const std::vector<LocalSearchFilter*>& filters, bool is_sequential,
2695  double farthest_seeds_ratio, double neighbors_ratio);
2697  bool BuildSolution() override;
2698  std::string DebugString() const override {
2699  return "GlobalCheapestInsertionFilteredDecisionBuilder";
2700  }
2701 
2702  private:
2703  class PairEntry;
2704  class NodeEntry;
2705  typedef absl::flat_hash_set<PairEntry*> PairEntries;
2706  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
2707 
2714  void InsertPairs();
2715 
2723  void InsertNodesOnRoutes(const std::vector<int>& nodes,
2724  const std::vector<int>& vehicles);
2725 
2731  void SequentialInsertNodes(const std::vector<int>& nodes);
2732 
2736  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
2737  std::vector<int>* used_vehicles,
2738  std::vector<int>* unused_vehicles);
2739 
2743  void InsertFarthestNodesAsSeeds();
2744 
2753  template <class Queue>
2754  int InsertSeedNode(
2755  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
2756  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
2757  // clang-format on
2758 
2761  void InitializePairPositions(
2762  AdjustablePriorityQueue<PairEntry>* priority_queue,
2763  std::vector<PairEntries>* pickup_to_entries,
2764  std::vector<PairEntries>* delivery_to_entries);
2767  void UpdatePairPositions(int vehicle, int64 insert_after,
2768  AdjustablePriorityQueue<PairEntry>* priority_queue,
2769  std::vector<PairEntries>* pickup_to_entries,
2770  std::vector<PairEntries>* delivery_to_entries) {
2771  UpdatePickupPositions(vehicle, insert_after, priority_queue,
2772  pickup_to_entries, delivery_to_entries);
2773  UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
2774  pickup_to_entries, delivery_to_entries);
2775  }
2778  void UpdatePickupPositions(int vehicle, int64 pickup_insert_after,
2779  AdjustablePriorityQueue<PairEntry>* priority_queue,
2780  std::vector<PairEntries>* pickup_to_entries,
2781  std::vector<PairEntries>* delivery_to_entries);
2784  void UpdateDeliveryPositions(
2785  int vehicle, int64 delivery_insert_after,
2786  AdjustablePriorityQueue<PairEntry>* priority_queue,
2787  std::vector<PairEntries>* pickup_to_entries,
2788  std::vector<PairEntries>* delivery_to_entries);
2791  void DeletePairEntry(PairEntry* entry,
2792  AdjustablePriorityQueue<PairEntry>* priority_queue,
2793  std::vector<PairEntries>* pickup_to_entries,
2794  std::vector<PairEntries>* delivery_to_entries);
2797  void InitializePositions(const std::vector<int>& nodes,
2798  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2799  std::vector<NodeEntries>* position_to_node_entries,
2800  const std::vector<int>& vehicles);
2803  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
2804  int64 insert_after,
2805  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2806  std::vector<NodeEntries>* node_entries);
2809  void DeleteNodeEntry(NodeEntry* entry,
2810  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2811  std::vector<NodeEntries>* node_entries);
2812 
2817  void AddNeighborForCostClass(int cost_class, int64 node_index,
2818  int64 neighbor_index, bool neighbor_is_pickup,
2819  bool neighbor_is_delivery);
2820 
2823  bool IsNeighborForCostClass(int cost_class, int64 node_index,
2824  int64 neighbor_index) const;
2825 
2827  const absl::flat_hash_set<int64>& GetPickupNeighborsOfNodeForCostClass(
2828  int cost_class, int64 node_index) {
2829  if (neighbors_ratio_ == 1) {
2830  return pickup_nodes_;
2831  }
2832  return node_index_to_pickup_neighbors_by_cost_class_[node_index]
2833  [cost_class];
2834  }
2835 
2837  const absl::flat_hash_set<int64>& GetDeliveryNeighborsOfNodeForCostClass(
2838  int cost_class, int64 node_index) {
2839  if (neighbors_ratio_ == 1) {
2840  return delivery_nodes_;
2841  }
2842  return node_index_to_delivery_neighbors_by_cost_class_[node_index]
2843  [cost_class];
2844  }
2845 
2846  const bool is_sequential_;
2847  const double farthest_seeds_ratio_;
2848  const double neighbors_ratio_;
2849 
2850  // clang-format off
2851  std::vector<std::vector<absl::flat_hash_set<int64> > >
2852  node_index_to_single_neighbors_by_cost_class_;
2853  std::vector<std::vector<absl::flat_hash_set<int64> > >
2854  node_index_to_pickup_neighbors_by_cost_class_;
2855  std::vector<std::vector<absl::flat_hash_set<int64> > >
2856  node_index_to_delivery_neighbors_by_cost_class_;
2857  // clang-format on
2858 
2862  absl::flat_hash_set<int64> pickup_nodes_;
2863  absl::flat_hash_set<int64> delivery_nodes_;
2864 };
2865 
2873  public:
2876  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2877  const std::vector<LocalSearchFilter*>& filters);
2879  bool BuildSolution() override;
2880  std::string DebugString() const override {
2881  return "LocalCheapestInsertionFilteredDecisionBuilder";
2882  }
2883 
2884  private:
2890  void ComputeEvaluatorSortedPositions(int64 node,
2891  std::vector<int64>* sorted_positions);
2896  void ComputeEvaluatorSortedPositionsOnRouteAfter(
2897  int64 node, int64 start, int64 next_after_start,
2898  std::vector<int64>* sorted_positions);
2899 };
2900 
2905  public:
2907  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
2909  bool BuildSolution() override;
2910 
2911  private:
2912  class PartialRoutesAndLargeVehicleIndicesFirst {
2913  public:
2914  explicit PartialRoutesAndLargeVehicleIndicesFirst(
2916  : builder_(builder) {}
2917  bool operator()(int vehicle1, int vehicle2) const;
2918 
2919  private:
2921  };
2923  template <typename Iterator>
2924  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
2925  Iterator end) const {
2926  const int size = model()->Size();
2927  std::vector<int64> nexts;
2928  for (Iterator it = start; it != end; ++it) {
2929  const int64 next = *it;
2930  if (next != node && (next >= size || !Contains(next))) {
2931  nexts.push_back(next);
2932  }
2933  }
2934  return nexts;
2935  }
2937  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
2938  virtual int64 FindTopSuccessor(int64 node,
2939  const std::vector<int64>& successors) = 0;
2940 };
2941 
2946  public:
2949  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
2950  const std::vector<LocalSearchFilter*>& filters);
2952  std::string DebugString() const override {
2953  return "EvaluatorCheapestAdditionFilteredDecisionBuilder";
2954  }
2955 
2956  private:
2958  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
2959  int64 FindTopSuccessor(int64 node,
2960  const std::vector<int64>& successors) override;
2961 
2962  std::function<int64(int64, int64)> evaluator_;
2963 };
2964 
2969  public:
2973  const std::vector<LocalSearchFilter*>& filters);
2975  std::string DebugString() const override {
2976  return "ComparatorCheapestAdditionFilteredDecisionBuilder";
2977  }
2978 
2979  private:
2981  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
2982  int64 FindTopSuccessor(int64 node,
2983  const std::vector<int64>& successors) override;
2984 
2985  Solver::VariableValueComparator comparator_;
2986 };
2987 
2997  public:
3001  double neighbors_ratio = 1.0;
3007  bool add_reverse_arcs = false;
3010  double arc_coefficient = 1.0;
3011  };
3012 
3015  SavingsParameters parameters,
3016  const std::vector<LocalSearchFilter*>& filters);
3018  bool BuildSolution() override;
3019 
3020  protected:
3021  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
3022 
3023  template <typename S>
3025 
3028  int64 fixed_cost;
3029 
3030  bool operator<(const VehicleClassEntry& other) const {
3031  return std::tie(fixed_cost, vehicle_class) <
3032  std::tie(other.fixed_cost, other.vehicle_class);
3033  }
3034  };
3035 
3036  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3037 
3038  virtual void BuildRoutesFromSavings() = 0;
3039 
3041  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3042  return saving.second / size_squared_;
3043  }
3045  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3046  return (saving.second % size_squared_) / Size();
3047  }
3049  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3050  return (saving.second % size_squared_) % Size();
3051  }
3053  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3054 
3064  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3065  int64 after_node);
3066 
3067  std::vector<int> type_index_of_vehicle_;
3068  // clang-format off
3069  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
3070  std::vector<std::deque<int> > vehicles_per_vehicle_class_;
3071  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3072  // clang-format on
3073 
3074  private:
3079  void AddSymetricArcsToAdjacencyLists(
3080  std::vector<std::vector<int64>>* adjacency_lists);
3081  // clang-format on
3082 
3089  void ComputeSavings();
3091  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3092  int after_node) const {
3093  return std::make_pair(saving, vehicle_type * size_squared_ +
3094  before_node * Size() + after_node);
3095  }
3096 
3104  void ComputeVehicleTypes();
3105 
3109  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3110 
3111  RoutingIndexManager* const manager_;
3112  const SavingsParameters savings_params_;
3113  int64 size_squared_;
3114 
3116 };
3117 
3120  public:
3123  SavingsParameters parameters,
3124  const std::vector<LocalSearchFilter*>& filters)
3125  : SavingsFilteredDecisionBuilder(model, manager, parameters, filters) {}
3127  std::string DebugString() const override {
3128  return "SequentialSavingsFilteredDecisionBuilder";
3129  }
3130 
3131  private:
3136  void BuildRoutesFromSavings() override;
3137  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3138 };
3139 
3142  public:
3145  SavingsParameters parameters,
3146  const std::vector<LocalSearchFilter*>& filters)
3147  : SavingsFilteredDecisionBuilder(model, manager, parameters, filters) {}
3149  std::string DebugString() const override {
3150  return "ParallelSavingsFilteredDecisionBuilder";
3151  }
3152 
3153  private:
3164  void BuildRoutesFromSavings() override;
3165 
3166  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3167 
3172  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3173  int64 after_node);
3174 
3176  std::vector<int64> first_node_on_route_;
3177  std::vector<int64> last_node_on_route_;
3181  std::vector<int> vehicle_of_first_or_last_node_;
3182 };
3183 
3187 
3190  public:
3192  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
3194  bool BuildSolution() override;
3195  std::string DebugString() const override {
3196  return "ChristofidesFilteredDecisionBuilder";
3197  }
3198 };
3199 
3204 bool SolveModelWithSat(const RoutingModel& model,
3205  const RoutingSearchParameters& search_parameters,
3206  const Assignment* initial_solution,
3207  Assignment* solution);
3208 
3210 
3212  public:
3213  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size);
3214  ~BasePathFilter() override {}
3215  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3216  int64 objective_min, int64 objective_max) override;
3217  void OnSynchronize(const Assignment* delta) override;
3218 
3219  protected:
3220  static const int64 kUnassigned;
3221 
3222  int64 GetNext(int64 node) const {
3223  return (new_nexts_[node] == kUnassigned)
3224  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3225  : new_nexts_[node];
3226  }
3227  int NumPaths() const { return starts_.size(); }
3228  int64 Start(int i) const { return starts_[i]; }
3229  int GetPath(int64 node) const { return paths_[node]; }
3230  int Rank(int64 node) const { return ranks_[node]; }
3231  bool IsDisabled() const { return status_ == DISABLED; }
3232  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3233  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3234  }
3235 
3236  private:
3237  enum Status { UNKNOWN, ENABLED, DISABLED };
3238 
3239  virtual bool DisableFiltering() const { return false; }
3240  virtual void OnBeforeSynchronizePaths() {}
3241  virtual void OnAfterSynchronizePaths() {}
3242  virtual void OnSynchronizePathFromStart(int64 start) {}
3243  virtual void InitializeAcceptPath() {}
3244  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3245  int64 chain_end) = 0;
3246  virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min,
3247  int64 objective_max) {
3248  return true;
3249  }
3251  void ComputePathStarts(std::vector<int64>* path_starts,
3252  std::vector<int>* index_to_path);
3253  bool HavePathsChanged();
3254  void SynchronizeFullAssignment();
3255  void UpdateAllRanks();
3256  void UpdatePathRanksFromStart(int start);
3257 
3258  std::vector<int64> node_path_starts_;
3259  std::vector<int64> starts_;
3260  std::vector<int> paths_;
3261  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3262  std::vector<int64> new_nexts_;
3263  std::vector<int> delta_touched_;
3264  SparseBitset<> touched_paths_;
3265  SparseBitset<> touched_path_nodes_;
3266  std::vector<int> ranks_;
3267 
3268  Status status_;
3269 };
3270 
3275 // TODO(user): Also call the solution finalizer on variables, with the
3281 // TODO(user): Avoid such false negatives.
3283  public:
3284  explicit CPFeasibilityFilter(const RoutingModel* routing_model);
3285  ~CPFeasibilityFilter() override {}
3286  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3287  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3288  int64 objective_min, int64 objective_max) override;
3289  void OnSynchronize(const Assignment* delta) override;
3290 
3291  private:
3292  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3293 
3294  static const int64 kUnassigned;
3295  const RoutingModel* const model_;
3296  Solver* const solver_;
3297  Assignment* const assignment_;
3298  Assignment* const temp_assignment_;
3299  DecisionBuilder* const restore_;
3300 };
3301 
3302 #if !defined(SWIG)
3303 IntVarLocalSearchFilter* MakeNodeDisjunctionFilter(
3304  const RoutingModel& routing_model);
3305 IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter(
3306  const RoutingModel& routing_model);
3307 IntVarLocalSearchFilter* MakeTypeRegulationsFilter(
3308  const RoutingModel& routing_model);
3309 std::vector<IntVarLocalSearchFilter*> MakeCumulFilters(
3310  const RoutingDimension& dimension, bool filter_objective_cost);
3311 IntVarLocalSearchFilter* MakePathCumulFilter(const RoutingDimension& dimension,
3312  bool propagate_own_objective_value,
3313  bool filter_objective_cost);
3314 IntVarLocalSearchFilter* MakeGlobalLPCumulFilter(
3315  GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost);
3316 IntVarLocalSearchFilter* MakePickupDeliveryFilter(
3317  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3318  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3319 IntVarLocalSearchFilter* MakeVehicleVarFilter(
3320  const RoutingModel& routing_model);
3321 IntVarLocalSearchFilter* MakeVehicleBreaksFilter(
3322  const RoutingModel& routing_model, const RoutingDimension& dimension);
3323 IntVarLocalSearchFilter* MakeCPFeasibilityFilter(
3324  const RoutingModel* routing_model);
3325 #endif
3326 
3327 } // namespace operations_research
3328 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
std::vector<::std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
int StartNewRouteWithBestVehicleOfType(int type, int64 before_node, int64 after_node)
Finds the best available vehicle of type "type" to start a new route to serve the arc before_node-->a...
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, bool propagate_own_objective_value, bool filter_objective_cost)
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
LocalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
void ArrangeIndices(std::vector< int64 > *indices)
bool BuildSolution() override
Virtual method to redefine to build a solution.
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:290
bool HasTemporalTypeRequirements() const
Definition: routing.h:775
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3232
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:333
int64 Start(int vehicle) const
Model inspection.
Definition: routing.h:1067
std::vector< IntVarLocalSearchFilter * > MakeCumulFilters(const RoutingDimension &dimension, bool filter_objective_cost)
DecisionBuilder * MakeSetValuesFromTargets(Solver *solver, std::vector< IntVar * > variables, std::vector< int64 > targets)
A decision builder which tries to assign values to variables as close as possible to target values fi...
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
DisjunctionIndex AddDisjunction(const std::vector< int64 > &indices, int64 penalty=kNoPenalty, int64 max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:2687
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:1057
std::function< bool(int64, int64, int64)> VariableValueComparator
void AddIntervalToAssignment(IntervalVar *const interval)
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:3010
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:223
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:2607
void AppendEvaluatedPositionsAfter(int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, std::vector< ValuedPosition > *valued_positions)
Helper method to the ComputeEvaluatorSortedPositions* methods.
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.
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:2561
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1152
bool AddMatrixDimension(std::vector< std::vector< int64 >> values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for...
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
Assignment * MutablePreAssignment()
Definition: routing.h:963
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 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2315
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
IntVar * FixedTransitVar(int64 index) const
Definition: routing.h:2066
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:3030
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:2676
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2101
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2265
IntVarFilteredDecisionBuilder(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< LocalSearchFilter * > &filters)
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type_
Definition: routing.h:3069
Model, model parameters or flags are not valid.
Definition: routing.h:219
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1104
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:302
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:864
const std::vector< absl::flat_hash_set< int > > & GetTemporalRequiredTypeAlternativesOfType(int type) const
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:45
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:1228
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:377
void InitialPropagate() override
This method performs the initial propagation of the constraint.
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
Definition: routing_types.h:44
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1208
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2013
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:611
double max_memory_usage_bytes
The number of neighbors considered for each node is also adapted so that the stored Savings don't use...
Definition: routing.h:3004
ParallelSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3143
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.
Deliveries must be performed in the same order as pickups.
Definition: routing.h:229
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1106
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1069
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:211
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1708
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:432
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2046
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2073
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:962
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:336
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:349
int64 GetArcCostForClass(int64 from_index, int64 to_index, int64 cost_class_index) const
Returns the cost of the segment between two nodes for a given cost class.
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:2996
void Post() override
This method is called when the constraint is processed by the solver.
BoundCost & bound_cost(int element)
Definition: routing.h:2015
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
const std::vector< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2082
gtl::ITIVector< DimensionIndex, int64 > dimension_evaluator_classes
dimension_evaluators[d]->Run(from, to) is the transit value of arc from->to for a dimension d.
Definition: routing.h:339
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2295
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3045
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:512
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:2546
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:233
Filter-based decision builder dedicated to routing.
Definition: routing.h:2590
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2075
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:319
void InitializePriorityQueue(std::vector< std::vector< StartEndValue > > *start_end_distances_per_node, Queue *priority_queue)
Initializes the priority_queue by inserting the best entry corresponding to each node,...
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:341
Checker for type requirements.
Definition: routing.h:1942
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:739
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:772
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
Status
Status of the search.
Definition: routing.h:209
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:235
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
int GetNonDeliveryCount(int type) const
Returns the number of pickups and fixed nodes from counts_of_type_["type"].
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:642
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 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:215
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
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...
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
const Assignment * PackCumulsOfOptimizerDimensionsFromAssignment(const Assignment *original_assignment, absl::Duration duration_limit)
For every dimension in the model with an optimizer in local/global_dimension_optimizers_,...
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
bool BuildSolution() override
Virtual method to redefine to build a solution.
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
Definition: routing.h:3001
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:2537
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1113
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1096
CheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:839
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:328
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2250
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:521
std::string DebugString() const override
Definition: routing.h:3286
CPFeasibilityFilter(const RoutingModel *routing_model)
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const
Same as above except that it returns default_value instead of 0 when penalty is not well defined (def...
const std::vector< int64 > & vehicle_span_upper_bounds() const
Definition: routing.h:2311
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:1978
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1192
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:2903
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1149
const E & Element(const V *const var) const
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:308
static const char kLightElement[]
Constraint types.
Definition: routing.h:1700
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
int RegisterPositiveTransitCallback(TransitCallback2 callback)
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2261
Status status() const
Returns the current status of the routing model.
Definition: routing.h:938
int GetVisitType(int64 index) const
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:332
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
EvaluatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1210
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
SavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:851
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2331
static const int64 kUnassigned
Definition: routing.h:3220
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:257
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
bool RoutesToAssignment(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices, bool close_routes, Assignment *const assignment) const
Fills an assignment from a specification of the routes of the vehicles.
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1159
Class to arrange indices by by their distance and their angles from the depot.
Definition: routing.h:2485
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
A structure to hold tasks described by their features.
Definition: routing.h:1715
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1099
int64 GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2307
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:606
const std::vector< std::pair< int, int > > & GetPickupIndexPairs(int64 node_index) const
Returns pairs for which the node is a pickup; the first element of each pair is the index in the pick...
int GetPath(int64 node) const
Definition: routing.h:3229
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
Definition: routing.h:2064
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size)
int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const
Returns the transition value for a given pair of nodes (as var index); this value is the one taken by...
void InitialPropagate() override
This method performs the initial propagation of the constraint.
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1212
void AddSoftSameVehicleConstraint(const std::vector< int64 > &indices, int64 cost)
Adds a soft contraint to force a set of variable indices to be on the same vehicle.
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2352
A DecisionBuilder is responsible for creating the search tree.
int64 GetHomogeneousCost(int64 from_index, int64 to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
Definition: routing.h:1118
void OnSynchronize(const Assignment *delta) override
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
std::vector< std::pair< int64, int64 > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
ComparatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, Solver::VariableValueComparator comparator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:2557
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
RoutingIndexPairs IndexPairs
Definition: routing.h:241
TypeRegulationsChecker(const RoutingModel &model)
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:781
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
const IntContainer & IntVarContainer() const
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:259
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:2599
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1046
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_max
Definition: routing.h:335
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:615
void SetValue(const IntVar *const var, int64 value)
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc evalua...
Definition: routing.h:2944
Local Search Filters are used for fast neighbor pruning.
SequentialSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3121
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2303
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
IntVar * SlackVar(int64 index) const
Definition: routing.h:2067
int RegisterTransitCallback(TransitCallback2 callback)
A constraint is the main modeling object.
bool BuildSolution() override
Virtual method to redefine to build a solution.
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(GlobalDimensionCumulOptimizer *optimizer, bool filter_objective_cost)
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1139
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2007
Decision builders building a solution using local search filters to evaluate its feasibility.
Definition: routing.h:2521
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:525
CheapestAdditionFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
const std::vector< IntVar * > & transits() const
Definition: routing.h:2074
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1133
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:1944
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:1090
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:321
void OnSynchronize(const Assignment *delta) override
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:2087
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:698
bool AddVectorDimension(std::vector< int64 > values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; ...
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:846
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1073
const std::vector< int64 > & vehicle_span_cost_coefficients() const
Definition: routing.h:2319
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2078
RoutingFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
bool BuildSolution() override
Virtual method to redefine to build a solution.
GlobalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters, bool is_sequential, double farthest_seeds_ratio, double neighbors_ratio)
Takes ownership of evaluators.
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
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:2094
void Post() override
This method is called when the constraint is processed by the solver.
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model)
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1147
ChristofidesFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2532
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:227
bool ApplyLocksToAllVehicles(const std::vector< std::vector< int64 >> &locks, bool close_routes)
Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for rout...
TypeRegulationsConstraint(const RoutingModel &model)
Checker for type incompatibilities.
Definition: routing.h:1926
void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration, int vehicle)
With breaks supposed to be consecutive, this forces the distance between breaks of size at least mini...
int64 GetTransitValueFromClass(int64 from_index, int64 to_index, int64 vehicle_class) const
Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicl...
Definition: routing.h:2057
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
Manager for any NodeIndex <-> variable index conversion.
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:694
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:234
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:217
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2298
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:1793
virtual bool CheckTypeRegulations(int type)=0
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:373
RoutingCostClassIndex CostClassIndex
Definition: routing.h:231
BoundCost bound_cost(int element) const
Definition: routing.h:2016
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
Definition: routing.h:3282
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:357
bool Check() override
This method is called to check the status of the limit.
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3071
std::vector< std::deque< int > > vehicles_per_vehicle_class_
Definition: routing.h:3070
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
bool AddDimensionWithVehicleTransitAndCapacity(const std::vector< int > &evaluator_indices, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
int64 GetArcCostForVehicle(int64 from_index, int64 to_index, int64 vehicle) const
Returns the cost of the transit arc between two nodes for a given vehicle.
int64 GetNext(int64 node) const
Definition: routing.h:3222
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:2568
A BaseObject is the root of all reversibly allocated objects.
std::vector< std::vector< StartEndValue > > ComputeStartEndDistanceForVehicles(const std::vector< int > &vehicles)
Computes and returns the distance of each uninserted node to every vehicle in "vehicles" as a std::ve...
virtual bool HasRegulationsToCheck() const =0
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,...
bool operator<(const DimensionCost &cost) const
Definition: routing.h:294
int GetNonDeliveredCount(int type) const
Same as above, but substracting the number of deliveries of "type".
std::function< int64(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
Definition: routing.h:2279
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the sets of same-vehicle/temporal requirement alternatives for the given type.
void 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...
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
void AddTemporalRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D temporally depends on type_R, any non-delivery node_D of type_D requires at least one non-d...
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty std::string if it is unset.
Definition: routing.h:556
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3053
std::function< int64(int64, int64)> RoutingTransitCallback2
Definition: routing_types.h:42
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:842
void AppendTasksFromPath(const std::vector< int64 > &path, const std::vector< int64 > &min_travels, const std::vector< int64 > &max_travels, const std::vector< int64 > &pre_travels, const std::vector< int64 > &post_travels, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
The class IntVar is a subset of IntExpr.
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:353
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1157
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:2597
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
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...
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2072
Generic path-based filter class.
Definition: routing.h:3211
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model)
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
void SetVisitType(int64 index, int type)
Set the node visit types and incompatibilities/requirements between the types (see below).
IntVar * TransitVar(int64 index) const
Definition: routing.h:2065
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:2341
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex(int64 index, int64 max_cardinality, F f) const
Calls f for each variable index of indices in the same disjunctions as the node corresponding to the ...
Definition: routing.h:587
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
Definition: routing.h:262
void SetSectors(int sectors)
Definition: routing.h:2490
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:334
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:3007
A Decision represents a choice point in the search tree.
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1201
Interval variables are often used in scheduling.
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1050
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:859
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc compar...
Definition: routing.h:2967
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:2871
void AddTemporalTypeIncompatibility(int type1, int type2)
virtual bool BuildSolution()=0
Virtual method to redefine to build a solution.
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:2566
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1725
bool BuildSolution() override
Virtual method to redefine to build a solution.
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &pure_transits, const std::vector< int > &dependent_transits, const RoutingDimension *base_dimension, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension with transits depending on the cumuls of another dimension.
Definition: routing.h:464
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
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...
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2050
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:268
void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor, int64 quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
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:1087
RoutingIndexPair IndexPair
Definition: routing.h:240
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:2543
int VehicleIndex(int index) const
Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/en...
Definition: routing.h:1076
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1195
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:213
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:579
int64 global_span_cost_coefficient() const
Definition: routing.h:2323
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
int vehicle_to_class(int vehicle) const
Definition: routing.h:2105
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3049
An Assignment is a variable -> domains mapping, used to report solutions to the user.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:550
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1724
std::function< int64(int64)> RoutingTransitCallback1
Definition: routing_types.h:41
RoutingDimensionIndex DimensionIndex
Definition: routing.h:232
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:742
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
Definition: routing.h:3041
int Rank(int64 node) const
Definition: routing.h:3230
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:381
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
bool Accept(const Assignment *delta, const Assignment *deltadelta, int64 objective_min, int64 objective_max) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
bool AddConstantDimensionWithSlack(int64 value, int64 capacity, int64 slack_max, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is t...
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
std::function< int64(int64, int64)> IndexEvaluator2
void AssignmentToRoutes(const Assignment &assignment, std::vector< std::vector< int64 >> *const routes) const
Converts the solution in the given assignment to routes for all vehicles.
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:236