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"
185 #include "ortools/glop/lp_solver.h"
186 #include "ortools/glop/parameters.pb.h"
187 #include "ortools/graph/graph.h"
188 #include "ortools/lp_data/lp_data.h"
189 #include "ortools/lp_data/lp_types.h"
190 #include "ortools/sat/theta_tree.h"
191 #include "ortools/util/range_query_function.h"
192 #include "ortools/util/sorted_interval_list.h"
193 
194 namespace operations_research {
195 
196 class GlobalDimensionCumulOptimizer;
197 class LocalDimensionCumulOptimizer;
198 class LocalSearchOperator;
199 #ifndef SWIG
200 class IntVarFilteredDecisionBuilder;
201 class IntVarFilteredHeuristic;
202 class IndexNeighborFinder;
203 #endif
204 class RoutingDimension;
205 #ifndef SWIG
206 using util::ReverseArcListGraph;
207 class SweepArranger;
208 #endif
209 struct SweepIndex;
210 
212  public:
214  enum Status {
225  };
226 
235  };
236  typedef RoutingCostClassIndex CostClassIndex;
237  typedef RoutingDimensionIndex DimensionIndex;
238  typedef RoutingDisjunctionIndex DisjunctionIndex;
239  typedef RoutingVehicleClassIndex VehicleClassIndex;
242 
243 // TODO(user): Remove all SWIG guards by adding the @ignore in .i.
244 #if !defined(SWIG)
247 #endif // SWIG
248 
249 #if !defined(SWIG)
250  struct StateDependentTransit {
263  RangeIntToIntFunction* transit;
264  RangeMinMaxIndexFunction* transit_plus_identity;
265  };
266  typedef std::function<StateDependentTransit(int64, int64)>
268 #endif // SWIG
269 
270 #if !defined(SWIG)
271  struct CostClass {
274 
289 
295  struct DimensionCost {
299  bool operator<(const DimensionCost& cost) const {
302  }
303  return cost_coefficient < cost.cost_coefficient;
304  }
305  };
306  std::vector<DimensionCost>
308 
311 
313  static bool LessThan(const CostClass& a, const CostClass& b) {
314  if (a.evaluator_index != b.evaluator_index) {
315  return a.evaluator_index < b.evaluator_index;
316  }
319  }
320  };
321 
322  struct VehicleClass {
326  int64 fixed_cost;
331  // TODO(user): Find equivalent start/end nodes wrt dimensions and
332  // callbacks.
337  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_min;
338  gtl::ITIVector<DimensionIndex, int64> dimension_start_cumuls_max;
339  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_min;
340  gtl::ITIVector<DimensionIndex, int64> dimension_end_cumuls_max;
341  gtl::ITIVector<DimensionIndex, int64> dimension_capacities;
344  gtl::ITIVector<DimensionIndex, int64> dimension_evaluator_classes;
347 
349  static bool LessThan(const VehicleClass& a, const VehicleClass& b);
350  };
351 #endif // defined(SWIG)
352 
359  int64 fixed_cost;
360 
361  bool operator<(const VehicleClassEntry& other) const {
362  return std::tie(fixed_cost, vehicle_class) <
363  std::tie(other.fixed_cost, other.vehicle_class);
364  }
365  };
366 
367  int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
368 
369  int Type(int vehicle) const {
370  DCHECK_LT(vehicle, type_index_of_vehicle.size());
371  return type_index_of_vehicle[vehicle];
372  }
373 
374  std::vector<int> type_index_of_vehicle;
375  // clang-format off
376  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
377  std::vector<std::deque<int> > vehicles_per_vehicle_class;
378  // clang-format on
379  };
380 
382  static const int64 kNoPenalty;
383 
387 
391 
395  explicit RoutingModel(const RoutingIndexManager& index_manager);
396  RoutingModel(const RoutingIndexManager& index_manager,
397  const RoutingModelParameters& parameters);
399 
406  const TransitCallback2& TransitCallback(int callback_index) const {
407  CHECK_LT(callback_index, transit_evaluators_.size());
408  return transit_evaluators_[callback_index];
409  }
410  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
411  CHECK_LT(callback_index, unary_transit_evaluators_.size());
412  return unary_transit_evaluators_[callback_index];
413  }
415  int callback_index) const {
416  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
417  return state_dependent_transit_evaluators_[callback_index];
418  }
419 
421 
433 
442  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
443  bool fix_start_cumul_to_zero, const std::string& name);
445  const std::vector<int>& evaluator_indices, int64 slack_max,
446  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
447  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
448  std::vector<int64> vehicle_capacities,
449  bool fix_start_cumul_to_zero,
450  const std::string& name);
452  const std::vector<int>& evaluator_indices, int64 slack_max,
453  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
454  const std::string& name);
461  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
462  int64 slack_max,
463  bool fix_start_cumul_to_zero,
464  const std::string& name);
465  bool AddConstantDimension(int64 value, int64 capacity,
466  bool fix_start_cumul_to_zero,
467  const std::string& name) {
468  return AddConstantDimensionWithSlack(value, capacity, 0,
469  fix_start_cumul_to_zero, name);
470  }
478  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
479  bool fix_start_cumul_to_zero,
480  const std::string& name);
489  std::vector<std::vector<int64> /*needed_for_swig*/> values,
490  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
498  const std::vector<int>& pure_transits,
499  const std::vector<int>& dependent_transits,
500  const RoutingDimension* base_dimension, int64 slack_max,
501  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
502  const std::string& name) {
503  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
504  pure_transits, dependent_transits, base_dimension, slack_max,
505  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
506  }
507 
510  const std::vector<int>& transits, const RoutingDimension* base_dimension,
511  int64 slack_max, std::vector<int64> vehicle_capacities,
512  bool fix_start_cumul_to_zero, const std::string& name);
515  int transit, const RoutingDimension* base_dimension, int64 slack_max,
516  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
517  const std::string& name);
519  int pure_transit, int dependent_transit,
520  const RoutingDimension* base_dimension, int64 slack_max,
521  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
522  const std::string& name);
523 
526  const std::function<int64(int64)>& f, int64 domain_start,
527  int64 domain_end);
528 
538  Constraint* MakePathSpansAndTotalSlacks(const RoutingDimension* dimension,
539  std::vector<IntVar*> spans,
540  std::vector<IntVar*> total_slacks);
541 
543  // TODO(user): rename.
544  std::vector<std::string> GetAllDimensionNames() const;
546  const std::vector<RoutingDimension*>& GetDimensions() const {
547  return dimensions_.get();
548  }
550  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
551  // clang-format off
554  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
556  return global_dimension_optimizers_;
557  }
558  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
560  return local_dimension_optimizers_;
561  }
562  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
564  return local_dimension_mp_optimizers_;
565  }
566  // clang-format on
567 
571  const RoutingDimension& dimension) const;
573  const RoutingDimension& dimension) const;
575  const RoutingDimension& dimension) const;
576 
578  bool HasDimension(const std::string& dimension_name) const;
581  const std::string& dimension_name) const;
585  const std::string& dimension_name) const;
590  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
591  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
592  primary_constrained_dimension_ = dimension_name;
593  }
595  const std::string& GetPrimaryConstrainedDimension() const {
596  return primary_constrained_dimension_;
597  }
614  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
615  int64 penalty = kNoPenalty,
616  int64 max_cardinality = 1);
618  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
619  int64 index) const {
620  return index_to_disjunctions_[index];
621  }
625  template <typename F>
627  int64 index, int64 max_cardinality, F f) const {
628  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
629  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
630  for (const int64 d_index : disjunctions_[disjunction].indices) {
631  f(d_index);
632  }
633  }
634  }
635  }
636 #if !defined(SWIGPYTHON)
637  const std::vector<int64>& GetDisjunctionIndices(
640  DisjunctionIndex index) const {
641  return disjunctions_[index].indices;
642  }
643 #endif // !defined(SWIGPYTHON)
644  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
646  return disjunctions_[index].value.penalty;
647  }
651  return disjunctions_[index].value.max_cardinality;
652  }
654  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
659  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
666 
670  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
671  int64 cost);
672 
677  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
678  int64 index);
679 
681  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
682  return allowed_vehicles_[index].empty() ||
683  allowed_vehicles_[index].find(vehicle) !=
684  allowed_vehicles_[index].end();
685  }
686 
701  // TODO(user): Remove this when model introspection detects linked nodes.
702  void AddPickupAndDelivery(int64 pickup, int64 delivery);
707  DisjunctionIndex delivery_disjunction);
708  // clang-format off
712  const std::vector<std::pair<int, int> >&
713  GetPickupIndexPairs(int64 node_index) const;
715  const std::vector<std::pair<int, int> >&
716  GetDeliveryIndexPairs(int64 node_index) const;
717  // clang-format on
718 
723  int vehicle);
725  int vehicle) const;
728 
730 
731 #ifndef SWIG
732  const IndexPairs& GetPickupAndDeliveryPairs() const {
734  return pickup_delivery_pairs_;
735  }
736  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
738  return pickup_delivery_disjunctions_;
739  }
740 #endif // SWIG
741  enum VisitTypePolicy {
768  };
769  // TODO(user): Support multiple visit types per node?
770  void SetVisitType(int64 index, int type, VisitTypePolicy type_policy);
771  int GetVisitType(int64 index) const;
772  const std::vector<int>& GetSingleNodesOfType(int type) const;
773  const std::vector<int>& GetPairIndicesOfType(int type) const;
777  // TODO(user): Reconsider the logic and potentially remove the need to
780  int GetNumberOfVisitTypes() const { return num_visit_types_; }
781  const std::vector<int>& GetTopologicallySortedVisitTypes() const {
782  DCHECK(closed_);
783  return topologically_sorted_visit_types_;
784  }
789  void AddHardTypeIncompatibility(int type1, int type2);
790  void AddTemporalTypeIncompatibility(int type1, int type2);
792  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
793  int type) const;
794  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
795  int type) const;
799  return has_hard_type_incompatibilities_;
800  }
802  return has_temporal_type_incompatibilities_;
803  }
815  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
821  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
828  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
829  // clang-format off
832  const std::vector<absl::flat_hash_set<int> >&
835  const std::vector<absl::flat_hash_set<int> >&
838  const std::vector<absl::flat_hash_set<int> >&
840  // clang-format on
844  return has_same_vehicle_type_requirements_;
845  }
847  return has_temporal_type_requirements_;
848  }
849 
852  bool HasTypeRegulations() const {
856  }
857 
862  int64 UnperformedPenalty(int64 var_index) const;
866  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
870  int64 GetDepot() const;
871 
876  void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
877  max_active_vehicles_ = max_active_vehicles;
878  }
880  int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
884  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
886  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
889  void SetFixedCostOfAllVehicles(int64 cost);
891  void SetFixedCostOfVehicle(int64 cost, int vehicle);
895  int64 GetFixedCostOfVehicle(int vehicle) const;
896 
912  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
913  int64 quadratic_cost_factor);
915  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
916  int64 quadratic_cost_factor,
917  int vehicle);
918 
919  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
920  return linear_cost_factor_of_vehicle_;
921  }
922  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
923  return quadratic_cost_factor_of_vehicle_;
924  }
925 
926  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
927  DCHECK_LT(vehicle, vehicles_);
928  consider_empty_route_costs_[vehicle] = consider_costs;
929  }
930 
931  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
932  DCHECK_LT(vehicle, vehicles_);
933  return consider_empty_route_costs_[vehicle];
934  }
935 
938 #ifndef SWIG
939  const Solver::IndexEvaluator2& first_solution_evaluator() const {
940  return first_solution_evaluator_;
941  }
942 #endif
943  void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator) {
945  first_solution_evaluator_ = std::move(evaluator);
946  }
951  void AddSearchMonitor(SearchMonitor* const monitor);
955  void AddAtSolutionCallback(std::function<void()> callback);
966  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost);
969  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
976  void CloseModel();
980  const RoutingSearchParameters& search_parameters);
987  const Assignment* Solve(const Assignment* assignment = nullptr);
995  const Assignment* SolveWithParameters(
996  const RoutingSearchParameters& search_parameters,
997  std::vector<const Assignment*>* solutions = nullptr);
999  const Assignment* assignment,
1000  const RoutingSearchParameters& search_parameters,
1001  std::vector<const Assignment*>* solutions = nullptr);
1008  Assignment* target_assignment, const RoutingModel* source_model,
1009  const Assignment* source_assignment);
1015  // TODO(user): Add support for non-homogeneous costs and disjunctions.
1018  Status status() const { return status_; }
1027  IntVar* ApplyLocks(const std::vector<int64>& locks);
1036  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
1037  bool close_routes);
1042  const Assignment* const PreAssignment() const { return preassignment_; }
1043  Assignment* MutablePreAssignment() { return preassignment_; }
1047  bool WriteAssignment(const std::string& file_name) const;
1051  Assignment* ReadAssignment(const std::string& file_name);
1054  Assignment* RestoreAssignment(const Assignment& solution);
1061  const std::vector<std::vector<int64>>& routes,
1062  bool ignore_inactive_indices);
1079  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
1080  bool ignore_inactive_indices, bool close_routes,
1081  Assignment* const assignment) const;
1085  void AssignmentToRoutes(const Assignment& assignment,
1086  std::vector<std::vector<int64>>* const routes) const;
1091 #ifndef SWIG
1092  std::vector<std::vector<int64>> GetRoutesFromAssignment(
1093  const Assignment& assignment);
1094 #endif
1095  Assignment* CompactAssignment(const Assignment& assignment) const;
1116  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1118  void AddToAssignment(IntVar* const var);
1119  void AddIntervalToAssignment(IntervalVar* const interval);
1131  const Assignment* original_assignment, absl::Duration duration_limit);
1132 #ifndef SWIG
1133  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1135  sweep_arranger_.reset(sweep_arranger);
1136  }
1138  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1139 #endif
1140  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1146  CHECK(filter != nullptr);
1147  if (closed_) {
1148  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1149  }
1150  extra_filters_.push_back(filter);
1151  }
1152 
1155  int64 Start(int vehicle) const { return starts_[vehicle]; }
1157  int64 End(int vehicle) const { return ends_[vehicle]; }
1159  bool IsStart(int64 index) const;
1161  bool IsEnd(int64 index) const { return index >= Size(); }
1164  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1168  int64 Next(const Assignment& assignment, int64 index) const;
1170  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1171 
1172 #if !defined(SWIGPYTHON)
1173  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1178  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1179 #endif
1180  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1183  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1187  IntVar* ActiveVehicleVar(int vehicle) const {
1188  return vehicle_active_[vehicle];
1189  }
1192  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1193  return vehicle_costs_considered_[vehicle];
1194  }
1197  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1199  IntVar* CostVar() const { return cost_; }
1200 
1203  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1204  int64 vehicle) const;
1207  return costs_are_homogeneous_across_vehicles_;
1208  }
1211  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1212  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1213  }
1216  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1223  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1224  int64 /*CostClassIndex*/ cost_class_index) const;
1227  DCHECK(closed_);
1228  return cost_class_index_of_vehicle_[vehicle];
1229  }
1232  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1233  DCHECK(closed_);
1234  if (cost_class_index == kCostClassIndexOfZeroCost) {
1235  return has_vehicle_with_zero_cost_class_;
1236  }
1237  return cost_class_index < cost_classes_.size();
1238  }
1240  int GetCostClassesCount() const { return cost_classes_.size(); }
1243  return std::max(0, GetCostClassesCount() - 1);
1244  }
1246  DCHECK(closed_);
1247  return vehicle_class_index_of_vehicle_[vehicle];
1248  }
1250  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1252  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1253  DCHECK(closed_);
1254  return same_vehicle_groups_[same_vehicle_group_[node]];
1255  }
1256 
1258  DCHECK(closed_);
1259  return vehicle_type_container_;
1260  }
1261 
1280  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1286  const Assignment& solution_assignment,
1287  const std::string& dimension_to_print) const;
1293 #ifndef SWIG
1294  std::vector<std::vector<std::pair<int64, int64>>> GetCumulBounds(
1295  const Assignment& solution_assignment, const RoutingDimension& dimension);
1296 #endif
1297  Solver* solver() const { return solver_.get(); }
1300 
1302  bool CheckLimit() {
1303  DCHECK(limit_ != nullptr);
1304  return limit_->Check();
1305  }
1306 
1308  absl::Duration RemainingTime() const {
1309  DCHECK(limit_ != nullptr);
1310  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1311  }
1312 
1315  int nodes() const { return nodes_; }
1317  int vehicles() const { return vehicles_; }
1319  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1320 
1324  const RoutingSearchParameters& search_parameters) const;
1326  const RoutingSearchParameters& search_parameters) const;
1328  operations_research::FirstSolutionStrategy::Value
1330  return automatic_first_solution_strategy_;
1331  }
1332 
1334  bool IsMatchingModel() const;
1335 
1336 #ifndef SWIG
1337  using GetTabuVarsCallback =
1340  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1341 
1342  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1343 #endif // SWIG
1344 
1346  // TODO(user): Find a way to test and restrict the access at the same time.
1358  DecisionBuilder* MakeGuidedSlackFinalizer(
1359  const RoutingDimension* dimension,
1360  std::function<int64(int64)> initializer);
1361 #ifndef SWIG
1362  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1367  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1368  std::vector<IntVar*> variables);
1369 #endif
1370  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1384  const RoutingDimension* dimension);
1385 
1386  private:
1388  enum RoutingLocalSearchOperator {
1389  RELOCATE = 0,
1390  RELOCATE_PAIR,
1391  LIGHT_RELOCATE_PAIR,
1392  RELOCATE_NEIGHBORS,
1393  EXCHANGE,
1394  EXCHANGE_PAIR,
1395  CROSS,
1396  CROSS_EXCHANGE,
1397  TWO_OPT,
1398  OR_OPT,
1399  GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1400  LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1401  GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1402  LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1403  GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1404  LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1405  RELOCATE_EXPENSIVE_CHAIN,
1406  LIN_KERNIGHAN,
1407  TSP_OPT,
1408  MAKE_ACTIVE,
1409  RELOCATE_AND_MAKE_ACTIVE,
1410  MAKE_ACTIVE_AND_RELOCATE,
1411  MAKE_INACTIVE,
1412  MAKE_CHAIN_INACTIVE,
1413  SWAP_ACTIVE,
1414  EXTENDED_SWAP_ACTIVE,
1415  NODE_PAIR_SWAP,
1416  PATH_LNS,
1417  FULL_PATH_LNS,
1418  TSP_LNS,
1419  INACTIVE_LNS,
1420  EXCHANGE_RELOCATE_PAIR,
1421  RELOCATE_SUBTRIP,
1422  EXCHANGE_SUBTRIP,
1423  LOCAL_SEARCH_OPERATOR_COUNTER
1424  };
1425 
1429  template <typename T>
1430  struct ValuedNodes {
1431  std::vector<int64> indices;
1432  T value;
1433  };
1434  struct DisjunctionValues {
1435  int64 penalty;
1436  int64 max_cardinality;
1437  };
1438  typedef ValuedNodes<DisjunctionValues> Disjunction;
1439 
1442  struct CostCacheElement {
1447  int index;
1448  CostClassIndex cost_class_index;
1449  int64 cost;
1450  };
1451 
1453  void Initialize();
1454  void AddNoCycleConstraintInternal();
1455  bool AddDimensionWithCapacityInternal(
1456  const std::vector<int>& evaluator_indices, int64 slack_max,
1457  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1458  const std::string& name);
1459  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1460  const std::vector<int>& pure_transits,
1461  const std::vector<int>& dependent_transits,
1462  const RoutingDimension* base_dimension, int64 slack_max,
1463  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1464  const std::string& name);
1465  bool InitializeDimensionInternal(
1466  const std::vector<int>& evaluator_indices,
1467  const std::vector<int>& state_dependent_evaluator_indices,
1468  int64 slack_max, bool fix_start_cumul_to_zero,
1469  RoutingDimension* dimension);
1470  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1471 
1499  void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1500 
1501  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1502  void ComputeVehicleClasses();
1510  void ComputeVehicleTypes();
1520  void FinalizeVisitTypes();
1521  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1522  CostClassIndex cost_class_index) const;
1523  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1524  int node_index,
1525  std::vector<IntVar*>* cost_elements);
1526  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1527  std::vector<IntVar*>* cost_elements);
1528  Assignment* DoRestoreAssignment();
1529  static const CostClassIndex kCostClassIndexOfZeroCost;
1530  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1531  DCHECK_LT(0, vehicles_);
1532  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1533  : kCostClassIndexOfZeroCost)
1534  .value();
1535  }
1536  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1537  const CostClass& cost_class) const;
1539  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1541  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1542  const std::vector<int64>& deliveries);
1545  IntVar* CreateSameVehicleCost(int vehicle_index);
1548  int FindNextActive(int index, const std::vector<int64>& indices) const;
1549 
1552  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1553  int vehicle) const;
1561  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1562  Assignment* compact_assignment) const;
1563 
1564  void QuietCloseModel();
1565  void QuietCloseModelWithParameters(
1566  const RoutingSearchParameters& parameters) {
1567  if (!closed_) {
1568  CloseModelWithParameters(parameters);
1569  }
1570  }
1571 
1573  bool SolveMatchingModel(Assignment* assignment,
1574  const RoutingSearchParameters& parameters);
1575 #ifndef SWIG
1576  bool AppendAssignmentIfFeasible(
1578  const Assignment& assignment,
1579  std::vector<std::unique_ptr<Assignment>>* assignments);
1580 #endif
1581  void LogSolution(const RoutingSearchParameters& parameters,
1583  const std::string& description, int64 solution_cost,
1584  int64 start_time_ms);
1587  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1588  bool check_compact_assignment) const;
1593  std::string FindErrorInSearchParametersForModel(
1594  const RoutingSearchParameters& search_parameters) const;
1596  void SetupSearch(const RoutingSearchParameters& search_parameters);
1598  // TODO(user): Document each auxiliary method.
1599  Assignment* GetOrCreateAssignment();
1600  Assignment* GetOrCreateTmpAssignment();
1601  RegularLimit* GetOrCreateLimit();
1602  RegularLimit* GetOrCreateLocalSearchLimit();
1603  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1604  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1605  LocalSearchOperator* CreateInsertionOperator();
1606  LocalSearchOperator* CreateMakeInactiveOperator();
1607  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1608  LocalSearchOperator* GetNeighborhoodOperators(
1609  const RoutingSearchParameters& search_parameters) const;
1610  std::vector<LocalSearchFilter*> GetOrCreateLocalSearchFilters(
1611  const RoutingSearchParameters& parameters);
1612  LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1613  const RoutingSearchParameters& parameters);
1614  std::vector<LocalSearchFilter*> GetOrCreateFeasibilityFilters(
1615  const RoutingSearchParameters& parameters);
1616  LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1617  const RoutingSearchParameters& parameters);
1618  LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1619  const RoutingSearchParameters& parameters);
1620  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1621  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1622  void CreateFirstSolutionDecisionBuilders(
1623  const RoutingSearchParameters& search_parameters);
1624  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1625  const RoutingSearchParameters& search_parameters) const;
1626  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1627  const RoutingSearchParameters& parameters) const;
1628  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1629  const RoutingSearchParameters& search_parameters);
1630  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1631  const RoutingSearchParameters& search_parameters);
1632  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1633  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1634  void SetupAssignmentCollector(
1635  const RoutingSearchParameters& search_parameters);
1636  void SetupTrace(const RoutingSearchParameters& search_parameters);
1637  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1638  bool UsesLightPropagation(
1639  const RoutingSearchParameters& search_parameters) const;
1640  GetTabuVarsCallback tabu_var_callback_;
1641 
1642  int GetVehicleStartClass(int64 start) const;
1643 
1644  void InitSameVehicleGroups(int number_of_groups) {
1645  same_vehicle_group_.assign(Size(), 0);
1646  same_vehicle_groups_.assign(number_of_groups, {});
1647  }
1648  void SetSameVehicleGroup(int index, int group) {
1649  same_vehicle_group_[index] = group;
1650  same_vehicle_groups_[group].push_back(index);
1651  }
1652 
1654  std::unique_ptr<Solver> solver_;
1655  int nodes_;
1656  int vehicles_;
1657  int max_active_vehicles_;
1658  Constraint* no_cycle_constraint_ = nullptr;
1660  std::vector<IntVar*> nexts_;
1661  std::vector<IntVar*> vehicle_vars_;
1662  std::vector<IntVar*> active_;
1663  // The following vectors are indexed by vehicle index.
1664  std::vector<IntVar*> vehicle_active_;
1665  std::vector<IntVar*> vehicle_costs_considered_;
1670  std::vector<IntVar*> is_bound_to_end_;
1671  mutable RevSwitch is_bound_to_end_ct_added_;
1673  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1674  gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1675  // clang-format off
1679  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1680  global_dimension_optimizers_;
1681  gtl::ITIVector<DimensionIndex, int> global_optimizer_index_;
1682  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1683  local_dimension_optimizers_;
1684  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1685  local_dimension_mp_optimizers_;
1686  // clang-format off
1687  gtl::ITIVector<DimensionIndex, int> local_optimizer_index_;
1688  std::string primary_constrained_dimension_;
1690  IntVar* cost_ = nullptr;
1691  std::vector<int> vehicle_to_transit_cost_;
1692  std::vector<int64> fixed_cost_of_vehicle_;
1693  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1694  bool has_vehicle_with_zero_cost_class_;
1695  std::vector<int64> linear_cost_factor_of_vehicle_;
1696  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1697  bool vehicle_amortized_cost_factors_set_;
1708  std::vector<bool> consider_empty_route_costs_;
1709 #ifndef SWIG
1710  gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1711 #endif // SWIG
1712  bool costs_are_homogeneous_across_vehicles_;
1713  bool cache_callbacks_;
1714  mutable std::vector<CostCacheElement> cost_cache_;
1715  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1716 #ifndef SWIG
1717  gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1718 #endif // SWIG
1719  VehicleTypeContainer vehicle_type_container_;
1720  std::function<int(int64)> vehicle_start_class_callback_;
1722  gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1723  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1725  std::vector<ValuedNodes<int64> > same_vehicle_costs_;
1727 #ifndef SWIG
1728  std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1729 #endif // SWIG
1730  IndexPairs pickup_delivery_pairs_;
1732  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1733  pickup_delivery_disjunctions_;
1734  // clang-format off
1735  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1736  // vector of pairs {pair_index, pickup_index} such that
1737  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1738  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1739  // Same as above for deliveries.
1740  std::vector<std::vector<std::pair<int, int> > >
1741  index_to_delivery_index_pairs_;
1742  // clang-format on
1743  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1744  // Same vehicle group to which a node belongs.
1745  std::vector<int> same_vehicle_group_;
1746  // Same vehicle node groups.
1747  std::vector<std::vector<int>> same_vehicle_groups_;
1748  // Node visit types
1749  // Variable index to visit type index.
1750  std::vector<int> index_to_visit_type_;
1751  // Variable index to VisitTypePolicy.
1752  std::vector<VisitTypePolicy> index_to_type_policy_;
1753  // clang-format off
1754  std::vector<std::vector<int> > single_nodes_of_type_;
1755  std::vector<std::vector<int> > pair_indices_of_type_;
1756 
1757  std::vector<absl::flat_hash_set<int> >
1758  hard_incompatible_types_per_type_index_;
1759  bool has_hard_type_incompatibilities_;
1760  std::vector<absl::flat_hash_set<int> >
1761  temporal_incompatible_types_per_type_index_;
1762  bool has_temporal_type_incompatibilities_;
1763 
1764  std::vector<std::vector<absl::flat_hash_set<int> > >
1765  same_vehicle_required_type_alternatives_per_type_index_;
1766  bool has_same_vehicle_type_requirements_;
1767  std::vector<std::vector<absl::flat_hash_set<int> > >
1768  required_type_alternatives_when_adding_type_index_;
1769  std::vector<std::vector<absl::flat_hash_set<int> > >
1770  required_type_alternatives_when_removing_type_index_;
1771  bool has_temporal_type_requirements_;
1772  absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
1773  trivially_infeasible_visit_types_to_policies_;
1774  // clang-format on
1775 
1776  // Visit types sorted topologically based on required-->dependent requirement
1777  // arcs between the types (if the requirement/dependency graph is acyclic).
1778  std::vector<int> topologically_sorted_visit_types_;
1779  int num_visit_types_;
1780  // Two indices are equivalent if they correspond to the same node (as given
1781  // to the constructors taking a RoutingIndexManager).
1782  std::vector<int> index_to_equivalence_class_;
1783  std::vector<int> index_to_vehicle_;
1784  std::vector<int64> starts_;
1785  std::vector<int64> ends_;
1786  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1787  // anymore.
1788  RoutingIndexManager manager_;
1789  int start_end_count_;
1790  // Model status
1791  bool closed_ = false;
1792  Status status_ = ROUTING_NOT_SOLVED;
1793  bool enable_deep_serialization_ = true;
1794 
1795  // Search data
1796  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1797  std::vector<IntVarFilteredDecisionBuilder*>
1798  first_solution_filtered_decision_builders_;
1799  Solver::IndexEvaluator2 first_solution_evaluator_;
1800  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
1801  FirstSolutionStrategy::UNSET;
1802  std::vector<LocalSearchOperator*> local_search_operators_;
1803  std::vector<SearchMonitor*> monitors_;
1804  SolutionCollector* collect_assignments_ = nullptr;
1805  SolutionCollector* collect_one_assignment_ = nullptr;
1806  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1807  DecisionBuilder* solve_db_ = nullptr;
1808  DecisionBuilder* improve_db_ = nullptr;
1809  DecisionBuilder* restore_assignment_ = nullptr;
1810  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1811  Assignment* assignment_ = nullptr;
1812  Assignment* preassignment_ = nullptr;
1813  Assignment* tmp_assignment_ = nullptr;
1814  std::vector<IntVar*> extra_vars_;
1815  std::vector<IntervalVar*> extra_intervals_;
1816  std::vector<LocalSearchOperator*> extra_operators_;
1817  LocalSearchFilterManager* local_search_filter_manager_ = nullptr;
1818  LocalSearchFilterManager* feasibility_filter_manager_ = nullptr;
1819  LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr;
1820  std::vector<LocalSearchFilter*> extra_filters_;
1821 #ifndef SWIG
1822  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1823  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1824  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1825  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1826  std::unique_ptr<SweepArranger> sweep_arranger_;
1827 #endif
1828 
1829  RegularLimit* limit_ = nullptr;
1830  RegularLimit* ls_limit_ = nullptr;
1831  RegularLimit* lns_limit_ = nullptr;
1832  RegularLimit* first_solution_lns_limit_ = nullptr;
1833 
1834  typedef std::pair<int64, int64> CacheKey;
1835  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1836  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1837  StateDependentTransitCallbackCache;
1838 
1839  std::vector<TransitCallback1> unary_transit_evaluators_;
1840  std::vector<TransitCallback2> transit_evaluators_;
1841  // The following vector stores a boolean per transit_evaluator_, indicating
1842  // whether the transits are all positive.
1843  // is_transit_evaluator_positive_ will be set to true only when registering a
1844  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1845  // The actual positivity of the transit values will only be checked in debug
1846  // mode, when calling RegisterPositiveTransitCallback().
1847  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1848  // transits are known to be positive, as the positivity of a callback will
1849  // allow some improvements in the solver, but will entail in errors if the
1850  // transits are falsely assumed positive.
1851  std::vector<bool> is_transit_evaluator_positive_;
1852  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1853  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1854  state_dependent_transit_evaluators_cache_;
1855 
1856  friend class RoutingDimension;
1858 
1859  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1860 };
1861 
1863 class RoutingModelVisitor : public BaseObject {
1864  public:
1866  static const char kLightElement[];
1867  static const char kLightElement2[];
1868  static const char kRemoveValues[];
1869 };
1870 
1871 #if !defined(SWIG)
1872 class DisjunctivePropagator {
1875  public:
1881  struct Tasks {
1883  std::vector<int64> start_min;
1884  std::vector<int64> start_max;
1885  std::vector<int64> duration_min;
1886  std::vector<int64> duration_max;
1887  std::vector<int64> end_min;
1888  std::vector<int64> end_max;
1889  std::vector<bool> is_preemptible;
1890  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1891  std::vector<std::pair<int64, int64>> distance_duration;
1892  int64 span_min = 0;
1893  int64 span_max = kint64max;
1894 
1895  void Clear() {
1896  start_min.clear();
1897  start_max.clear();
1898  duration_min.clear();
1899  duration_max.clear();
1900  end_min.clear();
1901  end_max.clear();
1902  is_preemptible.clear();
1903  forbidden_intervals.clear();
1904  distance_duration.clear();
1905  span_min = 0;
1906  span_max = kint64max;
1907  num_chain_tasks = 0;
1908  }
1909  };
1910 
1913  bool Propagate(Tasks* tasks);
1914 
1916  bool Precedences(Tasks* tasks);
1919  bool MirrorTasks(Tasks* tasks);
1921  bool EdgeFinding(Tasks* tasks);
1928  bool DistanceDuration(Tasks* tasks);
1931  bool ChainSpanMin(Tasks* tasks);
1937 
1938  private:
1941  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1943  std::vector<int> tasks_by_start_min_;
1944  std::vector<int> tasks_by_end_max_;
1945  std::vector<int> event_of_task_;
1946  std::vector<int> nonchain_tasks_by_start_max_;
1948  std::vector<int64> total_duration_before_;
1949 };
1950 
1952  std::vector<int64> min_travels;
1953  std::vector<int64> max_travels;
1954  std::vector<int64> pre_travels;
1955  std::vector<int64> post_travels;
1956 };
1957 
1958 void AppendTasksFromPath(const std::vector<int64>& path,
1959  const TravelBounds& travel_bounds,
1960  const RoutingDimension& dimension,
1962 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
1964 void FillPathEvaluation(const std::vector<int64>& path,
1965  const RoutingModel::TransitCallback2& evaluator,
1966  std::vector<int64>* values);
1967 void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64>& path,
1968  const RoutingDimension& dimension,
1969  TravelBounds* travel_bounds);
1970 #endif // !defined(SWIG)
1971 
1982 class GlobalVehicleBreaksConstraint : public Constraint {
1983  public:
1985  std::string DebugString() const override {
1986  return "GlobalVehicleBreaksConstraint";
1987  }
1988 
1989  void Post() override;
1990  void InitialPropagate() override;
1991 
1992  private:
1993  void PropagateNode(int node);
1994  void PropagateVehicle(int vehicle);
1995  void PropagateMaxBreakDistance(int vehicle);
1996 
1997  const RoutingModel* model_;
1998  const RoutingDimension* const dimension_;
1999  std::vector<Demon*> vehicle_demons_;
2000  std::vector<int64> path_;
2001 
2006  void FillPartialPathOfVehicle(int vehicle);
2007  void FillPathTravels(const std::vector<int64>& path);
2008 
2019  class TaskTranslator {
2020  public:
2021  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
2022  : start_(start),
2023  before_start_(before_start),
2024  after_start_(after_start) {}
2025  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2026  TaskTranslator() {}
2027 
2028  void SetStartMin(int64 value) {
2029  if (start_ != nullptr) {
2030  start_->SetMin(CapAdd(before_start_, value));
2031  } else if (interval_ != nullptr) {
2032  interval_->SetStartMin(value);
2033  }
2034  }
2035  void SetStartMax(int64 value) {
2036  if (start_ != nullptr) {
2037  start_->SetMax(CapAdd(before_start_, value));
2038  } else if (interval_ != nullptr) {
2039  interval_->SetStartMax(value);
2040  }
2041  }
2042  void SetDurationMin(int64 value) {
2043  if (interval_ != nullptr) {
2044  interval_->SetDurationMin(value);
2045  }
2046  }
2047  void SetEndMin(int64 value) {
2048  if (start_ != nullptr) {
2049  start_->SetMin(CapSub(value, after_start_));
2050  } else if (interval_ != nullptr) {
2051  interval_->SetEndMin(value);
2052  }
2053  }
2054  void SetEndMax(int64 value) {
2055  if (start_ != nullptr) {
2056  start_->SetMax(CapSub(value, after_start_));
2057  } else if (interval_ != nullptr) {
2058  interval_->SetEndMax(value);
2059  }
2060  }
2061 
2062  private:
2063  IntVar* start_ = nullptr;
2064  int64 before_start_;
2065  int64 after_start_;
2066  IntervalVar* interval_ = nullptr;
2067  };
2068 
2070  std::vector<TaskTranslator> task_translators_;
2071 
2073  DisjunctivePropagator disjunctive_propagator_;
2074  DisjunctivePropagator::Tasks tasks_;
2075 
2077  TravelBounds travel_bounds_;
2078 };
2079 
2081  public:
2082  explicit TypeRegulationsChecker(const RoutingModel& model);
2084 
2085  bool CheckVehicle(int vehicle,
2086  const std::function<int64(int64)>& next_accessor);
2087 
2088  protected:
2089 #ifndef SWIG
2091 #endif // SWIG
2092 
2109  };
2110 
2115  bool TypeOccursOnRoute(int type) const;
2122  bool TypeCurrentlyOnRoute(int type, int pos) const;
2123 
2124  void InitializeCheck(int vehicle,
2125  const std::function<int64(int64)>& next_accessor);
2126  virtual void OnInitializeCheck() {}
2127  virtual bool HasRegulationsToCheck() const = 0;
2128  virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2129  int pos) = 0;
2130  virtual bool FinalizeCheck() const { return true; }
2131 
2133 
2134  private:
2135  std::vector<TypePolicyOccurrence> occurrences_of_type_;
2136  std::vector<int64> current_route_visits_;
2137 };
2138 
2141  public:
2143  bool check_hard_incompatibilities);
2145 
2146  private:
2147  bool HasRegulationsToCheck() const override;
2148  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2152  bool check_hard_incompatibilities_;
2153 };
2154 
2157  public:
2158  explicit TypeRequirementChecker(const RoutingModel& model)
2159  : TypeRegulationsChecker(model) {}
2161 
2162  private:
2163  bool HasRegulationsToCheck() const override;
2164  void OnInitializeCheck() override {
2165  types_with_same_vehicle_requirements_on_route_.clear();
2166  }
2167  // clang-format off
2170  bool CheckRequiredTypesCurrentlyOnRoute(
2171  const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2172  int pos);
2173  // clang-format on
2174  bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2175  bool FinalizeCheck() const override;
2176 
2177  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2178 };
2179 
2220 class TypeRegulationsConstraint : public Constraint {
2221  public:
2222  explicit TypeRegulationsConstraint(const RoutingModel& model);
2223 
2224  void Post() override;
2225  void InitialPropagate() override;
2226 
2227  private:
2228  void PropagateNodeRegulations(int node);
2229  void CheckRegulationsOnVehicle(int vehicle);
2230 
2231  const RoutingModel& model_;
2232  TypeIncompatibilityChecker incompatibility_checker_;
2233  TypeRequirementChecker requirement_checker_;
2234  std::vector<Demon*> vehicle_demons_;
2235 };
2236 #if !defined SWIG
2237 class SimpleBoundCosts {
2250  public:
2251  struct BoundCost {
2252  int64 bound;
2253  int64 cost;
2254  };
2255  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2256  : bound_costs_(num_bounds, default_bound_cost) {}
2257  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2258  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2259  int Size() { return bound_costs_.size(); }
2262 
2263  private:
2264  std::vector<BoundCost> bound_costs_;
2265 };
2266 #endif // !defined SWIG
2267 
2285 // TODO(user): Break constraints need to know the service time of nodes
2289  public:
2292  RoutingModel* model() const { return model_; }
2296  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2299  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2300  int64 vehicle_class) const {
2301  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2302  to_index);
2303  }
2306  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2307  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2308  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2309  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2310 
2311 #if !defined(SWIGPYTHON)
2312  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2315  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2316  const std::vector<IntVar*>& transits() const { return transits_; }
2317  const std::vector<IntVar*>& slacks() const { return slacks_; }
2318 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2319  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2321  return forbidden_intervals_;
2322  }
2324  SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index,
2325  int64 min_value,
2326  int64 max_value) const;
2330  int64 min_value) const {
2331  DCHECK_LT(index, forbidden_intervals_.size());
2332  const SortedDisjointIntervalList& forbidden_intervals =
2333  forbidden_intervals_[index];
2334  const auto first_forbidden_interval_it =
2335  forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2336  if (first_forbidden_interval_it != forbidden_intervals.end() &&
2337  min_value >= first_forbidden_interval_it->start) {
2339  return CapAdd(first_forbidden_interval_it->end, 1);
2340  }
2342  return min_value;
2343  }
2349  int64 max_value) const {
2350  DCHECK_LT(index, forbidden_intervals_.size());
2351  const SortedDisjointIntervalList& forbidden_intervals =
2352  forbidden_intervals_[index];
2353  const auto last_forbidden_interval_it =
2354  forbidden_intervals.LastIntervalLessOrEqual(max_value);
2355  if (last_forbidden_interval_it != forbidden_intervals.end() &&
2356  max_value <= last_forbidden_interval_it->end) {
2358  return CapSub(last_forbidden_interval_it->start, 1);
2359  }
2361  return max_value;
2362  }
2364  const std::vector<int64>& vehicle_capacities() const {
2365  return vehicle_capacities_;
2366  }
2370  return model_->TransitCallback(
2371  class_evaluators_[vehicle_to_class_[vehicle]]);
2372  }
2377  int vehicle) const {
2378  return model_->UnaryTransitCallbackOrNull(
2379  class_evaluators_[vehicle_to_class_[vehicle]]);
2380  }
2383  bool AreVehicleTransitsPositive(int vehicle) const {
2384  return model()->is_transit_evaluator_positive_
2385  [class_evaluators_[vehicle_to_class_[vehicle]]];
2386  }
2387  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2388 #endif
2389 #endif
2390  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2394  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2401  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2408  void SetGlobalSpanCostCoefficient(int64 coefficient);
2409 
2410 #ifndef SWIG
2411  void SetCumulVarPiecewiseLinearCost(int64 index,
2416  const PiecewiseLinearFunction& cost);
2419  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2422  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2423  int64 index) const;
2424 #endif
2425 
2434  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2435  int64 coefficient);
2438  bool HasCumulVarSoftUpperBound(int64 index) const;
2442  int64 GetCumulVarSoftUpperBound(int64 index) const;
2446  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2447 
2460  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2461  int64 coefficient);
2464  bool HasCumulVarSoftLowerBound(int64 index) const;
2468  int64 GetCumulVarSoftLowerBound(int64 index) const;
2472  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2488  // TODO(user): Remove if !defined when routing.i is repaired.
2489 #if !defined(SWIGPYTHON)
2490  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2491  int pre_travel_evaluator,
2492  int post_travel_evaluator);
2493 #endif // !defined(SWIGPYTHON)
2494 
2496  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2497  std::vector<int64> node_visit_transits);
2498 
2503  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2504  int vehicle);
2509  bool HasBreakConstraints() const;
2510 #if !defined(SWIGPYTHON)
2514  std::vector<IntervalVar*> breaks, int vehicle,
2515  std::vector<int64> node_visit_transits,
2516  std::function<int64(int64, int64)> group_delays);
2517 
2519  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2520  int vehicle) const;
2523  // clang-format off
2524  const std::vector<std::pair<int64, int64> >&
2526  // clang-format on
2527 #endif
2528  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2529  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2530 
2532  const RoutingDimension* base_dimension() const { return base_dimension_; }
2540  int64 ShortestTransitionSlack(int64 node) const;
2541 
2543  const std::string& name() const { return name_; }
2544 
2546 #ifndef SWIG
2547  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2548  return path_precedence_graph_;
2549  }
2550 #endif // SWIG
2551 
2561  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2562 
2564  PickupToDeliveryLimitFunction limit_function, int pair_index);
2565 
2567 #ifndef SWIG
2568  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2569  int delivery) const;
2570 
2572  int64 first_node;
2574  int64 offset;
2575  };
2576 
2578  node_precedences_.push_back(precedence);
2579  }
2580  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2581  return node_precedences_;
2582  }
2583 #endif // SWIG
2584 
2585  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2586  AddNodePrecedence({first_node, second_node, offset});
2587  }
2588 
2589  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2590  return vehicle_span_upper_bounds_[vehicle];
2591  }
2592 #ifndef SWIG
2593  const std::vector<int64>& vehicle_span_upper_bounds() const {
2594  return vehicle_span_upper_bounds_;
2595  }
2596 #endif // SWIG
2597  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2598  return vehicle_span_cost_coefficients_[vehicle];
2599  }
2600 #ifndef SWIG
2601  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2602  return vehicle_span_cost_coefficients_;
2603  }
2604 #endif // SWIG
2606  return global_span_cost_coefficient_;
2607  }
2608 
2610  DCHECK_GE(global_optimizer_offset_, 0);
2611  return global_optimizer_offset_;
2612  }
2613  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2614  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2615  return 0;
2616  }
2617  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2618  return local_optimizer_offset_for_vehicle_[vehicle];
2619  }
2620 #if !defined SWIG
2624  int vehicle) {
2625  if (!HasSoftSpanUpperBounds()) {
2626  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2627  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2628  }
2629  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2630  }
2631  bool HasSoftSpanUpperBounds() const {
2632  return vehicle_soft_span_upper_bound_ != nullptr;
2633  }
2635  int vehicle) const {
2636  DCHECK(HasSoftSpanUpperBounds());
2637  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2638  }
2642  SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2644  vehicle_quadratic_cost_soft_span_upper_bound_ =
2645  absl::make_unique<SimpleBoundCosts>(
2646  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2647  }
2648  vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2649  bound_cost;
2650  }
2652  return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2653  }
2655  int vehicle) const {
2657  return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2658  }
2659 #endif
2660 
2661  private:
2662  struct SoftBound {
2663  IntVar* var;
2664  int64 bound;
2665  int64 coefficient;
2666  };
2667 
2668  struct PiecewiseLinearCost {
2669  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2670  IntVar* var;
2671  std::unique_ptr<PiecewiseLinearFunction> cost;
2672  };
2673 
2674  class SelfBased {};
2675  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2676  const std::string& name,
2677  const RoutingDimension* base_dimension);
2678  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2679  const std::string& name, SelfBased);
2680  void Initialize(const std::vector<int>& transit_evaluators,
2681  const std::vector<int>& state_dependent_transit_evaluators,
2682  int64 slack_max);
2683  void InitializeCumuls();
2684  void InitializeTransits(
2685  const std::vector<int>& transit_evaluators,
2686  const std::vector<int>& state_dependent_transit_evaluators,
2687  int64 slack_max);
2688  void InitializeTransitVariables(int64 slack_max);
2690  void SetupCumulVarSoftUpperBoundCosts(
2691  std::vector<IntVar*>* cost_elements) const;
2693  void SetupCumulVarSoftLowerBoundCosts(
2694  std::vector<IntVar*>* cost_elements) const;
2695  void SetupCumulVarPiecewiseLinearCosts(
2696  std::vector<IntVar*>* cost_elements) const;
2699  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2700  void SetupSlackAndDependentTransitCosts() const;
2702  void CloseModel(bool use_light_propagation);
2703 
2704  void SetOffsetForGlobalOptimizer(int64 offset) {
2705  global_optimizer_offset_ = std::max(Zero(), offset);
2706  }
2708  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2710  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2711  [](int64 offset) { return std::max(Zero(), offset); });
2712  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2713  }
2714 
2715  std::vector<IntVar*> cumuls_;
2716  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2717  std::vector<IntVar*> capacity_vars_;
2718  const std::vector<int64> vehicle_capacities_;
2719  std::vector<IntVar*> transits_;
2720  std::vector<IntVar*> fixed_transits_;
2723  std::vector<int> class_evaluators_;
2724  std::vector<int64> vehicle_to_class_;
2725 #ifndef SWIG
2726  ReverseArcListGraph<int, int> path_precedence_graph_;
2727 #endif
2728  // For every {first_node, second_node, offset} element in node_precedences_,
2729  // if both first_node and second_node are performed, then
2730  // cumuls_[second_node] must be greater than (or equal to)
2731  // cumuls_[first_node] + offset.
2732  std::vector<NodePrecedence> node_precedences_;
2733 
2734  // The transits of a dimension may depend on its cumuls or the cumuls of
2735  // another dimension. There can be no cycles, except for self loops, a
2736  // typical example for this is a time dimension.
2737  const RoutingDimension* const base_dimension_;
2738 
2739  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2740  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2741  // class.
2742  std::vector<int> state_dependent_class_evaluators_;
2743  std::vector<int64> state_dependent_vehicle_to_class_;
2744 
2745  // For each pickup/delivery pair_index for which limits have been set,
2746  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2747  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2748  std::vector<PickupToDeliveryLimitFunction>
2749  pickup_to_delivery_limits_per_pair_index_;
2750 
2751  // Used if some vehicle has breaks in this dimension, typically time.
2752  bool break_constraints_are_initialized_ = false;
2753  // clang-format off
2754  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2755  std::vector<std::vector<std::pair<int64, int64> > >
2756  vehicle_break_distance_duration_;
2757  // clang-format on
2758  // For each vehicle, stores the part of travel that is made directly
2759  // after (before) the departure (arrival) node of the travel.
2760  // These parts of the travel are non-interruptible, in particular by a break.
2761  std::vector<int> vehicle_pre_travel_evaluators_;
2762  std::vector<int> vehicle_post_travel_evaluators_;
2763 
2764  std::vector<IntVar*> slacks_;
2765  std::vector<IntVar*> dependent_transits_;
2766  std::vector<int64> vehicle_span_upper_bounds_;
2767  int64 global_span_cost_coefficient_;
2768  std::vector<int64> vehicle_span_cost_coefficients_;
2769  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2770  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2771  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2772  RoutingModel* const model_;
2773  const std::string name_;
2774  int64 global_optimizer_offset_;
2775  std::vector<int64> local_optimizer_offset_for_vehicle_;
2777  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2778  std::unique_ptr<SimpleBoundCosts>
2779  vehicle_quadratic_cost_soft_span_upper_bound_;
2780  friend class RoutingModel;
2782 
2783  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2784 };
2785 
2786 #ifndef SWIG
2787 class SweepArranger {
2790  public:
2791  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2792  virtual ~SweepArranger() {}
2793  void ArrangeIndices(std::vector<int64>* indices);
2794  void SetSectors(int sectors) { sectors_ = sectors; }
2795 
2796  private:
2797  std::vector<int> coordinates_;
2798  int sectors_;
2799 
2800  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2801 };
2802 #endif
2803 
2806 DecisionBuilder* MakeSetValuesFromTargets(Solver* solver,
2807  std::vector<IntVar*> variables,
2808  std::vector<int64> targets);
2809 
2810 #ifndef SWIG
2811 // Helper class that stores vehicles by their type. Two vehicles have the same
2812 // "vehicle type" iff they have the same cost class and start/end nodes.
2814  public:
2816  const RoutingModel::VehicleTypeContainer& vehicle_type_container)
2817  : vehicle_type_container_(&vehicle_type_container) {}
2818 
2819  int NumTypes() const { return vehicle_type_container_->NumTypes(); }
2820 
2821  int Type(int vehicle) const { return vehicle_type_container_->Type(vehicle); }
2822 
2823  void Reset() {
2824  sorted_vehicle_classes_per_type_ =
2825  vehicle_type_container_->sorted_vehicle_classes_per_type;
2826  const std::vector<std::deque<int>>& vehicles_per_class =
2827  vehicle_type_container_->vehicles_per_vehicle_class;
2828  vehicles_per_vehicle_class_.resize(vehicles_per_class.size());
2829  for (int i = 0; i < vehicles_per_vehicle_class_.size(); i++) {
2830  vehicles_per_vehicle_class_[i].resize(vehicles_per_class[i].size());
2831  std::copy(vehicles_per_class[i].begin(), vehicles_per_class[i].end(),
2832  vehicles_per_vehicle_class_[i].begin());
2833  }
2834  }
2835 
2836  int GetVehicleOfType(int type) const {
2837  DCHECK_LT(type, NumTypes());
2838  const std::set<VehicleClassEntry>& vehicle_classes =
2839  sorted_vehicle_classes_per_type_[type];
2840  if (vehicle_classes.empty()) {
2841  return -1;
2842  }
2843  const int vehicle_class = (vehicle_classes.begin())->vehicle_class;
2844  DCHECK(!vehicles_per_vehicle_class_[vehicle_class].empty());
2845  return vehicles_per_vehicle_class_[vehicle_class][0];
2846  }
2847 
2848  void ReinjectVehicleOfClass(int vehicle, int vehicle_class,
2849  int64 fixed_cost) {
2850  std::vector<int>& vehicles = vehicles_per_vehicle_class_[vehicle_class];
2851  if (vehicles.empty()) {
2852  // Add the vehicle class entry to the set (it was removed when
2853  // vehicles_per_vehicle_class_[vehicle_class] got empty).
2854  std::set<VehicleClassEntry>& vehicle_classes =
2855  sorted_vehicle_classes_per_type_[Type(vehicle)];
2856  const auto& insertion =
2857  vehicle_classes.insert({vehicle_class, fixed_cost});
2858  DCHECK(insertion.second);
2859  }
2860  vehicles.push_back(vehicle);
2861  }
2862 
2863  // Searches for the best compatible vehicle of the given type, i.e. the first
2864  // vehicle v of type 'type' for which vehicle_is_compatible(v) returns true.
2865  // If a compatible vehicle is found, its index is removed from
2866  // vehicles_per_vehicle_class_ and returned.
2867  // Returns -1 otherwise.
2869  int type, std::function<bool(int)> vehicle_is_compatible);
2870 
2871  private:
2872  using VehicleClassEntry =
2874  const RoutingModel::VehicleTypeContainer* const vehicle_type_container_;
2875  // clang-format off
2876  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
2877  std::vector<std::vector<int> > vehicles_per_vehicle_class_;
2878  // clang-format on
2879 };
2880 
2893 
2895 // TODO(user): Eventually move this to the core CP solver library
2897 class IntVarFilteredDecisionBuilder : public DecisionBuilder {
2898  public:
2900  std::unique_ptr<IntVarFilteredHeuristic> heuristic);
2901 
2903 
2904  Decision* Next(Solver* solver) override;
2905 
2906  std::string DebugString() const override;
2907 
2909  int64 number_of_decisions() const;
2910  int64 number_of_rejects() const;
2911 
2912  private:
2913  const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
2914 };
2915 
2918  public:
2919  IntVarFilteredHeuristic(Solver* solver, const std::vector<IntVar*>& vars,
2920  LocalSearchFilterManager* filter_manager);
2921 
2923 
2926  Assignment* const BuildSolution();
2927 
2930  int64 number_of_decisions() const { return number_of_decisions_; }
2931  int64 number_of_rejects() const { return number_of_rejects_; }
2932 
2933  virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; }
2934 
2935  protected:
2939  virtual bool InitializeSolution() { return true; }
2941  virtual bool BuildSolutionInternal() = 0;
2945  bool Commit();
2947  virtual bool StopSearch() { return false; }
2950  void SetValue(int64 index, int64 value) {
2951  if (!is_in_delta_[index]) {
2952  delta_->FastAdd(vars_[index])->SetValue(value);
2953  delta_indices_.push_back(index);
2954  is_in_delta_[index] = true;
2955  } else {
2956  delta_->SetValue(vars_[index], value);
2957  }
2958  }
2961  int64 Value(int64 index) const {
2962  return assignment_->IntVarContainer().Element(index).Value();
2963  }
2965  bool Contains(int64 index) const {
2966  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
2967  }
2970  int Size() const { return vars_.size(); }
2972  IntVar* Var(int64 index) const { return vars_[index]; }
2975 
2976  Assignment* const assignment_;
2977 
2978  private:
2981  bool FilterAccept();
2982 
2983  Solver* solver_;
2984  const std::vector<IntVar*> vars_;
2985  Assignment* const delta_;
2986  std::vector<int> delta_indices_;
2987  std::vector<bool> is_in_delta_;
2988  Assignment* const empty_;
2989  LocalSearchFilterManager* filter_manager_;
2991  int64 number_of_decisions_;
2992  int64 number_of_rejects_;
2993 };
2994 
2997  public:
2999  LocalSearchFilterManager* filter_manager);
3002  const Assignment* BuildSolutionFromRoutes(
3003  const std::function<int64(int64)>& next_accessor);
3004  RoutingModel* model() const { return model_; }
3006  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
3008  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
3014 
3015  protected:
3016  bool StopSearch() override { return model_->CheckLimit(); }
3017  virtual void SetVehicleIndex(int64 node, int vehicle) {}
3018  virtual void ResetVehicleIndices() {}
3019 
3020  private:
3022  bool InitializeSolution() override;
3023 
3024  RoutingModel* const model_;
3025  std::vector<int64> start_chain_ends_;
3026  std::vector<int64> end_chain_starts_;
3027 };
3028 
3030  public:
3033  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3034  std::function<int64(int64)> penalty_evaluator,
3035  LocalSearchFilterManager* filter_manager);
3037 
3038  protected:
3039  typedef std::pair<int64, int64> ValuedPosition;
3040  struct StartEndValue {
3041  int64 distance;
3042  int vehicle;
3043 
3044  bool operator<(const StartEndValue& other) const {
3045  return std::tie(distance, vehicle) <
3046  std::tie(other.distance, other.vehicle);
3047  }
3048  };
3049  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
3050 
3056  // clang-format off
3057  std::vector<std::vector<StartEndValue> >
3058  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
3059 
3064  template <class Queue>
3066  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
3067  Queue* priority_queue);
3068  // clang-format on
3069 
3074  void InsertBetween(int64 node, int64 predecessor, int64 successor);
3080  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
3081  std::vector<ValuedPosition>* valued_positions);
3086  int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert,
3087  int64 insert_after,
3088  int64 insert_before,
3089  int vehicle) const;
3092  int64 GetUnperformedValue(int64 node_to_insert) const;
3093 
3094  std::function<int64(int64, int64, int64)> evaluator_;
3095  std::function<int64(int64)> penalty_evaluator_;
3096 };
3097 
3107  public:
3121  };
3122 
3125  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3126  std::function<int64(int64)> penalty_evaluator,
3127  LocalSearchFilterManager* filter_manager,
3130  bool BuildSolutionInternal() override;
3131  std::string DebugString() const override {
3132  return "GlobalCheapestInsertionFilteredHeuristic";
3133  }
3134 
3135  private:
3136  class PairEntry;
3137  class NodeEntry;
3138  typedef absl::flat_hash_set<PairEntry*> PairEntries;
3139  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
3140 
3148  void InsertNodesByRequirementTopologicalOrder();
3149 
3156  void InsertPairs();
3157 
3165  void InsertNodesOnRoutes(const std::vector<int>& nodes,
3166  const absl::flat_hash_set<int>& vehicles);
3167 
3173  void SequentialInsertNodes(const std::vector<int>& nodes);
3174 
3178  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
3179  std::vector<int>* unused_vehicles,
3180  absl::flat_hash_set<int>* used_vehicles);
3181 
3185  void InsertFarthestNodesAsSeeds();
3186 
3195  template <class Queue>
3196  int InsertSeedNode(
3197  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
3198  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
3199  // clang-format on
3200 
3203  void InitializePairPositions(
3204  AdjustablePriorityQueue<PairEntry>* priority_queue,
3205  std::vector<PairEntries>* pickup_to_entries,
3206  std::vector<PairEntries>* delivery_to_entries);
3212  void InitializeInsertionEntriesPerformingPair(
3213  int64 pickup, int64 delivery, int64 penalty,
3214  AdjustablePriorityQueue<PairEntry>* priority_queue,
3215  std::vector<PairEntries>* pickup_to_entries,
3216  std::vector<PairEntries>* delivery_to_entries);
3219  void UpdatePairPositions(int vehicle, int64 insert_after,
3220  AdjustablePriorityQueue<PairEntry>* priority_queue,
3221  std::vector<PairEntries>* pickup_to_entries,
3222  std::vector<PairEntries>* delivery_to_entries) {
3223  UpdatePickupPositions(vehicle, insert_after, priority_queue,
3224  pickup_to_entries, delivery_to_entries);
3225  UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
3226  pickup_to_entries, delivery_to_entries);
3227  }
3230  void UpdatePickupPositions(int vehicle, int64 pickup_insert_after,
3231  AdjustablePriorityQueue<PairEntry>* priority_queue,
3232  std::vector<PairEntries>* pickup_to_entries,
3233  std::vector<PairEntries>* delivery_to_entries);
3236  void UpdateDeliveryPositions(
3237  int vehicle, int64 delivery_insert_after,
3238  AdjustablePriorityQueue<PairEntry>* priority_queue,
3239  std::vector<PairEntries>* pickup_to_entries,
3240  std::vector<PairEntries>* delivery_to_entries);
3243  void DeletePairEntry(PairEntry* entry,
3244  AdjustablePriorityQueue<PairEntry>* priority_queue,
3245  std::vector<PairEntries>* pickup_to_entries,
3246  std::vector<PairEntries>* delivery_to_entries);
3249  void InitializePositions(const std::vector<int>& nodes,
3250  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3251  std::vector<NodeEntries>* position_to_node_entries,
3252  const absl::flat_hash_set<int>& vehicles);
3258  void InitializeInsertionEntriesPerformingNode(
3259  int64 node, int64 penalty, const absl::flat_hash_set<int>& vehicles,
3260  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3261  std::vector<NodeEntries>* position_to_node_entries);
3264  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
3265  int64 insert_after,
3266  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3267  std::vector<NodeEntries>* node_entries);
3270  void DeleteNodeEntry(NodeEntry* entry,
3271  AdjustablePriorityQueue<NodeEntry>* priority_queue,
3272  std::vector<NodeEntries>* node_entries);
3273 
3276  void ComputeNeighborhoods();
3277 
3282  void AddNeighborForCostClass(int cost_class, int64 node_index,
3283  int64 neighbor_index, bool neighbor_is_pickup,
3284  bool neighbor_is_delivery);
3285 
3288  bool IsNeighborForCostClass(int cost_class, int64 node_index,
3289  int64 neighbor_index) const;
3290 
3292  const std::vector<int64>& GetPickupNeighborsOfNodeForCostClass(
3293  int cost_class, int64 node_index) const {
3294  if (gci_params_.neighbors_ratio == 1) {
3295  return pickup_nodes_;
3296  }
3297  return node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
3298  ->PositionsSetAtLeastOnce();
3299  }
3300 
3302  const std::vector<int64>& GetDeliveryNeighborsOfNodeForCostClass(
3303  int cost_class, int64 node_index) const {
3304  if (gci_params_.neighbors_ratio == 1) {
3305  return delivery_nodes_;
3306  }
3307  return node_index_to_delivery_neighbors_by_cost_class_
3308  [node_index][cost_class]
3309  ->PositionsSetAtLeastOnce();
3310  }
3311 
3313  const std::vector<int64>& GetSingleNeighborsOfNodeForCostClass(
3314  int cost_class, int64 node_index) const {
3315  if (gci_params_.neighbors_ratio == 1) {
3316  return single_nodes_;
3317  }
3318  return node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]
3319  ->PositionsSetAtLeastOnce();
3320  }
3321 
3323  std::vector<const std::vector<int64>*> GetNeighborsOfNodeForCostClass(
3324  int cost_class, int64 node_index) const {
3325  return {&GetSingleNeighborsOfNodeForCostClass(cost_class, node_index),
3326  &GetPickupNeighborsOfNodeForCostClass(cost_class, node_index),
3327  &GetDeliveryNeighborsOfNodeForCostClass(cost_class, node_index)};
3328  }
3329 
3330  void ResetVehicleIndices() override {
3331  node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
3332  }
3333 
3334  void SetVehicleIndex(int64 node, int vehicle) override {
3335  DCHECK_LT(node, node_index_to_vehicle_.size());
3336  node_index_to_vehicle_[node] = vehicle;
3337  }
3338 
3341  bool CheckVehicleIndices() const;
3342 
3343  GlobalCheapestInsertionParameters gci_params_;
3345  std::vector<int> node_index_to_vehicle_;
3346 
3347  // clang-format off
3348  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3349  node_index_to_single_neighbors_by_cost_class_;
3350  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3351  node_index_to_pickup_neighbors_by_cost_class_;
3352  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3353  node_index_to_delivery_neighbors_by_cost_class_;
3354  // clang-format on
3355 
3359  std::vector<int64> single_nodes_;
3360  std::vector<int64> pickup_nodes_;
3361  std::vector<int64> delivery_nodes_;
3362 };
3363 
3371  public:
3374  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3375  LocalSearchFilterManager* filter_manager);
3377  bool BuildSolutionInternal() override;
3378  std::string DebugString() const override {
3379  return "LocalCheapestInsertionFilteredHeuristic";
3380  }
3381 
3382  private:
3388  void ComputeEvaluatorSortedPositions(int64 node,
3389  std::vector<int64>* sorted_positions);
3394  void ComputeEvaluatorSortedPositionsOnRouteAfter(
3395  int64 node, int64 start, int64 next_after_start,
3396  std::vector<int64>* sorted_positions);
3397 
3398  std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
3399 };
3400 
3404  public:
3406  LocalSearchFilterManager* filter_manager);
3408  bool BuildSolutionInternal() override;
3409 
3410  private:
3411  class PartialRoutesAndLargeVehicleIndicesFirst {
3412  public:
3413  explicit PartialRoutesAndLargeVehicleIndicesFirst(
3414  const CheapestAdditionFilteredHeuristic& builder)
3415  : builder_(builder) {}
3416  bool operator()(int vehicle1, int vehicle2) const;
3417 
3418  private:
3419  const CheapestAdditionFilteredHeuristic& builder_;
3420  };
3422  template <typename Iterator>
3423  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
3424  Iterator end) const {
3425  const int size = model()->Size();
3426  std::vector<int64> nexts;
3427  for (Iterator it = start; it != end; ++it) {
3428  const int64 next = *it;
3429  if (next != node && (next >= size || !Contains(next))) {
3430  nexts.push_back(next);
3431  }
3432  }
3433  return nexts;
3434  }
3436  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
3437  virtual int64 FindTopSuccessor(int64 node,
3438  const std::vector<int64>& successors) = 0;
3439 };
3440 
3445  public:
3448  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
3449  LocalSearchFilterManager* filter_manager);
3451  std::string DebugString() const override {
3452  return "EvaluatorCheapestAdditionFilteredHeuristic";
3453  }
3454 
3455  private:
3457  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3458  int64 FindTopSuccessor(int64 node,
3459  const std::vector<int64>& successors) override;
3460 
3461  std::function<int64(int64, int64)> evaluator_;
3462 };
3463 
3468  public:
3471  RoutingModel* model, Solver::VariableValueComparator comparator,
3472  LocalSearchFilterManager* filter_manager);
3474  std::string DebugString() const override {
3475  return "ComparatorCheapestAdditionFilteredHeuristic";
3476  }
3477 
3478  private:
3480  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3481  int64 FindTopSuccessor(int64 node,
3482  const std::vector<int64>& successors) override;
3483 
3484  Solver::VariableValueComparator comparator_;
3485 };
3486 
3496  public:
3500  double neighbors_ratio = 1.0;
3506  bool add_reverse_arcs = false;
3509  double arc_coefficient = 1.0;
3510  };
3511 
3513  const RoutingIndexManager* manager,
3514  SavingsParameters parameters,
3515  LocalSearchFilterManager* filter_manager);
3517  bool BuildSolutionInternal() override;
3518 
3519  protected:
3520  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
3521 
3522  template <typename S>
3524 
3525  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3526 
3527  virtual void BuildRoutesFromSavings() = 0;
3528 
3530  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3531  return saving.second / size_squared_;
3532  }
3534  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3535  return (saving.second % size_squared_) / Size();
3536  }
3538  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3539  return (saving.second % size_squared_) % Size();
3540  }
3542  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3543 
3553  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3554  int64 after_node);
3555 
3556  // clang-format off
3557  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3558  // clang-format on
3559  std::unique_ptr<VehicleTypeCurator> vehicle_type_curator_;
3560 
3561  private:
3566  // clang-format off
3567  void AddSymmetricArcsToAdjacencyLists(
3568  std::vector<std::vector<int64> >* adjacency_lists);
3569  // clang-format on
3570 
3577  void ComputeSavings();
3579  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3580  int after_node) const {
3581  return std::make_pair(saving, vehicle_type * size_squared_ +
3582  before_node * Size() + after_node);
3583  }
3584 
3588  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3589 
3590  const RoutingIndexManager* const manager_;
3591  const SavingsParameters savings_params_;
3592  int64 size_squared_;
3593 
3595 };
3596 
3598  public:
3600  const RoutingIndexManager* manager,
3601  SavingsParameters parameters,
3602  LocalSearchFilterManager* filter_manager)
3603  : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
3605  std::string DebugString() const override {
3606  return "SequentialSavingsFilteredHeuristic";
3607  }
3608 
3609  private:
3614  void BuildRoutesFromSavings() override;
3615  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3616 };
3617 
3619  public:
3621  const RoutingIndexManager* manager,
3622  SavingsParameters parameters,
3623  LocalSearchFilterManager* filter_manager)
3624  : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
3626  std::string DebugString() const override {
3627  return "ParallelSavingsFilteredHeuristic";
3628  }
3629 
3630  private:
3641  void BuildRoutesFromSavings() override;
3642 
3643  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3644 
3649  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3650  int64 after_node);
3651 
3653  std::vector<int64> first_node_on_route_;
3654  std::vector<int64> last_node_on_route_;
3658  std::vector<int> vehicle_of_first_or_last_node_;
3659 };
3660 
3664 
3666  public:
3668  LocalSearchFilterManager* filter_manager,
3669  bool use_minimum_matching);
3671  bool BuildSolutionInternal() override;
3672  std::string DebugString() const override {
3673  return "ChristofidesFilteredHeuristic";
3674  }
3675 
3676  private:
3677  const bool use_minimum_matching_;
3678 };
3679 #endif // SWIG
3680 
3686  const RoutingSearchParameters& search_parameters,
3687  const Assignment* initial_solution,
3688  Assignment* solution);
3689 
3691 
3693  public:
3694  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size);
3695  ~BasePathFilter() override {}
3696  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3697  int64 objective_min, int64 objective_max) override;
3698  void OnSynchronize(const Assignment* delta) override;
3699 
3700  protected:
3701  static const int64 kUnassigned;
3702 
3703  int64 GetNext(int64 node) const {
3704  return (new_nexts_[node] == kUnassigned)
3705  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3706  : new_nexts_[node];
3707  }
3708  int NumPaths() const { return starts_.size(); }
3709  int64 Start(int i) const { return starts_[i]; }
3710  int GetPath(int64 node) const { return paths_[node]; }
3711  int Rank(int64 node) const { return ranks_[node]; }
3712  bool IsDisabled() const { return status_ == DISABLED; }
3713  const std::vector<int64>& GetTouchedPathStarts() const {
3714  return touched_paths_.PositionsSetAtLeastOnce();
3715  }
3716  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3717  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3718  }
3719 
3720  private:
3721  enum Status { UNKNOWN, ENABLED, DISABLED };
3722 
3723  virtual bool DisableFiltering() const { return false; }
3724  virtual void OnBeforeSynchronizePaths() {}
3725  virtual void OnAfterSynchronizePaths() {}
3726  virtual void OnSynchronizePathFromStart(int64 start) {}
3727  virtual void InitializeAcceptPath() {}
3728  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3729  int64 chain_end) = 0;
3730  virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min,
3731  int64 objective_max) {
3732  return true;
3733  }
3735  void ComputePathStarts(std::vector<int64>* path_starts,
3736  std::vector<int>* index_to_path);
3737  bool HavePathsChanged();
3738  void SynchronizeFullAssignment();
3739  void UpdateAllRanks();
3740  void UpdatePathRanksFromStart(int start);
3741 
3742  std::vector<int64> node_path_starts_;
3743  std::vector<int64> starts_;
3744  std::vector<int> paths_;
3745  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3746  std::vector<int64> new_nexts_;
3747  std::vector<int> delta_touched_;
3748  SparseBitset<> touched_paths_;
3749  SparseBitset<> touched_path_nodes_;
3750  std::vector<int> ranks_;
3751 
3752  Status status_;
3753 };
3754 
3759 // TODO(user): Also call the solution finalizer on variables, with the
3765 // TODO(user): Avoid such false negatives.
3767  public:
3768  explicit CPFeasibilityFilter(const RoutingModel* routing_model);
3769  ~CPFeasibilityFilter() override {}
3770  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3771  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3772  int64 objective_min, int64 objective_max) override;
3773  void OnSynchronize(const Assignment* delta) override;
3774 
3775  private:
3776  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3777 
3778  static const int64 kUnassigned;
3779  const RoutingModel* const model_;
3780  Solver* const solver_;
3781  Assignment* const assignment_;
3782  Assignment* const temp_assignment_;
3783  DecisionBuilder* const restore_;
3784 };
3785 
3786 #if !defined(SWIG)
3788  const RoutingModel& routing_model);
3790  const RoutingModel& routing_model);
3792  const RoutingModel& routing_model);
3794  const RoutingModel& routing_model);
3796  const std::vector<RoutingDimension*>& dimensions,
3797  const RoutingSearchParameters& parameters, bool filter_objective_cost,
3798  std::vector<LocalSearchFilter*>* filters);
3800  const RoutingDimension& dimension,
3801  const RoutingSearchParameters& parameters,
3802  bool propagate_own_objective_value, bool filter_objective_cost,
3803  bool can_use_lp = true);
3805  const RoutingDimension& dimension);
3807  GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost);
3809  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3810  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3812  const RoutingModel& routing_model);
3814  const RoutingModel& routing_model, const RoutingDimension& dimension);
3816  const RoutingModel* routing_model);
3817 #endif
3818 
3819 } // namespace operations_research
3820 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
std::unique_ptr< VehicleTypeCurator > vehicle_type_curator_
Definition: routing.h:3559
RoutingIndexPair IndexPair
Definition: routing.h:245
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:2939
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
std::string DebugString() const override
Definition: routing.h:3672
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
Generic filter-based heuristic applied to IntVars.
Definition: routing.h:2917
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
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...
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
~ComparatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3473
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2585
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...
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
int64 first_node
Definition: routing.h:2572
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1226
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:2299
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:626
int Type(int vehicle) const
Definition: routing.h:2821
std::vector< int64 > pre_travels
Definition: routing.h:1954
@ PICKUP_AND_DELIVERY_NO_ORDER
Any precedence is accepted.
Definition: routing.h:230
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
const std::vector< int64 > & vehicle_span_upper_bounds() const
Definition: routing.h:2593
const std::vector< int64 > & GetTouchedPathStarts() const
Definition: routing.h:3713
bool operator<(const StartEndValue &other) const
Definition: routing.h:3044
std::vector< int64 > start_max
Definition: routing.h:1884
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:410
bool HasPickupToDeliveryLimits() const
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1299
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; ...
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
void AddRequiredTypeAlternativesWhenRemovingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
The following requirements apply when visiting dependent nodes that remove their type from the route,...
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
int64 Value(int index) const
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
Definition: routing.h:926
int64 GetLastPossibleLessOrEqualValueForNode(int64 index, int64 max_value) const
Returns the largest value outside the forbidden intervals of node 'index' that is less than or equal ...
Definition: routing.h:2348
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2292
std::string DebugString() const override
Definition: routing.h:3770
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:852
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2547
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:264
std::pair< int64, int64 > ValuedPosition
Definition: routing.h:3039
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
void AddIntervalToAssignment(IntervalVar *const interval)
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
bool TypeCurrentlyOnRoute(int type, int pos) const
Returns true iff there's at least one instance of the given type on the route when scanning the route...
friend class RoutingDimension
Definition: routing.h:1856
virtual ~SweepArranger()
Definition: routing.h:2792
std::function< int64(int64)> RoutingTransitCallback1
Definition: routing_types.h:41
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size)
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the set of same-vehicle requirement alternatives for the given type.
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...
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
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:1164
int64 distance
Definition: routing.h:3041
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:390
std::string DebugString() const override
Definition: routing.h:3451
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:3006
int64 span_min
Definition: routing.h:1892
std::vector< int > type_index_of_vehicle
Definition: routing.h:374
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.
Definition: routing.h:211
int64 cost_coefficient
Definition: routing.h:297
std::vector< std::vector< int64 > > GetRoutesFromAssignment(const Assignment &assignment)
Converts the solution in the given assignment to routes for all vehicles.
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1157
void InitialPropagate() override
~CheapestInsertionFilteredHeuristic() override
Definition: routing.h:3036
virtual ~IntVarFilteredHeuristic()
Definition: routing.h:2922
int GetCompatibleVehicleOfType(int type, std::function< bool(int)> vehicle_is_compatible)
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1245
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model)
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:1982
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
void AppendTasksFromPath(const std::vector< int64 > &path, const TravelBounds &travel_bounds, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
void Clear()
Definition: routing.h:1895
int64 number_of_decisions() const
Returns statistics from its underlying heuristic.
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1206
~GlobalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:3129
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:2947
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2315
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:313
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:240
Filter-based heuristic dedicated to routing.
Definition: routing.h:2996
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:555
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:341
std::function< int64(int64)> penalty_evaluator_
Definition: routing.h:3095
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:238
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
virtual void BuildRoutesFromSavings()=0
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
~TypeIncompatibilityChecker() override
Definition: routing.h:2144
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:645
bool IsVarSynced(int index) const
IntVar * SlackVar(int64 index) const
Definition: routing.h:2309
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2220
static const int64 kUnassigned
Definition: routing.h:3701
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
Definition: routing.h:3523
RoutingCostClassIndex CostClassIndex
Definition: routing.h:236
RangeIntToIntFunction * transit
Definition: routing.h:263
std::vector< int64 > max_travels
Definition: routing.h:1953
VisitTypePolicy GetVisitTypePolicy(int64 index) const
std::string DebugString() const override
Definition: routing.h:3378
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
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.
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
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:3503
Manager for any NodeIndex <-> variable index conversion.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:737
std::string DebugString() const override
Definition: routing.h:3474
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:262
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1161
int GetNumberOfVisitTypes() const
Definition: routing.h:780
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2158
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2597
bool AddDimensionDependentDimensionWithVehicleCapacity(int transit, const RoutingDimension *base_dimension, int64 slack_max, int64 vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
Homogeneous versions of the functions above.
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
void SetQuadraticCostSoftSpanUpperBoundForVehicle(SimpleBoundCosts::BoundCost bound_cost, int vehicle)
If the span of vehicle on this dimension is larger than bound, the cost will be increased by cost * (...
Definition: routing.h:2641
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, std::vector< int64 > node_visit_transits)
Deprecated, sets pre_travel(i, j) = node_visit_transit[i].
int position_of_last_type_on_vehicle_up_to_visit
Position of the last node of policy TYPE_ON_VEHICLE_UP_TO_VISIT visited on the route.
Definition: routing.h:2108
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:346
@ TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
The visit doesn't have an impact on the number of types 'T' on the route, as it's (virtually) added a...
Definition: routing.h:767
bool HasTemporalTypeRequirements() const
Definition: routing.h:846
int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert, int64 insert_after, int64 insert_before, int vehicle) const
Returns the cost of inserting 'node_to_insert' between 'insert_after' and 'insert_before' on the 'veh...
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
~LocalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:3376
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
Definition: routing.h:3113
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:2376
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenAddingType(int type) const
Returns the set of requirement alternatives when adding the given type.
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
int Rank(int64 node) const
Definition: routing.h:3711
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
virtual bool HasRegulationsToCheck() const =0
IntVar * FixedTransitVar(int64 index) const
Definition: routing.h:2308
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2249
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1240
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:239
@ TYPE_ADDED_TO_VEHICLE
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:754
~RoutingFilteredHeuristic() override
Definition: routing.h:3000
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:3016
BoundCost bound_cost(int element) const
Definition: routing.h:2258
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:3370
std::string DebugString() const override
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:3506
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
void AddTemporalTypeIncompatibility(int type1, int type2)
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.
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
@ ROUTING_INVALID
Model, model parameters or flags are not valid.
Definition: routing.h:224
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:650
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:344
std::pair< int64, int64 > Saving
Definition: routing.h:3520
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2654
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
int num_chain_tasks
Definition: routing.h:1882
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
Definition: routing.h:2306
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2255
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3557
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2613
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:880
std::string DebugString() const override
Definition: routing.h:3605
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:3116
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1890
CostClass(int evaluator_index)
Definition: routing.h:309
int64 second_node
Definition: routing.h:2573
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:2561
std::vector< int64 > start_min
Definition: routing.h:1883
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2543
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:2950
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
static const char kLightElement[]
Constraint types.
Definition: routing.h:1866
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3542
~IntVarFilteredDecisionBuilder() override
Definition: routing.h:2902
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:333
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
int GetPath(int64 node) const
Definition: routing.h:3710
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
virtual void ResetVehicleIndices()
Definition: routing.h:3018
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1317
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1184
@ ROUTING_SUCCESS
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:218
int NumPaths() const
Definition: routing.h:3708
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
RoutingModel::VisitTypePolicy VisitTypePolicy
Definition: routing.h:2090
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenRemovingType(int type) const
Returns the set of requirement alternatives when removing the given type.
int64 GetGlobalOptimizerOffset() const
Definition: routing.h:2609
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
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:1175
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1138
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
const std::vector< int > & GetSingleNodesOfType(int type) const
void SetVisitType(int64 index, int type, VisitTypePolicy type_policy)
@ ROUTING_NOT_SOLVED
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:216
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
std::vector< std::vector< std::pair< int64, int64 > > > GetCumulBounds(const Assignment &solution_assignment, const RoutingDimension &dimension)
Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maxi...
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:2961
virtual ~TypeRegulationsChecker()
Definition: routing.h:2083
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64 > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, const RoutingSearchParameters &parameters, bool propagate_own_objective_value, bool filter_objective_cost, bool can_use_lp=true)
int64 span_max
Definition: routing.h:1893
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3534
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:337
~BasePathFilter() override
Definition: routing.h:3695
~ChristofidesFilteredHeuristic() override
Definition: routing.h:3670
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
int num_type_added_to_vehicle
Number of TYPE_ADDED_TO_VEHICLE and TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED node type policies seen on ...
Definition: routing.h:2097
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:1042
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
Status
Status of the search.
Definition: routing.h:214
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
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:2369
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:3403
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
Definition: routing.h:267
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:241
Definition: routing.h:2571
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:563
TypeRegulationsChecker(const RoutingModel &model)
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64 fixed_cost)
Definition: routing.h:2848
int GetVehicleOfType(int type) const
Definition: routing.h:2836
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:3094
int64 bound
Definition: routing.h:2252
A structure to hold tasks described by their features.
Definition: routing.h:1881
int num_type_removed_from_vehicle
Number of ADDED_TYPE_REMOVED_FROM_VEHICLE (effectively removing a type from the route) and TYPE_SIMUL...
Definition: routing.h:2103
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
The base class for all local search operators.
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)...
void SetMaximumNumberOfActiveVehicles(int max_active_vehicles)
Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an emp...
Definition: routing.h:876
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...
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
Definition: routing.h:2080
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:324
bool IsDisabled() const
Definition: routing.h:3712
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:939
friend class RoutingModel
Definition: routing.h:2780
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
void InitialPropagate() override
friend class SavingsFilteredHeuristicTestPeer
Definition: routing.h:3594
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
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...
Definition: routing.h:271
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
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...
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:931
virtual bool FinalizeCheck() const
Definition: routing.h:2130
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...
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:376
const RoutingDimension * dimension
Definition: routing.h:298
@ PICKUP_AND_DELIVERY_LIFO
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:232
Checker for type requirements.
Definition: routing.h:2156
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio) are considered as insertion positions during in...
Definition: routing.h:3120
void OnSynchronize(const Assignment *delta) override
int vehicle
Definition: routing.h:3042
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:406
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
int64 number_of_rejects() const
Definition: routing.h:2931
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
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:1145
Definition: routing.h:3497
void AddRequiredTypeAlternativesWhenAddingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_T...
const std::vector< int > & GetPairIndicesOfType(int type) const
ChristofidesFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2930
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
int64 Size() const
Returns the number of next variables in the model.
Definition: routing.h:1319
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...
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
Definition: routing.h:3530
void OnSynchronize(const Assignment *delta) override
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:922
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
void SetAssignmentFromOtherModelAssignment(Assignment *target_assignment, const RoutingModel *source_model, const Assignment *source_assignment)
Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variab...
int64 fixed_cost
Definition: routing.h:359
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:3008
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
std::string DebugString() const override
Definition: routing.h:1985
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:3106
Assignment * MutablePreAssignment()
Definition: routing.h:1043
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.
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
std::vector< int64 > post_travels
Definition: routing.h:1955
BoundCost & bound_cost(int element)
Definition: routing.h:2257
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_max
Definition: routing.h:340
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
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.
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
Definition: routing.h:752
std::vector< bool > is_preemptible
Definition: routing.h:1889
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.
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:654
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:2623
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
Class to arrange indices by by their distance and their angles from the depot.
Definition: routing.h:2789
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2288
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
static const char kLightElement2[]
Definition: routing.h:1867
RoutingModel(const RoutingIndexManager &index_manager, const RoutingModelParameters &parameters)
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
bool HasSoftSpanUpperBounds() const
Definition: routing.h:2631
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3538
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1302
int NumTypes() const
Definition: routing.h:367
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:944
~EvaluatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3450
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:361
std::vector< int64 > duration_min
Definition: routing.h:1885
const RoutingModel & model_
Definition: routing.h:2132
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
Definition: routing.h:2815
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
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:497
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:326
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1197
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1134
bool AddDimensionDependentDimensionWithVehicleCapacity(int pure_transit, int dependent_transit, const RoutingDimension *base_dimension, int64 slack_max, int64 vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
IntVar * TransitVar(int64 index) const
Definition: routing.h:2307
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
std::vector< int64 > min_travels
Definition: routing.h:1952
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1874
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:546
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model)
SimpleBoundCosts(const SimpleBoundCosts &)=delete
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
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:1340
~ParallelSavingsFilteredHeuristic() override
Definition: routing.h:3625
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
Definition: routing.h:595
std::vector< int64 > duration_max
Definition: routing.h:1886
IntVarLocalSearchFilter * MakeCumulBoundsPropagatorFilter(const RoutingDimension &dimension)
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
Definition: routing.h:1187
RoutingDimensionIndex DimensionIndex
Definition: routing.h:237
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:465
Definition: routing.h:2813
std::vector< int64 > end_max
Definition: routing.h:1888
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:3495
const std::vector< IntVar * > & transits() const
Definition: routing.h:2316
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1329
int Type(int vehicle) const
Definition: routing.h:369
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.
int64 GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2589
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
Definition: routing_types.h:44
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
RoutingFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:3509
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:228
bool ChainSpanMin(Tasks *tasks)
Propagates a lower bound of the chain span, end[num_chain_tasks] - start[0], to span_min.
Generic path-based filter class.
Definition: routing.h:3692
~TypeRequirementChecker() override
Definition: routing.h:2160
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
int64 global_span_cost_coefficient() const
Definition: routing.h:2605
void ResetSolution()
Resets the data members for a new solution.
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:45
Routing model visitor.
Definition: routing.h:1863
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1308
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:2972
int64 transit_evaluator_class
Definition: routing.h:296
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
Definition: routing.h:3766
Decision * Next(Solver *solver) override
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:919
Definition: routing.h:3108
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:386
virtual void SetVehicleIndex(int64 node, int vehicle)
Definition: routing.h:3017
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1315
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &transits, const RoutingDimension *base_dimension, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
As above, but pure_transits are taken to be zero evaluators.
Definition: routing.h:3618
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:295
~CheapestAdditionFilteredHeuristic() override
Definition: routing.h:3407
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
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...
int64 offset
Definition: routing.h:2574
int GetVisitType(int64 index) const
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.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:339
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
bool TypeOccursOnRoute(int type) const
Returns true iff any occurrence of the given type was seen on the route, i.e.
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
friend class RoutingModelInspector
Definition: routing.h:1857
Definition: routing.h:2093
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2532
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2383
Definition: routing.h:357
RoutingModel * model() const
Definition: routing.h:3004
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:2970
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2314
@ TYPE_ON_VEHICLE_UP_TO_VISIT
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
Definition: routing.h:762
@ ROUTING_FAIL
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:220
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
int64 cost
Definition: routing.h:2253
Struct used to sort and store vehicles by their type.
Definition: routing.h:356
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1891
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
Local Search Filters are used for fast neighbor pruning.
int RegisterPositiveTransitCallback(TransitCallback2 callback)
const Assignment * BuildSolutionFromRoutes(const std::function< int64(int64)> &next_accessor)
Builds a solution starting from the routes formed by the next accessor.
~RoutingDimension()
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)
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...
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:414
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:733
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:3500
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
int64 Start(int i) const
Definition: routing.h:3709
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...
TypeRegulationsConstraint(const RoutingModel &model)
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
void InitializePriorityQueue(std::vector< std::vector< StartEndValue > > *start_end_distances_per_node, Queue *priority_queue)
Initializes the priority_queue by inserting the best entry corresponding to each node,...
bool 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...
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2634
~SequentialSavingsFilteredHeuristic() override
Definition: routing.h:3604
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
const std::vector< int64 > & vehicle_span_cost_coefficients() const
Definition: routing.h:2601
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:273
GlobalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, LocalSearchFilterManager *filter_manager, GlobalCheapestInsertionParameters parameters)
Takes ownership of evaluators.
void Post() override
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:382
@ ROUTING_FAIL_TIMEOUT
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:222
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:559
Christofides addition heuristic.
Definition: routing.h:3665
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2580
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
std::string DebugString() const override
Definition: routing.h:3131
RoutingIndexPairs IndexPairs
Definition: routing.h:246
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1257
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2317
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:590
SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index, int64 min_value, int64 max_value) const
Returns allowed intervals for a given node in a given interval.
void InitializeCheck(int vehicle, const std::function< int64(int64)> &next_accessor)
void Reset()
Definition: routing.h:2823
friend class RoutingModelInspector
Definition: routing.h:2781
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Definition: routing.h:3599
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1250
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
Definition: routing.h:2251
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
Definition: routing.h:3040
bool ChainSpanMinDynamic(Tasks *tasks)
Computes a lower bound of the span of the chain, taking into account only the first nonchain task.
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()
Definition: routing.h:1951
Checker for type incompatibilities.
Definition: routing.h:2140
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
CPFeasibilityFilter(const RoutingModel *routing_model)
int64 GetFirstPossibleGreaterOrEqualValueForNode(int64 index, int64 min_value) const
Returns the smallest value outside the forbidden intervals of node 'index' that is greater than or eq...
Definition: routing.h:2329
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1199
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:2965
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
Definition: routing.h:3110
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:618
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
int64 GetNext(int64 node) const
Definition: routing.h:3703
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:1178
void ArrangeIndices(std::vector< int64 > *indices)
@ PICKUP_AND_DELIVERY_FIFO
Deliveries must be performed in the same order as pickups.
Definition: routing.h:234
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< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2364
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Definition: routing.h:3620
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3716
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...
Assignment *const assignment_
Definition: routing.h:2976
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
Definition: routing.h:3467
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1232
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:1211
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:798
int64 number_of_rejects() const
std::vector< std::pair< int64, int64 > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
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...
~CPFeasibilityFilter() override
Definition: routing.h:3769
virtual std::string DebugString() const
Definition: routing.h:2933
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
Definition: routing.h:3444
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:338
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:843
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1252
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1242
int end_equivalence_class
Definition: routing.h:334
bool operator<(const DimensionCost &cost) const
Definition: routing.h:299
int vehicle_class
Definition: routing.h:358
bool DistanceDuration(Tasks *tasks)
Propagates distance_duration constraints, if any.
Assignment *const BuildSolution()
Builds a solution.
SavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:681
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(GlobalDimensionCumulOptimizer *optimizer, bool filter_objective_cost)
~SavingsFilteredHeuristic() override
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,...
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
int64 Start(int vehicle) const
Model inspection.
Definition: routing.h:1155
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2320
int vehicle_to_class(int vehicle) const
Definition: routing.h:2387
std::pair< StartEndValue, int > Seed
Definition: routing.h:3049
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
Definition: routing.h:2897
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
Definition: routing.h:3029
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2651
const std::vector< int > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:781
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
std::vector< int64 > end_min
Definition: routing.h:1887
std::function< int64(int64, int64)> RoutingTransitCallback2
Definition: routing_types.h:42
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
Definition: routing.h:322
void SetSectors(int sectors)
Definition: routing.h:2794
int RegisterTransitCallback(TransitCallback2 callback)
CheapestAdditionFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilter * > *filters)
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1192
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:801
virtual void OnInitializeCheck()
Definition: routing.h:2126
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:307
Status status() const
Returns the current status of the routing model.
Definition: routing.h:1018
@ ADDED_TYPE_REMOVED_FROM_VEHICLE
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:759
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
void Post() override
int Size()
Definition: routing.h:2259
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:377
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
std::string DebugString() const override
Definition: routing.h:3626
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2577
IntVarLocalSearchFilter * MakeMaxActiveVehiclesFilter(const RoutingModel &routing_model)
Definition: routing.h:3597
static const char kRemoveValues[]
Definition: routing.h:1868
int NumTypes() const
Definition: routing.h:2819
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).