C++ Reference

C++ Reference: Routing

routing.h
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
68// TODO(user): Add a section on costs (vehicle arc costs, span costs,
69// disjunctions costs).
70//
156
157#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
158#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
159
160#include <algorithm>
161#include <deque>
162#include <functional>
163#include <memory>
164#include <set>
165#include <string>
166#include <tuple>
167#include <utility>
168#include <vector>
169
170#include "absl/container/flat_hash_map.h"
171#include "absl/container/flat_hash_set.h"
172#include "absl/functional/bind_front.h"
173#include "absl/memory/memory.h"
174#include "absl/time/time.h"
175#include "ortools/base/int_type.h"
176#include "ortools/base/integral_types.h"
177#include "ortools/base/logging.h"
178#include "ortools/base/macros.h"
179#include "ortools/base/map_util.h"
180#include "ortools/base/strong_vector.h"
187#include "ortools/graph/graph.h"
188#include "ortools/sat/theta_tree.h"
189#include "ortools/util/bitset.h"
190#include "ortools/util/piecewise_linear_function.h"
191#include "ortools/util/range_query_function.h"
192#include "ortools/util/saturated_arithmetic.h"
193#include "ortools/util/sorted_interval_list.h"
194
195namespace operations_research {
196
197class GlobalDimensionCumulOptimizer;
198class LocalDimensionCumulOptimizer;
199class LocalSearchPhaseParameters;
200#ifndef SWIG
201class IndexNeighborFinder;
202class IntVarFilteredDecisionBuilder;
203#endif
204class RoutingDimension;
205#ifndef SWIG
206using util::ReverseArcListGraph;
207class SweepArranger;
208#endif
209
211 public:
213 enum Status {
224 };
225
234 };
235 typedef RoutingCostClassIndex CostClassIndex;
236 typedef RoutingDimensionIndex DimensionIndex;
237 typedef RoutingDisjunctionIndex DisjunctionIndex;
238 typedef RoutingVehicleClassIndex VehicleClassIndex;
241
242// TODO(user): Remove all SWIG guards by adding the @ignore in .i.
243#if !defined(SWIG)
246#endif // SWIG
247
248#if !defined(SWIG)
262 RangeIntToIntFunction* transit;
263 RangeMinMaxIndexFunction* transit_plus_identity;
264 };
265 typedef std::function<StateDependentTransit(int64_t, int64_t)>
267#endif // SWIG
268
269#if !defined(SWIG)
270 struct CostClass {
273
288
298 bool operator<(const DimensionCost& cost) const {
301 }
303 }
304 };
305 std::vector<DimensionCost>
307
310
312 static bool LessThan(const CostClass& a, const CostClass& b) {
313 if (a.evaluator_index != b.evaluator_index) {
314 return a.evaluator_index < b.evaluator_index;
315 }
318 }
319 };
320
325 int64_t fixed_cost;
332 // TODO(user): Find equivalent start/end nodes wrt dimensions and
333 // callbacks.
338 absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_min;
339 absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_max;
340 absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_min;
341 absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_max;
342 absl::StrongVector<DimensionIndex, int64_t> dimension_capacities;
345 absl::StrongVector<DimensionIndex, int64_t> dimension_evaluator_classes;
350
352 static bool LessThan(const VehicleClass& a, const VehicleClass& b);
353 };
354#endif // defined(SWIG)
355
362 int64_t fixed_cost;
363
364 bool operator<(const VehicleClassEntry& other) const {
365 return std::tie(fixed_cost, vehicle_class) <
366 std::tie(other.fixed_cost, other.vehicle_class);
367 }
368 };
369
370 int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
371
372 int Type(int vehicle) const {
373 DCHECK_LT(vehicle, type_index_of_vehicle.size());
374 return type_index_of_vehicle[vehicle];
375 }
376
377 std::vector<int> type_index_of_vehicle;
378 // clang-format off
379 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
380 std::vector<std::deque<int> > vehicles_per_vehicle_class;
381 // clang-format on
382 };
383
396 public:
399 public:
402
403 const Domain& start_domain() const { return start_domain_; }
404 const Domain& end_domain() const { return end_domain_; }
405
406 private:
410 Domain start_domain_;
412 Domain end_domain_;
413 };
414
416 class Resource {
417 public:
419 const RoutingDimension* dimension) const;
420
421 private:
422 explicit Resource(const RoutingModel* model) : model_(model) {}
423
424 void SetDimensionAttributes(ResourceGroup::Attributes attributes,
425 const RoutingDimension* dimension);
426 const ResourceGroup::Attributes& GetDefaultAttributes() const;
427
428 const RoutingModel* const model_;
429 absl::flat_hash_map<DimensionIndex, ResourceGroup::Attributes>
430 dimension_attributes_;
431
432 friend class ResourceGroup;
433 };
434
435 explicit ResourceGroup(const RoutingModel* model)
436 : model_(model), vehicle_requires_resource_(model->vehicles(), false) {}
437
440 int AddResource(Attributes attributes, const RoutingDimension* dimension);
441
446
447 const std::vector<int>& GetVehiclesRequiringAResource() const {
448 return vehicles_requiring_resource_;
449 }
450
451 bool VehicleRequiresAResource(int vehicle) const {
452 return vehicle_requires_resource_[vehicle];
453 }
454
455 const std::vector<Resource>& GetResources() const { return resources_; }
456 const Resource& GetResource(int resource_index) const {
457 DCHECK_LT(resource_index, resources_.size());
458 return resources_[resource_index];
459 }
460 const absl::flat_hash_set<DimensionIndex>& GetAffectedDimensionIndices()
461 const {
462 return affected_dimension_indices_;
463 }
464 int Size() const { return resources_.size(); }
465
466 private:
467 const RoutingModel* const model_;
468 std::vector<Resource> resources_;
469 std::vector<bool> vehicle_requires_resource_;
470 std::vector<int> vehicles_requiring_resource_;
472 absl::flat_hash_set<DimensionIndex> affected_dimension_indices_;
473 };
474
476 static const int64_t kNoPenalty;
477
481
485
489 explicit RoutingModel(const RoutingIndexManager& index_manager);
490 RoutingModel(const RoutingIndexManager& index_manager,
491 const RoutingModelParameters& parameters);
493
495 int RegisterUnaryTransitVector(std::vector<int64_t> values);
498
500 std::vector<std::vector<int64_t> /*needed_for_swig*/> values);
503
505 const TransitCallback2& TransitCallback(int callback_index) const {
506 CHECK_LT(callback_index, transit_evaluators_.size());
507 return transit_evaluators_[callback_index];
508 }
509 const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
510 CHECK_LT(callback_index, unary_transit_evaluators_.size());
511 return unary_transit_evaluators_[callback_index];
512 }
514 int callback_index) const {
515 CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
516 return state_dependent_transit_evaluators_[callback_index];
517 }
518
520
532
541 bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity,
542 bool fix_start_cumul_to_zero, const std::string& name);
544 const std::vector<int>& evaluator_indices, int64_t slack_max,
545 int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
546 bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max,
547 std::vector<int64_t> vehicle_capacities,
548 bool fix_start_cumul_to_zero,
549 const std::string& name);
551 const std::vector<int>& evaluator_indices, int64_t slack_max,
552 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
553 const std::string& name);
562 std::pair<int, bool> AddConstantDimensionWithSlack(
563 int64_t value, int64_t capacity, int64_t slack_max,
564 bool fix_start_cumul_to_zero, const std::string& name);
565 std::pair<int, bool> AddConstantDimension(int64_t value, int64_t capacity,
566 bool fix_start_cumul_to_zero,
567 const std::string& name) {
568 return AddConstantDimensionWithSlack(value, capacity, 0,
569 fix_start_cumul_to_zero, name);
570 }
580 std::pair<int, bool> AddVectorDimension(std::vector<int64_t> values,
581 int64_t capacity,
582 bool fix_start_cumul_to_zero,
583 const std::string& name);
593 std::pair<int, bool> AddMatrixDimension(
594 std::vector<std::vector<int64_t> /*needed_for_swig*/> values,
595 int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
603 const std::vector<int>& pure_transits,
604 const std::vector<int>& dependent_transits,
605 const RoutingDimension* base_dimension, int64_t slack_max,
606 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
607 const std::string& name) {
608 return AddDimensionDependentDimensionWithVehicleCapacityInternal(
609 pure_transits, dependent_transits, base_dimension, slack_max,
610 std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
611 }
612
615 const std::vector<int>& transits, const RoutingDimension* base_dimension,
616 int64_t slack_max, std::vector<int64_t> vehicle_capacities,
617 bool fix_start_cumul_to_zero, const std::string& name);
620 int transit, const RoutingDimension* base_dimension, int64_t slack_max,
621 int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
622 const std::string& name);
624 int pure_transit, int dependent_transit,
625 const RoutingDimension* base_dimension, int64_t slack_max,
626 int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
627 const std::string& name);
628
631 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
632 int64_t domain_end);
633
644 std::vector<IntVar*> spans,
645 std::vector<IntVar*> total_slacks);
646
648 // TODO(user): rename.
649 std::vector<std::string> GetAllDimensionNames() const;
651 const std::vector<RoutingDimension*>& GetDimensions() const {
652 return dimensions_.get();
653 }
655 std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
656 // clang-format off
659 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
661 return global_dimension_optimizers_;
662 }
663 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
665 return global_dimension_mp_optimizers_;
666 }
667 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
669 return local_dimension_optimizers_;
670 }
671 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
673 return local_dimension_mp_optimizers_;
674 }
675 // clang-format on
676
680 const RoutingDimension& dimension) const;
682 const RoutingDimension& dimension) const;
684 const RoutingDimension& dimension) const;
686 const RoutingDimension& dimension) const;
687
689 bool HasDimension(const std::string& dimension_name) const;
692 const std::string& dimension_name) const;
696 const std::string& dimension_name) const;
701 void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
702 DCHECK(dimension_name.empty() || HasDimension(dimension_name));
703 primary_constrained_dimension_ = dimension_name;
704 }
706 const std::string& GetPrimaryConstrainedDimension() const {
707 return primary_constrained_dimension_;
708 }
709
713 // clang-format off
714 const std::vector<std::unique_ptr<ResourceGroup> >& GetResourceGroups()
715 const {
716 return resource_groups_;
717 }
718 // clang-format on
719 ResourceGroup* GetResourceGroup(int rg_index) const {
720 DCHECK_LT(rg_index, resource_groups_.size());
721 return resource_groups_[rg_index].get();
722 }
723
726 const std::vector<int>& GetDimensionResourceGroupIndices(
727 const RoutingDimension* dimension) const;
728
732 DCHECK_EQ(GetDimensionResourceGroupIndices(dimension).size(), 1);
733 return GetDimensionResourceGroupIndices(dimension)[0];
734 }
735
752 DisjunctionIndex AddDisjunction(const std::vector<int64_t>& indices,
753 int64_t penalty = kNoPenalty,
754 int64_t max_cardinality = 1);
756 const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
757 int64_t index) const {
758 return index_to_disjunctions_[index];
759 }
763 template <typename F>
765 int64_t index, int64_t max_cardinality, F f) const {
766 for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
767 if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
768 for (const int64_t d_index : disjunctions_[disjunction].indices) {
769 f(d_index);
770 }
771 }
772 }
773 }
774#if !defined(SWIGPYTHON)
777 const std::vector<int64_t>& GetDisjunctionNodeIndices(
778 DisjunctionIndex index) const {
779 return disjunctions_[index].indices;
780 }
781#endif // !defined(SWIGPYTHON)
783 int64_t GetDisjunctionPenalty(DisjunctionIndex index) const {
784 return disjunctions_[index].value.penalty;
785 }
789 return disjunctions_[index].value.max_cardinality;
790 }
792 int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
803 std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions() const;
810
814 void AddSoftSameVehicleConstraint(const std::vector<int64_t>& indices,
815 int64_t cost);
816
821 void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
822 int64_t index);
823
825 bool IsVehicleAllowedForIndex(int vehicle, int64_t index) {
826 return allowed_vehicles_[index].empty() ||
827 allowed_vehicles_[index].find(vehicle) !=
828 allowed_vehicles_[index].end();
829 }
830
845 // TODO(user): Remove this when model introspection detects linked nodes.
846 void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
851 DisjunctionIndex delivery_disjunction);
852 // clang-format off
856 const std::vector<std::pair<int, int> >&
857 GetPickupIndexPairs(int64_t node_index) const;
859 const std::vector<std::pair<int, int> >&
860 GetDeliveryIndexPairs(int64_t node_index) const;
861 // clang-format on
862
867 int vehicle);
869 int vehicle) const;
872
874
875#ifndef SWIG
878 return pickup_delivery_pairs_;
879 }
880 const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
882 return pickup_delivery_disjunctions_;
883 }
889 DCHECK(closed_);
890 return implicit_pickup_delivery_pairs_without_alternatives_;
891 }
892#endif // SWIG
904 enum VisitTypePolicy {
919 TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
920 };
921 // TODO(user): Support multiple visit types per node?
922 void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy);
923 int GetVisitType(int64_t index) const;
924 const std::vector<int>& GetSingleNodesOfType(int type) const;
925 const std::vector<int>& GetPairIndicesOfType(int type) const;
929 // TODO(user): Reconsider the logic and potentially remove the need to
932 int GetNumberOfVisitTypes() const { return num_visit_types_; }
933#ifndef SWIG
934 const std::vector<std::vector<int>>& GetTopologicallySortedVisitTypes()
935 const {
936 DCHECK(closed_);
937 return topologically_sorted_visit_types_;
938 }
939#endif // SWIG
944 void AddHardTypeIncompatibility(int type1, int type2);
945 void AddTemporalTypeIncompatibility(int type1, int type2);
947 const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
948 int type) const;
949 const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
950 int type) const;
954 return has_hard_type_incompatibilities_;
955 }
957 return has_temporal_type_incompatibilities_;
958 }
970 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
976 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
983 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
984 // clang-format off
987 const std::vector<absl::flat_hash_set<int> >&
990 const std::vector<absl::flat_hash_set<int> >&
993 const std::vector<absl::flat_hash_set<int> >&
995 // clang-format on
999 return has_same_vehicle_type_requirements_;
1000 }
1002 return has_temporal_type_requirements_;
1003 }
1004
1007 bool HasTypeRegulations() const {
1008 return HasTemporalTypeIncompatibilities() ||
1009 HasHardTypeIncompatibilities() || HasSameVehicleTypeRequirements() ||
1010 HasTemporalTypeRequirements();
1011 }
1012
1017 int64_t UnperformedPenalty(int64_t var_index) const;
1021 int64_t UnperformedPenaltyOrValue(int64_t default_value,
1022 int64_t var_index) const;
1026 int64_t GetDepot() const;
1027
1032 void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
1033 max_active_vehicles_ = max_active_vehicles;
1034 }
1036 int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
1040 void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
1042 void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
1045 void SetFixedCostOfAllVehicles(int64_t cost);
1047 void SetFixedCostOfVehicle(int64_t cost, int vehicle);
1051 int64_t GetFixedCostOfVehicle(int vehicle) const;
1052
1068 void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor,
1069 int64_t quadratic_cost_factor);
1071 void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor,
1072 int64_t quadratic_cost_factor,
1073 int vehicle);
1074
1075 const std::vector<int64_t>& GetAmortizedLinearCostFactorOfVehicles() const {
1076 return linear_cost_factor_of_vehicle_;
1077 }
1078 const std::vector<int64_t>& GetAmortizedQuadraticCostFactorOfVehicles()
1079 const {
1080 return quadratic_cost_factor_of_vehicle_;
1081 }
1082
1083 void SetVehicleUsedWhenEmpty(bool is_used, int vehicle) {
1084 DCHECK_LT(vehicle, vehicles_);
1085 vehicle_used_when_empty_[vehicle] = is_used;
1086 }
1087
1088 bool IsVehicleUsedWhenEmpty(int vehicle) const {
1089 DCHECK_LT(vehicle, vehicles_);
1090 return vehicle_used_when_empty_[vehicle];
1091 }
1092
1095#ifndef SWIG
1097 return first_solution_evaluator_;
1098 }
1099#endif
1102 first_solution_evaluator_ = std::move(evaluator);
1103 }
1108 void AddSearchMonitor(SearchMonitor* const monitor);
1112 void AddAtSolutionCallback(std::function<void()> callback);
1126 void AddVariableTargetToFinalizer(IntVar* var, int64_t target);
1137 const RoutingSearchParameters& search_parameters);
1144 const Assignment* Solve(const Assignment* assignment = nullptr);
1153 const RoutingSearchParameters& search_parameters,
1154 std::vector<const Assignment*>* solutions = nullptr);
1158 const Assignment* assignment,
1159 const RoutingSearchParameters& search_parameters,
1160 std::vector<const Assignment*>* solutions = nullptr);
1164 const std::vector<const Assignment*>& assignments,
1165 const RoutingSearchParameters& search_parameters,
1166 std::vector<const Assignment*>* solutions = nullptr);
1173 Assignment* target_assignment, const RoutingModel* source_model,
1174 const Assignment* source_assignment);
1180 // TODO(user): Add support for non-homogeneous costs and disjunctions.
1183 Status status() const { return status_; }
1192 IntVar* ApplyLocks(const std::vector<int64_t>& locks);
1201 bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64_t>>& locks,
1202 bool close_routes);
1207 const Assignment* const PreAssignment() const { return preassignment_; }
1208 Assignment* MutablePreAssignment() { return preassignment_; }
1212 bool WriteAssignment(const std::string& file_name) const;
1216 Assignment* ReadAssignment(const std::string& file_name);
1226 const std::vector<std::vector<int64_t>>& routes,
1227 bool ignore_inactive_indices);
1244 bool RoutesToAssignment(const std::vector<std::vector<int64_t>>& routes,
1245 bool ignore_inactive_indices, bool close_routes,
1246 Assignment* const assignment) const;
1251 const Assignment& assignment,
1252 std::vector<std::vector<int64_t>>* const routes) const;
1257#ifndef SWIG
1258 std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1259 const Assignment& assignment);
1260#endif
1278 Assignment* CompactAssignment(const Assignment& assignment) const;
1284 void AddToAssignment(IntVar* const var);
1297 const Assignment* original_assignment, absl::Duration duration_limit);
1298#ifndef SWIG
1299 // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1300 void SetSweepArranger(SweepArranger* sweep_arranger);
1302 SweepArranger* sweep_arranger() const;
1303#endif
1310 CHECK(filter != nullptr);
1311 if (closed_) {
1312 LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1313 }
1314 extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1315 extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1316 }
1317
1320 int64_t Start(int vehicle) const { return starts_[vehicle]; }
1322 int64_t End(int vehicle) const { return ends_[vehicle]; }
1324 bool IsStart(int64_t index) const;
1326 bool IsEnd(int64_t index) const { return index >= Size(); }
1329 int VehicleIndex(int64_t index) const { return index_to_vehicle_[index]; }
1333 int64_t Next(const Assignment& assignment, int64_t index) const;
1335 bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1336
1337#if !defined(SWIGPYTHON)
1340 const std::vector<IntVar*>& Nexts() const { return nexts_; }
1343 const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1347 const std::vector<IntVar*>& ResourceVars(int resource_group) const {
1348 return resource_vars_[resource_group];
1349 }
1350#endif
1353 IntVar* NextVar(int64_t index) const { return nexts_[index]; }
1355 IntVar* ActiveVar(int64_t index) const { return active_[index]; }
1358 IntVar* ActiveVehicleVar(int vehicle) const {
1359 return vehicle_active_[vehicle];
1360 }
1364 IntVar* VehicleRouteConsideredVar(int vehicle) const {
1365 return vehicle_route_considered_[vehicle];
1366 }
1369 IntVar* VehicleVar(int64_t index) const { return vehicle_vars_[index]; }
1373 IntVar* ResourceVar(int vehicle, int resource_group) const {
1374 DCHECK_LT(resource_group, resource_vars_.size());
1375 DCHECK_LT(vehicle, resource_vars_[resource_group].size());
1376 return resource_vars_[resource_group][vehicle];
1377 }
1379 IntVar* CostVar() const { return cost_; }
1380
1383 int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1384 int64_t vehicle) const;
1387 return costs_are_homogeneous_across_vehicles_;
1388 }
1391 int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const {
1392 return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1393 }
1396 int64_t GetArcCostForFirstSolution(int64_t from_index,
1397 int64_t to_index) const;
1404 int64_t GetArcCostForClass(int64_t from_index, int64_t to_index,
1405 int64_t /*CostClassIndex*/ cost_class_index) const;
1408 DCHECK(closed_);
1409 DCHECK_GE(vehicle, 0);
1410 DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1411 DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1412 return cost_class_index_of_vehicle_[vehicle];
1413 }
1416 bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1417 DCHECK(closed_);
1418 if (cost_class_index == kCostClassIndexOfZeroCost) {
1419 return has_vehicle_with_zero_cost_class_;
1420 }
1421 return cost_class_index < cost_classes_.size();
1422 }
1424 int GetCostClassesCount() const { return cost_classes_.size(); }
1427 return std::max(0, GetCostClassesCount() - 1);
1428 }
1430 DCHECK(closed_);
1431 return vehicle_class_index_of_vehicle_[vehicle];
1432 }
1435 int GetVehicleOfClass(VehicleClassIndex vehicle_class) const {
1436 DCHECK(closed_);
1437 const RoutingModel::VehicleTypeContainer& vehicle_type_container =
1438 GetVehicleTypeContainer();
1439 if (vehicle_class.value() >= GetVehicleClassesCount() ||
1440 vehicle_type_container.vehicles_per_vehicle_class[vehicle_class.value()]
1441 .empty()) {
1442 return -1;
1443 }
1444 return vehicle_type_container
1445 .vehicles_per_vehicle_class[vehicle_class.value()]
1446 .front();
1447 }
1449 int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1451 const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1452 DCHECK(closed_);
1453 return same_vehicle_groups_[same_vehicle_group_[node]];
1454 }
1455
1457 DCHECK(closed_);
1458 return vehicle_type_container_;
1459 }
1460
1479 bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1485 const Assignment& solution_assignment,
1486 const std::string& dimension_to_print) const;
1492#ifndef SWIG
1493 std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1494 const Assignment& solution_assignment, const RoutingDimension& dimension);
1495#endif
1498 Solver* solver() const { return solver_.get(); }
1499
1501 bool CheckLimit() {
1502 DCHECK(limit_ != nullptr);
1503 return limit_->Check();
1504 }
1505
1507 absl::Duration RemainingTime() const {
1508 DCHECK(limit_ != nullptr);
1509 return limit_->AbsoluteSolverDeadline() - solver_->Now();
1510 }
1511
1514 int nodes() const { return nodes_; }
1516 int vehicles() const { return vehicles_; }
1518 int64_t Size() const { return nodes_ + vehicles_ - start_end_count_; }
1519
1523 const RoutingSearchParameters& search_parameters) const;
1525 const RoutingSearchParameters& search_parameters) const;
1529 return automatic_first_solution_strategy_;
1530 }
1531
1533 bool IsMatchingModel() const;
1534
1535#ifndef SWIG
1539 std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1540
1542#endif // SWIG
1543
1545 // TODO(user): Find a way to test and restrict the access at the same time.
1558 const RoutingDimension* dimension,
1559 std::function<int64_t(int64_t)> initializer);
1560#ifndef SWIG
1561 // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1566 static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1567 std::vector<IntVar*> variables);
1568 // Read access to currently registered search monitors.
1569 const std::vector<SearchMonitor*>& GetSearchMonitors() const {
1570 return monitors_;
1571 }
1572#endif
1587 const RoutingDimension* dimension);
1588
1589 private:
1591 enum RoutingLocalSearchOperator {
1592 RELOCATE = 0,
1593 RELOCATE_PAIR,
1594 LIGHT_RELOCATE_PAIR,
1595 RELOCATE_NEIGHBORS,
1596 EXCHANGE,
1597 EXCHANGE_PAIR,
1598 CROSS,
1599 CROSS_EXCHANGE,
1600 TWO_OPT,
1601 OR_OPT,
1602 GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1603 LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1604 GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1605 LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1606 RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1607 GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1608 LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1609 RELOCATE_EXPENSIVE_CHAIN,
1610 LIN_KERNIGHAN,
1611 TSP_OPT,
1612 MAKE_ACTIVE,
1613 RELOCATE_AND_MAKE_ACTIVE,
1614 MAKE_ACTIVE_AND_RELOCATE,
1615 MAKE_INACTIVE,
1616 MAKE_CHAIN_INACTIVE,
1617 SWAP_ACTIVE,
1618 EXTENDED_SWAP_ACTIVE,
1619 NODE_PAIR_SWAP,
1620 PATH_LNS,
1621 FULL_PATH_LNS,
1622 TSP_LNS,
1623 INACTIVE_LNS,
1624 EXCHANGE_RELOCATE_PAIR,
1625 RELOCATE_SUBTRIP,
1626 EXCHANGE_SUBTRIP,
1627 LOCAL_SEARCH_OPERATOR_COUNTER
1628 };
1629
1633 template <typename T>
1634 struct ValuedNodes {
1635 std::vector<int64_t> indices;
1636 T value;
1637 };
1638 struct DisjunctionValues {
1639 int64_t penalty;
1640 int64_t max_cardinality;
1641 };
1642 typedef ValuedNodes<DisjunctionValues> Disjunction;
1643
1646 struct CostCacheElement {
1652 int index;
1653 CostClassIndex cost_class_index;
1654 int64_t cost;
1655 };
1656
1658 void Initialize();
1659 void AddNoCycleConstraintInternal();
1660 bool AddDimensionWithCapacityInternal(
1661 const std::vector<int>& evaluator_indices, int64_t slack_max,
1662 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1663 const std::string& name);
1664 bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1665 const std::vector<int>& pure_transits,
1666 const std::vector<int>& dependent_transits,
1667 const RoutingDimension* base_dimension, int64_t slack_max,
1668 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1669 const std::string& name);
1670 bool InitializeDimensionInternal(
1671 const std::vector<int>& evaluator_indices,
1672 const std::vector<int>& state_dependent_evaluator_indices,
1673 int64_t slack_max, bool fix_start_cumul_to_zero,
1674 RoutingDimension* dimension);
1675 DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1676
1704 void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1705
1706 void ComputeCostClasses(const RoutingSearchParameters& parameters);
1707 void ComputeVehicleClasses();
1715 void ComputeVehicleTypes();
1725 void FinalizeVisitTypes();
1726 // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_.
1727 void TopologicallySortVisitTypes();
1728 int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index,
1729 CostClassIndex cost_class_index) const;
1730 void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1731 int node_index,
1732 std::vector<IntVar*>* cost_elements);
1733 void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1734 std::vector<IntVar*>* cost_elements);
1735 Assignment* DoRestoreAssignment();
1736 static const CostClassIndex kCostClassIndexOfZeroCost;
1737 int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle) const {
1738 DCHECK_LT(0, vehicles_);
1739 return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1740 : kCostClassIndexOfZeroCost)
1741 .value();
1742 }
1743 int64_t GetDimensionTransitCostSum(int64_t i, int64_t j,
1744 const CostClass& cost_class) const;
1746 IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1748 void AddPickupAndDeliverySetsInternal(const std::vector<int64_t>& pickups,
1749 const std::vector<int64_t>& deliveries);
1752 IntVar* CreateSameVehicleCost(int vehicle_index);
1755 int FindNextActive(int index, const std::vector<int64_t>& indices) const;
1756
1759 bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1760 int vehicle) const;
1768 bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1769 Assignment* compact_assignment) const;
1770
1771 void QuietCloseModel();
1772 void QuietCloseModelWithParameters(
1773 const RoutingSearchParameters& parameters) {
1774 if (!closed_) {
1775 CloseModelWithParameters(parameters);
1776 }
1777 }
1778
1780 bool SolveMatchingModel(Assignment* assignment,
1781 const RoutingSearchParameters& parameters);
1782#ifndef SWIG
1784 bool AppendAssignmentIfFeasible(
1785 const Assignment& assignment,
1786 std::vector<std::unique_ptr<Assignment>>* assignments);
1787#endif
1789 void LogSolution(const RoutingSearchParameters& parameters,
1790 const std::string& description, int64_t solution_cost,
1791 int64_t start_time_ms);
1794 Assignment* CompactAssignmentInternal(const Assignment& assignment,
1795 bool check_compact_assignment) const;
1800 std::string FindErrorInSearchParametersForModel(
1801 const RoutingSearchParameters& search_parameters) const;
1803 void SetupSearch(const RoutingSearchParameters& search_parameters);
1805 // TODO(user): Document each auxiliary method.
1806 Assignment* GetOrCreateAssignment();
1807 Assignment* GetOrCreateTmpAssignment();
1808 RegularLimit* GetOrCreateLimit();
1809 RegularLimit* GetOrCreateLocalSearchLimit();
1810 RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1811 RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1812 LocalSearchOperator* CreateInsertionOperator();
1813 LocalSearchOperator* CreateMakeInactiveOperator();
1814 template <class T>
1815 LocalSearchOperator* CreateCPOperator(const T& operator_factory) {
1816 return operator_factory(solver_.get(), nexts_,
1817 CostsAreHomogeneousAcrossVehicles()
1818 ? std::vector<IntVar*>()
1819 : vehicle_vars_,
1820 vehicle_start_class_callback_);
1821 }
1822 template <class T>
1823 LocalSearchOperator* CreateCPOperator() {
1824 return CreateCPOperator(MakeLocalSearchOperator<T>);
1825 }
1826 template <class T, class Arg>
1827 LocalSearchOperator* CreateOperator(const Arg& arg) {
1828 return solver_->RevAlloc(new T(nexts_,
1829 CostsAreHomogeneousAcrossVehicles()
1830 ? std::vector<IntVar*>()
1831 : vehicle_vars_,
1832 vehicle_start_class_callback_, arg));
1833 }
1834 template <class T>
1835 LocalSearchOperator* CreatePairOperator() {
1836 return CreateOperator<T>(pickup_delivery_pairs_);
1837 }
1838 void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1839 LocalSearchOperator* ConcatenateOperators(
1840 const RoutingSearchParameters& search_parameters,
1841 const std::vector<LocalSearchOperator*>& operators) const;
1842 LocalSearchOperator* GetNeighborhoodOperators(
1843 const RoutingSearchParameters& search_parameters) const;
1844 std::vector<LocalSearchFilterManager::FilterEvent>
1845 GetOrCreateLocalSearchFilters(const RoutingSearchParameters& parameters,
1846 bool filter_cost = true);
1847 LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1848 const RoutingSearchParameters& parameters);
1849 std::vector<LocalSearchFilterManager::FilterEvent>
1850 GetOrCreateFeasibilityFilters(const RoutingSearchParameters& parameters);
1851 LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1852 const RoutingSearchParameters& parameters);
1853 LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1854 const RoutingSearchParameters& parameters);
1855 DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1856 DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1857 void CreateFirstSolutionDecisionBuilders(
1858 const RoutingSearchParameters& search_parameters);
1859 DecisionBuilder* GetFirstSolutionDecisionBuilder(
1860 const RoutingSearchParameters& search_parameters) const;
1861 IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1862 const RoutingSearchParameters& parameters) const;
1863 LocalSearchPhaseParameters* CreateLocalSearchParameters(
1864 const RoutingSearchParameters& search_parameters);
1865 DecisionBuilder* CreateLocalSearchDecisionBuilder(
1866 const RoutingSearchParameters& search_parameters);
1867 void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1868 void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1869 void SetupAssignmentCollector(
1870 const RoutingSearchParameters& search_parameters);
1871 void SetupTrace(const RoutingSearchParameters& search_parameters);
1872 void SetupImprovementLimit(const RoutingSearchParameters& search_parameters);
1873 void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1874 bool UsesLightPropagation(
1875 const RoutingSearchParameters& search_parameters) const;
1876 GetTabuVarsCallback tabu_var_callback_;
1877
1878 // Detects implicit pickup delivery pairs. These pairs are
1879 // non-pickup/delivery pairs for which there exists a unary dimension such
1880 // that the demand d of the implicit pickup is positive and the demand of the
1881 // implicit delivery is equal to -d.
1882 void DetectImplicitPickupAndDeliveries();
1883
1884 int GetVehicleStartClass(int64_t start) const;
1885
1886 void InitSameVehicleGroups(int number_of_groups) {
1887 same_vehicle_group_.assign(Size(), 0);
1888 same_vehicle_groups_.assign(number_of_groups, {});
1889 }
1890 void SetSameVehicleGroup(int index, int group) {
1891 same_vehicle_group_[index] = group;
1892 same_vehicle_groups_[group].push_back(index);
1893 }
1894
1896 std::unique_ptr<Solver> solver_;
1897 int nodes_;
1898 int vehicles_;
1899 int max_active_vehicles_;
1900 Constraint* no_cycle_constraint_ = nullptr;
1902 std::vector<IntVar*> nexts_;
1903 std::vector<IntVar*> vehicle_vars_;
1904 std::vector<IntVar*> active_;
1907 // clang-format off
1908 std::vector<std::vector<IntVar*> > resource_vars_;
1909 // clang-format on
1910 // The following vectors are indexed by vehicle index.
1911 std::vector<IntVar*> vehicle_active_;
1912 std::vector<IntVar*> vehicle_route_considered_;
1917 std::vector<IntVar*> is_bound_to_end_;
1918 mutable RevSwitch is_bound_to_end_ct_added_;
1920 absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1921 absl::StrongVector<DimensionIndex, RoutingDimension*> dimensions_;
1926 // clang-format off
1927 std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1929 absl::StrongVector<DimensionIndex, std::vector<int> >
1930 dimension_resource_group_indices_;
1931
1935 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1936 global_dimension_optimizers_;
1937 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1938 global_dimension_mp_optimizers_;
1939 absl::StrongVector<DimensionIndex, int> global_optimizer_index_;
1940 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1941 local_dimension_optimizers_;
1942 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1943 local_dimension_mp_optimizers_;
1944 // clang-format off
1945 absl::StrongVector<DimensionIndex, int> local_optimizer_index_;
1946 std::string primary_constrained_dimension_;
1948 IntVar* cost_ = nullptr;
1949 std::vector<int> vehicle_to_transit_cost_;
1950 std::vector<int64_t> fixed_cost_of_vehicle_;
1951 std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1952 bool has_vehicle_with_zero_cost_class_;
1953 std::vector<int64_t> linear_cost_factor_of_vehicle_;
1954 std::vector<int64_t> quadratic_cost_factor_of_vehicle_;
1955 bool vehicle_amortized_cost_factors_set_;
1967 std::vector<bool> vehicle_used_when_empty_;
1968#ifndef SWIG
1969 absl::StrongVector<CostClassIndex, CostClass> cost_classes_;
1970#endif // SWIG
1971 bool costs_are_homogeneous_across_vehicles_;
1972 bool cache_callbacks_;
1973 mutable std::vector<CostCacheElement> cost_cache_;
1974 std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1975#ifndef SWIG
1976 absl::StrongVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1977#endif // SWIG
1978 VehicleTypeContainer vehicle_type_container_;
1979 std::function<int(int64_t)> vehicle_start_class_callback_;
1981 absl::StrongVector<DisjunctionIndex, Disjunction> disjunctions_;
1982 std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1984 std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
1986#ifndef SWIG
1987 std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1988#endif // SWIG
1990 IndexPairs pickup_delivery_pairs_;
1991 IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
1992 std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1993 pickup_delivery_disjunctions_;
1994 // clang-format off
1995 // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
1996 // vector of pairs {pair_index, pickup_index} such that
1997 // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
1998 std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1999 // Same as above for deliveries.
2000 std::vector<std::vector<std::pair<int, int> > >
2001 index_to_delivery_index_pairs_;
2002 // clang-format on
2003 std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
2004 // Same vehicle group to which a node belongs.
2005 std::vector<int> same_vehicle_group_;
2006 // Same vehicle node groups.
2007 std::vector<std::vector<int>> same_vehicle_groups_;
2008 // Node visit types
2009 // Variable index to visit type index.
2010 std::vector<int> index_to_visit_type_;
2011 // Variable index to VisitTypePolicy.
2012 std::vector<VisitTypePolicy> index_to_type_policy_;
2013 // clang-format off
2014 std::vector<std::vector<int> > single_nodes_of_type_;
2015 std::vector<std::vector<int> > pair_indices_of_type_;
2016
2017 std::vector<absl::flat_hash_set<int> >
2018 hard_incompatible_types_per_type_index_;
2019 bool has_hard_type_incompatibilities_;
2020 std::vector<absl::flat_hash_set<int> >
2021 temporal_incompatible_types_per_type_index_;
2022 bool has_temporal_type_incompatibilities_;
2023
2024 std::vector<std::vector<absl::flat_hash_set<int> > >
2025 same_vehicle_required_type_alternatives_per_type_index_;
2026 bool has_same_vehicle_type_requirements_;
2027 std::vector<std::vector<absl::flat_hash_set<int> > >
2028 required_type_alternatives_when_adding_type_index_;
2029 std::vector<std::vector<absl::flat_hash_set<int> > >
2030 required_type_alternatives_when_removing_type_index_;
2031 bool has_temporal_type_requirements_;
2032 absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
2033 trivially_infeasible_visit_types_to_policies_;
2034
2035 // Visit types sorted topologically based on required-->dependent requirement
2036 // arcs between the types (if the requirement/dependency graph is acyclic).
2037 // Visit types of the same topological level are sorted in each sub-vector
2038 // by decreasing requirement "tightness", computed as the pair of the two
2039 // following criteria:
2040 //
2041 // 1) How highly *dependent* this type is, determined by
2042 // (total number of required alternative sets for that type)
2043 // / (average number of types in the required alternative sets)
2044 // 2) How highly *required* this type t is, computed as
2045 // SUM_{S required set containing t} ( 1 / |S| ),
2046 // i.e. the sum of reverse number of elements of all required sets
2047 // containing the type t.
2048 //
2049 // The higher these two numbers, the tighter the type is wrt requirements.
2050 std::vector<std::vector<int> > topologically_sorted_visit_types_;
2051 // clang-format on
2052 int num_visit_types_;
2053 // Two indices are equivalent if they correspond to the same node (as given
2054 // to the constructors taking a RoutingIndexManager).
2055 std::vector<int> index_to_equivalence_class_;
2056 std::vector<int> index_to_vehicle_;
2057 std::vector<int64_t> starts_;
2058 std::vector<int64_t> ends_;
2059 // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
2060 // anymore.
2061 RoutingIndexManager manager_;
2062 int start_end_count_;
2063 // Model status
2064 bool closed_ = false;
2065 Status status_ = ROUTING_NOT_SOLVED;
2066 bool enable_deep_serialization_ = true;
2067
2068 // Search data
2069 std::vector<DecisionBuilder*> first_solution_decision_builders_;
2070 std::vector<IntVarFilteredDecisionBuilder*>
2071 first_solution_filtered_decision_builders_;
2072 Solver::IndexEvaluator2 first_solution_evaluator_;
2073 FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
2074 FirstSolutionStrategy::UNSET;
2075 std::vector<LocalSearchOperator*> local_search_operators_;
2076 std::vector<SearchMonitor*> monitors_;
2077 SolutionCollector* collect_assignments_ = nullptr;
2078 SolutionCollector* collect_one_assignment_ = nullptr;
2079 SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
2080 DecisionBuilder* solve_db_ = nullptr;
2081 DecisionBuilder* improve_db_ = nullptr;
2082 DecisionBuilder* restore_assignment_ = nullptr;
2083 DecisionBuilder* restore_tmp_assignment_ = nullptr;
2084 Assignment* assignment_ = nullptr;
2085 Assignment* preassignment_ = nullptr;
2086 Assignment* tmp_assignment_ = nullptr;
2087 std::vector<IntVar*> extra_vars_;
2088 std::vector<IntervalVar*> extra_intervals_;
2089 std::vector<LocalSearchOperator*> extra_operators_;
2090 LocalSearchFilterManager* local_search_filter_manager_ = nullptr;
2091 LocalSearchFilterManager* feasibility_filter_manager_ = nullptr;
2092 LocalSearchFilterManager* strong_feasibility_filter_manager_ = nullptr;
2093 std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
2094#ifndef SWIG
2095 std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_cost_pairs_;
2096 std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_target_pairs_;
2097 absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
2098 absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
2099 std::unique_ptr<SweepArranger> sweep_arranger_;
2100#endif
2101
2102 RegularLimit* limit_ = nullptr;
2103 RegularLimit* ls_limit_ = nullptr;
2104 RegularLimit* lns_limit_ = nullptr;
2105 RegularLimit* first_solution_lns_limit_ = nullptr;
2106
2107 typedef std::pair<int64_t, int64_t> CacheKey;
2108 typedef absl::flat_hash_map<CacheKey, int64_t> TransitCallbackCache;
2109 typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
2110 StateDependentTransitCallbackCache;
2111
2112 std::vector<TransitCallback1> unary_transit_evaluators_;
2113 std::vector<TransitCallback2> transit_evaluators_;
2114 // The following vector stores a boolean per transit_evaluator_, indicating
2115 // whether the transits are all positive.
2116 // is_transit_evaluator_positive_ will be set to true only when registering a
2117 // callback via RegisterPositiveTransitCallback(), and to false otherwise.
2118 // The actual positivity of the transit values will only be checked in debug
2119 // mode, when calling RegisterPositiveTransitCallback().
2120 // Therefore, RegisterPositiveTransitCallback() should only be called when the
2121 // transits are known to be positive, as the positivity of a callback will
2122 // allow some improvements in the solver, but will entail in errors if the
2123 // transits are falsely assumed positive.
2124 std::vector<bool> is_transit_evaluator_positive_;
2125 std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
2126 std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
2127 state_dependent_transit_evaluators_cache_;
2128
2129 friend class RoutingDimension;
2130 friend class RoutingModelInspector;
2132
2133 DISALLOW_COPY_AND_ASSIGN(RoutingModel);
2134};
2135
2138 public:
2140 static const char kLightElement[];
2141 static const char kLightElement2[];
2142 static const char kRemoveValues[];
2143};
2144
2145#if !defined(SWIG)
2149 public:
2155 struct Tasks {
2156 int num_chain_tasks = 0;
2157 std::vector<int64_t> start_min;
2158 std::vector<int64_t> start_max;
2159 std::vector<int64_t> duration_min;
2160 std::vector<int64_t> duration_max;
2161 std::vector<int64_t> end_min;
2162 std::vector<int64_t> end_max;
2163 std::vector<bool> is_preemptible;
2164 std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
2165 std::vector<std::pair<int64_t, int64_t>> distance_duration;
2166 int64_t span_min = 0;
2167 int64_t span_max = kint64max;
2168
2169 void Clear() {
2170 start_min.clear();
2171 start_max.clear();
2172 duration_min.clear();
2173 duration_max.clear();
2174 end_min.clear();
2175 end_max.clear();
2176 is_preemptible.clear();
2177 forbidden_intervals.clear();
2178 distance_duration.clear();
2179 span_min = 0;
2180 span_max = kint64max;
2181 num_chain_tasks = 0;
2182 }
2183 };
2184
2187 bool Propagate(Tasks* tasks);
2188
2190 bool Precedences(Tasks* tasks);
2193 bool MirrorTasks(Tasks* tasks);
2195 bool EdgeFinding(Tasks* tasks);
2205 bool ChainSpanMin(Tasks* tasks);
2211
2212 private:
2215 sat::ThetaLambdaTree<int64_t> theta_lambda_tree_;
2217 std::vector<int> tasks_by_start_min_;
2218 std::vector<int> tasks_by_end_max_;
2219 std::vector<int> event_of_task_;
2220 std::vector<int> nonchain_tasks_by_start_max_;
2222 std::vector<int64_t> total_duration_before_;
2223};
2224
2226 std::vector<int64_t> min_travels;
2227 std::vector<int64_t> max_travels;
2228 std::vector<int64_t> pre_travels;
2229 std::vector<int64_t> post_travels;
2230};
2231
2232void AppendTasksFromPath(const std::vector<int64_t>& path,
2233 const TravelBounds& travel_bounds,
2234 const RoutingDimension& dimension,
2236void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
2238void FillPathEvaluation(const std::vector<int64_t>& path,
2239 const RoutingModel::TransitCallback2& evaluator,
2240 std::vector<int64_t>* values);
2241void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64_t>& path,
2242 const RoutingDimension& dimension,
2243 TravelBounds* travel_bounds);
2244#endif // !defined(SWIG)
2245
2257 public:
2259 std::string DebugString() const override {
2260 return "GlobalVehicleBreaksConstraint";
2261 }
2262
2263 void Post() override;
2264 void InitialPropagate() override;
2265
2266 private:
2267 void PropagateNode(int node);
2268 void PropagateVehicle(int vehicle);
2269 void PropagateMaxBreakDistance(int vehicle);
2270
2271 const RoutingModel* model_;
2272 const RoutingDimension* const dimension_;
2273 std::vector<Demon*> vehicle_demons_;
2274 std::vector<int64_t> path_;
2275
2280 void FillPartialPathOfVehicle(int vehicle);
2281 void FillPathTravels(const std::vector<int64_t>& path);
2282
2293 class TaskTranslator {
2294 public:
2295 TaskTranslator(IntVar* start, int64_t before_start, int64_t after_start)
2296 : start_(start),
2297 before_start_(before_start),
2298 after_start_(after_start) {}
2299 explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2300 TaskTranslator() {}
2301
2302 void SetStartMin(int64_t value) {
2303 if (start_ != nullptr) {
2304 start_->SetMin(CapAdd(before_start_, value));
2305 } else if (interval_ != nullptr) {
2306 interval_->SetStartMin(value);
2307 }
2308 }
2309 void SetStartMax(int64_t value) {
2310 if (start_ != nullptr) {
2311 start_->SetMax(CapAdd(before_start_, value));
2312 } else if (interval_ != nullptr) {
2313 interval_->SetStartMax(value);
2314 }
2315 }
2316 void SetDurationMin(int64_t value) {
2317 if (interval_ != nullptr) {
2318 interval_->SetDurationMin(value);
2319 }
2320 }
2321 void SetEndMin(int64_t value) {
2322 if (start_ != nullptr) {
2323 start_->SetMin(CapSub(value, after_start_));
2324 } else if (interval_ != nullptr) {
2325 interval_->SetEndMin(value);
2326 }
2327 }
2328 void SetEndMax(int64_t value) {
2329 if (start_ != nullptr) {
2330 start_->SetMax(CapSub(value, after_start_));
2331 } else if (interval_ != nullptr) {
2332 interval_->SetEndMax(value);
2333 }
2334 }
2335
2336 private:
2337 IntVar* start_ = nullptr;
2338 int64_t before_start_;
2339 int64_t after_start_;
2340 IntervalVar* interval_ = nullptr;
2341 };
2342
2344 std::vector<TaskTranslator> task_translators_;
2345
2347 DisjunctivePropagator disjunctive_propagator_;
2348 DisjunctivePropagator::Tasks tasks_;
2349
2351 TravelBounds travel_bounds_;
2352};
2353
2355 public:
2356 explicit TypeRegulationsChecker(const RoutingModel& model);
2358
2359 bool CheckVehicle(int vehicle,
2360 const std::function<int64_t(int64_t)>& next_accessor);
2361
2362 protected:
2363#ifndef SWIG
2365#endif // SWIG
2366
2371 int num_type_added_to_vehicle = 0;
2377 int num_type_removed_from_vehicle = 0;
2382 int position_of_last_type_on_vehicle_up_to_visit = -1;
2383 };
2384
2389 bool TypeOccursOnRoute(int type) const;
2396 bool TypeCurrentlyOnRoute(int type, int pos) const;
2397
2398 void InitializeCheck(int vehicle,
2399 const std::function<int64_t(int64_t)>& next_accessor);
2400 virtual void OnInitializeCheck() {}
2401 virtual bool HasRegulationsToCheck() const = 0;
2402 virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2403 int pos) = 0;
2404 virtual bool FinalizeCheck() const { return true; }
2405
2407
2408 private:
2409 std::vector<TypePolicyOccurrence> occurrences_of_type_;
2410 std::vector<int64_t> current_route_visits_;
2411};
2412
2415 public:
2417 bool check_hard_incompatibilities);
2419
2420 private:
2421 bool HasRegulationsToCheck() const override;
2422 bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2426 bool check_hard_incompatibilities_;
2427};
2428
2431 public:
2433 : TypeRegulationsChecker(model) {}
2435
2436 private:
2437 bool HasRegulationsToCheck() const override;
2438 void OnInitializeCheck() override {
2439 types_with_same_vehicle_requirements_on_route_.clear();
2440 }
2441 // clang-format off
2444 bool CheckRequiredTypesCurrentlyOnRoute(
2445 const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2446 int pos);
2447 // clang-format on
2448 bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2449 bool FinalizeCheck() const override;
2450
2451 absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2452};
2453
2495 public:
2497
2498 void Post() override;
2499 void InitialPropagate() override;
2500
2501 private:
2502 void PropagateNodeRegulations(int node);
2503 void CheckRegulationsOnVehicle(int vehicle);
2504
2505 const RoutingModel& model_;
2506 TypeIncompatibilityChecker incompatibility_checker_;
2507 TypeRequirementChecker requirement_checker_;
2508 std::vector<Demon*> vehicle_demons_;
2509};
2510#if !defined SWIG
2524 public:
2525 struct BoundCost {
2526 int64_t bound;
2527 int64_t cost;
2528 };
2529 SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2530 : bound_costs_(num_bounds, default_bound_cost) {}
2531 BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2532 BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2533 int Size() { return bound_costs_.size(); }
2536
2537 private:
2538 std::vector<BoundCost> bound_costs_;
2539};
2540#endif // !defined SWIG
2541
2559// TODO(user): Break constraints need to know the service time of nodes
2563 public:
2566 RoutingModel* model() const { return model_; }
2570 int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2571 int64_t vehicle) const;
2574 int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index,
2575 int64_t vehicle_class) const {
2576 return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2577 to_index);
2578 }
2581 IntVar* CumulVar(int64_t index) const { return cumuls_[index]; }
2582 IntVar* TransitVar(int64_t index) const { return transits_[index]; }
2583 IntVar* FixedTransitVar(int64_t index) const {
2584 return fixed_transits_[index];
2585 }
2586 IntVar* SlackVar(int64_t index) const { return slacks_[index]; }
2587
2588#if !defined(SWIGPYTHON)
2591 const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2592 const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2593 const std::vector<IntVar*>& transits() const { return transits_; }
2594 const std::vector<IntVar*>& slacks() const { return slacks_; }
2595#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2597 const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2598 return forbidden_intervals_;
2599 }
2601 SortedDisjointIntervalList GetAllowedIntervalsInRange(
2602 int64_t index, int64_t min_value, int64_t max_value) const;
2606 int64_t min_value) const {
2607 DCHECK_LT(index, forbidden_intervals_.size());
2608 const SortedDisjointIntervalList& forbidden_intervals =
2609 forbidden_intervals_[index];
2610 const auto first_forbidden_interval_it =
2611 forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2612 if (first_forbidden_interval_it != forbidden_intervals.end() &&
2613 min_value >= first_forbidden_interval_it->start) {
2615 return CapAdd(first_forbidden_interval_it->end, 1);
2616 }
2618 return min_value;
2619 }
2625 int64_t max_value) const {
2626 DCHECK_LT(index, forbidden_intervals_.size());
2627 const SortedDisjointIntervalList& forbidden_intervals =
2628 forbidden_intervals_[index];
2629 const auto last_forbidden_interval_it =
2630 forbidden_intervals.LastIntervalLessOrEqual(max_value);
2631 if (last_forbidden_interval_it != forbidden_intervals.end() &&
2632 max_value <= last_forbidden_interval_it->end) {
2634 return CapSub(last_forbidden_interval_it->start, 1);
2635 }
2637 return max_value;
2638 }
2640 const std::vector<int64_t>& vehicle_capacities() const {
2641 return vehicle_capacities_;
2642 }
2646 return model_->TransitCallback(
2647 class_evaluators_[vehicle_to_class_[vehicle]]);
2648 }
2649
2653 RoutingVehicleClassIndex vehicle_class) const {
2654 const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2655 DCHECK_NE(vehicle, -1);
2656 return transit_evaluator(vehicle);
2657 }
2658
2663 int vehicle) const {
2664 return model_->UnaryTransitCallbackOrNull(
2665 class_evaluators_[vehicle_to_class_[vehicle]]);
2666 }
2669 bool AreVehicleTransitsPositive(int vehicle) const {
2670 return model()->is_transit_evaluator_positive_
2671 [class_evaluators_[vehicle_to_class_[vehicle]]];
2672 }
2673 int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2674#endif
2675#endif
2679 void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle);
2686 void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle);
2687 void SetSpanCostCoefficientForAllVehicles(int64_t coefficient);
2694 void SetGlobalSpanCostCoefficient(int64_t coefficient);
2695
2696#ifndef SWIG
2702 const PiecewiseLinearFunction& cost);
2705 bool HasCumulVarPiecewiseLinearCost(int64_t index) const;
2708 const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2709 int64_t index) const;
2710#endif
2711
2720 void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound,
2721 int64_t coefficient);
2724 bool HasCumulVarSoftUpperBound(int64_t index) const;
2728 int64_t GetCumulVarSoftUpperBound(int64_t index) const;
2732 int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const;
2733
2743 void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound,
2744 int64_t coefficient);
2747 bool HasCumulVarSoftLowerBound(int64_t index) const;
2751 int64_t GetCumulVarSoftLowerBound(int64_t index) const;
2755 int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const;
2771 // TODO(user): Remove if !defined when routing.i is repaired.
2772#if !defined(SWIGPYTHON)
2773 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2774 int pre_travel_evaluator,
2775 int post_travel_evaluator);
2776#endif // !defined(SWIGPYTHON)
2777
2779 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2780 std::vector<int64_t> node_visit_transits);
2781
2786 void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration,
2787 int vehicle);
2793#if !defined(SWIGPYTHON)
2797 std::vector<IntervalVar*> breaks, int vehicle,
2798 std::vector<int64_t> node_visit_transits,
2799 std::function<int64_t(int64_t, int64_t)> delays);
2800
2802 const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2803 int vehicle) const;
2806 // clang-format off
2807 const std::vector<std::pair<int64_t, int64_t> >&
2809 // clang-format on
2810#endif
2811 int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2812 int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2813
2815 const RoutingDimension* base_dimension() const { return base_dimension_; }
2823 int64_t ShortestTransitionSlack(int64_t node) const;
2824
2826 const std::string& name() const { return name_; }
2827
2829#ifndef SWIG
2830 const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2831 return path_precedence_graph_;
2832 }
2833#endif // SWIG
2834
2844 typedef std::function<int64_t(int, int)> PickupToDeliveryLimitFunction;
2845
2847 PickupToDeliveryLimitFunction limit_function, int pair_index);
2848
2850#ifndef SWIG
2851 int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2852 int delivery) const;
2853
2855 int64_t first_node;
2857 int64_t offset;
2858 };
2859
2861 node_precedences_.push_back(precedence);
2862 }
2863 const std::vector<NodePrecedence>& GetNodePrecedences() const {
2864 return node_precedences_;
2865 }
2866#endif // SWIG
2867
2868 void AddNodePrecedence(int64_t first_node, int64_t second_node,
2869 int64_t offset) {
2870 AddNodePrecedence({first_node, second_node, offset});
2871 }
2872
2873 int64_t GetSpanUpperBoundForVehicle(int vehicle) const {
2874 return vehicle_span_upper_bounds_[vehicle];
2875 }
2876#ifndef SWIG
2877 const std::vector<int64_t>& vehicle_span_upper_bounds() const {
2878 return vehicle_span_upper_bounds_;
2879 }
2880#endif // SWIG
2881 int64_t GetSpanCostCoefficientForVehicle(int vehicle) const {
2882 return vehicle_span_cost_coefficients_[vehicle];
2883 }
2884#ifndef SWIG
2886 RoutingVehicleClassIndex vehicle_class) const {
2887 const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2888 DCHECK_NE(vehicle, -1);
2889 return GetSpanCostCoefficientForVehicle(vehicle);
2890 }
2891#endif // SWIG
2892#ifndef SWIG
2893 const std::vector<int64_t>& vehicle_span_cost_coefficients() const {
2894 return vehicle_span_cost_coefficients_;
2895 }
2896#endif // SWIG
2898 return global_span_cost_coefficient_;
2899 }
2900
2902 DCHECK_GE(global_optimizer_offset_, 0);
2903 return global_optimizer_offset_;
2904 }
2905 int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2906 if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2907 return 0;
2908 }
2909 DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2910 return local_optimizer_offset_for_vehicle_[vehicle];
2911 }
2912#if !defined SWIG
2916 int vehicle) {
2917 if (!HasSoftSpanUpperBounds()) {
2918 vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2919 model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2920 }
2921 vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2922 }
2924 return vehicle_soft_span_upper_bound_ != nullptr;
2925 }
2927 int vehicle) const {
2928 DCHECK(HasSoftSpanUpperBounds());
2929 return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2930 }
2934 SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2935 if (!HasQuadraticCostSoftSpanUpperBounds()) {
2936 vehicle_quadratic_cost_soft_span_upper_bound_ =
2937 absl::make_unique<SimpleBoundCosts>(
2938 model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2939 }
2940 vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2941 bound_cost;
2942 }
2944 return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2945 }
2947 int vehicle) const {
2948 DCHECK(HasQuadraticCostSoftSpanUpperBounds());
2949 return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2950 }
2951#endif
2952
2953 private:
2954 struct SoftBound {
2955 IntVar* var;
2956 int64_t bound;
2957 int64_t coefficient;
2958 };
2959
2960 struct PiecewiseLinearCost {
2961 PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2962 IntVar* var;
2963 std::unique_ptr<PiecewiseLinearFunction> cost;
2964 };
2965
2966 class SelfBased {};
2967 RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2968 const std::string& name,
2969 const RoutingDimension* base_dimension);
2970 RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2971 const std::string& name, SelfBased);
2972 void Initialize(const std::vector<int>& transit_evaluators,
2973 const std::vector<int>& state_dependent_transit_evaluators,
2974 int64_t slack_max);
2975 void InitializeCumuls();
2976 void InitializeTransits(
2977 const std::vector<int>& transit_evaluators,
2978 const std::vector<int>& state_dependent_transit_evaluators,
2979 int64_t slack_max);
2980 void InitializeTransitVariables(int64_t slack_max);
2982 void SetupCumulVarSoftUpperBoundCosts(
2983 std::vector<IntVar*>* cost_elements) const;
2985 void SetupCumulVarSoftLowerBoundCosts(
2986 std::vector<IntVar*>* cost_elements) const;
2987 void SetupCumulVarPiecewiseLinearCosts(
2988 std::vector<IntVar*>* cost_elements) const;
2991 void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
2992 void SetupSlackAndDependentTransitCosts() const;
2994 void CloseModel(bool use_light_propagation);
2995
2996 void SetOffsetForGlobalOptimizer(int64_t offset) {
2997 global_optimizer_offset_ = std::max(Zero(), offset);
2998 }
3000 void SetVehicleOffsetsForLocalOptimizer(std::vector<int64_t> offsets) {
3002 std::transform(offsets.begin(), offsets.end(), offsets.begin(),
3003 [](int64_t offset) { return std::max(Zero(), offset); });
3004 local_optimizer_offset_for_vehicle_ = std::move(offsets);
3005 }
3006
3007 std::vector<IntVar*> cumuls_;
3008 std::vector<SortedDisjointIntervalList> forbidden_intervals_;
3009 std::vector<IntVar*> capacity_vars_;
3010 const std::vector<int64_t> vehicle_capacities_;
3011 std::vector<IntVar*> transits_;
3012 std::vector<IntVar*> fixed_transits_;
3015 std::vector<int> class_evaluators_;
3016 std::vector<int64_t> vehicle_to_class_;
3017#ifndef SWIG
3018 ReverseArcListGraph<int, int> path_precedence_graph_;
3019#endif
3020 // For every {first_node, second_node, offset} element in node_precedences_,
3021 // if both first_node and second_node are performed, then
3022 // cumuls_[second_node] must be greater than (or equal to)
3023 // cumuls_[first_node] + offset.
3024 std::vector<NodePrecedence> node_precedences_;
3025
3026 // The transits of a dimension may depend on its cumuls or the cumuls of
3027 // another dimension. There can be no cycles, except for self loops, a
3028 // typical example for this is a time dimension.
3029 const RoutingDimension* const base_dimension_;
3030
3031 // Values in state_dependent_class_evaluators_ correspond to the evaluators
3032 // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
3033 // class.
3034 std::vector<int> state_dependent_class_evaluators_;
3035 std::vector<int64_t> state_dependent_vehicle_to_class_;
3036
3037 // For each pickup/delivery pair_index for which limits have been set,
3038 // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
3039 // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
3040 std::vector<PickupToDeliveryLimitFunction>
3041 pickup_to_delivery_limits_per_pair_index_;
3042
3043 // Used if some vehicle has breaks in this dimension, typically time.
3044 bool break_constraints_are_initialized_ = false;
3045 // clang-format off
3046 std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
3047 std::vector<std::vector<std::pair<int64_t, int64_t> > >
3048 vehicle_break_distance_duration_;
3049 // clang-format on
3050 // For each vehicle, stores the part of travel that is made directly
3051 // after (before) the departure (arrival) node of the travel.
3052 // These parts of the travel are non-interruptible, in particular by a break.
3053 std::vector<int> vehicle_pre_travel_evaluators_;
3054 std::vector<int> vehicle_post_travel_evaluators_;
3055
3056 std::vector<IntVar*> slacks_;
3057 std::vector<IntVar*> dependent_transits_;
3058 std::vector<int64_t> vehicle_span_upper_bounds_;
3059 int64_t global_span_cost_coefficient_;
3060 std::vector<int64_t> vehicle_span_cost_coefficients_;
3061 std::vector<SoftBound> cumul_var_soft_upper_bound_;
3062 std::vector<SoftBound> cumul_var_soft_lower_bound_;
3063 std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
3064 RoutingModel* const model_;
3065 const std::string name_;
3066 int64_t global_optimizer_offset_;
3067 std::vector<int64_t> local_optimizer_offset_for_vehicle_;
3069 std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
3070 std::unique_ptr<SimpleBoundCosts>
3071 vehicle_quadratic_cost_soft_span_upper_bound_;
3072 friend class RoutingModel;
3073 friend class RoutingModelInspector;
3075 const std::vector<RoutingDimension*>& dimensions,
3076 const RoutingSearchParameters& parameters, bool filter_objective_cost,
3077 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3078
3079 DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
3080};
3081
3085 std::vector<IntVar*> variables,
3086 std::vector<int64_t> targets);
3087
3093 const RoutingSearchParameters& search_parameters,
3094 const Assignment* initial_solution,
3095 Assignment* solution);
3096
3097#if !defined(SWIG)
3099 const RoutingModel& routing_model, const RoutingDimension& dimension);
3100
3101// A decision builder that monitors solutions, and tries to fix dimension
3102// variables whose route did not change in the candidate solution.
3103// Dimension variables are Cumul, Slack and break variables of all dimensions.
3104// The user must make sure that those variables will be always be fixed at
3105// solution, typically by composing another DecisionBuilder after this one.
3106// If this DecisionBuilder returns a non-nullptr value at some node of the
3107// search tree, it will always return nullptr in the subtree of that node.
3108// Moreover, the decision will be a simultaneous assignment of the dimension
3109// variables of unchanged routes on the left branch, and an empty decision on
3110// the right branch.
3112 RoutingModel* model);
3113#endif
3114
3115} // namespace operations_research
3116#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
An Assignment is a variable -> domains mapping, used to report solutions to the user.
A BaseObject is the root of all reversibly allocated objects.
A constraint is the main modeling object.
A DecisionBuilder is responsible for creating the search tree.
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
Definition: routing.h:2148
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
bool DistanceDuration(Tasks *tasks)
Propagates distance_duration constraints, if any.
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
bool ChainSpanMinDynamic(Tasks *tasks)
Computes a lower bound of the span of the chain, taking into account only the first nonchain task.
bool ChainSpanMin(Tasks *tasks)
Propagates a lower bound of the chain span, end[num_chain_tasks] - start[0], to span_min.
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
Definition: routing.h:2256
void Post() override
This method is called when the constraint is processed by the solver.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
std::string DebugString() const override
Definition: routing.h:2259
The class IntVar is a subset of IntExpr.
Interval variables are often used in scheduling.
Local Search Filters are used for fast neighbor pruning.
The base class for all local search operators.
Dimensions represent quantities accumulated at nodes along the routes.
Definition: routing.h:2562
void SetQuadraticCostSoftSpanUpperBoundForVehicle(SimpleBoundCosts::BoundCost bound_cost, int vehicle)
If the span of vehicle on this dimension is larger than bound, the cost will be increased by cost * (...
Definition: routing.h:2933
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2926
const std::vector< IntVar * > & transits() const
Definition: routing.h:2593
IntVar * TransitVar(int64_t index) const
Definition: routing.h:2582
friend void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters &parameters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
void SetSpanCostCoefficientForAllVehicles(int64_t coefficient)
void SetCumulVarPiecewiseLinearCost(int64_t index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
const std::vector< int64_t > & vehicle_span_upper_bounds() const
Definition: routing.h:2877
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2826
int64_t GetSpanCostCoefficientForVehicleClass(RoutingVehicleClassIndex vehicle_class) const
Definition: routing.h:2885
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2591
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:2915
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2640
bool HasCumulVarPiecewiseLinearCost(int64_t index) const
Returns true if a piecewise linear cost has been set for a given variable index.
int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
int64_t GetGlobalOptimizerOffset() const
Definition: routing.h:2901
IntVar * CumulVar(int64_t index) const
Get the cumul, transit and slack variables for the given node (given as int64_t var index).
Definition: routing.h:2581
int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
bool HasCumulVarSoftLowerBound(int64_t index) const
Returns true if a soft lower bound has been set for a given variable index.
IntVar * SlackVar(int64_t index) const
Definition: routing.h:2586
int64_t GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2881
int64_t global_span_cost_coefficient() const
Definition: routing.h:2897
void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration, int vehicle)
With breaks supposed to be consecutive, this forces the distance between breaks of size at least mini...
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:2645
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2594
int64_t GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2873
const std::vector< int64_t > & vehicle_span_cost_coefficients() const
Definition: routing.h:2893
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2669
void AddNodePrecedence(int64_t first_node, int64_t second_node, int64_t offset)
Definition: routing.h:2868
IntVar * FixedTransitVar(int64_t index) const
Definition: routing.h:2583
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
SortedDisjointIntervalList GetAllowedIntervalsInRange(int64_t index, int64_t min_value, int64_t max_value) const
Returns allowed intervals for a given node in a given interval.
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
std::function< int64_t(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
Definition: routing.h:2844
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2860
int64_t GetFirstPossibleGreaterOrEqualValueForNode(int64_t index, int64_t min_value) const
Returns the smallest value outside the forbidden intervals of node 'index' that is greater than or eq...
Definition: routing.h:2605
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:2662
int GetPreTravelEvaluatorOfVehicle(int vehicle) const
!defined(SWIGPYTHON)
bool HasCumulVarSoftUpperBound(int64_t index) const
Returns true if a soft upper bound has been set for a given variable index.
bool HasQuadraticCostSoftSpanUpperBounds() const
Definition: routing.h:2943
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2566
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2863
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2597
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2830
const RoutingModel::TransitCallback2 & class_transit_evaluator(RoutingVehicleClassIndex vehicle_class) const
Returns the callback evaluating the transit value between two node indices for a given vehicle class.
Definition: routing.h:2652
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
int vehicle_to_class(int vehicle) const
Definition: routing.h:2673
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64_t index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, std::vector< int64_t > node_visit_transits, std::function< int64_t(int64_t, int64_t)> delays)
Deprecated, sets pre_travel(i, j) = node_visit_transit[i] and post_travel(i, j) = delays(i,...
int64_t ShortestTransitionSlack(int64_t node) const
It makes sense to use the function only for self-dependent dimension.
int64_t GetTransitValue(int64_t from_index, int64_t to_index, int64_t vehicle) const
Returns the transition value for a given pair of nodes (as var index); this value is the one taken by...
int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index, int64_t vehicle_class) const
Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicl...
Definition: routing.h:2574
int64_t GetLastPossibleLessOrEqualValueForNode(int64_t index, int64_t max_value) const
Returns the largest value outside the forbidden intervals of node 'index' that is less than or equal ...
Definition: routing.h:2624
int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2905
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, std::vector< int64_t > node_visit_transits)
Deprecated, sets pre_travel(i, j) = node_visit_transit[i].
const std::vector< IntVar * > & fixed_transits() const
Definition: routing.h:2592
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2815
void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound, int64_t coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
int64_t GetCumulVarSoftUpperBound(int64_t index) const
Returns the soft upper bound of a cumul variable for a given variable index.
const std::vector< std::pair< int64_t, int64_t > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle)
!defined(SWIGCSHARP) && !defined(SWIGJAVA) !defined(SWIGPYTHON)
void SetGlobalSpanCostCoefficient(int64_t coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound, int64_t coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2946
int64_t GetCumulVarSoftLowerBound(int64_t index) const
Returns the soft lower bound of a cumul variable for a given variable index.
Manager for any NodeIndex <-> variable index conversion.
Attributes(Domain start_domain, Domain end_domain)
A Resource sets attributes (costs/constraints) for a set of dimensions.
Definition: routing.h:416
const ResourceGroup::Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
Definition: routing.h:395
const std::vector< int > & GetVehiclesRequiringAResource() const
Definition: routing.h:447
bool VehicleRequiresAResource(int vehicle) const
Definition: routing.h:451
int AddResource(Attributes attributes, const RoutingDimension *dimension)
Adds a Resource with the given attributes for the corresponding dimension.
const Resource & GetResource(int resource_index) const
Definition: routing.h:456
const std::vector< Resource > & GetResources() const
Definition: routing.h:455
ResourceGroup(const RoutingModel *model)
Definition: routing.h:435
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
Definition: routing.h:460
void NotifyVehicleRequiresAResource(int vehicle)
Notifies that the given vehicle index requires a resource from this group if the vehicle is used (i....
int64_t ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
const Assignment * SolveFromAssignmentsWithParameters(const std::vector< const Assignment * > &assignments, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Same as above but will try all assignments in order as first solutions until one succeeds.
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Definition: routing.h:1096
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1498
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:505
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
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:1539
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
int nodes() const
Sizes and indices Returns the number of nodes in the model.
Definition: routing.h:1514
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &pure_transits, const std::vector< int > &dependent_transits, const RoutingDimension *base_dimension, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension with transits depending on the cumuls of another dimension.
Definition: routing.h:602
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const
Definition: routing.h:1429
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
IntVar * ResourceVar(int vehicle, int resource_group) const
Returns the resource variable for the given vehicle index in the given resource group.
Definition: routing.h:1373
ResourceGroup * GetResourceGroup(int rg_index) const
Definition: routing.h:719
const std::vector< SearchMonitor * > & GetSearchMonitors() const
Definition: routing.h:1569
void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex(int64_t index, int64_t max_cardinality, F f) const
Calls f for each variable index of indices in the same disjunctions as the node corresponding to the ...
Definition: routing.h:764
RoutingIndexPair IndexPair
Definition: routing.h:244
std::pair< int, bool > AddMatrixDimension(std::vector< std::vector< int64_t > > values, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for...
const std::vector< int > & GetPairIndicesOfType(int type) const
RoutingTransitCallback1 TransitCallback1
Definition: routing.h:239
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
const std::vector< int > & GetDimensionResourceGroupIndices(const RoutingDimension *dimension) const
Returns the indices of resource groups for this dimension.
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:1343
bool AddDimensionDependentDimensionWithVehicleCapacity(int transit, const RoutingDimension *base_dimension, int64_t slack_max, int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
Homogeneous versions of the functions above.
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
Definition: routing.h:877
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...
bool IsVehicleUsedWhenEmpty(int vehicle) const
Definition: routing.h:1088
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &transits, const RoutingDimension *base_dimension, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
As above, but pure_transits are taken to be zero evaluators.
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenRemovingType(int type) const
Returns the set of requirement alternatives when removing the given type.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
Definition: routing.h:881
bool HasMandatoryDisjunctions() const
Returns true if the model contains mandatory disjunctions (ones with kNoPenalty as penalty).
RoutingModel(const RoutingIndexManager &index_manager, const RoutingModelParameters &parameters)
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
Definition: routing.h:1449
int64_t GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
std::pair< int, bool > AddVectorDimension(std::vector< int64_t > values, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; ...
bool IsStart(int64_t index) const
Returns true if 'index' represents the first node of a route.
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
void AddSoftSameVehicleConstraint(const std::vector< int64_t > &indices, int64_t cost)
Adds a soft constraint to force a set of variable indices to be on the same vehicle.
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
Definition: routing.h:672
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
bool CheckLimit()
Returns true if the search limit has been crossed.
Definition: routing.h:1501
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
Definition: routing.h:888
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
int GetDimensionResourceGroupIndex(const RoutingDimension *dimension) const
Returns the index of the resource group attached to the dimension.
Definition: routing.h:731
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64_t node_index) const
Same as above for deliveries.
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
IntVar * VehicleVar(int64_t index) const
Returns the vehicle variable of the node corresponding to index.
Definition: routing.h:1369
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
Definition: routing.h:904
@ TYPE_ADDED_TO_VEHICLE
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:906
@ ADDED_TYPE_REMOVED_FROM_VEHICLE
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:911
@ TYPE_ON_VEHICLE_UP_TO_VISIT
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
Definition: routing.h:914
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
Definition: routing.h:1391
LocalDimensionCumulOptimizer * GetMutableLocalCumulOptimizer(const RoutingDimension &dimension) const
int RegisterUnaryTransitVector(std::vector< int64_t > values)
Registers 'callback' and returns its index.
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:1309
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the set of same-vehicle requirement alternatives for the given type.
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1518
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
int GetVisitType(int64_t index) const
bool RoutesToAssignment(const std::vector< std::vector< int64_t > > &routes, bool ignore_inactive_indices, bool close_routes, Assignment *const assignment) const
Fills an assignment from a specification of the routes of the vehicles.
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulMPOptimizers() const
Definition: routing.h:664
bool HasTemporalTypeRequirements() const
Definition: routing.h:1001
IntVar * NextVar(int64_t index) const
!defined(SWIGPYTHON)
Definition: routing.h:1353
static const int64_t kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:476
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
RoutingTransitCallback2 TransitCallback2
Definition: routing.h:240
DisjunctionIndex AddDisjunction(const std::vector< int64_t > &indices, int64_t penalty=kNoPenalty, int64_t max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
Definition: routing.h:1358
int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:788
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
std::vector< std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
std::pair< int, bool > AddConstantDimensionWithSlack(int64_t value, int64_t capacity, int64_t slack_max, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is t...
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64_t > > &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Same as above, except that if assignment is not null, it will be used as the initial solution.
Status
Status of the search.
Definition: routing.h:213
@ ROUTING_SUCCESS
Problem solved successfully after calling RoutingModel::Solve().
Definition: routing.h:217
@ ROUTING_FAIL
No solution found to the problem after calling RoutingModel::Solve().
Definition: routing.h:219
@ ROUTING_NOT_SOLVED
Problem not solved yet (before calling RoutingModel::Solve()).
Definition: routing.h:215
@ ROUTING_INVALID
Model, model parameters or flags are not valid.
Definition: routing.h:223
@ ROUTING_FAIL_TIMEOUT
Time limit reached before finding a solution with RoutingModel::Solve().
Definition: routing.h:221
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
Definition: routing.h:1416
void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy)
int64_t GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
void SetSweepArranger(SweepArranger *sweep_arranger)
void AddTemporalTypeIncompatibility(int type1, int type2)
const std::vector< int > & GetSingleNodesOfType(int type) const
RoutingIndexPairs IndexPairs
Definition: routing.h:245
void SetFixedCostOfVehicle(int64_t cost, int vehicle)
Sets the fixed cost of one vehicle route.
std::vector< std::vector< std::pair< int64_t, int64_t > > > GetCumulBounds(const Assignment &solution_assignment, const RoutingDimension &dimension)
Returns a vector cumul_bounds, for which cumul_bounds[i][j] is a pair containing the minimum and maxi...
const std::vector< absl::flat_hash_set< int > > & GetRequiredTypeAlternativesWhenAddingType(int type) const
Returns the set of requirement alternatives when adding the given type.
bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64_t(int64_t)> &f, int64_t domain_start, int64_t domain_end)
Creates a cached StateDependentTransit from an std::function.
void AddPickupAndDelivery(int64_t pickup, int64_t delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
VisitTypePolicy GetVisitTypePolicy(int64_t index) const
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
Definition: routing.h:509
int64_t GetArcCostForFirstSolution(int64_t from_index, int64_t to_index) const
Returns the cost of the arc in the context of the first solution strategy.
bool IsVehicleAllowedForIndex(int vehicle, int64_t index)
Returns true if a vehicle is allowed to visit a given node.
Definition: routing.h:825
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1456
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
IntVar * ApplyLocks(const std::vector< int64_t > &locks)
Applies a lock chain to the next search.
int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index, int64_t vehicle) const
Returns the cost of the transit arc between two nodes for a given vehicle.
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
void SetMaximumNumberOfActiveVehicles(int max_active_vehicles)
Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an emp...
Definition: routing.h:1032
void AssignmentToRoutes(const Assignment &assignment, std::vector< std::vector< int64_t > > *const routes) const
Converts the solution in the given assignment to routes for all vehicles.
const std::vector< IntVar * > & ResourceVars(int resource_group) const
Returns vehicle resource variables for a given resource group, such that ResourceVars(r_g)[v] is the ...
Definition: routing.h:1347
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:934
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:651
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
int RegisterTransitCallback(TransitCallback2 callback)
void AddVariableTargetToFinalizer(IntVar *var, int64_t target)
Add a variable to set the closest possible to the target value in the solution finalizer.
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Definition: routing.h:513
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_,...
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:1340
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64_t index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:756
int64_t UnperformedPenaltyOrValue(int64_t default_value, int64_t var_index) const
Same as above except that it returns default_value instead of 0 when penalty is not well defined (def...
const std::vector< int64_t > & GetAmortizedLinearCostFactorOfVehicles() const
Definition: routing.h:1075
int AddResourceGroup()
Adds a resource group to the routing model.
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:1036
RoutingDimensionIndex DimensionIndex
Definition: routing.h:236
void SetVehicleUsedWhenEmpty(bool is_used, int vehicle)
Definition: routing.h:1083
Assignment * MutablePreAssignment()
Definition: routing.h:1208
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:668
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
LocalDimensionCumulOptimizer * GetMutableLocalCumulMPOptimizer(const RoutingDimension &dimension) const
std::pair< int, bool > AddConstantDimension(int64_t value, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Definition: routing.h:565
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:953
void AddRequiredTypeAlternativesWhenRemovingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
The following requirements apply when visiting dependent nodes that remove their type from the route,...
std::vector< std::vector< int64_t > > GetRoutesFromAssignment(const Assignment &assignment)
Converts the solution in the given assignment to routes for all vehicles.
int64_t Next(const Assignment &assignment, int64_t index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor, int64_t quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
int RegisterPositiveTransitCallback(TransitCallback2 callback)
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
Definition: routing.h:227
@ PICKUP_AND_DELIVERY_LIFO
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:231
@ PICKUP_AND_DELIVERY_NO_ORDER
Any precedence is accepted.
Definition: routing.h:229
@ PICKUP_AND_DELIVERY_FIFO
Deliveries must be performed in the same order as pickups.
Definition: routing.h:233
int64_t Start(int vehicle) const
Model inspection.
Definition: routing.h:1320
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...
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1516
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:792
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64_t index)
Sets the vehicles which can visit a given node.
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
int64_t UnperformedPenalty(int64_t var_index) const
Get the "unperformed" penalty of a node.
void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor, int64_t quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
IntVar * ActiveVar(int64_t index) const
Returns the active variable of the node corresponding to index.
Definition: routing.h:1355
int64_t GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
Definition: routing.h:1007
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:1101
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:238
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64_t cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
void AddIntervalToAssignment(IntervalVar *const interval)
void SetArcCostEvaluatorOfAllVehicles(int evaluator_index)
Sets the cost function of the model such that the cost of a segment of a route between node 'from' an...
bool ApplyLocksToAllVehicles(const std::vector< std::vector< int64_t > > &locks, bool close_routes)
Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for rout...
std::vector< std::pair< int64_t, int64_t > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64_t(int64_t)> initializer)
The next few members are in the public section only for testing purposes.
std::function< StateDependentTransit(int64_t, int64_t)> VariableIndexEvaluator2
Definition: routing.h:266
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1426
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulOptimizer(const RoutingDimension &dimension) const
Returns the global/local dimension cumul optimizer for a given dimension, or nullptr if there is none...
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
Definition: routing.h:1379
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:998
int64_t GetArcCostForClass(int64_t from_index, int64_t to_index, int64_t cost_class_index) const
Returns the cost of the segment between two nodes for a given cost class.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
Definition: routing.h:701
void SetAssignmentFromOtherModelAssignment(Assignment *target_assignment, const RoutingModel *source_model, const Assignment *source_assignment)
Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variab...
void 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,...
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
const std::vector< std::pair< int, int > > & GetPickupIndexPairs(int64_t node_index) const
Returns pairs for which the node is a pickup; the first element of each pair is the index in the pick...
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
DecisionBuilder * MakeSelfDependentDimensionFinalizer(const RoutingDimension *dimension)
SWIG
int RegisterUnaryTransitCallback(TransitCallback1 callback)
int64_t GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1326
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
RoutingCostClassIndex CostClassIndex
Definition: routing.h:235
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:956
bool HasMaxCardinalityConstrainedDisjunctions() const
Returns true if the model contains at least one disjunction which is constrained by its max_cardinali...
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
Definition: routing.h:1424
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:1078
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
void AddRequiredTypeAlternativesWhenAddingType(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D depends on type_R when adding type_D, any node_D of type_D and VisitTypePolicy TYPE_ADDED_T...
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
Definition: routing.h:1528
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1507
Status status() const
Returns the current status of the routing model.
Definition: routing.h:1183
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1451
int RegisterTransitMatrix(std::vector< std::vector< int64_t > > values)
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
Definition: routing.h:484
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1386
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
Definition: routing.h:714
CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1407
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
void SetFixedCostOfAllVehicles(int64_t cost)
Sets the fixed cost of all vehicle routes.
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
int VehicleIndex(int64_t index) const
Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/en...
Definition: routing.h:1329
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:660
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
int GetVehicleOfClass(VehicleClassIndex vehicle_class) const
Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class.
Definition: routing.h:1435
bool AddDimensionDependentDimensionWithVehicleCapacity(int pure_transit, int dependent_transit, const RoutingDimension *base_dimension, int64_t slack_max, int64_t vehicle_capacity, bool fix_start_cumul_to_zero, const std::string &name)
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:480
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
Definition: routing.h:706
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
IntVar * VehicleRouteConsideredVar(int vehicle) const
Returns the variable specifying whether or not the given vehicle route is considered for costs and co...
Definition: routing.h:1364
bool AddDimensionWithVehicleTransitAndCapacity(const std::vector< int > &evaluator_indices, int64_t slack_max, std::vector< int64_t > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
RoutingDisjunctionIndex DisjunctionIndex
Definition: routing.h:237
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1322
bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
Definition: routing.h:1207
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
const std::vector< int64_t > & GetDisjunctionNodeIndices(DisjunctionIndex index) const
Returns the variable indices of the nodes in the disjunction of index 'index'.
Definition: routing.h:777
A search monitor is a simple set of callbacks to monitor all search events.
A structure meant to store soft bounds and associated violation constants.
Definition: routing.h:2523
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2529
BoundCost & bound_cost(int element)
Definition: routing.h:2531
BoundCost bound_cost(int element) const
Definition: routing.h:2532
SimpleBoundCosts(const SimpleBoundCosts &)=delete
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
Checker for type incompatibilities.
Definition: routing.h:2414
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
virtual bool HasRegulationsToCheck() const =0
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
bool CheckVehicle(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
TypeRegulationsChecker(const RoutingModel &model)
void InitializeCheck(int vehicle, const std::function< int64_t(int64_t)> &next_accessor)
bool TypeCurrentlyOnRoute(int type, int pos) const
Returns true iff there's at least one instance of the given type on the route when scanning the route...
bool TypeOccursOnRoute(int type) const
Returns true iff any occurrence of the given type was seen on the route, i.e.
The following constraint ensures that incompatibilities and requirements between types are respected.
Definition: routing.h:2494
void Post() override
This method is called when the constraint is processed by the solver.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
TypeRegulationsConstraint(const RoutingModel &model)
Checker for type requirements.
Definition: routing.h:2430
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2432
Collection of objects used to extend the Constraint Solver library.
std::function< int64_t(int64_t, int64_t)> RoutingTransitCallback2
Definition: routing_types.h:43
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64_t > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
int64_t Zero()
NOLINT.
DecisionBuilder * MakeRestoreDimensionValuesForUnchangedRoutes(RoutingModel *model)
std::pair< std::vector< int64_t >, std::vector< int64_t > > RoutingIndexPair
Definition: routing_types.h:45
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 AppendTasksFromPath(const std::vector< int64_t > &path, const TravelBounds &travel_bounds, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
std::function< int64_t(int64_t)> RoutingTransitCallback1
Definition: routing_types.h:42
void FillPathEvaluation(const std::vector< int64_t > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64_t > *values)
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:46
DecisionBuilder * MakeSetValuesFromTargets(Solver *solver, std::vector< IntVar * > variables, std::vector< int64_t > targets)
A decision builder which tries to assign values to variables as close as possible to target values fi...
A structure to hold tasks described by their features.
Definition: routing.h:2155
std::vector< std::pair< int64_t, int64_t > > distance_duration
Definition: routing.h:2165
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:2164
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:294
bool operator<(const DimensionCost &cost) const
Definition: routing.h:298
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:272
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:312
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:306
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:261
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:263
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:325
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
Definition: routing.h:341
std::vector< int > required_resource_group_indices
Sorted set of resource groups for which the vehicle requires a resource.
Definition: routing.h:349
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:347
bool used_when_empty
Whether or not the vehicle is used when empty.
Definition: routing.h:327
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:334
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
absl::StrongVector< DimensionIndex, int64_t > dimension_capacities
Definition: routing.h:342
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_min
Definition: routing.h:340
absl::StrongVector< DimensionIndex, int64_t > dimension_evaluator_classes
dimension_evaluators[d]->Run(from, to) is the transit value of arc from->to for a dimension d.
Definition: routing.h:345
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:338
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_max
Definition: routing.h:339
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:323
Definition: routing.h:360
int64_t fixed_cost
Definition: routing.h:362
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:364
int vehicle_class
Definition: routing.h:361
Struct used to sort and store vehicles by their type.
Definition: routing.h:359
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:379
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:380
std::vector< int64_t > post_travels
Definition: routing.h:2229
std::vector< int64_t > max_travels
Definition: routing.h:2227
std::vector< int64_t > pre_travels
Definition: routing.h:2228
std::vector< int64_t > min_travels
Definition: routing.h:2226