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/integral_types.h"
176#include "ortools/base/logging.h"
177#include "ortools/base/macros.h"
178#include "ortools/base/map_util.h"
179#include "ortools/base/strong_int.h"
180#include "ortools/base/strong_vector.h"
183#include "ortools/constraint_solver/routing_enums.pb.h"
185#include "ortools/constraint_solver/routing_parameters.pb.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 {
226 };
227
236 };
237 typedef RoutingCostClassIndex CostClassIndex;
238 typedef RoutingDimensionIndex DimensionIndex;
239 typedef RoutingDisjunctionIndex DisjunctionIndex;
240 typedef RoutingVehicleClassIndex VehicleClassIndex;
243
244// TODO(user): Remove all SWIG guards by adding the @ignore in .i.
245#if !defined(SWIG)
248#endif // SWIG
249
250#if !defined(SWIG)
264 RangeIntToIntFunction* transit;
265 RangeMinMaxIndexFunction* transit_plus_identity;
266 };
267 typedef std::function<StateDependentTransit(int64_t, int64_t)>
269#endif // SWIG
270
271#if !defined(SWIG)
272 struct CostClass {
275
290
300 bool operator<(const DimensionCost& cost) const {
303 }
305 }
306 };
307 std::vector<DimensionCost>
309
312
314 static bool LessThan(const CostClass& a, const CostClass& b) {
315 if (a.evaluator_index != b.evaluator_index) {
316 return a.evaluator_index < b.evaluator_index;
317 }
320 }
321 };
322
327 int64_t fixed_cost;
334 // TODO(user): Find equivalent start/end nodes wrt dimensions and
335 // callbacks.
340 absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_min;
341 absl::StrongVector<DimensionIndex, int64_t> dimension_start_cumuls_max;
342 absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_min;
343 absl::StrongVector<DimensionIndex, int64_t> dimension_end_cumuls_max;
344 absl::StrongVector<DimensionIndex, int64_t> dimension_capacities;
347 absl::StrongVector<DimensionIndex, int64_t> dimension_evaluator_classes;
352
354 static bool LessThan(const VehicleClass& a, const VehicleClass& b);
355 };
356#endif // defined(SWIG)
357
364 int64_t fixed_cost;
365
366 bool operator<(const VehicleClassEntry& other) const {
367 return std::tie(fixed_cost, vehicle_class) <
368 std::tie(other.fixed_cost, other.vehicle_class);
369 }
370 };
371
372 int NumTypes() const { return sorted_vehicle_classes_per_type.size(); }
373
374 int Type(int vehicle) const {
375 DCHECK_LT(vehicle, type_index_of_vehicle.size());
376 return type_index_of_vehicle[vehicle];
377 }
378
379 std::vector<int> type_index_of_vehicle;
380 // clang-format off
381 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type;
382 std::vector<std::deque<int> > vehicles_per_vehicle_class;
383 // clang-format on
384 };
385
386 #if !defined(SWIG)
399 public:
402 public:
405
406 const Domain& start_domain() const { return start_domain_; }
407 const Domain& end_domain() const { return end_domain_; }
408
409 private:
413 Domain start_domain_;
415 Domain end_domain_;
416 };
417
419 class Resource {
420 public:
422 const RoutingDimension* dimension) const;
423
424 private:
425 explicit Resource(const RoutingModel* model) : model_(model) {}
426
427 void SetDimensionAttributes(ResourceGroup::Attributes attributes,
428 const RoutingDimension* dimension);
429 const ResourceGroup::Attributes& GetDefaultAttributes() const;
430
431 const RoutingModel* const model_;
432 absl::flat_hash_map<DimensionIndex, ResourceGroup::Attributes>
433 dimension_attributes_;
434
435 friend class ResourceGroup;
436 };
437
438 explicit ResourceGroup(const RoutingModel* model)
439 : model_(model), vehicle_requires_resource_(model->vehicles(), false) {}
440
443 int AddResource(Attributes attributes, const RoutingDimension* dimension);
444
449
450 const std::vector<int>& GetVehiclesRequiringAResource() const {
451 return vehicles_requiring_resource_;
452 }
453
454 bool VehicleRequiresAResource(int vehicle) const {
455 return vehicle_requires_resource_[vehicle];
456 }
457
458 const std::vector<Resource>& GetResources() const { return resources_; }
459 const Resource& GetResource(int resource_index) const {
460 DCHECK_LT(resource_index, resources_.size());
461 return resources_[resource_index];
462 }
463 const absl::flat_hash_set<DimensionIndex>& GetAffectedDimensionIndices()
464 const {
465 return affected_dimension_indices_;
466 }
467 int Size() const { return resources_.size(); }
468
469 private:
470 const RoutingModel* const model_;
471 std::vector<Resource> resources_;
472 std::vector<bool> vehicle_requires_resource_;
473 std::vector<int> vehicles_requiring_resource_;
475 absl::flat_hash_set<DimensionIndex> affected_dimension_indices_;
476 };
477 #endif // !defined(SWIG)
478
480 static const int64_t kNoPenalty;
481
485
489
493 explicit RoutingModel(const RoutingIndexManager& index_manager);
494 RoutingModel(const RoutingIndexManager& index_manager,
495 const RoutingModelParameters& parameters);
497
499 int RegisterUnaryTransitVector(std::vector<int64_t> values);
502
504 std::vector<std::vector<int64_t> /*needed_for_swig*/> values);
507
509 const TransitCallback2& TransitCallback(int callback_index) const {
510 CHECK_LT(callback_index, transit_evaluators_.size());
511 return transit_evaluators_[callback_index];
512 }
513 const TransitCallback1& UnaryTransitCallbackOrNull(int callback_index) const {
514 CHECK_LT(callback_index, unary_transit_evaluators_.size());
515 return unary_transit_evaluators_[callback_index];
516 }
518 int callback_index) const {
519 CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
520 return state_dependent_transit_evaluators_[callback_index];
521 }
522
524
536
545 bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity,
546 bool fix_start_cumul_to_zero, const std::string& name);
548 const std::vector<int>& evaluator_indices, int64_t slack_max,
549 int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
550 bool AddDimensionWithVehicleCapacity(int evaluator_index, int64_t slack_max,
551 std::vector<int64_t> vehicle_capacities,
552 bool fix_start_cumul_to_zero,
553 const std::string& name);
555 const std::vector<int>& evaluator_indices, int64_t slack_max,
556 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
557 const std::string& name);
566 std::pair<int, bool> AddConstantDimensionWithSlack(
567 int64_t value, int64_t capacity, int64_t slack_max,
568 bool fix_start_cumul_to_zero, const std::string& name);
569 std::pair<int, bool> AddConstantDimension(int64_t value, int64_t capacity,
570 bool fix_start_cumul_to_zero,
571 const std::string& name) {
572 return AddConstantDimensionWithSlack(value, capacity, 0,
573 fix_start_cumul_to_zero, name);
574 }
584 std::pair<int, bool> AddVectorDimension(std::vector<int64_t> values,
585 int64_t capacity,
586 bool fix_start_cumul_to_zero,
587 const std::string& name);
597 std::pair<int, bool> AddMatrixDimension(
598 std::vector<std::vector<int64_t> /*needed_for_swig*/> values,
599 int64_t capacity, bool fix_start_cumul_to_zero, const std::string& name);
607 const std::vector<int>& pure_transits,
608 const std::vector<int>& dependent_transits,
609 const RoutingDimension* base_dimension, int64_t slack_max,
610 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
611 const std::string& name) {
612 return AddDimensionDependentDimensionWithVehicleCapacityInternal(
613 pure_transits, dependent_transits, base_dimension, slack_max,
614 std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
615 }
616
619 const std::vector<int>& transits, const RoutingDimension* base_dimension,
620 int64_t slack_max, std::vector<int64_t> vehicle_capacities,
621 bool fix_start_cumul_to_zero, const std::string& name);
624 int transit, const RoutingDimension* base_dimension, int64_t slack_max,
625 int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
626 const std::string& name);
628 int pure_transit, int dependent_transit,
629 const RoutingDimension* base_dimension, int64_t slack_max,
630 int64_t vehicle_capacity, bool fix_start_cumul_to_zero,
631 const std::string& name);
632
635 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
636 int64_t domain_end);
637
648 std::vector<IntVar*> spans,
649 std::vector<IntVar*> total_slacks);
650
652 // TODO(user): rename.
653 std::vector<std::string> GetAllDimensionNames() const;
655 const std::vector<RoutingDimension*>& GetDimensions() const {
656 return dimensions_.get();
657 }
659 std::vector<RoutingDimension*> GetDimensionsWithSoftOrSpanCosts() const;
660 // clang-format off
663 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
665 return global_dimension_optimizers_;
666 }
667 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
669 return global_dimension_mp_optimizers_;
670 }
671 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
673 return local_dimension_optimizers_;
674 }
675 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
677 return local_dimension_mp_optimizers_;
678 }
679 // clang-format on
680
684 const RoutingDimension& dimension) const;
686 const RoutingDimension& dimension) const;
688 const RoutingDimension& dimension) const;
690 const RoutingDimension& dimension) const;
691
693 bool HasDimension(const std::string& dimension_name) const;
696 const std::string& dimension_name) const;
700 const std::string& dimension_name) const;
705 void SetPrimaryConstrainedDimension(const std::string& dimension_name) {
706 DCHECK(dimension_name.empty() || HasDimension(dimension_name));
707 primary_constrained_dimension_ = dimension_name;
708 }
710 const std::string& GetPrimaryConstrainedDimension() const {
711 return primary_constrained_dimension_;
712 }
713
717#if !defined(SWIG)
718 // clang-format off
719 const std::vector<std::unique_ptr<ResourceGroup> >& GetResourceGroups()
720 const {
721 return resource_groups_;
722 }
723 // clang-format on
724 ResourceGroup* GetResourceGroup(int rg_index) const {
725 DCHECK_LT(rg_index, resource_groups_.size());
726 return resource_groups_[rg_index].get();
727 }
728#endif // !defined(SWIG)
729
732 const std::vector<int>& GetDimensionResourceGroupIndices(
733 const RoutingDimension* dimension) const;
734
738 DCHECK_EQ(GetDimensionResourceGroupIndices(dimension).size(), 1);
739 return GetDimensionResourceGroupIndices(dimension)[0];
740 }
741
758 DisjunctionIndex AddDisjunction(const std::vector<int64_t>& indices,
759 int64_t penalty = kNoPenalty,
760 int64_t max_cardinality = 1);
762 const std::vector<DisjunctionIndex>& GetDisjunctionIndices(
763 int64_t index) const {
764 return index_to_disjunctions_[index];
765 }
769 template <typename F>
771 int64_t index, int64_t max_cardinality, F f) const {
772 for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
773 if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
774 for (const int64_t d_index : disjunctions_[disjunction].indices) {
775 f(d_index);
776 }
777 }
778 }
779 }
780#if !defined(SWIGPYTHON)
783 const std::vector<int64_t>& GetDisjunctionNodeIndices(
784 DisjunctionIndex index) const {
785 return disjunctions_[index].indices;
786 }
787#endif // !defined(SWIGPYTHON)
789 int64_t GetDisjunctionPenalty(DisjunctionIndex index) const {
790 return disjunctions_[index].value.penalty;
791 }
795 return disjunctions_[index].value.max_cardinality;
796 }
798 int GetNumberOfDisjunctions() const { return disjunctions_.size(); }
809 std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions() const;
816
820 void AddSoftSameVehicleConstraint(const std::vector<int64_t>& indices,
821 int64_t cost);
822
827 void SetAllowedVehiclesForIndex(const std::vector<int>& vehicles,
828 int64_t index);
829
831 bool IsVehicleAllowedForIndex(int vehicle, int64_t index) {
832 return allowed_vehicles_[index].empty() ||
833 allowed_vehicles_[index].find(vehicle) !=
834 allowed_vehicles_[index].end();
835 }
836
851 // TODO(user): Remove this when model introspection detects linked nodes.
852 void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
857 DisjunctionIndex delivery_disjunction);
858 // clang-format off
862 const std::vector<std::pair<int, int> >&
863 GetPickupIndexPairs(int64_t node_index) const;
865 const std::vector<std::pair<int, int> >&
866 GetDeliveryIndexPairs(int64_t node_index) const;
867 // clang-format on
868
873 int vehicle);
875 int vehicle) const;
878
880
881#ifndef SWIG
884 return pickup_delivery_pairs_;
885 }
886 const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
888 return pickup_delivery_disjunctions_;
889 }
895 DCHECK(closed_);
896 return implicit_pickup_delivery_pairs_without_alternatives_;
897 }
898#endif // SWIG
910 enum VisitTypePolicy {
925 TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
926 };
927 // TODO(user): Support multiple visit types per node?
928 void SetVisitType(int64_t index, int type, VisitTypePolicy type_policy);
929 int GetVisitType(int64_t index) const;
930 const std::vector<int>& GetSingleNodesOfType(int type) const;
931 const std::vector<int>& GetPairIndicesOfType(int type) const;
935 // TODO(user): Reconsider the logic and potentially remove the need to
938 int GetNumberOfVisitTypes() const { return num_visit_types_; }
939#ifndef SWIG
940 const std::vector<std::vector<int>>& GetTopologicallySortedVisitTypes()
941 const {
942 DCHECK(closed_);
943 return topologically_sorted_visit_types_;
944 }
945#endif // SWIG
950 void AddHardTypeIncompatibility(int type1, int type2);
951 void AddTemporalTypeIncompatibility(int type1, int type2);
953 const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
954 int type) const;
955 const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
956 int type) const;
960 return has_hard_type_incompatibilities_;
961 }
963 return has_temporal_type_incompatibilities_;
964 }
976 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
982 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
989 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
990 // clang-format off
993 const std::vector<absl::flat_hash_set<int> >&
996 const std::vector<absl::flat_hash_set<int> >&
999 const std::vector<absl::flat_hash_set<int> >&
1001 // clang-format on
1005 return has_same_vehicle_type_requirements_;
1006 }
1008 return has_temporal_type_requirements_;
1009 }
1010
1013 bool HasTypeRegulations() const {
1014 return HasTemporalTypeIncompatibilities() ||
1015 HasHardTypeIncompatibilities() || HasSameVehicleTypeRequirements() ||
1016 HasTemporalTypeRequirements();
1017 }
1018
1023 int64_t UnperformedPenalty(int64_t var_index) const;
1027 int64_t UnperformedPenaltyOrValue(int64_t default_value,
1028 int64_t var_index) const;
1032 int64_t GetDepot() const;
1033
1038 void SetMaximumNumberOfActiveVehicles(int max_active_vehicles) {
1039 max_active_vehicles_ = max_active_vehicles;
1040 }
1042 int GetMaximumNumberOfActiveVehicles() const { return max_active_vehicles_; }
1046 void SetArcCostEvaluatorOfAllVehicles(int evaluator_index);
1048 void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle);
1051 void SetFixedCostOfAllVehicles(int64_t cost);
1053 void SetFixedCostOfVehicle(int64_t cost, int vehicle);
1057 int64_t GetFixedCostOfVehicle(int vehicle) const;
1058
1074 void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor,
1075 int64_t quadratic_cost_factor);
1077 void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor,
1078 int64_t quadratic_cost_factor,
1079 int vehicle);
1080
1081 const std::vector<int64_t>& GetAmortizedLinearCostFactorOfVehicles() const {
1082 return linear_cost_factor_of_vehicle_;
1083 }
1084 const std::vector<int64_t>& GetAmortizedQuadraticCostFactorOfVehicles()
1085 const {
1086 return quadratic_cost_factor_of_vehicle_;
1087 }
1088
1089 void SetVehicleUsedWhenEmpty(bool is_used, int vehicle) {
1090 DCHECK_LT(vehicle, vehicles_);
1091 vehicle_used_when_empty_[vehicle] = is_used;
1092 }
1093
1094 bool IsVehicleUsedWhenEmpty(int vehicle) const {
1095 DCHECK_LT(vehicle, vehicles_);
1096 return vehicle_used_when_empty_[vehicle];
1097 }
1098
1101#ifndef SWIG
1103 return first_solution_evaluator_;
1104 }
1105#endif
1108 first_solution_evaluator_ = std::move(evaluator);
1109 }
1114 void AddSearchMonitor(SearchMonitor* const monitor);
1118 void AddAtSolutionCallback(std::function<void()> callback);
1135 void AddVariableTargetToFinalizer(IntVar* var, int64_t target);
1139 int64_t cost);
1150 const RoutingSearchParameters& search_parameters);
1157 const Assignment* Solve(const Assignment* assignment = nullptr);
1166 const RoutingSearchParameters& search_parameters,
1167 std::vector<const Assignment*>* solutions = nullptr);
1171 const Assignment* assignment,
1172 const RoutingSearchParameters& search_parameters,
1173 std::vector<const Assignment*>* solutions = nullptr);
1177 const std::vector<const Assignment*>& assignments,
1178 const RoutingSearchParameters& search_parameters,
1179 std::vector<const Assignment*>* solutions = nullptr);
1186 Assignment* target_assignment, const RoutingModel* source_model,
1187 const Assignment* source_assignment);
1193 // TODO(user): Add support for non-homogeneous costs and disjunctions.
1196 Status status() const { return status_; }
1205 IntVar* ApplyLocks(const std::vector<int64_t>& locks);
1214 bool ApplyLocksToAllVehicles(const std::vector<std::vector<int64_t>>& locks,
1215 bool close_routes);
1220 const Assignment* const PreAssignment() const { return preassignment_; }
1221 Assignment* MutablePreAssignment() { return preassignment_; }
1225 bool WriteAssignment(const std::string& file_name) const;
1229 Assignment* ReadAssignment(const std::string& file_name);
1239 const std::vector<std::vector<int64_t>>& routes,
1240 bool ignore_inactive_indices);
1257 bool RoutesToAssignment(const std::vector<std::vector<int64_t>>& routes,
1258 bool ignore_inactive_indices, bool close_routes,
1259 Assignment* const assignment) const;
1264 const Assignment& assignment,
1265 std::vector<std::vector<int64_t>>* const routes) const;
1270#ifndef SWIG
1271 std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1272 const Assignment& assignment);
1273#endif
1291 Assignment* CompactAssignment(const Assignment& assignment) const;
1297 void AddToAssignment(IntVar* const var);
1310 const Assignment* original_assignment, absl::Duration duration_limit);
1311#ifndef SWIG
1312 // TODO(user): Revisit if coordinates are added to the RoutingModel class.
1313 void SetSweepArranger(SweepArranger* sweep_arranger);
1315 SweepArranger* sweep_arranger() const;
1316#endif
1323 CHECK(filter != nullptr);
1324 if (closed_) {
1325 LOG(WARNING) << "Model is closed, filter addition will be ignored.";
1326 }
1327 extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1328 extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1329 }
1330
1333 int64_t Start(int vehicle) const { return starts_[vehicle]; }
1335 int64_t End(int vehicle) const { return ends_[vehicle]; }
1337 bool IsStart(int64_t index) const;
1339 bool IsEnd(int64_t index) const { return index >= Size(); }
1342 int VehicleIndex(int64_t index) const { return index_to_vehicle_[index]; }
1346 int64_t Next(const Assignment& assignment, int64_t index) const;
1348 bool IsVehicleUsed(const Assignment& assignment, int vehicle) const;
1349
1350#if !defined(SWIGPYTHON)
1353 const std::vector<IntVar*>& Nexts() const { return nexts_; }
1356 const std::vector<IntVar*>& VehicleVars() const { return vehicle_vars_; }
1360 const std::vector<IntVar*>& ResourceVars(int resource_group) const {
1361 return resource_vars_[resource_group];
1362 }
1363#endif
1366 IntVar* NextVar(int64_t index) const { return nexts_[index]; }
1368 IntVar* ActiveVar(int64_t index) const { return active_[index]; }
1371 IntVar* ActiveVehicleVar(int vehicle) const {
1372 return vehicle_active_[vehicle];
1373 }
1377 IntVar* VehicleRouteConsideredVar(int vehicle) const {
1378 return vehicle_route_considered_[vehicle];
1379 }
1382 IntVar* VehicleVar(int64_t index) const { return vehicle_vars_[index]; }
1386 IntVar* ResourceVar(int vehicle, int resource_group) const {
1387 DCHECK_LT(resource_group, resource_vars_.size());
1388 DCHECK_LT(vehicle, resource_vars_[resource_group].size());
1389 return resource_vars_[resource_group][vehicle];
1390 }
1392 IntVar* CostVar() const { return cost_; }
1393
1396 int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1397 int64_t vehicle) const;
1400 return costs_are_homogeneous_across_vehicles_;
1401 }
1404 int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const {
1405 return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0);
1406 }
1409 int64_t GetArcCostForFirstSolution(int64_t from_index,
1410 int64_t to_index) const;
1417 int64_t GetArcCostForClass(int64_t from_index, int64_t to_index,
1418 int64_t /*CostClassIndex*/ cost_class_index) const;
1421 DCHECK(closed_);
1422 DCHECK_GE(vehicle, 0);
1423 DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1424 DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1425 return cost_class_index_of_vehicle_[vehicle];
1426 }
1429 bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const {
1430 DCHECK(closed_);
1431 if (cost_class_index == kCostClassIndexOfZeroCost) {
1432 return has_vehicle_with_zero_cost_class_;
1433 }
1434 return cost_class_index < cost_classes_.size();
1435 }
1437 int GetCostClassesCount() const { return cost_classes_.size(); }
1440 return std::max(0, GetCostClassesCount() - 1);
1441 }
1443 DCHECK(closed_);
1444 return vehicle_class_index_of_vehicle_[vehicle];
1445 }
1448 int GetVehicleOfClass(VehicleClassIndex vehicle_class) const {
1449 DCHECK(closed_);
1450 const RoutingModel::VehicleTypeContainer& vehicle_type_container =
1451 GetVehicleTypeContainer();
1452 if (vehicle_class.value() >= GetVehicleClassesCount() ||
1453 vehicle_type_container.vehicles_per_vehicle_class[vehicle_class.value()]
1454 .empty()) {
1455 return -1;
1456 }
1457 return vehicle_type_container
1458 .vehicles_per_vehicle_class[vehicle_class.value()]
1459 .front();
1460 }
1462 int GetVehicleClassesCount() const { return vehicle_classes_.size(); }
1464 const std::vector<int>& GetSameVehicleIndicesOfIndex(int node) const {
1465 DCHECK(closed_);
1466 return same_vehicle_groups_[same_vehicle_group_[node]];
1467 }
1468
1470 DCHECK(closed_);
1471 return vehicle_type_container_;
1472 }
1473
1492 bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1498 const Assignment& solution_assignment,
1499 const std::string& dimension_to_print) const;
1505#ifndef SWIG
1506 std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1507 const Assignment& solution_assignment, const RoutingDimension& dimension);
1508#endif
1511 Solver* solver() const { return solver_.get(); }
1512
1514 bool CheckLimit() {
1515 DCHECK(limit_ != nullptr);
1516 return limit_->Check();
1517 }
1518
1520 absl::Duration RemainingTime() const {
1521 DCHECK(limit_ != nullptr);
1522 return limit_->AbsoluteSolverDeadline() - solver_->Now();
1523 }
1524
1527 int nodes() const { return nodes_; }
1529 int vehicles() const { return vehicles_; }
1531 int64_t Size() const { return nodes_ + vehicles_ - start_end_count_; }
1532
1536 const RoutingSearchParameters& search_parameters) const;
1538 const RoutingSearchParameters& search_parameters) const;
1540 operations_research::FirstSolutionStrategy::Value
1542 return automatic_first_solution_strategy_;
1543 }
1544
1546 bool IsMatchingModel() const;
1547
1548#ifndef SWIG
1552 std::function<std::vector<operations_research::IntVar*>(RoutingModel*)>;
1553
1555#endif // SWIG
1556
1558 // TODO(user): Find a way to test and restrict the access at the same time.
1571 const RoutingDimension* dimension,
1572 std::function<int64_t(int64_t)> initializer);
1573#ifndef SWIG
1574 // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h.
1579 static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1580 std::vector<IntVar*> variables);
1581 // Read access to currently registered search monitors.
1582 const std::vector<SearchMonitor*>& GetSearchMonitors() const {
1583 return monitors_;
1584 }
1585#endif
1600 const RoutingDimension* dimension);
1601
1602 private:
1604 enum RoutingLocalSearchOperator {
1605 RELOCATE = 0,
1606 RELOCATE_PAIR,
1607 LIGHT_RELOCATE_PAIR,
1608 RELOCATE_NEIGHBORS,
1609 EXCHANGE,
1610 EXCHANGE_PAIR,
1611 CROSS,
1612 CROSS_EXCHANGE,
1613 TWO_OPT,
1614 OR_OPT,
1615 GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1616 LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1617 GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1618 LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1619 RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1620 GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1621 LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1622 RELOCATE_EXPENSIVE_CHAIN,
1623 LIN_KERNIGHAN,
1624 TSP_OPT,
1625 MAKE_ACTIVE,
1626 RELOCATE_AND_MAKE_ACTIVE,
1627 MAKE_ACTIVE_AND_RELOCATE,
1628 MAKE_INACTIVE,
1629 MAKE_CHAIN_INACTIVE,
1630 SWAP_ACTIVE,
1631 EXTENDED_SWAP_ACTIVE,
1632 NODE_PAIR_SWAP,
1633 PATH_LNS,
1634 FULL_PATH_LNS,
1635 TSP_LNS,
1636 INACTIVE_LNS,
1637 EXCHANGE_RELOCATE_PAIR,
1638 RELOCATE_SUBTRIP,
1639 EXCHANGE_SUBTRIP,
1640 LOCAL_SEARCH_OPERATOR_COUNTER
1641 };
1642
1646 template <typename T>
1647 struct ValuedNodes {
1648 std::vector<int64_t> indices;
1649 T value;
1650 };
1651 struct DisjunctionValues {
1652 int64_t penalty;
1653 int64_t max_cardinality;
1654 };
1655 typedef ValuedNodes<DisjunctionValues> Disjunction;
1656
1659 struct CostCacheElement {
1665 int index;
1666 CostClassIndex cost_class_index;
1667 int64_t cost;
1668 };
1669
1671 void Initialize();
1672 void AddNoCycleConstraintInternal();
1673 bool AddDimensionWithCapacityInternal(
1674 const std::vector<int>& evaluator_indices, int64_t slack_max,
1675 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1676 const std::string& name);
1677 bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1678 const std::vector<int>& pure_transits,
1679 const std::vector<int>& dependent_transits,
1680 const RoutingDimension* base_dimension, int64_t slack_max,
1681 std::vector<int64_t> vehicle_capacities, bool fix_start_cumul_to_zero,
1682 const std::string& name);
1683 bool InitializeDimensionInternal(
1684 const std::vector<int>& evaluator_indices,
1685 const std::vector<int>& state_dependent_evaluator_indices,
1686 int64_t slack_max, bool fix_start_cumul_to_zero,
1687 RoutingDimension* dimension);
1688 DimensionIndex GetDimensionIndex(const std::string& dimension_name) const;
1689
1717 void StoreDimensionCumulOptimizers(const RoutingSearchParameters& parameters);
1718
1719 void ComputeCostClasses(const RoutingSearchParameters& parameters);
1720 void ComputeVehicleClasses();
1728 void ComputeVehicleTypes();
1738 void FinalizeVisitTypes();
1739 // Called by FinalizeVisitTypes() to setup topologically_sorted_visit_types_.
1740 void TopologicallySortVisitTypes();
1741 int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index,
1742 CostClassIndex cost_class_index) const;
1743 void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters,
1744 int node_index,
1745 std::vector<IntVar*>* cost_elements);
1746 void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index,
1747 std::vector<IntVar*>* cost_elements);
1748 Assignment* DoRestoreAssignment();
1749 static const CostClassIndex kCostClassIndexOfZeroCost;
1750 int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle) const {
1751 DCHECK_LT(0, vehicles_);
1752 return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1753 : kCostClassIndexOfZeroCost)
1754 .value();
1755 }
1756 int64_t GetDimensionTransitCostSum(int64_t i, int64_t j,
1757 const CostClass& cost_class) const;
1759 IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1761 void AddPickupAndDeliverySetsInternal(const std::vector<int64_t>& pickups,
1762 const std::vector<int64_t>& deliveries);
1765 IntVar* CreateSameVehicleCost(int vehicle_index);
1768 int FindNextActive(int index, const std::vector<int64_t>& indices) const;
1769
1772 bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index,
1773 int vehicle) const;
1781 bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle,
1782 Assignment* compact_assignment) const;
1783
1784 void QuietCloseModel();
1785 void QuietCloseModelWithParameters(
1786 const RoutingSearchParameters& parameters) {
1787 if (!closed_) {
1788 CloseModelWithParameters(parameters);
1789 }
1790 }
1791
1793 bool SolveMatchingModel(Assignment* assignment,
1794 const RoutingSearchParameters& parameters);
1795#ifndef SWIG
1797 bool AppendAssignmentIfFeasible(
1798 const Assignment& assignment,
1799 std::vector<std::unique_ptr<Assignment>>* assignments);
1800#endif
1802 void LogSolution(const RoutingSearchParameters& parameters,
1803 const std::string& description, int64_t solution_cost,
1804 int64_t start_time_ms);
1807 Assignment* CompactAssignmentInternal(const Assignment& assignment,
1808 bool check_compact_assignment) const;
1813 std::string FindErrorInSearchParametersForModel(
1814 const RoutingSearchParameters& search_parameters) const;
1816 void SetupSearch(const RoutingSearchParameters& search_parameters);
1818 // TODO(user): Document each auxiliary method.
1819 Assignment* GetOrCreateAssignment();
1820 Assignment* GetOrCreateTmpAssignment();
1821 RegularLimit* GetOrCreateLimit();
1822 RegularLimit* GetOrCreateLocalSearchLimit();
1823 RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1824 RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1825 LocalSearchOperator* CreateInsertionOperator();
1826 LocalSearchOperator* CreateMakeInactiveOperator();
1827 template <class T>
1828 LocalSearchOperator* CreateCPOperator(const T& operator_factory) {
1829 return operator_factory(solver_.get(), nexts_,
1830 CostsAreHomogeneousAcrossVehicles()
1831 ? std::vector<IntVar*>()
1832 : vehicle_vars_,
1833 vehicle_start_class_callback_);
1834 }
1835 template <class T>
1836 LocalSearchOperator* CreateCPOperator() {
1837 return CreateCPOperator(MakeLocalSearchOperator<T>);
1838 }
1839 template <class T, class Arg>
1840 LocalSearchOperator* CreateOperator(const Arg& arg) {
1841 return solver_->RevAlloc(new T(nexts_,
1842 CostsAreHomogeneousAcrossVehicles()
1843 ? std::vector<IntVar*>()
1844 : vehicle_vars_,
1845 vehicle_start_class_callback_, arg));
1846 }
1847 template <class T>
1848 LocalSearchOperator* CreatePairOperator() {
1849 return CreateOperator<T>(pickup_delivery_pairs_);
1850 }
1851 void CreateNeighborhoodOperators(const RoutingSearchParameters& parameters);
1852 LocalSearchOperator* ConcatenateOperators(
1853 const RoutingSearchParameters& search_parameters,
1854 const std::vector<LocalSearchOperator*>& operators) const;
1855 LocalSearchOperator* GetNeighborhoodOperators(
1856 const RoutingSearchParameters& search_parameters) const;
1857
1858 struct FilterOptions {
1859 bool filter_objective;
1860 bool filter_with_cp_solver;
1861
1862 bool operator==(const FilterOptions& other) const {
1863 return other.filter_objective == filter_objective &&
1864 other.filter_with_cp_solver == filter_with_cp_solver;
1865 }
1866 template <typename H>
1867 friend H AbslHashValue(H h, const FilterOptions& options) {
1868 return H::combine(std::move(h), options.filter_objective,
1869 options.filter_with_cp_solver);
1870 }
1871 };
1872 std::vector<LocalSearchFilterManager::FilterEvent> CreateLocalSearchFilters(
1873 const RoutingSearchParameters& parameters, const FilterOptions& options);
1874 LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1875 const RoutingSearchParameters& parameters, const FilterOptions& options);
1876 DecisionBuilder* CreateSolutionFinalizer(
1877 const RoutingSearchParameters& parameters, SearchLimit* lns_limit);
1878 DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1879 void CreateFirstSolutionDecisionBuilders(
1880 const RoutingSearchParameters& search_parameters);
1881 DecisionBuilder* GetFirstSolutionDecisionBuilder(
1882 const RoutingSearchParameters& search_parameters) const;
1883 IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1884 const RoutingSearchParameters& parameters) const;
1885 LocalSearchPhaseParameters* CreateLocalSearchParameters(
1886 const RoutingSearchParameters& search_parameters);
1887 DecisionBuilder* CreateLocalSearchDecisionBuilder(
1888 const RoutingSearchParameters& search_parameters);
1889 void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters);
1890 void SetupMetaheuristics(const RoutingSearchParameters& search_parameters);
1891 void SetupAssignmentCollector(
1892 const RoutingSearchParameters& search_parameters);
1893 void SetupTrace(const RoutingSearchParameters& search_parameters);
1894 void SetupImprovementLimit(const RoutingSearchParameters& search_parameters);
1895 void SetupSearchMonitors(const RoutingSearchParameters& search_parameters);
1896 bool UsesLightPropagation(
1897 const RoutingSearchParameters& search_parameters) const;
1898 GetTabuVarsCallback tabu_var_callback_;
1899
1900 // Detects implicit pickup delivery pairs. These pairs are
1901 // non-pickup/delivery pairs for which there exists a unary dimension such
1902 // that the demand d of the implicit pickup is positive and the demand of the
1903 // implicit delivery is equal to -d.
1904 void DetectImplicitPickupAndDeliveries();
1905
1906 int GetVehicleStartClass(int64_t start) const;
1907
1908 void InitSameVehicleGroups(int number_of_groups) {
1909 same_vehicle_group_.assign(Size(), 0);
1910 same_vehicle_groups_.assign(number_of_groups, {});
1911 }
1912 void SetSameVehicleGroup(int index, int group) {
1913 same_vehicle_group_[index] = group;
1914 same_vehicle_groups_[group].push_back(index);
1915 }
1916
1918 std::unique_ptr<Solver> solver_;
1919 int nodes_;
1920 int vehicles_;
1921 int max_active_vehicles_;
1922 Constraint* no_cycle_constraint_ = nullptr;
1924 std::vector<IntVar*> nexts_;
1925 std::vector<IntVar*> vehicle_vars_;
1926 std::vector<IntVar*> active_;
1929 // clang-format off
1930 std::vector<std::vector<IntVar*> > resource_vars_;
1931 // clang-format on
1932 // The following vectors are indexed by vehicle index.
1933 std::vector<IntVar*> vehicle_active_;
1934 std::vector<IntVar*> vehicle_route_considered_;
1939 std::vector<IntVar*> is_bound_to_end_;
1940 mutable RevSwitch is_bound_to_end_ct_added_;
1942 absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1943 absl::StrongVector<DimensionIndex, RoutingDimension*> dimensions_;
1948 // clang-format off
1949 std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1951 absl::StrongVector<DimensionIndex, std::vector<int> >
1952 dimension_resource_group_indices_;
1953
1957 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1958 global_dimension_optimizers_;
1959 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1960 global_dimension_mp_optimizers_;
1961 absl::StrongVector<DimensionIndex, int> global_optimizer_index_;
1962 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1963 local_dimension_optimizers_;
1964 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1965 local_dimension_mp_optimizers_;
1966 // clang-format off
1967 absl::StrongVector<DimensionIndex, int> local_optimizer_index_;
1968 std::string primary_constrained_dimension_;
1970 IntVar* cost_ = nullptr;
1971 std::vector<int> vehicle_to_transit_cost_;
1972 std::vector<int64_t> fixed_cost_of_vehicle_;
1973 std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1974 bool has_vehicle_with_zero_cost_class_;
1975 std::vector<int64_t> linear_cost_factor_of_vehicle_;
1976 std::vector<int64_t> quadratic_cost_factor_of_vehicle_;
1977 bool vehicle_amortized_cost_factors_set_;
1989 std::vector<bool> vehicle_used_when_empty_;
1990#ifndef SWIG
1991 absl::StrongVector<CostClassIndex, CostClass> cost_classes_;
1992#endif // SWIG
1993 bool costs_are_homogeneous_across_vehicles_;
1994 bool cache_callbacks_;
1995 mutable std::vector<CostCacheElement> cost_cache_;
1996 std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1997#ifndef SWIG
1998 absl::StrongVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1999#endif // SWIG
2000 VehicleTypeContainer vehicle_type_container_;
2001 std::function<int(int64_t)> vehicle_start_class_callback_;
2003 absl::StrongVector<DisjunctionIndex, Disjunction> disjunctions_;
2004 std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
2006 std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
2008#ifndef SWIG
2009 std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
2010#endif // SWIG
2012 IndexPairs pickup_delivery_pairs_;
2013 IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
2014 std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
2015 pickup_delivery_disjunctions_;
2016 // clang-format off
2017 // If node_index is a pickup, index_to_pickup_index_pairs_[node_index] is the
2018 // vector of pairs {pair_index, pickup_index} such that
2019 // (pickup_delivery_pairs_[pair_index].first)[pickup_index] == node_index
2020 std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
2021 // Same as above for deliveries.
2022 std::vector<std::vector<std::pair<int, int> > >
2023 index_to_delivery_index_pairs_;
2024 // clang-format on
2025 std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
2026 // Same vehicle group to which a node belongs.
2027 std::vector<int> same_vehicle_group_;
2028 // Same vehicle node groups.
2029 std::vector<std::vector<int>> same_vehicle_groups_;
2030 // Node visit types
2031 // Variable index to visit type index.
2032 std::vector<int> index_to_visit_type_;
2033 // Variable index to VisitTypePolicy.
2034 std::vector<VisitTypePolicy> index_to_type_policy_;
2035 // clang-format off
2036 std::vector<std::vector<int> > single_nodes_of_type_;
2037 std::vector<std::vector<int> > pair_indices_of_type_;
2038
2039 std::vector<absl::flat_hash_set<int> >
2040 hard_incompatible_types_per_type_index_;
2041 bool has_hard_type_incompatibilities_;
2042 std::vector<absl::flat_hash_set<int> >
2043 temporal_incompatible_types_per_type_index_;
2044 bool has_temporal_type_incompatibilities_;
2045
2046 std::vector<std::vector<absl::flat_hash_set<int> > >
2047 same_vehicle_required_type_alternatives_per_type_index_;
2048 bool has_same_vehicle_type_requirements_;
2049 std::vector<std::vector<absl::flat_hash_set<int> > >
2050 required_type_alternatives_when_adding_type_index_;
2051 std::vector<std::vector<absl::flat_hash_set<int> > >
2052 required_type_alternatives_when_removing_type_index_;
2053 bool has_temporal_type_requirements_;
2054 absl::flat_hash_map</*type*/int, absl::flat_hash_set<VisitTypePolicy> >
2055 trivially_infeasible_visit_types_to_policies_;
2056
2057 // Visit types sorted topologically based on required-->dependent requirement
2058 // arcs between the types (if the requirement/dependency graph is acyclic).
2059 // Visit types of the same topological level are sorted in each sub-vector
2060 // by decreasing requirement "tightness", computed as the pair of the two
2061 // following criteria:
2062 //
2063 // 1) How highly *dependent* this type is, determined by
2064 // (total number of required alternative sets for that type)
2065 // / (average number of types in the required alternative sets)
2066 // 2) How highly *required* this type t is, computed as
2067 // SUM_{S required set containing t} ( 1 / |S| ),
2068 // i.e. the sum of reverse number of elements of all required sets
2069 // containing the type t.
2070 //
2071 // The higher these two numbers, the tighter the type is wrt requirements.
2072 std::vector<std::vector<int> > topologically_sorted_visit_types_;
2073 // clang-format on
2074 int num_visit_types_;
2075 // Two indices are equivalent if they correspond to the same node (as given
2076 // to the constructors taking a RoutingIndexManager).
2077 std::vector<int> index_to_equivalence_class_;
2078 std::vector<int> index_to_vehicle_;
2079 std::vector<int64_t> starts_;
2080 std::vector<int64_t> ends_;
2081 // TODO(user): b/62478706 Once the port is done, this shouldn't be needed
2082 // anymore.
2083 RoutingIndexManager manager_;
2084 int start_end_count_;
2085 // Model status
2086 bool closed_ = false;
2087 Status status_ = ROUTING_NOT_SOLVED;
2088 bool enable_deep_serialization_ = true;
2089
2090 // Search data
2091 std::vector<DecisionBuilder*> first_solution_decision_builders_;
2092 std::vector<IntVarFilteredDecisionBuilder*>
2093 first_solution_filtered_decision_builders_;
2094 Solver::IndexEvaluator2 first_solution_evaluator_;
2095 FirstSolutionStrategy::Value automatic_first_solution_strategy_ =
2096 FirstSolutionStrategy::UNSET;
2097 std::vector<LocalSearchOperator*> local_search_operators_;
2098 std::vector<SearchMonitor*> monitors_;
2099 SolutionCollector* collect_assignments_ = nullptr;
2100 SolutionCollector* collect_one_assignment_ = nullptr;
2101 SolutionCollector* packed_dimensions_assignment_collector_ = nullptr;
2102 DecisionBuilder* solve_db_ = nullptr;
2103 DecisionBuilder* improve_db_ = nullptr;
2104 DecisionBuilder* restore_assignment_ = nullptr;
2105 DecisionBuilder* restore_tmp_assignment_ = nullptr;
2106 Assignment* assignment_ = nullptr;
2107 Assignment* preassignment_ = nullptr;
2108 Assignment* tmp_assignment_ = nullptr;
2109 std::vector<IntVar*> extra_vars_;
2110 std::vector<IntervalVar*> extra_intervals_;
2111 std::vector<LocalSearchOperator*> extra_operators_;
2112 absl::flat_hash_map<FilterOptions, LocalSearchFilterManager*>
2113 local_search_filter_managers_;
2114 std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
2115#ifndef SWIG
2116 struct VarTarget {
2117 VarTarget(IntVar* v, int64_t t) : var(v), target(t) {}
2118
2119 IntVar* var;
2120 int64_t target;
2121 };
2122 std::vector<std::pair<VarTarget, int64_t>>
2123 weighted_finalizer_variable_targets_;
2124 std::vector<VarTarget> finalizer_variable_targets_;
2125 absl::flat_hash_map<IntVar*, int> weighted_finalizer_variable_index_;
2126 absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
2127 std::unique_ptr<SweepArranger> sweep_arranger_;
2128#endif
2129
2130 RegularLimit* limit_ = nullptr;
2131 RegularLimit* ls_limit_ = nullptr;
2132 RegularLimit* lns_limit_ = nullptr;
2133 RegularLimit* first_solution_lns_limit_ = nullptr;
2134
2135 typedef std::pair<int64_t, int64_t> CacheKey;
2136 typedef absl::flat_hash_map<CacheKey, int64_t> TransitCallbackCache;
2137 typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
2138 StateDependentTransitCallbackCache;
2139
2140 std::vector<TransitCallback1> unary_transit_evaluators_;
2141 std::vector<TransitCallback2> transit_evaluators_;
2142 // The following vector stores a boolean per transit_evaluator_, indicating
2143 // whether the transits are all positive.
2144 // is_transit_evaluator_positive_ will be set to true only when registering a
2145 // callback via RegisterPositiveTransitCallback(), and to false otherwise.
2146 // The actual positivity of the transit values will only be checked in debug
2147 // mode, when calling RegisterPositiveTransitCallback().
2148 // Therefore, RegisterPositiveTransitCallback() should only be called when the
2149 // transits are known to be positive, as the positivity of a callback will
2150 // allow some improvements in the solver, but will entail in errors if the
2151 // transits are falsely assumed positive.
2152 std::vector<bool> is_transit_evaluator_positive_;
2153 std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
2154 std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
2155 state_dependent_transit_evaluators_cache_;
2156
2157 friend class RoutingDimension;
2158 friend class RoutingModelInspector;
2160
2161 DISALLOW_COPY_AND_ASSIGN(RoutingModel);
2162};
2163
2166 public:
2168 static const char kLightElement[];
2169 static const char kLightElement2[];
2170 static const char kRemoveValues[];
2171};
2172
2173#if !defined(SWIG)
2177 public:
2183 struct Tasks {
2184 int num_chain_tasks = 0;
2185 std::vector<int64_t> start_min;
2186 std::vector<int64_t> start_max;
2187 std::vector<int64_t> duration_min;
2188 std::vector<int64_t> duration_max;
2189 std::vector<int64_t> end_min;
2190 std::vector<int64_t> end_max;
2191 std::vector<bool> is_preemptible;
2192 std::vector<const SortedDisjointIntervalList*> forbidden_intervals;
2193 std::vector<std::pair<int64_t, int64_t>> distance_duration;
2194 int64_t span_min = 0;
2195 int64_t span_max = kint64max;
2196
2197 void Clear() {
2198 start_min.clear();
2199 start_max.clear();
2200 duration_min.clear();
2201 duration_max.clear();
2202 end_min.clear();
2203 end_max.clear();
2204 is_preemptible.clear();
2205 forbidden_intervals.clear();
2206 distance_duration.clear();
2207 span_min = 0;
2208 span_max = kint64max;
2209 num_chain_tasks = 0;
2210 }
2211 };
2212
2215 bool Propagate(Tasks* tasks);
2216
2218 bool Precedences(Tasks* tasks);
2221 bool MirrorTasks(Tasks* tasks);
2223 bool EdgeFinding(Tasks* tasks);
2233 bool ChainSpanMin(Tasks* tasks);
2239
2240 private:
2243 sat::ThetaLambdaTree<int64_t> theta_lambda_tree_;
2245 std::vector<int> tasks_by_start_min_;
2246 std::vector<int> tasks_by_end_max_;
2247 std::vector<int> event_of_task_;
2248 std::vector<int> nonchain_tasks_by_start_max_;
2250 std::vector<int64_t> total_duration_before_;
2251};
2252
2254 std::vector<int64_t> min_travels;
2255 std::vector<int64_t> max_travels;
2256 std::vector<int64_t> pre_travels;
2257 std::vector<int64_t> post_travels;
2258};
2259
2260void AppendTasksFromPath(const std::vector<int64_t>& path,
2261 const TravelBounds& travel_bounds,
2262 const RoutingDimension& dimension,
2264void AppendTasksFromIntervals(const std::vector<IntervalVar*>& intervals,
2266void FillPathEvaluation(const std::vector<int64_t>& path,
2267 const RoutingModel::TransitCallback2& evaluator,
2268 std::vector<int64_t>* values);
2269void FillTravelBoundsOfVehicle(int vehicle, const std::vector<int64_t>& path,
2270 const RoutingDimension& dimension,
2271 TravelBounds* travel_bounds);
2272#endif // !defined(SWIG)
2273
2285 public:
2287 std::string DebugString() const override {
2288 return "GlobalVehicleBreaksConstraint";
2289 }
2290
2291 void Post() override;
2292 void InitialPropagate() override;
2293
2294 private:
2295 void PropagateNode(int node);
2296 void PropagateVehicle(int vehicle);
2297 void PropagateMaxBreakDistance(int vehicle);
2298
2299 const RoutingModel* model_;
2300 const RoutingDimension* const dimension_;
2301 std::vector<Demon*> vehicle_demons_;
2302 std::vector<int64_t> path_;
2303
2308 void FillPartialPathOfVehicle(int vehicle);
2309 void FillPathTravels(const std::vector<int64_t>& path);
2310
2321 class TaskTranslator {
2322 public:
2323 TaskTranslator(IntVar* start, int64_t before_start, int64_t after_start)
2324 : start_(start),
2325 before_start_(before_start),
2326 after_start_(after_start) {}
2327 explicit TaskTranslator(IntervalVar* interval) : interval_(interval) {}
2328 TaskTranslator() {}
2329
2330 void SetStartMin(int64_t value) {
2331 if (start_ != nullptr) {
2332 start_->SetMin(CapAdd(before_start_, value));
2333 } else if (interval_ != nullptr) {
2334 interval_->SetStartMin(value);
2335 }
2336 }
2337 void SetStartMax(int64_t value) {
2338 if (start_ != nullptr) {
2339 start_->SetMax(CapAdd(before_start_, value));
2340 } else if (interval_ != nullptr) {
2341 interval_->SetStartMax(value);
2342 }
2343 }
2344 void SetDurationMin(int64_t value) {
2345 if (interval_ != nullptr) {
2346 interval_->SetDurationMin(value);
2347 }
2348 }
2349 void SetEndMin(int64_t value) {
2350 if (start_ != nullptr) {
2351 start_->SetMin(CapSub(value, after_start_));
2352 } else if (interval_ != nullptr) {
2353 interval_->SetEndMin(value);
2354 }
2355 }
2356 void SetEndMax(int64_t value) {
2357 if (start_ != nullptr) {
2358 start_->SetMax(CapSub(value, after_start_));
2359 } else if (interval_ != nullptr) {
2360 interval_->SetEndMax(value);
2361 }
2362 }
2363
2364 private:
2365 IntVar* start_ = nullptr;
2366 int64_t before_start_;
2367 int64_t after_start_;
2368 IntervalVar* interval_ = nullptr;
2369 };
2370
2372 std::vector<TaskTranslator> task_translators_;
2373
2375 DisjunctivePropagator disjunctive_propagator_;
2376 DisjunctivePropagator::Tasks tasks_;
2377
2379 TravelBounds travel_bounds_;
2380};
2381
2383 public:
2384 explicit TypeRegulationsChecker(const RoutingModel& model);
2386
2387 bool CheckVehicle(int vehicle,
2388 const std::function<int64_t(int64_t)>& next_accessor);
2389
2390 protected:
2391#ifndef SWIG
2393#endif // SWIG
2394
2399 int num_type_added_to_vehicle = 0;
2405 int num_type_removed_from_vehicle = 0;
2410 int position_of_last_type_on_vehicle_up_to_visit = -1;
2411 };
2412
2417 bool TypeOccursOnRoute(int type) const;
2424 bool TypeCurrentlyOnRoute(int type, int pos) const;
2425
2426 void InitializeCheck(int vehicle,
2427 const std::function<int64_t(int64_t)>& next_accessor);
2428 virtual void OnInitializeCheck() {}
2429 virtual bool HasRegulationsToCheck() const = 0;
2430 virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy,
2431 int pos) = 0;
2432 virtual bool FinalizeCheck() const { return true; }
2433
2435
2436 private:
2437 std::vector<TypePolicyOccurrence> occurrences_of_type_;
2438 std::vector<int64_t> current_route_visits_;
2439};
2440
2443 public:
2445 bool check_hard_incompatibilities);
2447
2448 private:
2449 bool HasRegulationsToCheck() const override;
2450 bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2454 bool check_hard_incompatibilities_;
2455};
2456
2459 public:
2461 : TypeRegulationsChecker(model) {}
2463
2464 private:
2465 bool HasRegulationsToCheck() const override;
2466 void OnInitializeCheck() override {
2467 types_with_same_vehicle_requirements_on_route_.clear();
2468 }
2469 // clang-format off
2472 bool CheckRequiredTypesCurrentlyOnRoute(
2473 const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2474 int pos);
2475 // clang-format on
2476 bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos) override;
2477 bool FinalizeCheck() const override;
2478
2479 absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2480};
2481
2523 public:
2525
2526 void Post() override;
2527 void InitialPropagate() override;
2528
2529 private:
2530 void PropagateNodeRegulations(int node);
2531 void CheckRegulationsOnVehicle(int vehicle);
2532
2533 const RoutingModel& model_;
2534 TypeIncompatibilityChecker incompatibility_checker_;
2535 TypeRequirementChecker requirement_checker_;
2536 std::vector<Demon*> vehicle_demons_;
2537};
2538#if !defined SWIG
2552 public:
2553 struct BoundCost {
2554 int64_t bound;
2555 int64_t cost;
2556 };
2557 SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
2558 : bound_costs_(num_bounds, default_bound_cost) {}
2559 BoundCost& bound_cost(int element) { return bound_costs_[element]; }
2560 BoundCost bound_cost(int element) const { return bound_costs_[element]; }
2561 int Size() { return bound_costs_.size(); }
2564
2565 private:
2566 std::vector<BoundCost> bound_costs_;
2567};
2568#endif // !defined SWIG
2569
2587// TODO(user): Break constraints need to know the service time of nodes
2591 public:
2594 RoutingModel* model() const { return model_; }
2598 int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2599 int64_t vehicle) const;
2602 int64_t GetTransitValueFromClass(int64_t from_index, int64_t to_index,
2603 int64_t vehicle_class) const {
2604 return model_->TransitCallback(class_evaluators_[vehicle_class])(from_index,
2605 to_index);
2606 }
2609 IntVar* CumulVar(int64_t index) const { return cumuls_[index]; }
2610 IntVar* TransitVar(int64_t index) const { return transits_[index]; }
2611 IntVar* FixedTransitVar(int64_t index) const {
2612 return fixed_transits_[index];
2613 }
2614 IntVar* SlackVar(int64_t index) const { return slacks_[index]; }
2615
2616#if !defined(SWIGPYTHON)
2619 const std::vector<IntVar*>& cumuls() const { return cumuls_; }
2620 const std::vector<IntVar*>& fixed_transits() const { return fixed_transits_; }
2621 const std::vector<IntVar*>& transits() const { return transits_; }
2622 const std::vector<IntVar*>& slacks() const { return slacks_; }
2623#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2625 const std::vector<SortedDisjointIntervalList>& forbidden_intervals() const {
2626 return forbidden_intervals_;
2627 }
2629 SortedDisjointIntervalList GetAllowedIntervalsInRange(
2630 int64_t index, int64_t min_value, int64_t max_value) const;
2634 int64_t min_value) const {
2635 DCHECK_LT(index, forbidden_intervals_.size());
2636 const SortedDisjointIntervalList& forbidden_intervals =
2637 forbidden_intervals_[index];
2638 const auto first_forbidden_interval_it =
2639 forbidden_intervals.FirstIntervalGreaterOrEqual(min_value);
2640 if (first_forbidden_interval_it != forbidden_intervals.end() &&
2641 min_value >= first_forbidden_interval_it->start) {
2643 return CapAdd(first_forbidden_interval_it->end, 1);
2644 }
2646 return min_value;
2647 }
2653 int64_t max_value) const {
2654 DCHECK_LT(index, forbidden_intervals_.size());
2655 const SortedDisjointIntervalList& forbidden_intervals =
2656 forbidden_intervals_[index];
2657 const auto last_forbidden_interval_it =
2658 forbidden_intervals.LastIntervalLessOrEqual(max_value);
2659 if (last_forbidden_interval_it != forbidden_intervals.end() &&
2660 max_value <= last_forbidden_interval_it->end) {
2662 return CapSub(last_forbidden_interval_it->start, 1);
2663 }
2665 return max_value;
2666 }
2668 const std::vector<int64_t>& vehicle_capacities() const {
2669 return vehicle_capacities_;
2670 }
2674 return model_->TransitCallback(
2675 class_evaluators_[vehicle_to_class_[vehicle]]);
2676 }
2677
2681 RoutingVehicleClassIndex vehicle_class) const {
2682 const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2683 DCHECK_NE(vehicle, -1);
2684 return transit_evaluator(vehicle);
2685 }
2686
2691 int vehicle) const {
2692 return model_->UnaryTransitCallbackOrNull(
2693 class_evaluators_[vehicle_to_class_[vehicle]]);
2694 }
2697 bool AreVehicleTransitsPositive(int vehicle) const {
2698 return model()->is_transit_evaluator_positive_
2699 [class_evaluators_[vehicle_to_class_[vehicle]]];
2700 }
2701 int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; }
2702#endif
2703#endif
2707 void SetSpanUpperBoundForVehicle(int64_t upper_bound, int vehicle);
2714 void SetSpanCostCoefficientForVehicle(int64_t coefficient, int vehicle);
2715 void SetSpanCostCoefficientForAllVehicles(int64_t coefficient);
2722 void SetGlobalSpanCostCoefficient(int64_t coefficient);
2723
2724#ifndef SWIG
2730 const PiecewiseLinearFunction& cost);
2733 bool HasCumulVarPiecewiseLinearCost(int64_t index) const;
2736 const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost(
2737 int64_t index) const;
2738#endif
2739
2748 void SetCumulVarSoftUpperBound(int64_t index, int64_t upper_bound,
2749 int64_t coefficient);
2752 bool HasCumulVarSoftUpperBound(int64_t index) const;
2756 int64_t GetCumulVarSoftUpperBound(int64_t index) const;
2760 int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t index) const;
2761
2771 void SetCumulVarSoftLowerBound(int64_t index, int64_t lower_bound,
2772 int64_t coefficient);
2775 bool HasCumulVarSoftLowerBound(int64_t index) const;
2779 int64_t GetCumulVarSoftLowerBound(int64_t index) const;
2783 int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t index) const;
2799 // TODO(user): Remove if !defined when routing.i is repaired.
2800#if !defined(SWIGPYTHON)
2801 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2802 int pre_travel_evaluator,
2803 int post_travel_evaluator);
2804#endif // !defined(SWIGPYTHON)
2805
2807 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks, int vehicle,
2808 std::vector<int64_t> node_visit_transits);
2809
2814 void SetBreakDistanceDurationOfVehicle(int64_t distance, int64_t duration,
2815 int vehicle);
2821#if !defined(SWIGPYTHON)
2825 std::vector<IntervalVar*> breaks, int vehicle,
2826 std::vector<int64_t> node_visit_transits,
2827 std::function<int64_t(int64_t, int64_t)> delays);
2828
2830 const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2831 int vehicle) const;
2834 // clang-format off
2835 const std::vector<std::pair<int64_t, int64_t> >&
2837 // clang-format on
2838#endif
2839 int GetPreTravelEvaluatorOfVehicle(int vehicle) const;
2840 int GetPostTravelEvaluatorOfVehicle(int vehicle) const;
2841
2843 const RoutingDimension* base_dimension() const { return base_dimension_; }
2851 int64_t ShortestTransitionSlack(int64_t node) const;
2852
2854 const std::string& name() const { return name_; }
2855
2857#ifndef SWIG
2858 const ReverseArcListGraph<int, int>& GetPathPrecedenceGraph() const {
2859 return path_precedence_graph_;
2860 }
2861#endif // SWIG
2862
2872 typedef std::function<int64_t(int, int)> PickupToDeliveryLimitFunction;
2873
2875 PickupToDeliveryLimitFunction limit_function, int pair_index);
2876
2878#ifndef SWIG
2879 int64_t GetPickupToDeliveryLimitForPair(int pair_index, int pickup,
2880 int delivery) const;
2881
2883 int64_t first_node;
2885 int64_t offset;
2886 };
2887
2889 node_precedences_.push_back(precedence);
2890 }
2891 const std::vector<NodePrecedence>& GetNodePrecedences() const {
2892 return node_precedences_;
2893 }
2894#endif // SWIG
2895
2896 void AddNodePrecedence(int64_t first_node, int64_t second_node,
2897 int64_t offset) {
2898 AddNodePrecedence({first_node, second_node, offset});
2899 }
2900
2901 int64_t GetSpanUpperBoundForVehicle(int vehicle) const {
2902 return vehicle_span_upper_bounds_[vehicle];
2903 }
2904#ifndef SWIG
2905 const std::vector<int64_t>& vehicle_span_upper_bounds() const {
2906 return vehicle_span_upper_bounds_;
2907 }
2908#endif // SWIG
2909 int64_t GetSpanCostCoefficientForVehicle(int vehicle) const {
2910 return vehicle_span_cost_coefficients_[vehicle];
2911 }
2912#ifndef SWIG
2914 RoutingVehicleClassIndex vehicle_class) const {
2915 const int vehicle = model_->GetVehicleOfClass(vehicle_class);
2916 DCHECK_NE(vehicle, -1);
2917 return GetSpanCostCoefficientForVehicle(vehicle);
2918 }
2919#endif // SWIG
2920#ifndef SWIG
2921 const std::vector<int64_t>& vehicle_span_cost_coefficients() const {
2922 return vehicle_span_cost_coefficients_;
2923 }
2924#endif // SWIG
2926 return global_span_cost_coefficient_;
2927 }
2928
2930 DCHECK_GE(global_optimizer_offset_, 0);
2931 return global_optimizer_offset_;
2932 }
2933 int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const {
2934 if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2935 return 0;
2936 }
2937 DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2938 return local_optimizer_offset_for_vehicle_[vehicle];
2939 }
2940#if !defined SWIG
2944 int vehicle) {
2945 if (!HasSoftSpanUpperBounds()) {
2946 vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2947 model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2948 }
2949 vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2950 }
2952 return vehicle_soft_span_upper_bound_ != nullptr;
2953 }
2955 int vehicle) const {
2956 DCHECK(HasSoftSpanUpperBounds());
2957 return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2958 }
2962 SimpleBoundCosts::BoundCost bound_cost, int vehicle) {
2963 if (!HasQuadraticCostSoftSpanUpperBounds()) {
2964 vehicle_quadratic_cost_soft_span_upper_bound_ =
2965 absl::make_unique<SimpleBoundCosts>(
2966 model_->vehicles(), SimpleBoundCosts::BoundCost{kint64max, 0});
2967 }
2968 vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2969 bound_cost;
2970 }
2972 return vehicle_quadratic_cost_soft_span_upper_bound_ != nullptr;
2973 }
2975 int vehicle) const {
2976 DCHECK(HasQuadraticCostSoftSpanUpperBounds());
2977 return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2978 }
2979#endif
2980
2981 private:
2982 struct SoftBound {
2983 IntVar* var;
2984 int64_t bound;
2985 int64_t coefficient;
2986 };
2987
2988 struct PiecewiseLinearCost {
2989 PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2990 IntVar* var;
2991 std::unique_ptr<PiecewiseLinearFunction> cost;
2992 };
2993
2994 class SelfBased {};
2995 RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2996 const std::string& name,
2997 const RoutingDimension* base_dimension);
2998 RoutingDimension(RoutingModel* model, std::vector<int64_t> vehicle_capacities,
2999 const std::string& name, SelfBased);
3000 void Initialize(const std::vector<int>& transit_evaluators,
3001 const std::vector<int>& state_dependent_transit_evaluators,
3002 int64_t slack_max);
3003 void InitializeCumuls();
3004 void InitializeTransits(
3005 const std::vector<int>& transit_evaluators,
3006 const std::vector<int>& state_dependent_transit_evaluators,
3007 int64_t slack_max);
3008 void InitializeTransitVariables(int64_t slack_max);
3010 void SetupCumulVarSoftUpperBoundCosts(
3011 std::vector<IntVar*>* cost_elements) const;
3013 void SetupCumulVarSoftLowerBoundCosts(
3014 std::vector<IntVar*>* cost_elements) const;
3015 void SetupCumulVarPiecewiseLinearCosts(
3016 std::vector<IntVar*>* cost_elements) const;
3019 void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements) const;
3020 void SetupSlackAndDependentTransitCosts() const;
3022 void CloseModel(bool use_light_propagation);
3023
3024 void SetOffsetForGlobalOptimizer(int64_t offset) {
3025 global_optimizer_offset_ = std::max(Zero(), offset);
3026 }
3028 void SetVehicleOffsetsForLocalOptimizer(std::vector<int64_t> offsets) {
3030 std::transform(offsets.begin(), offsets.end(), offsets.begin(),
3031 [](int64_t offset) { return std::max(Zero(), offset); });
3032 local_optimizer_offset_for_vehicle_ = std::move(offsets);
3033 }
3034
3035 std::vector<IntVar*> cumuls_;
3036 std::vector<SortedDisjointIntervalList> forbidden_intervals_;
3037 std::vector<IntVar*> capacity_vars_;
3038 const std::vector<int64_t> vehicle_capacities_;
3039 std::vector<IntVar*> transits_;
3040 std::vector<IntVar*> fixed_transits_;
3043 std::vector<int> class_evaluators_;
3044 std::vector<int64_t> vehicle_to_class_;
3045#ifndef SWIG
3046 ReverseArcListGraph<int, int> path_precedence_graph_;
3047#endif
3048 // For every {first_node, second_node, offset} element in node_precedences_,
3049 // if both first_node and second_node are performed, then
3050 // cumuls_[second_node] must be greater than (or equal to)
3051 // cumuls_[first_node] + offset.
3052 std::vector<NodePrecedence> node_precedences_;
3053
3054 // The transits of a dimension may depend on its cumuls or the cumuls of
3055 // another dimension. There can be no cycles, except for self loops, a
3056 // typical example for this is a time dimension.
3057 const RoutingDimension* const base_dimension_;
3058
3059 // Values in state_dependent_class_evaluators_ correspond to the evaluators
3060 // in RoutingModel::state_dependent_transit_evaluators_ for each vehicle
3061 // class.
3062 std::vector<int> state_dependent_class_evaluators_;
3063 std::vector<int64_t> state_dependent_vehicle_to_class_;
3064
3065 // For each pickup/delivery pair_index for which limits have been set,
3066 // pickup_to_delivery_limits_per_pair_index_[pair_index] contains the
3067 // PickupToDeliveryLimitFunction for the pickup and deliveries in this pair.
3068 std::vector<PickupToDeliveryLimitFunction>
3069 pickup_to_delivery_limits_per_pair_index_;
3070
3071 // Used if some vehicle has breaks in this dimension, typically time.
3072 bool break_constraints_are_initialized_ = false;
3073 // clang-format off
3074 std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
3075 std::vector<std::vector<std::pair<int64_t, int64_t> > >
3076 vehicle_break_distance_duration_;
3077 // clang-format on
3078 // For each vehicle, stores the part of travel that is made directly
3079 // after (before) the departure (arrival) node of the travel.
3080 // These parts of the travel are non-interruptible, in particular by a break.
3081 std::vector<int> vehicle_pre_travel_evaluators_;
3082 std::vector<int> vehicle_post_travel_evaluators_;
3083
3084 std::vector<IntVar*> slacks_;
3085 std::vector<IntVar*> dependent_transits_;
3086 std::vector<int64_t> vehicle_span_upper_bounds_;
3087 int64_t global_span_cost_coefficient_;
3088 std::vector<int64_t> vehicle_span_cost_coefficients_;
3089 std::vector<SoftBound> cumul_var_soft_upper_bound_;
3090 std::vector<SoftBound> cumul_var_soft_lower_bound_;
3091 std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
3092 RoutingModel* const model_;
3093 const std::string name_;
3094 int64_t global_optimizer_offset_;
3095 std::vector<int64_t> local_optimizer_offset_for_vehicle_;
3097 std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
3098 std::unique_ptr<SimpleBoundCosts>
3099 vehicle_quadratic_cost_soft_span_upper_bound_;
3100 friend class RoutingModel;
3101 friend class RoutingModelInspector;
3103 const std::vector<RoutingDimension*>& dimensions,
3104 const RoutingSearchParameters& parameters, bool filter_objective_cost,
3105 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3106
3107 DISALLOW_COPY_AND_ASSIGN(RoutingDimension);
3108};
3109
3113 std::vector<IntVar*> variables,
3114 std::vector<int64_t> targets);
3115
3121 const RoutingSearchParameters& search_parameters,
3122 const Assignment* initial_solution,
3123 Assignment* solution);
3124
3125#if !defined(SWIG)
3127 const RoutingModel& routing_model, const RoutingDimension& dimension);
3128
3129// A decision builder that monitors solutions, and tries to fix dimension
3130// variables whose route did not change in the candidate solution.
3131// Dimension variables are Cumul, Slack and break variables of all dimensions.
3132// The user must make sure that those variables will be always be fixed at
3133// solution, typically by composing another DecisionBuilder after this one.
3134// If this DecisionBuilder returns a non-nullptr value at some node of the
3135// search tree, it will always return nullptr in the subtree of that node.
3136// Moreover, the decision will be a simultaneous assignment of the dimension
3137// variables of unchanged routes on the left branch, and an empty decision on
3138// the right branch.
3140 RoutingModel* model);
3141#endif
3142
3143} // namespace operations_research
3144#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:2176
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:2284
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:2287
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:2590
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:2961
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2954
const std::vector< IntVar * > & transits() const
Definition: routing.h:2621
IntVar * TransitVar(int64_t index) const
Definition: routing.h:2610
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:2905
const std::string & name() const
Returns the name of the dimension.
Definition: routing.h:2854
int64_t GetSpanCostCoefficientForVehicleClass(RoutingVehicleClassIndex vehicle_class) const
Definition: routing.h:2913
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Definition: routing.h:2619
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:2943
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
Definition: routing.h:2668
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:2929
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:2609
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:2614
int64_t GetSpanCostCoefficientForVehicle(int vehicle) const
Definition: routing.h:2909
int64_t global_span_cost_coefficient() const
Definition: routing.h:2925
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:2673
const std::vector< IntVar * > & slacks() const
Definition: routing.h:2622
int64_t GetSpanUpperBoundForVehicle(int vehicle) const
Definition: routing.h:2901
const std::vector< int64_t > & vehicle_span_cost_coefficients() const
Definition: routing.h:2921
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
Definition: routing.h:2697
void AddNodePrecedence(int64_t first_node, int64_t second_node, int64_t offset)
Definition: routing.h:2896
IntVar * FixedTransitVar(int64_t index) const
Definition: routing.h:2611
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:2872
void AddNodePrecedence(NodePrecedence precedence)
Definition: routing.h:2888
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:2633
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:2690
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:2971
RoutingModel * model() const
Returns the model on which the dimension was created.
Definition: routing.h:2594
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
const std::vector< NodePrecedence > & GetNodePrecedences() const
Definition: routing.h:2891
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
Definition: routing.h:2625
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
Definition: routing.h:2858
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:2680
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
int vehicle_to_class(int vehicle) const
Definition: routing.h:2701
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:2602
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:2652
int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const
Definition: routing.h:2933
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:2620
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
Definition: routing.h:2843
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:2974
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:419
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:398
const std::vector< int > & GetVehiclesRequiringAResource() const
Definition: routing.h:450
bool VehicleRequiresAResource(int vehicle) const
Definition: routing.h:454
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:459
const std::vector< Resource > & GetResources() const
Definition: routing.h:458
ResourceGroup(const RoutingModel *model)
Definition: routing.h:438
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
Definition: routing.h:463
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:1102
Solver * solver() const
Returns the underlying constraint solver.
Definition: routing.h:1511
const TransitCallback2 & TransitCallback(int callback_index) const
Definition: routing.h:509
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:1552
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:1527
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:606
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const
Definition: routing.h:1442
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:1386
ResourceGroup * GetResourceGroup(int rg_index) const
Definition: routing.h:724
const std::vector< SearchMonitor * > & GetSearchMonitors() const
Definition: routing.h:1582
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:770
RoutingIndexPair IndexPair
Definition: routing.h:246
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:241
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:1356
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:883
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:1094
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:887
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:1462
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:676
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:1514
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
Definition: routing.h:894
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
int GetDimensionResourceGroupIndex(const RoutingDimension *dimension) const
Returns the index of the resource group attached to the dimension.
Definition: routing.h:737
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:1382
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:910
@ TYPE_ADDED_TO_VEHICLE
When visited, the number of types 'T' on the vehicle increases by one.
Definition: routing.h:912
@ ADDED_TYPE_REMOVED_FROM_VEHICLE
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
Definition: routing.h:917
@ 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:920
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
void AddWeightedVariableTargetToFinalizer(IntVar *var, int64_t target, int64_t cost)
Same as above with a weighted priority: the higher the cost, the more priority it has to be set close...
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:1404
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:1322
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:1531
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:668
bool HasTemporalTypeRequirements() const
Definition: routing.h:1007
IntVar * NextVar(int64_t index) const
!defined(SWIGPYTHON)
Definition: routing.h:1366
static const int64_t kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
Definition: routing.h:480
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:242
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:1371
int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
Definition: routing.h:794
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_INFEASIBLE
Problem proven to be infeasible.
Definition: routing.h:225
@ 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:1429
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 AddWeightedVariableMaximizedByFinalizer(IntVar *var, int64_t cost)
Adds a variable to maximize in the solution finalizer, with a weighted priority: the higher the more ...
void SetSweepArranger(SweepArranger *sweep_arranger)
void AddTemporalTypeIncompatibility(int type1, int type2)
const std::vector< int > & GetSingleNodesOfType(int type) const
RoutingIndexPairs IndexPairs
Definition: routing.h:247
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:513
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:831
const VehicleTypeContainer & GetVehicleTypeContainer() const
Definition: routing.h:1469
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:1038
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:1360
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
Definition: routing.h:940
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
Definition: routing.h:655
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:517
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:1353
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64_t index) const
Returns the indices of the disjunctions to which an index belongs.
Definition: routing.h:762
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:1081
int AddResourceGroup()
Adds a resource group to the routing model.
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
Definition: routing.h:1042
RoutingDimensionIndex DimensionIndex
Definition: routing.h:238
void SetVehicleUsedWhenEmpty(bool is_used, int vehicle)
Definition: routing.h:1089
Assignment * MutablePreAssignment()
Definition: routing.h:1221
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
Definition: routing.h:672
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:569
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
Definition: routing.h:959
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:229
@ PICKUP_AND_DELIVERY_LIFO
Deliveries must be performed in reverse order of pickups.
Definition: routing.h:233
@ PICKUP_AND_DELIVERY_NO_ORDER
Any precedence is accepted.
Definition: routing.h:231
@ PICKUP_AND_DELIVERY_FIFO
Deliveries must be performed in the same order as pickups.
Definition: routing.h:235
int64_t Start(int vehicle) const
Model inspection.
Definition: routing.h:1333
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:1529
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
Definition: routing.h:798
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:1368
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:1013
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
Definition: routing.h:1107
RoutingVehicleClassIndex VehicleClassIndex
Definition: routing.h:240
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:268
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
Definition: routing.h:1439
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:1392
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
Definition: routing.h:1004
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:705
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:1339
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:237
bool HasTemporalTypeIncompatibilities() const
Definition: routing.h:962
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:1437
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
Definition: routing.h:1084
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:1541
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Definition: routing.h:1520
Status status() const
Returns the current status of the routing model.
Definition: routing.h:1196
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
Definition: routing.h:1464
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:488
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
Definition: routing.h:1399
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
Definition: routing.h:719
CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const
Get the cost class index of the given vehicle.
Definition: routing.h:1420
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:1342
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:664
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:1448
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:484
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
Definition: routing.h:710
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:1377
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:239
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1335
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:1220
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:783
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:2551
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
Definition: routing.h:2557
BoundCost & bound_cost(int element)
Definition: routing.h:2559
BoundCost bound_cost(int element) const
Definition: routing.h:2560
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:2442
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:2522
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:2458
TypeRequirementChecker(const RoutingModel &model)
Definition: routing.h:2460
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:2183
std::vector< std::pair< int64_t, int64_t > > distance_duration
Definition: routing.h:2193
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
Definition: routing.h:2192
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
Definition: routing.h:296
bool operator<(const DimensionCost &cost) const
Definition: routing.h:300
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
Definition: routing.h:274
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
Definition: routing.h:314
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
Definition: routing.h:308
What follows is relevant for models with time/state dependent transits.
Definition: routing.h:263
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
Definition: routing.h:265
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
Definition: routing.h:327
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
Definition: routing.h:343
std::vector< int > required_resource_group_indices
Sorted set of resource groups for which the vehicle requires a resource.
Definition: routing.h:351
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
Definition: routing.h:349
bool used_when_empty
Whether or not the vehicle is used when empty.
Definition: routing.h:329
int start_equivalence_class
Vehicle start and end equivalence classes.
Definition: routing.h:336
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:344
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_min
Definition: routing.h:342
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:347
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
Definition: routing.h:340
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_max
Definition: routing.h:341
CostClassIndex cost_class_index
The cost class of the vehicle.
Definition: routing.h:325
Definition: routing.h:362
int64_t fixed_cost
Definition: routing.h:364
bool operator<(const VehicleClassEntry &other) const
Definition: routing.h:366
int vehicle_class
Definition: routing.h:363
Struct used to sort and store vehicles by their type.
Definition: routing.h:361
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
Definition: routing.h:381
std::vector< std::deque< int > > vehicles_per_vehicle_class
Definition: routing.h:382
std::vector< int64_t > post_travels
Definition: routing.h:2257
std::vector< int64_t > max_travels
Definition: routing.h:2255
std::vector< int64_t > pre_travels
Definition: routing.h:2256
std::vector< int64_t > min_travels
Definition: routing.h:2254