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 
354  static const int64 kNoPenalty;
355 
359 
363 
367  explicit RoutingModel(const RoutingIndexManager& index_manager);
368  RoutingModel(const RoutingIndexManager& index_manager,
369  const RoutingModelParameters& parameters);
370  ~RoutingModel();
371 
378  const TransitCallback2& TransitCallback(int callback_index) const {
379  CHECK_LT(callback_index, transit_evaluators_.size());
380  return transit_evaluators_[callback_index];
381  }
382  const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
383  CHECK_LT(callback_index, unary_transit_evaluators_.size());
384  return unary_transit_evaluators_[callback_index];
385  }
387  int callback_index) const {
388  CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
389  return state_dependent_transit_evaluators_[callback_index];
390  }
391 
393 
405 
414  bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity,
415  bool fix_start_cumul_to_zero, const std::string& name);
417  const std::vector<int>& evaluator_indices, int64 slack_max,
418  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
419  bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max,
420  std::vector<int64> vehicle_capacities,
421  bool fix_start_cumul_to_zero,
422  const std::string& name);
424  const std::vector<int>& evaluator_indices, int64 slack_max,
425  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
426  const std::string& name);
433  bool AddConstantDimensionWithSlack(int64 value, int64 capacity,
434  int64 slack_max,
435  bool fix_start_cumul_to_zero,
436  const std::string& name);
437  bool AddConstantDimension(int64 value, int64 capacity,
438  bool fix_start_cumul_to_zero,
439  const std::string& name) {
440  return AddConstantDimensionWithSlack(value, capacity, 0,
441  fix_start_cumul_to_zero, name);
442  }
450  bool AddVectorDimension(std::vector<int64> values, int64 capacity,
451  bool fix_start_cumul_to_zero,
452  const std::string& name);
460  bool AddMatrixDimension(
461  std::vector<std::vector<int64> /*needed_for_swig*/> values,
462  int64 capacity, bool fix_start_cumul_to_zero, const std::string& name);
470  const std::vector<int>& pure_transits,
471  const std::vector<int>& dependent_transits,
472  const RoutingDimension* base_dimension, int64 slack_max,
473  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
474  const std::string& name) {
475  return AddDimensionDependentDimensionWithVehicleCapacityInternal(
476  pure_transits, dependent_transits, base_dimension, slack_max,
477  std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
478  }
479 
482  const std::vector<int>& transits, const RoutingDimension* base_dimension,
483  int64 slack_max, std::vector<int64> vehicle_capacities,
484  bool fix_start_cumul_to_zero, const std::string& name);
487  int transit, const RoutingDimension* base_dimension, int64 slack_max,
488  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
489  const std::string& name);
491  int pure_transit, int dependent_transit,
492  const RoutingDimension* base_dimension, int64 slack_max,
493  int64 vehicle_capacity, bool fix_start_cumul_to_zero,
494  const std::string& name);
495 
498  const std::function<int64(int64)>& f, int64 domain_start,
499  int64 domain_end);
500 
511  std::vector<IntVar*> spans,
512  std::vector<IntVar*> total_slacks);
513 
515  // TODO(user): rename.
516  std::vector<std::string> GetAllDimensionNames() const;
518  const std::vector<RoutingDimension*>& GetDimensions() const {
519  return dimensions_.get();
520  }
522  std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
523  // clang-format off
526  const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
528  return global_dimension_optimizers_;
529  }
530  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
532  return local_dimension_optimizers_;
533  }
534  const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
536  return local_dimension_mp_optimizers_;
537  }
538  // clang-format on
539 
543  const RoutingDimension& dimension) const;
545  const RoutingDimension& dimension) const;
547  const RoutingDimension& dimension) const;
548 
550  bool HasDimension(const std::string& dimension_name) const;
553  const std::string& dimension_name) const;
557  const std::string& dimension_name) const;
562  void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
563  DCHECK(dimension_name.empty() || HasDimension(dimension_name));
564  primary_constrained_dimension_ = dimension_name;
565  }
567  const std::string& GetPrimaryConstrainedDimension() const {
568  return primary_constrained_dimension_;
569  }
586  DisjunctionIndex AddDisjunction(const std::vector<int64>& indices,
587  int64 penalty = kNoPenalty,
588  int64 max_cardinality = 1);
590  const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
591  int64 index) const {
592  return index_to_disjunctions_[index];
593  }
597  template <typename F>
599  int64 index, int64 max_cardinality, F f) const {
600  for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
601  if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
602  for (const int64 d_index : disjunctions_[disjunction].indices) {
603  f(d_index);
604  }
605  }
606  }
607  }
608 #if !defined(SWIGPYTHON)
609  const std::vector<int64>& GetDisjunctionIndices(
612  DisjunctionIndex index) const {
613  return disjunctions_[index].indices;
614  }
615 #endif // !defined(SWIGPYTHON)
616  int64 GetDisjunctionPenalty(DisjunctionIndex index) const {
618  return disjunctions_[index].value.penalty;
619  }
623  return disjunctions_[index].value.max_cardinality;
624  }
626  int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
631  std::vector<std::pair<int64, int64>> GetPerfectBinaryDisjunctions() const;
638 
642  void AddSoftSameVehicleConstraint(const std::vector<int64>& indices,
643  int64 cost);
644 
649  void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
650  int64 index);
651 
653  bool IsVehicleAllowedForIndex(int vehicle, int64 index) {
654  return allowed_vehicles_[index].empty() ||
655  allowed_vehicles_[index].find(vehicle) !=
656  allowed_vehicles_[index].end();
657  }
658 
673  // TODO(user): Remove this when model introspection detects linked nodes.
674  void AddPickupAndDelivery(int64 pickup, int64 delivery);
678  void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
679  DisjunctionIndex delivery_disjunction);
680  // clang-format off
684  const std::vector<std::pair<int, int> >&
685  GetPickupIndexPairs(int64 node_index) const;
687  const std::vector<std::pair<int, int> >&
688  GetDeliveryIndexPairs(int64 node_index) const;
689  // clang-format on
690 
695  int vehicle);
697  int vehicle) const;
700 
701  int GetNumOfSingletonNodes() const;
702 
703 #ifndef SWIG
704  const IndexPairs& GetPickupAndDeliveryPairs() const {
706  return pickup_delivery_pairs_;
707  }
708  const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
710  return pickup_delivery_disjunctions_;
711  }
712 #endif // SWIG
713  // TODO(user): Support multiple visit types per node?
729  void SetVisitType(int64 index, int type);
730  int GetVisitType(int64 index) const;
733  // TODO(user): Reconsider the logic and potentially remove the need to
735  void CloseVisitTypes();
736  int GetNumberOfVisitTypes() const { return num_visit_types_; }
741  void AddHardTypeIncompatibility(int type1, int type2);
742  void AddTemporalTypeIncompatibility(int type1, int type2);
744  const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
745  int type) const;
746  const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
747  int type) const;
751  return has_hard_type_incompatibilities_;
752  }
754  return has_temporal_type_incompatibilities_;
755  }
767  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
772  int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
773  // clang-format off
776  const std::vector<absl::flat_hash_set<int> >&
778  const std::vector<absl::flat_hash_set<int> >&
780  // clang-format on
784  return has_same_vehicle_type_requirements_;
785  }
787  return has_temporal_type_requirements_;
788  }
789 
792  bool HasTypeRegulations() const {
796  }
797 
802  int64 UnperformedPenalty(int64 var_index) const;
806  int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const;
810  int64 GetDepot() const;
811 
815  void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
817  void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
820  void SetFixedCostOfAllVehicles(int64 cost);
822  void SetFixedCostOfVehicle(int64 cost, int vehicle);
826  int64 GetFixedCostOfVehicle(int vehicle) const;
827 
843  void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor,
844  int64 quadratic_cost_factor);
846  void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor,
847  int64 quadratic_cost_factor,
848  int vehicle);
849 
850  const std::vector<int64>& GetAmortizedLinearCostFactorOfVehicles() const {
851  return linear_cost_factor_of_vehicle_;
852  }
853  const std::vector<int64>& GetAmortizedQuadraticCostFactorOfVehicles() const {
854  return quadratic_cost_factor_of_vehicle_;
855  }
856 
857  void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle) {
858  DCHECK_LT(vehicle, vehicles_);
859  consider_empty_route_costs_[vehicle] = consider_costs;
860  }
861 
862  bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const {
863  DCHECK_LT(vehicle, vehicles_);
864  return consider_empty_route_costs_[vehicle];
865  }
866 
869 #ifndef SWIG
871  return first_solution_evaluator_;
872  }
873 #endif
876  first_solution_evaluator_ = std::move(evaluator);
877  }
880  void AddLocalSearchOperator(LocalSearchOperator* ls_operator);
882  void AddSearchMonitor(SearchMonitor* const monitor);
886  void AddAtSolutionCallback(std::function<void()> callback);
891  void AddVariableMinimizedByFinalizer(IntVar* var);
894  void AddVariableMaximizedByFinalizer(IntVar* var);
897  void AddWeightedVariableMinimizedByFinalizer(IntVar* var, int64 cost);
900  void AddVariableTargetToFinalizer(IntVar* var, int64 target);
907  void CloseModel();
911  const RoutingSearchParameters& search_parameters);
918  const Assignment* Solve(const Assignment* assignment = nullptr);
926  const Assignment* SolveWithParameters(
927  const RoutingSearchParameters& search_parameters,
928  std::vector<const Assignment*>* solutions = nullptr);
929  const Assignment* SolveFromAssignmentWithParameters(
930  const Assignment* assignment,
931  const RoutingSearchParameters& search_parameters,
932  std::vector<const Assignment*>* solutions = nullptr);
939  Assignment* target_assignment, const RoutingModel* source_model,
940  const Assignment* source_assignment);
946  // TODO(user): Add support for non-homogeneous costs and disjunctions.
947  int64 ComputeLowerBound();
949  Status status() const { return status_; }
958  IntVar* ApplyLocks(const std::vector<int64>& locks);
967  bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64>>& locks,
968  bool close_routes);
973  const Assignment* const PreAssignment() const { return preassignment_; }
974  Assignment* MutablePreAssignment() { return preassignment_; }
978  bool WriteAssignment(const std::string& file_name) const;
982  Assignment* ReadAssignment(const std::string& file_name);
985  Assignment* RestoreAssignment(const Assignment& solution);
992  const std::vector<std::vector<int64>>& routes,
993  bool ignore_inactive_indices);
1010  bool RoutesToAssignment(const std::vector<std::vector<int64>>& routes,
1011  bool ignore_inactive_indices, bool close_routes,
1012  Assignment* const assignment) const;
1016  void AssignmentToRoutes(const Assignment& assignment,
1017  std::vector<std::vector<int64>>* const routes) const;
1035  Assignment* CompactAssignment(const Assignment& assignment) const;
1039  Assignment* CompactAndCheckAssignment(const Assignment& assignment) const;
1041  void AddToAssignment(IntVar* const var);
1042  void AddIntervalToAssignment(IntervalVar* const interval);
1054  const Assignment* original_assignment, absl::Duration duration_limit);
1055 #ifndef SWIG
1056  // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1058  sweep_arranger_.reset(sweep_arranger);
1059  }
1061  SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); }
1062 #endif
1063  void AddLocalSearchFilter(LocalSearchFilter* filter) {
1069  CHECK(filter != nullptr);
1070  if (closed_) {
1071  LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1072  }
1073  extra_filters_.push_back(filter);
1074  }
1075 
1078  int64 Start(int vehicle) const { return starts_[vehicle]; }
1080  int64 End(int vehicle) const { return ends_[vehicle]; }
1082  bool IsStart(int64 index) const;
1084  bool IsEnd(int64 index) const { return index >= Size(); }
1087  int VehicleIndex(int index) const { return index_to_vehicle_[index]; }
1091  int64 Next(const Assignment& assignment, int64 index) const;
1093  bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1094 
1095 #if !defined(SWIGPYTHON)
1096  const std::vector<IntVar*>& Nexts() const { return nexts_; }
1101  const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1102 #endif
1103  IntVar* NextVar(int64 index) const { return nexts_[index]; }
1106  IntVar* ActiveVar(int64 index) const { return active_[index]; }
1110  IntVar* VehicleCostsConsideredVar(int vehicle) const {
1111  return vehicle_costs_considered_[vehicle];
1112  }
1115  IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; }
1117  IntVar* CostVar() const { return cost_; }
1118 
1121  int64 GetArcCostForVehicle(int64 from_index, int64 to_index,
1122  int64 vehicle) const;
1125  return costs_are_homogeneous_across_vehicles_;
1126  }
1129  int64 GetHomogeneousCost(int64 from_index, int64 to_index) const {
1130  return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1131  }
1134  int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const;
1141  int64 GetArcCostForClass(int64 from_index, int64 to_index,
1142  int64 /*CostClassIndex*/ cost_class_index) const;
1145  DCHECK(closed_);
1146  return cost_class_index_of_vehicle_[vehicle];
1147  }
1150  bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1151  DCHECK(closed_);
1152  if (cost_class_index == kCostClassIndexOfZeroCost) {
1153  return has_vehicle_with_zero_cost_class_;
1154  }
1155  return cost_class_index < cost_classes_.size();
1156  }
1158  int GetCostClassesCount() const { return cost_classes_.size(); }
1161  return std::max(0, GetCostClassesCount() - 1);
1162  }
1164  DCHECK(closed_);
1165  return vehicle_class_index_of_vehicle_[vehicle];
1166  }
1168  int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1170  const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1171  DCHECK(closed_);
1172  return same_vehicle_groups_[same_vehicle_group_[node]];
1173  }
1192  bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2);
1197  std::string DebugOutputAssignment(
1198  const Assignment& solution_assignment,
1199  const std::string& dimension_to_print) const;
1200 
1203  Solver* solver() const { return solver_.get(); }
1204 
1206  bool CheckLimit() {
1207  DCHECK(limit_ != nullptr);
1208  return limit_->Check();
1209  }
1210 
1212  absl::Duration RemainingTime() const {
1213  DCHECK(limit_ != nullptr);
1214  return limit_->AbsoluteSolverDeadline() - solver_->Now();
1215  }
1216 
1219  int nodes() const { return nodes_; }
1221  int vehicles() const { return vehicles_; }
1223  int64 Size() const { return nodes_ + vehicles_ - start_end_count_; }
1224 
1228  const RoutingSearchParameters& search_parameters) const;
1230  const RoutingSearchParameters& search_parameters) const;
1234  return automatic_first_solution_strategy_;
1235  }
1236 
1238  bool IsMatchingModel() const;
1239 
1240 #ifndef SWIG
1241  using GetTabuVarsCallback =
1244  std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1245 
1246  void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback);
1247 #endif // SWIG
1248 
1250  // TODO(user): Find a way to test and restrict the access at the same time.
1263  const RoutingDimension* dimension,
1264  std::function<int64(int64)> initializer);
1265 #ifndef SWIG
1266  // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1271  static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1272  std::vector<IntVar*> variables);
1273 #endif
1274  DecisionBuilder* MakeSelfDependentDimensionFinalizer(
1288  const RoutingDimension* dimension);
1289 
1290  private:
1292  enum RoutingLocalSearchOperator {
1293  RELOCATE = 0,
1294  RELOCATE_PAIR,
1295  LIGHT_RELOCATE_PAIR,
1296  RELOCATE_NEIGHBORS,
1297  EXCHANGE,
1298  EXCHANGE_PAIR,
1299  CROSS,
1300  CROSS_EXCHANGE,
1301  TWO_OPT,
1302  OR_OPT,
1303  GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1304  LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1305  GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1306  LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1307  RELOCATE_EXPENSIVE_CHAIN,
1308  LIN_KERNIGHAN,
1309  TSP_OPT,
1310  MAKE_ACTIVE,
1311  RELOCATE_AND_MAKE_ACTIVE,
1312  MAKE_ACTIVE_AND_RELOCATE,
1313  MAKE_INACTIVE,
1314  MAKE_CHAIN_INACTIVE,
1315  SWAP_ACTIVE,
1316  EXTENDED_SWAP_ACTIVE,
1317  NODE_PAIR_SWAP,
1318  PATH_LNS,
1319  FULL_PATH_LNS,
1320  TSP_LNS,
1321  INACTIVE_LNS,
1322  EXCHANGE_RELOCATE_PAIR,
1323  RELOCATE_SUBTRIP,
1324  EXCHANGE_SUBTRIP,
1325  LOCAL_SEARCH_OPERATOR_COUNTER
1326  };
1327 
1331  template <typename T>
1332  struct ValuedNodes {
1333  std::vector<int64> indices;
1334  T value;
1335  };
1336  struct DisjunctionValues {
1337  int64 penalty;
1338  int64 max_cardinality;
1339  };
1340  typedef ValuedNodes<DisjunctionValues> Disjunction;
1341 
1344  struct CostCacheElement {
1349  int index;
1350  CostClassIndex cost_class_index;
1351  int64 cost;
1352  };
1353 
1355  void Initialize();
1356  void AddNoCycleConstraintInternal();
1357  bool AddDimensionWithCapacityInternal(
1358  const std::vector<int>& evaluator_indices, int64 slack_max,
1359  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1360  const std::string& name);
1361  bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1362  const std::vector<int>& pure_transits,
1363  const std::vector<int>& dependent_transits,
1364  const RoutingDimension* base_dimension, int64 slack_max,
1365  std::vector<int64> vehicle_capacities, bool fix_start_cumul_to_zero,
1366  const std::string& name);
1367  bool InitializeDimensionInternal(
1368  const std::vector<int>& evaluator_indices,
1369  const std::vector<int>& state_dependent_evaluator_indices,
1370  int64 slack_max, bool fix_start_cumul_to_zero,
1371  RoutingDimension* dimension);
1372  DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1373 
1401  void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1402 
1403  void ComputeCostClasses(const RoutingSearchParameters& parameters);
1404  void ComputeVehicleClasses();
1405  int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1406  CostClassIndex cost_class_index) const;
1407  void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1408  int node_index,
1409  std::vector<IntVar*>* cost_elements);
1410  void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1411  std::vector<IntVar*>* cost_elements);
1412  Assignment* DoRestoreAssignment();
1413  static const CostClassIndex kCostClassIndexOfZeroCost;
1414  int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const {
1415  DCHECK_LT(0, vehicles_);
1416  return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1417  : kCostClassIndexOfZeroCost)
1418  .value();
1419  }
1420  int64 GetDimensionTransitCostSum(int64 i, int64 j,
1421  const CostClass& cost_class) const;
1423  IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1425  void AddPickupAndDeliverySetsInternal(const std::vector<int64>& pickups,
1426  const std::vector<int64>& deliveries);
1429  IntVar* CreateSameVehicleCost(int vehicle_index);
1432  int FindNextActive(int index, const std::vector<int64>& indices) const;
1433 
1436  bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1437  int vehicle) const;
1445  bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1446  Assignment* compact_assignment) const;
1447 
1448  void QuietCloseModel();
1449  void QuietCloseModelWithParameters(
1450  const RoutingSearchParameters& parameters) {
1451  if (!closed_) {
1452  CloseModelWithParameters(parameters);
1453  }
1454  }
1455 
1457  bool SolveMatchingModel(Assignment* assignment,
1458  const RoutingSearchParameters& parameters);
1459 #ifndef SWIG
1460  bool AppendAssignmentIfFeasible(
1462  const Assignment& assignment,
1463  std::vector<std::unique_ptr<Assignment>>* assignments);
1464 #endif
1465  void LogSolution(const RoutingSearchParameters& parameters,
1467  const std::string& description, int64 solution_cost,
1468  int64 start_time_ms);
1471  Assignment* CompactAssignmentInternal(const Assignment& assignment,
1472  bool check_compact_assignment) const;
1477  std::string FindErrorInSearchParametersForModel(
1478  const RoutingSearchParameters& search_parameters) const;
1480  void SetupSearch(const RoutingSearchParameters& search_parameters);
1482  // TODO(user): Document each auxiliary method.
1483  Assignment* GetOrCreateAssignment();
1484  Assignment* GetOrCreateTmpAssignment();
1485  RegularLimit* GetOrCreateLimit();
1486  RegularLimit* GetOrCreateLocalSearchLimit();
1487  RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1488  RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1489  LocalSearchOperator* CreateInsertionOperator();
1490  LocalSearchOperator* CreateMakeInactiveOperator();
1491  void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1492  LocalSearchOperator* GetNeighborhoodOperators(
1493  const RoutingSearchParameters& search_parameters) const;
1494  const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters(
1495  const RoutingSearchParameters& parameters);
1496  const std::vector<LocalSearchFilter*>& GetOrCreateFeasibilityFilters(
1497  const RoutingSearchParameters& parameters);
1498  DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1499  DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1500  void CreateFirstSolutionDecisionBuilders(
1501  const RoutingSearchParameters& search_parameters);
1502  DecisionBuilder* GetFirstSolutionDecisionBuilder(
1503  const RoutingSearchParameters& search_parameters) const;
1504  IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1505  const RoutingSearchParameters& parameters) const;
1506  LocalSearchPhaseParameters* CreateLocalSearchParameters(
1507  const RoutingSearchParameters& search_parameters);
1508  DecisionBuilder* CreateLocalSearchDecisionBuilder(
1509  const RoutingSearchParameters& search_parameters);
1510  void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1511  void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1512  void SetupAssignmentCollector(
1513  const RoutingSearchParameters& search_parameters);
1514  void SetupTrace(const RoutingSearchParameters& search_parameters);
1515  void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1516  bool UsesLightPropagation(
1517  const RoutingSearchParameters& search_parameters) const;
1518  GetTabuVarsCallback tabu_var_callback_;
1519 
1520  int GetVehicleStartClass(int64 start) const;
1521 
1522  void InitSameVehicleGroups(int number_of_groups) {
1523  same_vehicle_group_.assign(Size(), 0);
1524  same_vehicle_groups_.assign(number_of_groups, {});
1525  }
1526  void SetSameVehicleGroup(int index, int group) {
1527  same_vehicle_group_[index] = group;
1528  same_vehicle_groups_[group].push_back(index);
1529  }
1530 
1532  std::unique_ptr<Solver> solver_;
1533  int nodes_;
1534  int vehicles_;
1535  Constraint* no_cycle_constraint_ = nullptr;
1537  std::vector<IntVar*> nexts_;
1538  std::vector<IntVar*> vehicle_vars_;
1539  std::vector<IntVar*> active_;
1540  std::vector<IntVar*> vehicle_costs_considered_;
1545  std::vector<IntVar*> is_bound_to_end_;
1546  mutable RevSwitch is_bound_to_end_ct_added_;
1548  absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1549  gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1550  // clang-format off
1554  std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1555  global_dimension_optimizers_;
1556  gtl::ITIVector<DimensionIndex, int> global_optimizer_index_;
1557  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1558  local_dimension_optimizers_;
1559  std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1560  local_dimension_mp_optimizers_;
1561  // clang-format off
1562  gtl::ITIVector<DimensionIndex, int> local_optimizer_index_;
1563  std::string primary_constrained_dimension_;
1565  IntVar* cost_ = nullptr;
1566  std::vector<int> vehicle_to_transit_cost_;
1567  std::vector<int64> fixed_cost_of_vehicle_;
1568  std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1569  bool has_vehicle_with_zero_cost_class_;
1570  std::vector<int64> linear_cost_factor_of_vehicle_;
1571  std::vector<int64> quadratic_cost_factor_of_vehicle_;
1572  bool vehicle_amortized_cost_factors_set_;
1583  std::vector<bool> consider_empty_route_costs_;
1584 #ifndef SWIG
1585  gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1586 #endif // SWIG
1587  bool costs_are_homogeneous_across_vehicles_;
1588  bool cache_callbacks_;
1589  mutable std::vector<CostCacheElement> cost_cache_;
1590  std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1591 #ifndef SWIG
1592  gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1593 #endif // SWIG
1594  std::function<int(int64)> vehicle_start_class_callback_;
1596  gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1597  std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1599  std::vector<ValuedNodes<int64> > same_vehicle_costs_;
1601 #ifndef SWIG
1602  std::vector<std::unordered_set<int>> allowed_vehicles_;
1603 #endif // SWIG
1604  IndexPairs pickup_delivery_pairs_;
1606  std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1607  pickup_delivery_disjunctions_;
1608  // clang-format off
1609  // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1610  // vector of pairs {pair_index, pickup_index} such that
1611  // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1612  std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1613  // Same as above for deliveries.
1614  std::vector<std::vector<std::pair<int, int> > >
1615  index_to_delivery_index_pairs_;
1616  // clang-format on
1617  std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1618  // Same vehicle group to which a node belongs.
1619  std::vector<int> same_vehicle_group_;
1620  // Same vehicle node groups.
1621  std::vector<std::vector<int>> same_vehicle_groups_;
1622  // Node visit types
1623  // Variable index to visit type index.
1624  std::vector<int> index_to_visit_type_;
1625  // clang-format off
1626  std::vector<absl::flat_hash_set<int> >
1627  hard_incompatible_types_per_type_index_;
1628  bool has_hard_type_incompatibilities_;
1629  std::vector<absl::flat_hash_set<int> >
1630  temporal_incompatible_types_per_type_index_;
1631  bool has_temporal_type_incompatibilities_;
1632 
1633  std::vector<std::vector<absl::flat_hash_set<int> > >
1634  same_vehicle_required_type_alternatives_per_type_index_;
1635  bool has_same_vehicle_type_requirements_;
1636  std::vector<std::vector<absl::flat_hash_set<int> > >
1637  temporal_required_type_alternatives_per_type_index_;
1638  bool has_temporal_type_requirements_;
1639  absl::flat_hash_set<int> trivially_infeasible_visit_types_;
1640  // clang-format on
1641  int num_visit_types_;
1642  // Two indices are equivalent if they correspond to the same node (as given
1643  // to the constructors taking a RoutingIndexManager).
1644  std::vector<int> index_to_equivalence_class_;
1645  std::vector<int> index_to_vehicle_;
1646  std::vector<int64> starts_;
1647  std::vector<int64> ends_;
1648  // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
1649  // anymore.
1650  RoutingIndexManager manager_;
1651  int start_end_count_;
1652  // Model status
1653  bool closed_ = false;
1654  Status status_ = ROUTING_NOT_SOLVED;
1655  bool enable_deep_serialization_ = true;
1656 
1657  // Search data
1658  std::vector<DecisionBuilder*> first_solution_decision_builders_;
1659  std::vector<IntVarFilteredDecisionBuilder*>
1660  first_solution_filtered_decision_builders_;
1661  Solver::IndexEvaluator2 first_solution_evaluator_;
1662  FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
1664  std::vector<LocalSearchOperator*> local_search_operators_;
1665  std::vector<SearchMonitor*> monitors_;
1666  SolutionCollector* collect_assignments_ = nullptr;
1667  SolutionCollector* collect_one_assignment_ = nullptr;
1668  SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
1669  DecisionBuilder* solve_db_ = nullptr;
1670  DecisionBuilder* improve_db_ = nullptr;
1671  DecisionBuilder* restore_assignment_ = nullptr;
1672  DecisionBuilder* restore_tmp_assignment_ = nullptr;
1673  Assignment* assignment_ = nullptr;
1674  Assignment* preassignment_ = nullptr;
1675  Assignment* tmp_assignment_ = nullptr;
1676  std::vector<IntVar*> extra_vars_;
1677  std::vector<IntervalVar*> extra_intervals_;
1678  std::vector<LocalSearchOperator*> extra_operators_;
1679  std::vector<LocalSearchFilter*> filters_;
1680  std::vector<LocalSearchFilter*> feasibility_filters_;
1681  std::vector<LocalSearchFilter*> extra_filters_;
1682 #ifndef SWIG
1683  std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1684  std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1685  absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1686  absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1687  std::unique_ptr<SweepArranger> sweep_arranger_;
1688 #endif
1689 
1690  RegularLimit* limit_ = nullptr;
1691  RegularLimit* ls_limit_ = nullptr;
1692  RegularLimit* lns_limit_ = nullptr;
1693  RegularLimit* first_solution_lns_limit_ = nullptr;
1694 
1695  typedef std::pair<int64, int64> CacheKey;
1696  typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1697  typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1698  StateDependentTransitCallbackCache;
1699 
1700  std::vector<TransitCallback1> unary_transit_evaluators_;
1701  std::vector<TransitCallback2> transit_evaluators_;
1702  // The following vector stores a boolean per transit_evaluator_, indicating
1703  // whether the transits are all positive.
1704  // is_transit_evaluator_positive_ will be set to true only when registering a
1705  // callback via RegisterPositiveTransitCallback(), and to false otherwise.
1706  // The actual positivity of the transit values will only be checked in debug
1707  // mode, when calling RegisterPositiveTransitCallback().
1708  // Therefore, RegisterPositiveTransitCallback() should only be called when the
1709  // transits are known to be positive, as the positivity of a callback will
1710  // allow some improvements in the solver, but will entail in errors if the
1711  // transits are falsely assumed positive.
1712  std::vector<bool> is_transit_evaluator_positive_;
1713  std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1714  std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1715  state_dependent_transit_evaluators_cache_;
1716 
1717  friend class RoutingDimension;
1719 
1720  DISALLOW_COPY_AND_ASSIGN(RoutingModel);
1721 };
1722 
1725  public:
1727  static const char kLightElement[];
1728  static const char kLightElement2[];
1729  static const char kRemoveValues[];
1730 };
1731 
1732 #if !defined(SWIG)
1733 class DisjunctivePropagator {
1736  public:
1742  struct Tasks {
1744  std::vector<int64> start_min;
1745  std::vector<int64> start_max;
1746  std::vector<int64> duration_min;
1747  std::vector<int64> duration_max;
1748  std::vector<int64> end_min;
1749  std::vector<int64> end_max;
1750  std::vector<bool> is_preemptible;
1751  std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
1752  std::vector<std::pair<int64, int64>> distance_duration;
1753 
1754  void Clear() {
1755  start_min.clear();
1756  start_max.clear();
1757  duration_min.clear();
1758  duration_max.clear();
1759  end_min.clear();
1760  end_max.clear();
1761  is_preemptible.clear();
1762  forbidden_intervals.clear();
1763  distance_duration.clear();
1764  }
1765  };
1766 
1769  bool Propagate(Tasks* tasks);
1770 
1772  bool Precedences(Tasks* tasks);
1775  bool MirrorTasks(Tasks* tasks);
1777  bool EdgeFinding(Tasks* tasks);
1780  bool DetectablePrecedencesWithChain(Tasks* tasks);
1782  bool ForbiddenIntervals(Tasks* tasks);
1783  bool DistanceDuration(Tasks* tasks);
1784 
1785  private:
1788  sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1790  std::vector<int> tasks_by_start_min_;
1791  std::vector<int> tasks_by_end_max_;
1792  std::vector<int> event_of_task_;
1793  std::vector<int> nonchain_tasks_by_start_max_;
1794 };
1795 
1796 void AppendTasksFromPath(const std::vector<int64>& path,
1797  const std::vector<int64>& min_travels,
1798  const std::vector<int64>& max_travels,
1799  const std::vector<int64>& pre_travels,
1800  const std::vector<int64>& post_travels,
1801  const RoutingDimension& dimension,
1802  DisjunctivePropagator::Tasks* tasks);
1803 void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
1804  DisjunctivePropagator::Tasks* tasks);
1805 void FillPathEvaluation(const std::vector<int64>& path,
1806  const RoutingModel::TransitCallback2& evaluator,
1807  std::vector<int64>* values);
1808 #endif // !defined(SWIG)
1809 
1821  public:
1822  explicit GlobalVehicleBreaksConstraint(const RoutingDimension* dimension);
1823  std::string DebugString() const override {
1824  return "GlobalVehicleBreaksConstraint";
1825  }
1826 
1827  void Post() override;
1828  void InitialPropagate() override;
1829 
1830  private:
1831  void PropagateNode(int node);
1832  void PropagateVehicle(int vehicle);
1833  void PropagateMaxBreakDistance(int vehicle);
1834 
1835  const RoutingModel* model_;
1836  const RoutingDimension* const dimension_;
1837  std::vector<Demon*> vehicle_demons_;
1838  std::vector<int64> path_;
1839 
1844  void FillPartialPathOfVehicle(int vehicle);
1845  void FillPathTravels(const std::vector<int64>& path);
1846 
1857  class TaskTranslator {
1858  public:
1859  TaskTranslator(IntVar* start, int64 before_start, int64 after_start)
1860  : start_(start),
1861  before_start_(before_start),
1862  after_start_(after_start) {}
1863  explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
1864  TaskTranslator() {}
1865 
1866  void SetStartMin(int64 value) {
1867  if (start_ != nullptr) {
1868  start_->SetMin(CapAdd(before_start_, value));
1869  } else if (interval_ != nullptr) {
1870  interval_->SetStartMin(value);
1871  }
1872  }
1873  void SetStartMax(int64 value) {
1874  if (start_ != nullptr) {
1875  start_->SetMax(CapAdd(before_start_, value));
1876  } else if (interval_ != nullptr) {
1877  interval_->SetStartMax(value);
1878  }
1879  }
1880  void SetDurationMin(int64 value) {
1881  if (interval_ != nullptr) {
1882  interval_->SetDurationMin(value);
1883  }
1884  }
1885  void SetEndMin(int64 value) {
1886  if (start_ != nullptr) {
1887  start_->SetMin(CapSub(value, after_start_));
1888  } else if (interval_ != nullptr) {
1889  interval_->SetEndMin(value);
1890  }
1891  }
1892  void SetEndMax(int64 value) {
1893  if (start_ != nullptr) {
1894  start_->SetMax(CapSub(value, after_start_));
1895  } else if (interval_ != nullptr) {
1896  interval_->SetEndMax(value);
1897  }
1898  }
1899 
1900  private:
1901  IntVar* start_ = nullptr;
1902  int64 before_start_;
1903  int64 after_start_;
1904  IntervalVar* interval_ = nullptr;
1905  };
1906 
1908  std::vector<TaskTranslator> task_translators_;
1909 
1911  DisjunctivePropagator disjunctive_propagator_;
1912  DisjunctivePropagator::Tasks tasks_;
1913 
1915  std::vector<int64> min_travel_;
1916  std::vector<int64> max_travel_;
1917  std::vector<int64> pre_travel_;
1918  std::vector<int64> post_travel_;
1919 };
1920 
1922  public:
1923  explicit TypeRegulationsChecker(const RoutingModel& model);
1925 
1926  bool CheckVehicle(int vehicle,
1927  const std::function<int64(int64)>& next_accessor);
1928 
1929  protected:
1931  struct NodeCount {
1933  int pickup = 0;
1934  int delivery = 0;
1935  };
1936 
1939  int GetNonDeliveryCount(int type) const;
1941  int GetNonDeliveredCount(int type) const;
1942 
1943  virtual bool HasRegulationsToCheck() const = 0;
1944  virtual void InitializeCheck() {}
1945  virtual bool CheckTypeRegulations(int type) = 0;
1946  virtual bool FinalizeCheck() const { return true; }
1947 
1949 
1950  private:
1951  std::vector<PickupDeliveryStatus> pickup_delivery_status_of_node_;
1952  std::vector<NodeCount> counts_of_type_;
1953 };
1954 
1957  public:
1959  bool check_hard_incompatibilities);
1961 
1962  private:
1963  bool HasRegulationsToCheck() const override;
1964  bool CheckTypeRegulations(int type) override;
1968  bool check_hard_incompatibilities_;
1969 };
1970 
1973  public:
1974  explicit TypeRequirementChecker(const RoutingModel& model)
1975  : TypeRegulationsChecker(model) {}
1977 
1978  private:
1979  bool HasRegulationsToCheck() const override;
1980  void InitializeCheck() override {
1981  types_with_same_vehicle_requirements_on_route_.clear();
1982  }
1983  bool CheckTypeRegulations(int type) override;
1984  bool FinalizeCheck() const override;
1985 
1986  absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
1987 };
1988 
2009  public:
2010  explicit TypeRegulationsConstraint(const RoutingModel& model);
2011 
2012  void Post() override;
2013  void InitialPropagate() override;
2014 
2015  private:
2016  void PropagateNodeRegulations(int node);
2017  void CheckRegulationsOnVehicle(int vehicle);
2018 
2019  const RoutingModel& model_;
2020  TypeIncompatibilityChecker incompatibility_checker_;
2021  TypeRequirementChecker requirement_checker_;
2022  std::vector<Demon*> vehicle_demons_;
2023 };
2024 #if !defined SWIG
2025 class SimpleBoundCosts {
2038  public:
2039  struct BoundCost {
2040  int64 bound;
2041  int64 cost;
2042  };
2043  SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2044  : bound_costs_(num_bounds, default_bound_cost) {}
2045  BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2046  BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2047  int Size() { return bound_costs_.size(); }
2048  SimpleBoundCosts(const SimpleBoundCosts&) = delete;
2049  SimpleBoundCosts operator=(const SimpleBoundCosts&) = delete;
2050 
2051  private:
2052  std::vector<BoundCost> bound_costs_;
2053 };
2054 #endif // !defined SWIG
2055 
2073 // TODO(user): Break constraints need to know the service time of nodes
2077  public:
2080  RoutingModel* model() const { return model_; }
2084  int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const;
2087  int64 GetTransitValueFromClass(int64 from_index, int64 to_index,
2088  int64 vehicle_class) const {
2089  return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2090  to_index);
2091  }
2094  IntVar* CumulVar(int64 index) const { return cumuls_[index]; }
2095  IntVar* TransitVar(int64 index) const { return transits_[index]; }
2096  IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; }
2097  IntVar* SlackVar(int64 index) const { return slacks_[index]; }
2098 
2099 #if !defined(SWIGPYTHON)
2100  const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2103  const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2104  const std::vector<IntVar*>& transits() const { return transits_; }
2105  const std::vector<IntVar*>& slacks() const { return slacks_; }
2106 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2107  const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2109  return forbidden_intervals_;
2110  }
2112  SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index,
2113  int64 min_value,
2114  int64 max_value) const;
2118  int64 min_value) const {
2119  DCHECK_LT(index, forbidden_intervals_.size());
2120  const SortedDisjointIntervalList& forbidden_intervals =
2121  forbidden_intervals_[index];
2122  const auto first_forbidden_interval_it =
2123  forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2124  if (first_forbidden_interval_it != forbidden_intervals.end() &&
2125  min_value >= first_forbidden_interval_it->start) {
2127  return CapAdd(first_forbidden_interval_it->end, 1);
2128  }
2130  return min_value;
2131  }
2137  int64 max_value) const {
2138  DCHECK_LT(index, forbidden_intervals_.size());
2139  const SortedDisjointIntervalList& forbidden_intervals =
2140  forbidden_intervals_[index];
2141  const auto last_forbidden_interval_it =
2142  forbidden_intervals.LastIntervalLessOrEqual(max_value);
2143  if (last_forbidden_interval_it != forbidden_intervals.end() &&
2144  max_value <= last_forbidden_interval_it->end) {
2146  return CapSub(last_forbidden_interval_it->start, 1);
2147  }
2149  return max_value;
2150  }
2152  const std::vector<int64>& vehicle_capacities() const {
2153  return vehicle_capacities_;
2154  }
2158  return model_->TransitCallback(
2159  class_evaluators_[vehicle_to_class_[vehicle]]);
2160  }
2165  int vehicle) const {
2166  return model_->UnaryTransitCallbackOrNull(
2167  class_evaluators_[vehicle_to_class_[vehicle]]);
2168  }
2171  bool AreVehicleTransitsPositive(int vehicle) const {
2172  return model()->is_transit_evaluator_positive_
2173  [class_evaluators_[vehicle_to_class_[vehicle]]];
2174  }
2175  int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2176 #endif
2177 #endif
2178  void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle);
2182  void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle);
2189  void SetSpanCostCoefficientForAllVehicles(int64 coefficient);
2196  void SetGlobalSpanCostCoefficient(int64 coefficient);
2197 
2198 #ifndef SWIG
2199  void SetCumulVarPiecewiseLinearCost(int64 index,
2204  const PiecewiseLinearFunction& cost);
2207  bool HasCumulVarPiecewiseLinearCost(int64 index) const;
2210  const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2211  int64 index) const;
2212 #endif
2213 
2222  void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound,
2223  int64 coefficient);
2226  bool HasCumulVarSoftUpperBound(int64 index) const;
2230  int64 GetCumulVarSoftUpperBound(int64 index) const;
2234  int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const;
2235 
2248  void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound,
2249  int64 coefficient);
2252  bool HasCumulVarSoftLowerBound(int64 index) const;
2256  int64 GetCumulVarSoftLowerBound(int64 index) const;
2260  int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const;
2276  // TODO(user): Remove if !defined when routing.i is repaired.
2277 #if !defined(SWIGPYTHON)
2278  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2279  int pre_travel_evaluator,
2280  int post_travel_evaluator);
2281 #endif // !defined(SWIGPYTHON)
2282 
2284  void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2285  std::vector<int64> node_visit_transits);
2286 
2291  void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration,
2292  int vehicle);
2295  void InitializeBreaks();
2297  bool HasBreakConstraints() const;
2298 #if !defined(SWIGPYTHON)
2302  std::vector<IntervalVar*> breaks, int vehicle,
2303  std::vector<int64> node_visit_transits,
2304  std::function<int64(int64, int64)> group_delays);
2305 
2307  const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2308  int vehicle) const;
2311  // clang-format off
2312  const std::vector<std::pair<int64, int64> >&
2313  GetBreakDistanceDurationOfVehicle(int vehicle) const;
2314  // clang-format on
2315 #endif
2316  int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2317  int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2318 
2320  const RoutingDimension* base_dimension() const { return base_dimension_; }
2328  int64 ShortestTransitionSlack(int64 node) const;
2329 
2331  const std::string& name() const { return name_; }
2332 
2334 #ifndef SWIG
2335  const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2336  return path_precedence_graph_;
2337  }
2338 #endif // SWIG
2339 
2349  typedef std::function<int64(int, int)> PickupToDeliveryLimitFunction;
2350 
2352  PickupToDeliveryLimitFunction limit_function, int pair_index);
2353 
2354  bool HasPickupToDeliveryLimits() const;
2355 #ifndef SWIG
2356  int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2357  int delivery) const;
2358 
2360  int64 first_node;
2362  int64 offset;
2363  };
2364 
2366  node_precedences_.push_back(precedence);
2367  }
2368  const std::vector<NodePrecedence>& GetNodePrecedences() const {
2369  return node_precedences_;
2370  }
2371 #endif // SWIG
2372 
2373  void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset) {
2374  AddNodePrecedence({first_node, second_node, offset});
2375  }
2376 
2377  int64 GetSpanUpperBoundForVehicle(int vehicle) const {
2378  return vehicle_span_upper_bounds_[vehicle];
2379  }
2380 #ifndef SWIG
2381  const std::vector<int64>& vehicle_span_upper_bounds() const {
2382  return vehicle_span_upper_bounds_;
2383  }
2384 #endif // SWIG
2385  int64 GetSpanCostCoefficientForVehicle(int vehicle) const {
2386  return vehicle_span_cost_coefficients_[vehicle];
2387  }
2388 #ifndef SWIG
2389  const std::vector<int64>& vehicle_span_cost_coefficients() const {
2390  return vehicle_span_cost_coefficients_;
2391  }
2392 #endif // SWIG
2394  return global_span_cost_coefficient_;
2395  }
2396 
2398  DCHECK_GE(global_optimizer_offset_, 0);
2399  return global_optimizer_offset_;
2400  }
2401  int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2402  if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2403  return 0;
2404  }
2405  DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2406  return local_optimizer_offset_for_vehicle_[vehicle];
2407  }
2408 #if !defined SWIG
2412  int vehicle) {
2413  if (!HasSoftSpanUpperBounds()) {
2414  vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2415  model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2416  }
2417  vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2418  }
2419  bool HasSoftSpanUpperBounds() const {
2420  return vehicle_soft_span_upper_bound_ != nullptr;
2421  }
2423  int vehicle) const {
2424  DCHECK(HasSoftSpanUpperBounds());
2425  return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2426  }
2427 #endif
2428 
2429  private:
2430  struct SoftBound {
2431  IntVar* var;
2432  int64 bound;
2433  int64 coefficient;
2434  };
2435 
2436  struct PiecewiseLinearCost {
2437  PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2438  IntVar* var;
2439  std::unique_ptr<PiecewiseLinearFunction> cost;
2440  };
2441 
2442  class SelfBased {};
2443  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2444  const std::string& name,
2445  const RoutingDimension* base_dimension);
2446  RoutingDimension(RoutingModel* model, std::vector<int64> vehicle_capacities,
2447  const std::string& name, SelfBased);
2448  void Initialize(const std::vector<int>& transit_evaluators,
2449  const std::vector<int>& state_dependent_transit_evaluators,
2450  int64 slack_max);
2451  void InitializeCumuls();
2452  void InitializeTransits(
2453  const std::vector<int>& transit_evaluators,
2454  const std::vector<int>& state_dependent_transit_evaluators,
2455  int64 slack_max);
2456  void InitializeTransitVariables(int64 slack_max);
2458  void SetupCumulVarSoftUpperBoundCosts(
2459  std::vector<IntVar*>* cost_elements) const;
2461  void SetupCumulVarSoftLowerBoundCosts(
2462  std::vector<IntVar*>* cost_elements) const;
2463  void SetupCumulVarPiecewiseLinearCosts(
2464  std::vector<IntVar*>* cost_elements) const;
2467  void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2468  void SetupSlackAndDependentTransitCosts() const;
2470  void CloseModel(bool use_light_propagation);
2471 
2472  void SetOffsetForGlobalOptimizer(int64 offset) {
2473  global_optimizer_offset_ = std::max(Zero(), offset);
2474  }
2476  void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2478  std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2479  [](int64 offset) { return std::max(Zero(), offset); });
2480  local_optimizer_offset_for_vehicle_ = std::move(offsets);
2481  }
2482 
2483  std::vector<IntVar*> cumuls_;
2484  std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2485  std::vector<IntVar*> capacity_vars_;
2486  const std::vector<int64> vehicle_capacities_;
2487  std::vector<IntVar*> transits_;
2488  std::vector<IntVar*> fixed_transits_;
2491  std::vector<int> class_evaluators_;
2492  std::vector<int64> vehicle_to_class_;
2493 #ifndef SWIG
2494  ReverseArcListGraph<int, int> path_precedence_graph_;
2495 #endif
2496  // For every {first_node, second_node, offset} element in node_precedences_,
2497  // if both first_node and second_node are performed, then
2498  // cumuls_[second_node] must be greater than (or equal to)
2499  // cumuls_[first_node] + offset.
2500  std::vector<NodePrecedence> node_precedences_;
2501 
2502  // The transits of a dimension may depend on its cumuls or the cumuls of
2503  // another dimension. There can be no cycles, except for self loops, a
2504  // typical example for this is a time dimension.
2505  const RoutingDimension* const base_dimension_;
2506 
2507  // Values in state_dependent_class_evaluators_ correspond to the evaluators
2508  // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
2509  // class.
2510  std::vector<int> state_dependent_class_evaluators_;
2511  std::vector<int64> state_dependent_vehicle_to_class_;
2512 
2513  // For each pickup/delivery pair_index for which limits have been set,
2514  // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
2515  // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
2516  std::vector<PickupToDeliveryLimitFunction>
2517  pickup_to_delivery_limits_per_pair_index_;
2518 
2519  // Used if some vehicle has breaks in this dimension, typically time.
2520  bool break_constraints_are_initialized_ = false;
2521  // clang-format off
2522  std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2523  std::vector<std::vector<std::pair<int64, int64> > >
2524  vehicle_break_distance_duration_;
2525  // clang-format on
2526  // For each vehicle, stores the part of travel that is made directly
2527  // after (before) the departure (arrival) node of the travel.
2528  // These parts of the travel are non-interruptible, in particular by a break.
2529  std::vector<int> vehicle_pre_travel_evaluators_;
2530  std::vector<int> vehicle_post_travel_evaluators_;
2531 
2532  std::vector<IntVar*> slacks_;
2533  std::vector<IntVar*> dependent_transits_;
2534  std::vector<int64> vehicle_span_upper_bounds_;
2535  int64 global_span_cost_coefficient_;
2536  std::vector<int64> vehicle_span_cost_coefficients_;
2537  std::vector<SoftBound> cumul_var_soft_upper_bound_;
2538  std::vector<SoftBound> cumul_var_soft_lower_bound_;
2539  std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2540  RoutingModel* const model_;
2541  const std::string name_;
2542  int64 global_optimizer_offset_;
2543  std::vector<int64> local_optimizer_offset_for_vehicle_;
2545  std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2546  friend class RoutingModel;
2548 
2549  DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
2550 };
2551 
2552 #ifndef SWIG
2553 class SweepArranger {
2556  public:
2557  explicit SweepArranger(const std::vector<std::pair<int64, int64>>& points);
2558  virtual ~SweepArranger() {}
2559  void ArrangeIndices(std::vector<int64>* indices);
2560  void SetSectors(int sectors) { sectors_ = sectors; }
2561 
2562  private:
2563  std::vector<int> coordinates_;
2564  int sectors_;
2565 
2566  DISALLOW_COPY_AND_ASSIGN(SweepArranger);
2567 };
2568 #endif
2569 
2572 DecisionBuilder* MakeSetValuesFromTargets(Solver* solver,
2573  std::vector<IntVar*> variables,
2574  std::vector<int64> targets);
2575 
2576 #ifndef SWIG
2577 
2591 // TODO(user): Eventually move this to the core CP solver library
2594  public:
2596  std::unique_ptr<IntVarFilteredHeuristic> heuristic);
2597 
2599 
2600  Decision* Next(Solver* solver) override;
2601 
2602  std::string DebugString() const override;
2603 
2605  int64 number_of_decisions() const;
2606  int64 number_of_rejects() const;
2607 
2608  private:
2609  const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
2610 };
2611 
2614  public:
2615  IntVarFilteredHeuristic(Solver* solver, const std::vector<IntVar*>& vars,
2616  const std::vector<LocalSearchFilter*>& filters);
2617 
2619 
2622  Assignment* const BuildSolution();
2623 
2626  int64 number_of_decisions() const { return number_of_decisions_; }
2627  int64 number_of_rejects() const { return number_of_rejects_; }
2628 
2629  virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; }
2630 
2631  protected:
2633  void ResetSolution();
2635  virtual bool InitializeSolution() { return true; }
2637  virtual bool BuildSolutionInternal() = 0;
2641  bool Commit();
2643  virtual bool StopSearch() { return false; }
2646  void SetValue(int64 index, int64 value) {
2647  if (!is_in_delta_[index]) {
2648  delta_->FastAdd(vars_[index])->SetValue(value);
2649  delta_indices_.push_back(index);
2650  is_in_delta_[index] = true;
2651  } else {
2652  delta_->SetValue(vars_[index], value);
2653  }
2654  }
2657  int64 Value(int64 index) const {
2658  return assignment_->IntVarContainer().Element(index).Value();
2659  }
2661  bool Contains(int64 index) const {
2662  return assignment_->IntVarContainer().Element(index).Var() != nullptr;
2663  }
2666  int Size() const { return vars_.size(); }
2668  IntVar* Var(int64 index) const { return vars_[index]; }
2670  void SynchronizeFilters();
2671 
2673 
2674  private:
2677  bool FilterAccept();
2678 
2679  const std::vector<IntVar*> vars_;
2680  Assignment* const delta_;
2681  std::vector<int> delta_indices_;
2682  std::vector<bool> is_in_delta_;
2683  Assignment* const empty_;
2684  LocalSearchFilterManager filter_manager_;
2686  int64 number_of_decisions_;
2687  int64 number_of_rejects_;
2688 };
2689 
2692  public:
2694  const std::vector<LocalSearchFilter*>& filters);
2698  const std::function<int64(int64)>& next_accessor);
2699  RoutingModel* model() const { return model_; }
2701  int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
2703  int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
2706  void MakeDisjunctionNodesUnperformed(int64 node);
2709 
2710  protected:
2711  bool StopSearch() override { return model_->CheckLimit(); }
2712  virtual void SetVehicleIndex(int64 node, int vehicle) {}
2713  virtual void ResetVehicleIndices() {}
2714 
2715  private:
2717  bool InitializeSolution() override;
2718 
2719  RoutingModel* const model_;
2720  std::vector<int64> start_chain_ends_;
2721  std::vector<int64> end_chain_starts_;
2722 };
2723 
2725  public:
2728  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2729  std::function<int64(int64)> penalty_evaluator,
2730  const std::vector<LocalSearchFilter*>& filters);
2732 
2733  protected:
2734  typedef std::pair<int64, int64> ValuedPosition;
2735  struct StartEndValue {
2736  int64 distance;
2737  int vehicle;
2738 
2739  bool operator<(const StartEndValue& other) const {
2740  return std::tie(distance, vehicle) <
2741  std::tie(other.distance, other.vehicle);
2742  }
2743  };
2744  typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
2745 
2751  // clang-format off
2752  std::vector<std::vector<StartEndValue> >
2753  ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
2754 
2759  template <class Queue>
2761  std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
2762  Queue* priority_queue);
2763  // clang-format on
2764 
2769  void InsertBetween(int64 node, int64 predecessor, int64 successor);
2775  int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
2776  std::vector<ValuedPosition>* valued_positions);
2781  int64 GetInsertionCostForNodeAtPosition(int64 node_to_insert,
2782  int64 insert_after,
2783  int64 insert_before,
2784  int vehicle) const;
2787  int64 GetUnperformedValue(int64 node_to_insert) const;
2788 
2789  std::function<int64(int64, int64, int64)> evaluator_;
2790  std::function<int64(int64)> penalty_evaluator_;
2791 };
2792 
2802  public:
2816  };
2817 
2820  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
2821  std::function<int64(int64)> penalty_evaluator,
2822  const std::vector<LocalSearchFilter*>& filters,
2825  bool BuildSolutionInternal() override;
2826  std::string DebugString() const override {
2827  return "GlobalCheapestInsertionFilteredHeuristic";
2828  }
2829 
2830  private:
2831  class PairEntry;
2832  class NodeEntry;
2833  typedef absl::flat_hash_set<PairEntry*> PairEntries;
2834  typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
2835 
2842  void InsertPairs();
2843 
2851  void InsertNodesOnRoutes(const std::vector<int>& nodes,
2852  const absl::flat_hash_set<int>& vehicles);
2853 
2859  void SequentialInsertNodes(const std::vector<int>& nodes);
2860 
2864  void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
2865  std::vector<int>* unused_vehicles,
2866  absl::flat_hash_set<int>* used_vehicles);
2867 
2871  void InsertFarthestNodesAsSeeds();
2872 
2881  template <class Queue>
2882  int InsertSeedNode(
2883  std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
2884  Queue* priority_queue, std::vector<bool>* is_vehicle_used);
2885  // clang-format on
2886 
2889  void InitializePairPositions(
2890  AdjustablePriorityQueue<PairEntry>* priority_queue,
2891  std::vector<PairEntries>* pickup_to_entries,
2892  std::vector<PairEntries>* delivery_to_entries);
2898  void InitializeInsertionEntriesPerformingPair(
2899  int64 pickup, int64 delivery, int64 penalty,
2900  AdjustablePriorityQueue<PairEntry>* priority_queue,
2901  std::vector<PairEntries>* pickup_to_entries,
2902  std::vector<PairEntries>* delivery_to_entries);
2905  void UpdatePairPositions(int vehicle, int64 insert_after,
2906  AdjustablePriorityQueue<PairEntry>* priority_queue,
2907  std::vector<PairEntries>* pickup_to_entries,
2908  std::vector<PairEntries>* delivery_to_entries) {
2909  UpdatePickupPositions(vehicle, insert_after, priority_queue,
2910  pickup_to_entries, delivery_to_entries);
2911  UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
2912  pickup_to_entries, delivery_to_entries);
2913  }
2916  void UpdatePickupPositions(int vehicle, int64 pickup_insert_after,
2917  AdjustablePriorityQueue<PairEntry>* priority_queue,
2918  std::vector<PairEntries>* pickup_to_entries,
2919  std::vector<PairEntries>* delivery_to_entries);
2922  void UpdateDeliveryPositions(
2923  int vehicle, int64 delivery_insert_after,
2924  AdjustablePriorityQueue<PairEntry>* priority_queue,
2925  std::vector<PairEntries>* pickup_to_entries,
2926  std::vector<PairEntries>* delivery_to_entries);
2929  void DeletePairEntry(PairEntry* entry,
2930  AdjustablePriorityQueue<PairEntry>* priority_queue,
2931  std::vector<PairEntries>* pickup_to_entries,
2932  std::vector<PairEntries>* delivery_to_entries);
2935  void InitializePositions(const std::vector<int>& nodes,
2936  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2937  std::vector<NodeEntries>* position_to_node_entries,
2938  const absl::flat_hash_set<int>& vehicles);
2944  void InitializeInsertionEntriesPerformingNode(
2945  int64 node, int64 penalty, const absl::flat_hash_set<int>& vehicles,
2946  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2947  std::vector<NodeEntries>* position_to_node_entries);
2950  void UpdatePositions(const std::vector<int>& nodes, int vehicle,
2951  int64 insert_after,
2952  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2953  std::vector<NodeEntries>* node_entries);
2956  void DeleteNodeEntry(NodeEntry* entry,
2957  AdjustablePriorityQueue<NodeEntry>* priority_queue,
2958  std::vector<NodeEntries>* node_entries);
2959 
2964  void AddNeighborForCostClass(int cost_class, int64 node_index,
2965  int64 neighbor_index, bool neighbor_is_pickup,
2966  bool neighbor_is_delivery);
2967 
2970  bool IsNeighborForCostClass(int cost_class, int64 node_index,
2971  int64 neighbor_index) const;
2972 
2974  const std::vector<int64>& GetPickupNeighborsOfNodeForCostClass(
2975  int cost_class, int64 node_index) const {
2976  if (gci_params_.neighbors_ratio == 1) {
2977  return pickup_nodes_;
2978  }
2979  return node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
2980  ->PositionsSetAtLeastOnce();
2981  }
2982 
2984  const std::vector<int64>& GetDeliveryNeighborsOfNodeForCostClass(
2985  int cost_class, int64 node_index) const {
2986  if (gci_params_.neighbors_ratio == 1) {
2987  return delivery_nodes_;
2988  }
2989  return node_index_to_delivery_neighbors_by_cost_class_
2990  [node_index][cost_class]
2991  ->PositionsSetAtLeastOnce();
2992  }
2993 
2995  const std::vector<int64>& GetSingleNeighborsOfNodeForCostClass(
2996  int cost_class, int64 node_index) const {
2997  if (gci_params_.neighbors_ratio == 1) {
2998  return single_nodes_;
2999  }
3000  return node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]
3001  ->PositionsSetAtLeastOnce();
3002  }
3003 
3005  std::vector<const std::vector<int64>*> GetNeighborsOfNodeForCostClass(
3006  int cost_class, int64 node_index) const {
3007  return {&GetSingleNeighborsOfNodeForCostClass(cost_class, node_index),
3008  &GetPickupNeighborsOfNodeForCostClass(cost_class, node_index),
3009  &GetDeliveryNeighborsOfNodeForCostClass(cost_class, node_index)};
3010  }
3011 
3012  void ResetVehicleIndices() override {
3013  node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
3014  }
3015 
3016  void SetVehicleIndex(int64 node, int vehicle) override {
3017  DCHECK_LT(node, node_index_to_vehicle_.size());
3018  node_index_to_vehicle_[node] = vehicle;
3019  }
3020 
3023  bool CheckVehicleIndices() const;
3024 
3025  GlobalCheapestInsertionParameters gci_params_;
3027  std::vector<int> node_index_to_vehicle_;
3028 
3029  // clang-format off
3030  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3031  node_index_to_single_neighbors_by_cost_class_;
3032  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3033  node_index_to_pickup_neighbors_by_cost_class_;
3034  std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
3035  node_index_to_delivery_neighbors_by_cost_class_;
3036  // clang-format on
3037 
3041  std::vector<int64> single_nodes_;
3042  std::vector<int64> pickup_nodes_;
3043  std::vector<int64> delivery_nodes_;
3044 };
3045 
3053  public:
3056  RoutingModel* model, std::function<int64(int64, int64, int64)> evaluator,
3057  const std::vector<LocalSearchFilter*>& filters);
3059  bool BuildSolutionInternal() override;
3060  std::string DebugString() const override {
3061  return "LocalCheapestInsertionFilteredHeuristic";
3062  }
3063 
3064  private:
3070  void ComputeEvaluatorSortedPositions(int64 node,
3071  std::vector<int64>* sorted_positions);
3076  void ComputeEvaluatorSortedPositionsOnRouteAfter(
3077  int64 node, int64 start, int64 next_after_start,
3078  std::vector<int64>* sorted_positions);
3079 
3080  std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
3081 };
3082 
3086  public:
3088  RoutingModel* model, const std::vector<LocalSearchFilter*>& filters);
3090  bool BuildSolutionInternal() override;
3091 
3092  private:
3093  class PartialRoutesAndLargeVehicleIndicesFirst {
3094  public:
3095  explicit PartialRoutesAndLargeVehicleIndicesFirst(
3096  const CheapestAdditionFilteredHeuristic& builder)
3097  : builder_(builder) {}
3098  bool operator()(int vehicle1, int vehicle2) const;
3099 
3100  private:
3101  const CheapestAdditionFilteredHeuristic& builder_;
3102  };
3104  template <typename Iterator>
3105  std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
3106  Iterator end) const {
3107  const int size = model()->Size();
3108  std::vector<int64> nexts;
3109  for (Iterator it = start; it != end; ++it) {
3110  const int64 next = *it;
3111  if (next != node && (next >= size || !Contains(next))) {
3112  nexts.push_back(next);
3113  }
3114  }
3115  return nexts;
3116  }
3118  virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
3119  virtual int64 FindTopSuccessor(int64 node,
3120  const std::vector<int64>& successors) = 0;
3121 };
3122 
3127  public:
3130  RoutingModel* model, std::function<int64(int64, int64)> evaluator,
3131  const std::vector<LocalSearchFilter*>& filters);
3133  std::string DebugString() const override {
3134  return "EvaluatorCheapestAdditionFilteredHeuristic";
3135  }
3136 
3137  private:
3139  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3140  int64 FindTopSuccessor(int64 node,
3141  const std::vector<int64>& successors) override;
3142 
3143  std::function<int64(int64, int64)> evaluator_;
3144 };
3145 
3150  public:
3154  const std::vector<LocalSearchFilter*>& filters);
3156  std::string DebugString() const override {
3157  return "ComparatorCheapestAdditionFilteredHeuristic";
3158  }
3159 
3160  private:
3162  void SortSuccessors(int64 node, std::vector<int64>* successors) override;
3163  int64 FindTopSuccessor(int64 node,
3164  const std::vector<int64>& successors) override;
3165 
3166  Solver::VariableValueComparator comparator_;
3167 };
3168 
3178  public:
3182  double neighbors_ratio = 1.0;
3188  bool add_reverse_arcs = false;
3191  double arc_coefficient = 1.0;
3192  };
3193 
3195  const RoutingIndexManager* manager,
3196  SavingsParameters parameters,
3197  const std::vector<LocalSearchFilter*>& filters);
3198  ~SavingsFilteredHeuristic() override;
3199  bool BuildSolutionInternal() override;
3200 
3201  protected:
3202  typedef std::pair</*saving*/ int64, /*saving index*/ int64> Saving;
3203 
3204  template <typename S>
3206 
3209  int64 fixed_cost;
3210 
3211  bool operator<(const VehicleClassEntry& other) const {
3212  return std::tie(fixed_cost, vehicle_class) <
3213  std::tie(other.fixed_cost, other.vehicle_class);
3214  }
3215  };
3216 
3217  virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
3218 
3219  virtual void BuildRoutesFromSavings() = 0;
3220 
3222  int64 GetVehicleTypeFromSaving(const Saving& saving) const {
3223  return saving.second / size_squared_;
3224  }
3226  int64 GetBeforeNodeFromSaving(const Saving& saving) const {
3227  return (saving.second % size_squared_) / Size();
3228  }
3230  int64 GetAfterNodeFromSaving(const Saving& saving) const {
3231  return (saving.second % size_squared_) % Size();
3232  }
3234  int64 GetSavingValue(const Saving& saving) const { return saving.first; }
3235 
3245  int StartNewRouteWithBestVehicleOfType(int type, int64 before_node,
3246  int64 after_node);
3247 
3248  std::vector<int> type_index_of_vehicle_;
3249  // clang-format off
3250  std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
3251  std::vector<std::deque<int> > vehicles_per_vehicle_class_;
3252  std::unique_ptr<SavingsContainer<Saving> > savings_container_;
3253  // clang-format on
3254 
3255  private:
3260  // clang-format off
3261  void AddSymmetricArcsToAdjacencyLists(
3262  std::vector<std::vector<int64> >* adjacency_lists);
3263  // clang-format on
3264 
3271  void ComputeSavings();
3273  Saving BuildSaving(int64 saving, int vehicle_type, int before_node,
3274  int after_node) const {
3275  return std::make_pair(saving, vehicle_type * size_squared_ +
3276  before_node * Size() + after_node);
3277  }
3278 
3286  void ComputeVehicleTypes();
3287 
3291  int64 MaxNumNeighborsPerNode(int num_vehicle_types) const;
3292 
3293  const RoutingIndexManager* const manager_;
3294  const SavingsParameters savings_params_;
3295  int64 size_squared_;
3296 
3298 };
3299 
3301  public:
3303  RoutingModel* model, const RoutingIndexManager* manager,
3304  SavingsParameters parameters,
3305  const std::vector<LocalSearchFilter*>& filters)
3306  : SavingsFilteredHeuristic(model, manager, parameters, filters) {}
3308  std::string DebugString() const override {
3309  return "SequentialSavingsFilteredHeuristic";
3310  }
3311 
3312  private:
3317  void BuildRoutesFromSavings() override;
3318  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
3319 };
3320 
3322  public:
3324  RoutingModel* model, const RoutingIndexManager* manager,
3325  SavingsParameters parameters,
3326  const std::vector<LocalSearchFilter*>& filters)
3327  : SavingsFilteredHeuristic(model, manager, parameters, filters) {}
3329  std::string DebugString() const override {
3330  return "ParallelSavingsFilteredHeuristic";
3331  }
3332 
3333  private:
3344  void BuildRoutesFromSavings() override;
3345 
3346  double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
3347 
3352  void MergeRoutes(int first_vehicle, int second_vehicle, int64 before_node,
3353  int64 after_node);
3354 
3356  std::vector<int64> first_node_on_route_;
3357  std::vector<int64> last_node_on_route_;
3361  std::vector<int> vehicle_of_first_or_last_node_;
3362 };
3363 
3367 
3369  public:
3371  const std::vector<LocalSearchFilter*>& filters,
3372  bool use_minimum_matching);
3374  bool BuildSolutionInternal() override;
3375  std::string DebugString() const override {
3376  return "ChristofidesFilteredHeuristic";
3377  }
3378 
3379  private:
3380  const bool use_minimum_matching_;
3381 };
3382 #endif // SWIG
3383 
3388 bool SolveModelWithSat(const RoutingModel& model,
3389  const RoutingSearchParameters& search_parameters,
3390  const Assignment* initial_solution,
3391  Assignment* solution);
3392 
3394 
3396  public:
3397  BasePathFilter(const std::vector<IntVar*>& nexts, int next_domain_size);
3398  ~BasePathFilter() override {}
3399  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3400  int64 objective_min, int64 objective_max) override;
3401  void OnSynchronize(const Assignment* delta) override;
3402 
3403  protected:
3404  static const int64 kUnassigned;
3405 
3406  int64 GetNext(int64 node) const {
3407  return (new_nexts_[node] == kUnassigned)
3408  ? (IsVarSynced(node) ? Value(node) : kUnassigned)
3409  : new_nexts_[node];
3410  }
3411  int NumPaths() const { return starts_.size(); }
3412  int64 Start(int i) const { return starts_[i]; }
3413  int GetPath(int64 node) const { return paths_[node]; }
3414  int Rank(int64 node) const { return ranks_[node]; }
3415  bool IsDisabled() const { return status_ == DISABLED; }
3416  const std::vector<int64>& GetTouchedPathStarts() const {
3417  return touched_paths_.PositionsSetAtLeastOnce();
3418  }
3419  const std::vector<int64>& GetNewSynchronizedUnperformedNodes() const {
3420  return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3421  }
3422 
3423  private:
3424  enum Status { UNKNOWN, ENABLED, DISABLED };
3425 
3426  virtual bool DisableFiltering() const { return false; }
3427  virtual void OnBeforeSynchronizePaths() {}
3428  virtual void OnAfterSynchronizePaths() {}
3429  virtual void OnSynchronizePathFromStart(int64 start) {}
3430  virtual void InitializeAcceptPath() {}
3431  virtual bool AcceptPath(int64 path_start, int64 chain_start,
3432  int64 chain_end) = 0;
3433  virtual bool FinalizeAcceptPath(const Assignment* delta, int64 objective_min,
3434  int64 objective_max) {
3435  return true;
3436  }
3438  void ComputePathStarts(std::vector<int64>* path_starts,
3439  std::vector<int>* index_to_path);
3440  bool HavePathsChanged();
3441  void SynchronizeFullAssignment();
3442  void UpdateAllRanks();
3443  void UpdatePathRanksFromStart(int start);
3444 
3445  std::vector<int64> node_path_starts_;
3446  std::vector<int64> starts_;
3447  std::vector<int> paths_;
3448  SparseBitset<int64> new_synchronized_unperformed_nodes_;
3449  std::vector<int64> new_nexts_;
3450  std::vector<int> delta_touched_;
3451  SparseBitset<> touched_paths_;
3452  SparseBitset<> touched_path_nodes_;
3453  std::vector<int> ranks_;
3454 
3455  Status status_;
3456 };
3457 
3462 // TODO(user): Also call the solution finalizer on variables, with the
3468 // TODO(user): Avoid such false negatives.
3470  public:
3471  explicit CPFeasibilityFilter(const RoutingModel* routing_model);
3472  ~CPFeasibilityFilter() override {}
3473  std::string DebugString() const override { return "CPFeasibilityFilter"; }
3474  bool Accept(const Assignment* delta, const Assignment* deltadelta,
3475  int64 objective_min, int64 objective_max) override;
3476  void OnSynchronize(const Assignment* delta) override;
3477 
3478  private:
3479  void AddDeltaToAssignment(const Assignment* delta, Assignment* assignment);
3480 
3481  static const int64 kUnassigned;
3482  const RoutingModel* const model_;
3483  Solver* const solver_;
3484  Assignment* const assignment_;
3485  Assignment* const temp_assignment_;
3486  DecisionBuilder* const restore_;
3487 };
3488 
3489 #if !defined(SWIG)
3490 IntVarLocalSearchFilter* MakeNodeDisjunctionFilter(
3491  const RoutingModel& routing_model);
3492 IntVarLocalSearchFilter* MakeVehicleAmortizedCostFilter(
3493  const RoutingModel& routing_model);
3494 IntVarLocalSearchFilter* MakeTypeRegulationsFilter(
3495  const RoutingModel& routing_model);
3497  const std::vector<RoutingDimension*>& dimensions,
3498  const RoutingSearchParameters& parameters, bool filter_objective_cost,
3499  std::vector<LocalSearchFilter*>* filters);
3500 IntVarLocalSearchFilter* MakePathCumulFilter(
3501  const RoutingDimension& dimension,
3502  const RoutingSearchParameters& parameters,
3503  bool propagate_own_objective_value, bool filter_objective_cost);
3504 IntVarLocalSearchFilter* MakeCumulBoundsPropagatorFilter(
3505  const RoutingDimension& dimension);
3506 IntVarLocalSearchFilter* MakeGlobalLPCumulFilter(
3507  GlobalDimensionCumulOptimizer* optimizer, bool filter_objective_cost);
3508 IntVarLocalSearchFilter* MakePickupDeliveryFilter(
3509  const RoutingModel& routing_model, const RoutingModel::IndexPairs& pairs,
3510  const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3511 IntVarLocalSearchFilter* MakeVehicleVarFilter(
3512  const RoutingModel& routing_model);
3513 IntVarLocalSearchFilter* MakeVehicleBreaksFilter(
3514  const RoutingModel& routing_model, const RoutingDimension& dimension);
3515 IntVarLocalSearchFilter* MakeCPFeasibilityFilter(
3516  const RoutingModel* routing_model);
3517 #endif
3518 
3519 } // namespace operations_research
3520 #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.
RoutingIndexPair IndexPair
Definition: routing.h:245
virtual bool InitializeSolution()
Virtual method to initialize the solution.
Definition: routing.h:2635
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
std::string DebugString() const override
Definition: routing.h:3375
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3323
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
const IntContainer & IntVarContainer() const
Generic filter-based heuristic applied to IntVars.
Definition: routing.h:2613
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:3155
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Definition: routing.h:2373
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:2360
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1144
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:2087
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:598
@ 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:2381
const std::vector< int64 > & GetTouchedPathStarts() const
Definition: routing.h:3416
bool operator<(const StartEndValue &other) const
Definition: routing.h:2739
std::vector< int64 > start_max
Definition: routing.h:1745
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:382
bool HasPickupToDeliveryLimits() const
@ DELIVERY
Definition: routing.h:1930
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1203
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 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:857
A BaseObject is the root of all reversibly allocated objects.
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:2136
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2080
std::string DebugString() const override
Definition: routing.h:3473
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:792
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2335
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:264
std::pair< int64, int64 > ValuedPosition
Definition: routing.h:2734
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)
int vehicle_class
Definition: routing.h:3208
friend class RoutingDimension
Definition: routing.h:1717
std::vector< int > type_index_of_vehicle_
Definition: routing.h:3248
virtual ~SweepArranger()
Definition: routing.h:2558
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 sets of same-vehicle/temporal 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...
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:1087
int64 distance
Definition: routing.h:2736
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:362
std::string DebugString() const override
Definition: routing.h:3133
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
Definition: routing.h:2701
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
void SetValue(const IntVar *const var, int64 value)
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< LocalSearchFilter * > &filters)
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1080
void InitialPropagate() override
This method performs the initial propagation of the constraint.
~CheapestInsertionFilteredHeuristic() override
Definition: routing.h:2731
virtual ~IntVarFilteredHeuristic()
Definition: routing.h:2618
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
Definition: routing.h:1163
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:1820
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
void Clear()
Definition: routing.h:1754
int64 number_of_decisions() const
Returns statistics from its underlying heuristic.
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1124
~GlobalCheapestInsertionFilteredHeuristic() override
Definition: routing.h:2824
virtual bool StopSearch()
Returns true if the search must be stopped.
Definition: routing.h:2643
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2103
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
int64 Zero()
NOLINT.
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:240
Filter-based heuristic dedicated to routing.
Definition: routing.h:2691
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:527
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
Definition: routing.h:341
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
std::function< int64(int64)> penalty_evaluator_
Definition: routing.h:2790
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:238
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
virtual void BuildRoutesFromSavings()=0
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
~TypeIncompatibilityChecker() override
Definition: routing.h:1960
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
Definition: routing.h:617
bool IsVarSynced(int index) const
IntVar * SlackVar(int64 index) const
Definition: routing.h:2097
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2008
static const int64 kUnassigned
Definition: routing.h:3404
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
Definition: routing.h:3205
RoutingCostClassIndex CostClassIndex
Definition: routing.h:236
RangeIntToIntFunction * transit
Definition: routing.h:263
std::string DebugString() const override
Definition: routing.h:3060
A DecisionBuilder is responsible for creating the search tree.
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
void SetValue(int64 v)
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:3185
Manager for any NodeIndex <-> variable index conversion.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:709
std::string DebugString() const override
Definition: routing.h:3156
const E & Element(const V *const var) const
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:1084
int GetNumberOfVisitTypes() const
Definition: routing.h:736
absl::Time AbsoluteSolverDeadline() const
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:1974
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2385
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:346
bool HasTemporalTypeRequirements() const
Definition: routing.h:786
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:3058
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
Definition: routing.h:2808
ChristofidesFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters, bool use_minimum_matching)
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:2164
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:3414
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
int GetNonDeliveryCount(int type) const
Returns the number of pickups and fixed nodes from counts_of_type_["type"].
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:2096
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2037
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1158
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:239
int delivery
Definition: routing.h:1934
~RoutingFilteredHeuristic() override
Definition: routing.h:2695
bool StopSearch() override
Returns true if the search must be stopped.
Definition: routing.h:2711
BoundCost bound_cost(int element) const
Definition: routing.h:2046
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Definition: routing.h:3051
std::string DebugString() const override
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
Definition: routing.h:3188
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:622
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:3202
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'.
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:1743
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:2094
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2043
std::unique_ptr< SavingsContainer< Saving > > savings_container_
Definition: routing.h:3252
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2401
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
std::string DebugString() const override
Definition: routing.h:3308
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:2811
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:1751
CostClass(int evaluator_index)
Definition: routing.h:309
int64 second_node
Definition: routing.h:2361
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:2349
std::vector< int64 > start_min
Definition: routing.h:1744
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2331
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Definition: routing.h:2646
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
int64 fixed_cost
Definition: routing.h:3209
static const char kLightElement[]
Constraint types.
Definition: routing.h:1727
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
Definition: routing.h:3234
~IntVarFilteredDecisionBuilder() override
Definition: routing.h:2598
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:3413
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
virtual void ResetVehicleIndices()
Definition: routing.h:2713
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1221
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1107
@ ROUTING_SUCCESS
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:218
int NumPaths() const
Definition: routing.h:3411
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
int64 GetGlobalOptimizerOffset() const
Definition: routing.h:2397
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:1098
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
Definition: routing.h:1061
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
@ 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.
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
Definition: routing.h:2657
virtual ~TypeRegulationsChecker()
Definition: routing.h:1924
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.
static constexpr Value UNSET
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
Definition: routing.h:3226
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:3398
~ChristofidesFilteredHeuristic() override
Definition: routing.h:3373
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:973
The class IntVar is a subset of IntExpr.
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:2157
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
Definition: routing.h:3085
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
GlobalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters, GlobalCheapestInsertionParameters parameters)
Takes ownership of evaluators.
Definition: routing.h:2359
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:535
TypeRegulationsChecker(const RoutingModel &model)
Definition: routing.h:1931
std::function< int64(int64, int64, int64)> evaluator_
Definition: routing.h:2789
int64 bound
Definition: routing.h:2040
A structure to hold tasks described by their features.
Definition: routing.h:1742
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
int GetNonDeliveredCount(int type) const
Same as above, but subtracting the number of deliveries of "type".
A Decision represents a choice point in the search tree.
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)...
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:1921
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:324
bool IsDisabled() const
Definition: routing.h:3415
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:870
friend class RoutingModel
Definition: routing.h:2546
void InitialPropagate() override
This method performs the initial propagation of the constraint.
std::function< bool(int64, int64, int64)> VariableValueComparator
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type_
Definition: routing.h:3250
friend class SavingsFilteredHeuristicTestPeer
Definition: routing.h:3297
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.
RoutingFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
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 Check() override
This method is called to check the status of the limit.
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
Definition: routing.h:862
virtual bool FinalizeCheck() const
Definition: routing.h:1946
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...
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:1972
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio) are considered as insertion positions during in...
Definition: routing.h:2815
void OnSynchronize(const Assignment *delta) override
int vehicle
Definition: routing.h:2737
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:378
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
int64 number_of_rejects() const
Definition: routing.h:2627
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:1068
Definition: routing.h:3179
virtual void InitializeCheck()
Definition: routing.h:1944
FirstSolutionStrategy_Value Value
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
Definition: routing.h:2626
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:1223
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:3222
void OnSynchronize(const Assignment *delta) override
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:853
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...
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
Definition: routing.h:2703
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:1823
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
Definition: routing.h:2800
Assignment * MutablePreAssignment()
Definition: routing.h:974
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.
BoundCost & bound_cost(int element)
Definition: routing.h:2045
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.
std::vector< bool > is_preemptible
Definition: routing.h:1750
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:626
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:2411
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:2555
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2076
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
static const char kLightElement2[]
Definition: routing.h:1728
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:2419
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
Definition: routing.h:3230
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1206
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:875
void SetVisitType(int64 index, int type)
Set the node visit types and incompatibilities/requirements between the types (see below).
~EvaluatorCheapestAdditionFilteredHeuristic() override
Definition: routing.h:3132
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:3211
std::vector< int64 > duration_min
Definition: routing.h:1746
const RoutingModel & model_
Definition: routing.h:1948
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:469
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:1115
void SetSweepArranger(SweepArranger *sweep_arranger)
Definition: routing.h:1057
@ NONE
Definition: routing.h:1930
IntVar * TransitVar(int64 index) const
Definition: routing.h:2095
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:1735
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:518
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model)
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:1244
~ParallelSavingsFilteredHeuristic() override
Definition: routing.h:3328
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:567
std::vector< int64 > duration_max
Definition: routing.h:1747
IntVarLocalSearchFilter * MakeCumulBoundsPropagatorFilter(const RoutingDimension &dimension)
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:437
std::vector< int64 > end_max
Definition: routing.h:1749
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
Definition: routing.h:3177
const std::vector< IntVar * > & transits() const
Definition: routing.h:2104
CheapestAdditionFilteredHeuristic(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
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:1233
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:2377
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
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
Definition: routing.h:3191
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:228
Generic path-based filter class.
Definition: routing.h:3395
~TypeRequirementChecker() override
Definition: routing.h:1976
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:2393
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:1724
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1212
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Definition: routing.h:2668
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:3469
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
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:850
Definition: routing.h:2803
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:358
std::vector< std::deque< int > > vehicles_per_vehicle_class_
Definition: routing.h:3251
virtual void SetVehicleIndex(int64 node, int vehicle)
Definition: routing.h:2712
int non_pickup_delivery
Definition: routing.h:1932
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1219
Definition: routing.h:3321
@ PICKUP
Definition: routing.h:1930
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:3089
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:2362
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.
A constraint is the main modeling object.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
Definition: routing.h:339
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
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:1718
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:2320
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2171
RoutingModel * model() const
Definition: routing.h:2699
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
Definition: routing.h:2666
PickupDeliveryStatus
Definition: routing.h:1930
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2102
@ 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:2041
std::vector< std::pair< int64, int64 > > distance_duration
Definition: routing.h:1752
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:386
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:705
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:3182
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:3412
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,...
Definition: routing.h:3207
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:2422
~SequentialSavingsFilteredHeuristic() override
Definition: routing.h:3307
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:2389
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:273
void Post() override
This method is called when the constraint is processed by the solver.
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:354
@ 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:531
Christofides addition heuristic.
Definition: routing.h:3368
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:2368
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
std::string DebugString() const override
Definition: routing.h:2826
int pickup
Definition: routing.h:1933
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 std::vector< IntVar * > & slacks() const
Definition: routing.h:2105
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:562
SortedDisjointIntervalList GetAllowedIntervalsInRange(int64 index, int64 min_value, int64 max_value) const
Returns allowed intervals for a given node in a given interval.
friend class RoutingModelInspector
Definition: routing.h:2547
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1168
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
Definition: routing.h:2039
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:2735
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...
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
~RoutingModel()
Checker for type incompatibilities.
Definition: routing.h:1956
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:2117
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1117
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
Definition: routing.h:2661
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
Definition: routing.h:2805
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:590
Solver Class.
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:3406
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:1101
void ArrangeIndices(std::vector< int64 > *indices)
void AppendTasksFromPath(const std::vector< int64 > &path, const std::vector< int64 > &min_travels, const std::vector< int64 > &max_travels, const std::vector< int64 > &pre_travels, const std::vector< int64 > &post_travels, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
@ 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:2152
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
Definition: routing.h:3419
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:2672
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
Definition: routing.h:3148
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1150
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:1129
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:750
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...
SavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
~CPFeasibilityFilter() override
Definition: routing.h:3472
const std::vector< absl::flat_hash_set< int > > & GetTemporalRequiredTypeAlternativesOfType(int type) const
std::function< int64(int64, int64)> IndexEvaluator2
virtual std::string DebugString() const
Definition: routing.h:2629
FirstSolutionStrategy_Value
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
Definition: routing.h:3125
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
Definition: routing.h:338
int64 Value() const
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:783
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1170
virtual bool CheckTypeRegulations(int type)=0
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1160
Interval variables are often used in scheduling.
int end_equivalence_class
Definition: routing.h:334
bool operator<(const DimensionCost &cost) const
Definition: routing.h:299
bool DistanceDuration(Tasks *tasks)
Assignment *const BuildSolution()
Builds a solution.
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:653
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:1078
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:2108
int vehicle_to_class(int vehicle) const
Definition: routing.h:2175
std::pair< StartEndValue, int > Seed
Definition: routing.h:2744
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
Definition: routing.h:2593
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
Definition: routing.h:2724
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
Definition: routing.h:3302
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
std::vector< int64 > end_min
Definition: routing.h:1748
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:2560
int RegisterTransitCallback(TransitCallback2 callback)
void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilter * > *filters)
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, const RoutingSearchParameters &parameters, bool propagate_own_objective_value, bool filter_objective_cost)
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
Definition: routing.h:1110
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:753
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:949
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
void Post() override
This method is called when the constraint is processed by the solver.
int Size()
Definition: routing.h:2047
void AddTemporalRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D temporally depends on type_R, any non-delivery node_D of type_D requires at least one non-d...
IntVar * Var() const
std::string DebugString() const override
Definition: routing.h:3329
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2365
Definition: routing.h:3300
static const char kRemoveValues[]
Definition: routing.h:1729
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).