157#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
158#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
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"
196class GlobalDimensionCumulOptimizer;
197class LocalDimensionCumulOptimizer;
198class LocalSearchPhaseParameters;
200class IndexNeighborFinder;
201class IntVarFilteredDecisionBuilder;
203class RoutingDimension;
304 std::vector<DimensionCost>
312 if (
a.evaluator_index !=
b.evaluator_index) {
313 return a.evaluator_index <
b.evaluator_index;
315 return a.dimension_transit_evaluator_class_and_cost_coefficient <
316 b.dimension_transit_evaluator_class_and_cost_coefficient;
419 void SetDimensionAttributes(
Attributes attributes,
421 const Attributes& GetDefaultAttributes()
const;
424 absl::flat_hash_map<DimensionIndex, Attributes> dimension_attributes_;
435 const std::vector<Resource>&
GetResources()
const {
return resources_; }
438 return affected_dimension_indices_;
440 int Size()
const {
return resources_.size(); }
444 std::vector<Resource> resources_;
446 absl::flat_hash_set<DimensionIndex> affected_dimension_indices_;
475 std::vector<std::vector<int64_t> > values);
481 CHECK_LT(callback_index, transit_evaluators_.size());
482 return transit_evaluators_[callback_index];
485 CHECK_LT(callback_index, unary_transit_evaluators_.size());
486 return unary_transit_evaluators_[callback_index];
489 int callback_index)
const {
490 CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
491 return state_dependent_transit_evaluators_[callback_index];
517 bool fix_start_cumul_to_zero,
const std::string&
name);
519 const std::vector<int>& evaluator_indices, int64_t slack_max,
520 int64_t
capacity,
bool fix_start_cumul_to_zero,
const std::string&
name);
522 std::vector<int64_t> vehicle_capacities,
523 bool fix_start_cumul_to_zero,
524 const std::string&
name);
526 const std::vector<int>& evaluator_indices, int64_t slack_max,
527 std::vector<int64_t> vehicle_capacities,
bool fix_start_cumul_to_zero,
528 const std::string&
name);
539 bool fix_start_cumul_to_zero,
const std::string&
name);
541 bool fix_start_cumul_to_zero,
542 const std::string&
name) {
544 fix_start_cumul_to_zero,
name);
557 bool fix_start_cumul_to_zero,
558 const std::string&
name);
569 std::vector<std::vector<int64_t> > values,
570 int64_t
capacity,
bool fix_start_cumul_to_zero,
const std::string&
name);
578 const std::vector<int>& pure_transits,
579 const std::vector<int>& dependent_transits,
581 std::vector<int64_t> vehicle_capacities,
bool fix_start_cumul_to_zero,
582 const std::string&
name) {
583 return AddDimensionDependentDimensionWithVehicleCapacityInternal(
584 pure_transits, dependent_transits, base_dimension, slack_max,
585 std::move(vehicle_capacities), fix_start_cumul_to_zero,
name);
591 int64_t slack_max, std::vector<int64_t> vehicle_capacities,
592 bool fix_start_cumul_to_zero,
const std::string&
name);
596 int64_t vehicle_capacity,
bool fix_start_cumul_to_zero,
597 const std::string&
name);
599 int pure_transit,
int dependent_transit,
601 int64_t vehicle_capacity,
bool fix_start_cumul_to_zero,
602 const std::string&
name);
606 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
619 std::vector<IntVar*> spans,
620 std::vector<IntVar*> total_slacks);
627 return dimensions_.get();
634 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
636 return global_dimension_optimizers_;
638 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
640 return global_dimension_mp_optimizers_;
642 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
644 return local_dimension_optimizers_;
646 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
648 return local_dimension_mp_optimizers_;
664 bool HasDimension(
const std::string& dimension_name)
const;
667 const std::string& dimension_name)
const;
671 const std::string& dimension_name)
const;
678 primary_constrained_dimension_ = dimension_name;
682 return primary_constrained_dimension_;
690 return resource_groups_;
717 int64_t max_cardinality = 1);
720 int64_t
index)
const {
721 return index_to_disjunctions_[
index];
726 template <
typename F>
728 int64_t
index, int64_t max_cardinality, F f)
const {
730 if (disjunctions_[disjunction].
value.max_cardinality == max_cardinality) {
731 for (
const int64_t d_index : disjunctions_[disjunction].indices) {
737#if !defined(SWIGPYTHON)
742 return disjunctions_[
index].indices;
746 int64_t GetDisjunctionPenalty(DisjunctionIndex index) const {
747 return disjunctions_[
index].value.penalty;
752 return disjunctions_[
index].value.max_cardinality;
760 std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions()
const;
766 void IgnoreDisjunctionsAlreadyForcedToZero();
771 void AddSoftSameVehicleConstraint(
const std::vector<int64_t>& indices,
778 void SetAllowedVehiclesForIndex(
const std::vector<int>& vehicles,
783 return allowed_vehicles_[
index].empty() ||
784 allowed_vehicles_[
index].find(vehicle) !=
785 allowed_vehicles_[
index].end();
803 void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
807 void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
808 DisjunctionIndex delivery_disjunction);
813 const std::vector<std::pair<int, int> >&
814 GetPickupIndexPairs(int64_t node_index)
const;
816 const std::vector<std::pair<int, int> >&
817 GetDeliveryIndexPairs(int64_t node_index)
const;
822 void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy);
823 void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy,
825 PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(
830 int GetNumOfSingletonNodes()
const;
835 return pickup_delivery_pairs_;
837 const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
839 return pickup_delivery_disjunctions_;
847 return implicit_pickup_delivery_pairs_without_alternatives_;
861 enum VisitTypePolicy {
876 TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
879 void SetVisitType(int64_t
index,
int type, VisitTypePolicy type_policy);
880 int GetVisitType(int64_t
index)
const;
881 const std::vector<int>& GetSingleNodesOfType(
int type)
const;
882 const std::vector<int>& GetPairIndicesOfType(
int type)
const;
883 VisitTypePolicy GetVisitTypePolicy(int64_t
index)
const;
888 void CloseVisitTypes();
894 return topologically_sorted_visit_types_;
901 void AddHardTypeIncompatibility(int type1, int type2);
902 void AddTemporalTypeIncompatibility(
int type1,
int type2);
904 const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
906 const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
911 return has_hard_type_incompatibilities_;
914 return has_temporal_type_incompatibilities_;
926 void AddSameVehicleRequiredTypeAlternatives(
927 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
932 void AddRequiredTypeAlternativesWhenAddingType(
933 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
939 void AddRequiredTypeAlternativesWhenRemovingType(
940 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
944 const std::vector<absl::flat_hash_set<int> >&
945 GetSameVehicleRequiredTypeAlternativesOfType(
int type)
const;
947 const std::vector<absl::flat_hash_set<int> >&
948 GetRequiredTypeAlternativesWhenAddingType(
int type)
const;
950 const std::vector<absl::flat_hash_set<int> >&
951 GetRequiredTypeAlternativesWhenRemovingType(
int type)
const;
956 return has_same_vehicle_type_requirements_;
959 return has_temporal_type_requirements_;
965 return HasTemporalTypeIncompatibilities() ||
966 HasHardTypeIncompatibilities() || HasSameVehicleTypeRequirements() ||
967 HasTemporalTypeRequirements();
974 int64_t UnperformedPenalty(int64_t var_index)
const;
978 int64_t UnperformedPenaltyOrValue(int64_t default_value,
979 int64_t var_index)
const;
983 int64_t GetDepot()
const;
990 max_active_vehicles_ = max_active_vehicles;
997 void SetArcCostEvaluatorOfAllVehicles(
int evaluator_index);
999 void SetArcCostEvaluatorOfVehicle(
int evaluator_index,
int vehicle);
1002 void SetFixedCostOfAllVehicles(int64_t
cost);
1004 void SetFixedCostOfVehicle(int64_t
cost,
int vehicle);
1008 int64_t GetFixedCostOfVehicle(
int vehicle)
const;
1025 void SetAmortizedCostFactorsOfAllVehicles(int64_t linear_cost_factor,
1026 int64_t quadratic_cost_factor);
1028 void SetAmortizedCostFactorsOfVehicle(int64_t linear_cost_factor,
1029 int64_t quadratic_cost_factor,
1033 return linear_cost_factor_of_vehicle_;
1037 return quadratic_cost_factor_of_vehicle_;
1042 consider_empty_route_costs_[vehicle] = consider_costs;
1047 return consider_empty_route_costs_[vehicle];
1054 return first_solution_evaluator_;
1059 first_solution_evaluator_ = std::move(evaluator);
1069 void AddAtSolutionCallback(std::function<
void()>
callback);
1074 void AddVariableMinimizedByFinalizer(
IntVar*
var);
1077 void AddVariableMaximizedByFinalizer(
IntVar*
var);
1080 void AddWeightedVariableMinimizedByFinalizer(
IntVar*
var, int64_t
cost);
1083 void AddVariableTargetToFinalizer(
IntVar*
var, int64_t target);
1093 void CloseModelWithParameters(
1111 std::vector<const Assignment*>* solutions =
nullptr);
1114 const Assignment* SolveFromAssignmentWithParameters(
1117 std::vector<const Assignment*>* solutions =
nullptr);
1120 const Assignment* SolveFromAssignmentsWithParameters(
1121 const std::vector<const Assignment*>& assignments,
1123 std::vector<const Assignment*>* solutions =
nullptr);
1129 void SetAssignmentFromOtherModelAssignment(
1138 int64_t ComputeLowerBound();
1149 IntVar* ApplyLocks(
const std::vector<int64_t>& locks);
1158 bool ApplyLocksToAllVehicles(
const std::vector<std::vector<int64_t>>& locks,
1169 bool WriteAssignment(
const std::string& file_name)
const;
1173 Assignment* ReadAssignment(
const std::string& file_name);
1183 const std::vector<std::vector<int64_t>>& routes,
1184 bool ignore_inactive_indices);
1201 bool RoutesToAssignment(
const std::vector<std::vector<int64_t>>& routes,
1202 bool ignore_inactive_indices,
bool close_routes,
1207 void AssignmentToRoutes(
1209 std::vector<std::vector<int64_t>>*
const routes)
const;
1215 std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1241 void AddToAssignment(
IntVar*
const var);
1253 const Assignment* PackCumulsOfOptimizerDimensionsFromAssignment(
1254 const Assignment* original_assignment, absl::Duration duration_limit);
1267 CHECK(filter !=
nullptr);
1269 LOG(
WARNING) <<
"Model is closed, filter addition will be ignored.";
1271 extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1272 extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
1277 int64_t
Start(
int vehicle)
const {
return starts_[vehicle]; }
1279 int64_t
End(
int vehicle)
const {
return ends_[vehicle]; }
1281 bool IsStart(int64_t
index)
const;
1292 bool IsVehicleUsed(
const Assignment& assignment,
int vehicle)
const;
1294#if !defined(SWIGPYTHON)
1297 const std::vector<IntVar*>&
Nexts()
const {
return nexts_; }
1300 const std::vector<IntVar*>&
VehicleVars()
const {
return vehicle_vars_; }
1310 return vehicle_active_[vehicle];
1315 return vehicle_costs_considered_[vehicle];
1325 int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1326 int64_t vehicle)
const;
1329 return costs_are_homogeneous_across_vehicles_;
1334 return GetArcCostForVehicle(from_index, to_index, 0);
1338 int64_t GetArcCostForFirstSolution(int64_t from_index,
1339 int64_t to_index)
const;
1346 int64_t GetArcCostForClass(int64_t from_index, int64_t to_index,
1347 int64_t cost_class_index)
const;
1352 DCHECK_LT(vehicle, cost_class_index_of_vehicle_.size());
1353 DCHECK_GE(cost_class_index_of_vehicle_[vehicle], 0);
1354 return cost_class_index_of_vehicle_[vehicle];
1360 if (cost_class_index == kCostClassIndexOfZeroCost) {
1361 return has_vehicle_with_zero_cost_class_;
1363 return cost_class_index < cost_classes_.size();
1369 return std::max(0, GetCostClassesCount() - 1);
1373 return vehicle_class_index_of_vehicle_[vehicle];
1380 GetVehicleTypeContainer();
1386 return vehicle_type_container
1395 return same_vehicle_groups_[same_vehicle_group_[node]];
1400 return vehicle_type_container_;
1421 bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1426 std::string DebugOutputAssignment(
1428 const std::string& dimension_to_print)
const;
1435 std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1451 return limit_->AbsoluteSolverDeadline() - solver_->Now();
1460 int64_t
Size()
const {
return nodes_ + vehicles_ - start_end_count_; }
1464 int64_t GetNumberOfDecisionsInFirstSolution(
1466 int64_t GetNumberOfRejectsInFirstSolution(
1471 return automatic_first_solution_strategy_;
1475 bool IsMatchingModel()
const;
1481 std::function<std::vector<operations_research::IntVar*>(
RoutingModel*)>;
1501 std::function<int64_t(int64_t)> initializer);
1508 static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1509 std::vector<IntVar*> variables);
1529 enum RoutingLocalSearchOperator {
1532 LIGHT_RELOCATE_PAIR,
1540 GLOBAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1541 LOCAL_CHEAPEST_INSERTION_CLOSE_NODES_LNS,
1542 GLOBAL_CHEAPEST_INSERTION_PATH_LNS,
1543 LOCAL_CHEAPEST_INSERTION_PATH_LNS,
1544 RELOCATE_PATH_GLOBAL_CHEAPEST_INSERTION_INSERT_UNPERFORMED,
1545 GLOBAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1546 LOCAL_CHEAPEST_INSERTION_EXPENSIVE_CHAIN_LNS,
1547 RELOCATE_EXPENSIVE_CHAIN,
1551 RELOCATE_AND_MAKE_ACTIVE,
1552 MAKE_ACTIVE_AND_RELOCATE,
1554 MAKE_CHAIN_INACTIVE,
1556 EXTENDED_SWAP_ACTIVE,
1562 EXCHANGE_RELOCATE_PAIR,
1565 LOCAL_SEARCH_OPERATOR_COUNTER
1571 template <
typename T>
1572 struct ValuedNodes {
1573 std::vector<int64_t> indices;
1576 struct DisjunctionValues {
1578 int64_t max_cardinality;
1580 typedef ValuedNodes<DisjunctionValues> Disjunction;
1584 struct CostCacheElement {
1591 CostClassIndex cost_class_index;
1597 void AddNoCycleConstraintInternal();
1598 bool AddDimensionWithCapacityInternal(
1599 const std::vector<int>& evaluator_indices, int64_t slack_max,
1600 std::vector<int64_t> vehicle_capacities,
bool fix_start_cumul_to_zero,
1601 const std::string&
name);
1602 bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1603 const std::vector<int>& pure_transits,
1604 const std::vector<int>& dependent_transits,
1605 const RoutingDimension* base_dimension, int64_t slack_max,
1606 std::vector<int64_t> vehicle_capacities,
bool fix_start_cumul_to_zero,
1607 const std::string&
name);
1608 bool InitializeDimensionInternal(
1609 const std::vector<int>& evaluator_indices,
1610 const std::vector<int>& state_dependent_evaluator_indices,
1611 int64_t slack_max,
bool fix_start_cumul_to_zero,
1612 RoutingDimension* dimension);
1613 DimensionIndex GetDimensionIndex(
const std::string& dimension_name)
const;
1642 void StoreDimensionCumulOptimizers(
const RoutingSearchParameters&
parameters);
1644 void ComputeCostClasses(
const RoutingSearchParameters&
parameters);
1645 void ComputeVehicleClasses();
1653 void ComputeVehicleTypes();
1663 void FinalizeVisitTypes();
1665 void TopologicallySortVisitTypes();
1666 int64_t GetArcCostForClassInternal(int64_t from_index, int64_t to_index,
1667 CostClassIndex cost_class_index)
const;
1668 void AppendHomogeneousArcCosts(
const RoutingSearchParameters&
parameters,
1670 std::vector<IntVar*>* cost_elements);
1671 void AppendArcCosts(
const RoutingSearchParameters&
parameters,
int node_index,
1672 std::vector<IntVar*>* cost_elements);
1673 Assignment* DoRestoreAssignment();
1674 static const CostClassIndex kCostClassIndexOfZeroCost;
1675 int64_t SafeGetCostClassInt64OfVehicle(int64_t vehicle)
const {
1677 return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1678 : kCostClassIndexOfZeroCost)
1681 int64_t GetDimensionTransitCostSum(int64_t i, int64_t j,
1682 const CostClass& cost_class)
const;
1684 IntVar* CreateDisjunction(DisjunctionIndex disjunction);
1686 void AddPickupAndDeliverySetsInternal(
const std::vector<int64_t>& pickups,
1687 const std::vector<int64_t>& deliveries);
1690 IntVar* CreateSameVehicleCost(
int vehicle_index);
1693 int FindNextActive(
int index,
const std::vector<int64_t>& indices)
const;
1697 bool RouteCanBeUsedByVehicle(
const Assignment& assignment,
int start_index,
1706 bool ReplaceUnusedVehicle(
int unused_vehicle,
int active_vehicle,
1707 Assignment* compact_assignment)
const;
1709 void QuietCloseModel();
1710 void QuietCloseModelWithParameters(
1718 bool SolveMatchingModel(Assignment* assignment,
1722 bool AppendAssignmentIfFeasible(
1723 const Assignment& assignment,
1724 std::vector<std::unique_ptr<Assignment>>* assignments);
1727 void LogSolution(
const RoutingSearchParameters&
parameters,
1728 const std::string& description, int64_t solution_cost,
1729 int64_t start_time_ms);
1732 Assignment* CompactAssignmentInternal(
const Assignment& assignment,
1733 bool check_compact_assignment)
const;
1738 std::string FindErrorInSearchParametersForModel(
1739 const RoutingSearchParameters& search_parameters)
const;
1741 void SetupSearch(
const RoutingSearchParameters& search_parameters);
1744 Assignment* GetOrCreateAssignment();
1745 Assignment* GetOrCreateTmpAssignment();
1746 RegularLimit* GetOrCreateLimit();
1747 RegularLimit* GetOrCreateLocalSearchLimit();
1748 RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1749 RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1750 LocalSearchOperator* CreateInsertionOperator();
1751 LocalSearchOperator* CreateMakeInactiveOperator();
1753 LocalSearchOperator* CreateCPOperator(
const T& operator_factory) {
1754 return operator_factory(solver_.get(), nexts_,
1755 CostsAreHomogeneousAcrossVehicles()
1756 ? std::vector<IntVar*>()
1758 vehicle_start_class_callback_);
1761 LocalSearchOperator* CreateCPOperator() {
1762 return CreateCPOperator(absl::bind_front(MakeLocalSearchOperator<T>));
1764 template <
class T,
class Arg>
1765 LocalSearchOperator* CreateOperator(
const Arg& arg) {
1766 return solver_->RevAlloc(
new T(nexts_,
1767 CostsAreHomogeneousAcrossVehicles()
1768 ? std::vector<IntVar*>()
1770 vehicle_start_class_callback_, arg));
1773 LocalSearchOperator* CreatePairOperator() {
1774 return CreateOperator<T>(pickup_delivery_pairs_);
1776 void CreateNeighborhoodOperators(
const RoutingSearchParameters&
parameters);
1777 LocalSearchOperator* ConcatenateOperators(
1778 const RoutingSearchParameters& search_parameters,
1779 const std::vector<LocalSearchOperator*>& operators)
const;
1780 LocalSearchOperator* GetNeighborhoodOperators(
1781 const RoutingSearchParameters& search_parameters)
const;
1782 std::vector<LocalSearchFilterManager::FilterEvent>
1783 GetOrCreateLocalSearchFilters(
const RoutingSearchParameters&
parameters,
1784 bool filter_cost =
true);
1785 LocalSearchFilterManager* GetOrCreateLocalSearchFilterManager(
1787 std::vector<LocalSearchFilterManager::FilterEvent>
1788 GetOrCreateFeasibilityFilters(
const RoutingSearchParameters&
parameters);
1789 LocalSearchFilterManager* GetOrCreateFeasibilityFilterManager(
1791 LocalSearchFilterManager* GetOrCreateStrongFeasibilityFilterManager(
1793 DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1794 DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1795 void CreateFirstSolutionDecisionBuilders(
1796 const RoutingSearchParameters& search_parameters);
1797 DecisionBuilder* GetFirstSolutionDecisionBuilder(
1798 const RoutingSearchParameters& search_parameters)
const;
1799 IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1800 const RoutingSearchParameters&
parameters)
const;
1801 LocalSearchPhaseParameters* CreateLocalSearchParameters(
1802 const RoutingSearchParameters& search_parameters);
1803 DecisionBuilder* CreateLocalSearchDecisionBuilder(
1804 const RoutingSearchParameters& search_parameters);
1805 void SetupDecisionBuilders(
const RoutingSearchParameters& search_parameters);
1806 void SetupMetaheuristics(
const RoutingSearchParameters& search_parameters);
1807 void SetupAssignmentCollector(
1808 const RoutingSearchParameters& search_parameters);
1809 void SetupTrace(
const RoutingSearchParameters& search_parameters);
1810 void SetupImprovementLimit(
const RoutingSearchParameters& search_parameters);
1811 void SetupSearchMonitors(
const RoutingSearchParameters& search_parameters);
1812 bool UsesLightPropagation(
1813 const RoutingSearchParameters& search_parameters)
const;
1814 GetTabuVarsCallback tabu_var_callback_;
1820 void DetectImplicitPickupAndDeliveries();
1822 int GetVehicleStartClass(int64_t start)
const;
1824 void InitSameVehicleGroups(
int number_of_groups) {
1825 same_vehicle_group_.assign(Size(), 0);
1826 same_vehicle_groups_.assign(number_of_groups, {});
1828 void SetSameVehicleGroup(
int index,
int group) {
1829 same_vehicle_group_[
index] = group;
1830 same_vehicle_groups_[group].push_back(
index);
1834 std::unique_ptr<Solver> solver_;
1837 int max_active_vehicles_;
1838 Constraint* no_cycle_constraint_ =
nullptr;
1840 std::vector<IntVar*> nexts_;
1841 std::vector<IntVar*> vehicle_vars_;
1842 std::vector<IntVar*> active_;
1844 std::vector<IntVar*> vehicle_active_;
1845 std::vector<IntVar*> vehicle_costs_considered_;
1850 std::vector<IntVar*> is_bound_to_end_;
1851 mutable RevSwitch is_bound_to_end_ct_added_;
1853 absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1860 std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1863 dimension_resource_group_indices_;
1868 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1869 global_dimension_optimizers_;
1870 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1871 global_dimension_mp_optimizers_;
1873 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1874 local_dimension_optimizers_;
1875 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1876 local_dimension_mp_optimizers_;
1879 std::string primary_constrained_dimension_;
1881 IntVar* cost_ =
nullptr;
1882 std::vector<int> vehicle_to_transit_cost_;
1883 std::vector<int64_t> fixed_cost_of_vehicle_;
1884 std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1885 bool has_vehicle_with_zero_cost_class_;
1886 std::vector<int64_t> linear_cost_factor_of_vehicle_;
1887 std::vector<int64_t> quadratic_cost_factor_of_vehicle_;
1888 bool vehicle_amortized_cost_factors_set_;
1899 std::vector<bool> consider_empty_route_costs_;
1903 bool costs_are_homogeneous_across_vehicles_;
1904 bool cache_callbacks_;
1905 mutable std::vector<CostCacheElement> cost_cache_;
1906 std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1910 VehicleTypeContainer vehicle_type_container_;
1911 std::function<int(int64_t)> vehicle_start_class_callback_;
1914 std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
1916 std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
1919 std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
1922 IndexPairs pickup_delivery_pairs_;
1923 IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
1924 std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
1925 pickup_delivery_disjunctions_;
1930 std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1932 std::vector<std::vector<std::pair<int, int> > >
1933 index_to_delivery_index_pairs_;
1935 std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1937 std::vector<int> same_vehicle_group_;
1939 std::vector<std::vector<int>> same_vehicle_groups_;
1942 std::vector<int> index_to_visit_type_;
1944 std::vector<VisitTypePolicy> index_to_type_policy_;
1946 std::vector<std::vector<int> > single_nodes_of_type_;
1947 std::vector<std::vector<int> > pair_indices_of_type_;
1949 std::vector<absl::flat_hash_set<int> >
1950 hard_incompatible_types_per_type_index_;
1951 bool has_hard_type_incompatibilities_;
1952 std::vector<absl::flat_hash_set<int> >
1953 temporal_incompatible_types_per_type_index_;
1954 bool has_temporal_type_incompatibilities_;
1956 std::vector<std::vector<absl::flat_hash_set<int> > >
1957 same_vehicle_required_type_alternatives_per_type_index_;
1958 bool has_same_vehicle_type_requirements_;
1959 std::vector<std::vector<absl::flat_hash_set<int> > >
1960 required_type_alternatives_when_adding_type_index_;
1961 std::vector<std::vector<absl::flat_hash_set<int> > >
1962 required_type_alternatives_when_removing_type_index_;
1963 bool has_temporal_type_requirements_;
1964 absl::flat_hash_map<int, absl::flat_hash_set<VisitTypePolicy> >
1965 trivially_infeasible_visit_types_to_policies_;
1982 std::vector<std::vector<int> > topologically_sorted_visit_types_;
1984 int num_visit_types_;
1987 std::vector<int> index_to_equivalence_class_;
1988 std::vector<int> index_to_vehicle_;
1989 std::vector<int64_t> starts_;
1990 std::vector<int64_t> ends_;
1993 RoutingIndexManager manager_;
1994 int start_end_count_;
1996 bool closed_ =
false;
1997 Status status_ = ROUTING_NOT_SOLVED;
1998 bool enable_deep_serialization_ =
true;
2001 std::vector<DecisionBuilder*> first_solution_decision_builders_;
2002 std::vector<IntVarFilteredDecisionBuilder*>
2003 first_solution_filtered_decision_builders_;
2004 Solver::IndexEvaluator2 first_solution_evaluator_;
2006 FirstSolutionStrategy::UNSET;
2007 std::vector<LocalSearchOperator*> local_search_operators_;
2008 std::vector<SearchMonitor*> monitors_;
2009 SolutionCollector* collect_assignments_ =
nullptr;
2010 SolutionCollector* collect_one_assignment_ =
nullptr;
2011 SolutionCollector* packed_dimensions_assignment_collector_ =
nullptr;
2012 DecisionBuilder* solve_db_ =
nullptr;
2013 DecisionBuilder* improve_db_ =
nullptr;
2014 DecisionBuilder* restore_assignment_ =
nullptr;
2015 DecisionBuilder* restore_tmp_assignment_ =
nullptr;
2016 Assignment* assignment_ =
nullptr;
2017 Assignment* preassignment_ =
nullptr;
2018 Assignment* tmp_assignment_ =
nullptr;
2019 std::vector<IntVar*> extra_vars_;
2020 std::vector<IntervalVar*> extra_intervals_;
2021 std::vector<LocalSearchOperator*> extra_operators_;
2022 LocalSearchFilterManager* local_search_filter_manager_ =
nullptr;
2023 LocalSearchFilterManager* feasibility_filter_manager_ =
nullptr;
2024 LocalSearchFilterManager* strong_feasibility_filter_manager_ =
nullptr;
2025 std::vector<LocalSearchFilterManager::FilterEvent> extra_filters_;
2027 std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_cost_pairs_;
2028 std::vector<std::pair<IntVar*, int64_t>> finalizer_variable_target_pairs_;
2029 absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
2030 absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
2031 std::unique_ptr<SweepArranger> sweep_arranger_;
2034 RegularLimit*
limit_ =
nullptr;
2035 RegularLimit* ls_limit_ =
nullptr;
2036 RegularLimit* lns_limit_ =
nullptr;
2037 RegularLimit* first_solution_lns_limit_ =
nullptr;
2039 typedef std::pair<int64_t, int64_t> CacheKey;
2040 typedef absl::flat_hash_map<CacheKey, int64_t> TransitCallbackCache;
2041 typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
2042 StateDependentTransitCallbackCache;
2044 std::vector<TransitCallback1> unary_transit_evaluators_;
2045 std::vector<TransitCallback2> transit_evaluators_;
2056 std::vector<bool> is_transit_evaluator_positive_;
2057 std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
2058 std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
2059 state_dependent_transit_evaluators_cache_;
2072 static const char kLightElement[];
2073 static const char kLightElement2[];
2074 static const char kRemoveValues[];
2088 int num_chain_tasks = 0;
2098 int64_t span_min = 0;
2104 duration_min.clear();
2105 duration_max.clear();
2108 is_preemptible.clear();
2109 forbidden_intervals.clear();
2110 distance_duration.clear();
2113 num_chain_tasks = 0;
2119 bool Propagate(Tasks* tasks);
2122 bool Precedences(Tasks* tasks);
2125 bool MirrorTasks(Tasks* tasks);
2127 bool EdgeFinding(Tasks* tasks);
2130 bool DetectablePrecedencesWithChain(Tasks* tasks);
2132 bool ForbiddenIntervals(Tasks* tasks);
2134 bool DistanceDuration(Tasks* tasks);
2137 bool ChainSpanMin(Tasks* tasks);
2142 bool ChainSpanMinDynamic(Tasks* tasks);
2149 std::vector<int> tasks_by_start_min_;
2150 std::vector<int> tasks_by_end_max_;
2151 std::vector<int> event_of_task_;
2152 std::vector<int> nonchain_tasks_by_start_max_;
2154 std::vector<int64_t> total_duration_before_;
2172 std::vector<int64_t>* values);
2192 return "GlobalVehicleBreaksConstraint";
2195 void Post()
override;
2196 void InitialPropagate()
override;
2199 void PropagateNode(
int node);
2200 void PropagateVehicle(
int vehicle);
2201 void PropagateMaxBreakDistance(
int vehicle);
2205 std::vector<Demon*> vehicle_demons_;
2206 std::vector<int64_t> path_;
2212 void FillPartialPathOfVehicle(
int vehicle);
2213 void FillPathTravels(
const std::vector<int64_t>& path);
2225 class TaskTranslator {
2227 TaskTranslator(
IntVar* start, int64_t before_start, int64_t after_start)
2229 before_start_(before_start),
2230 after_start_(after_start) {}
2234 void SetStartMin(int64_t
value) {
2235 if (start_ !=
nullptr) {
2237 }
else if (interval_ !=
nullptr) {
2238 interval_->SetStartMin(
value);
2241 void SetStartMax(int64_t
value) {
2242 if (start_ !=
nullptr) {
2244 }
else if (interval_ !=
nullptr) {
2245 interval_->SetStartMax(
value);
2248 void SetDurationMin(int64_t
value) {
2249 if (interval_ !=
nullptr) {
2250 interval_->SetDurationMin(
value);
2253 void SetEndMin(int64_t
value) {
2254 if (start_ !=
nullptr) {
2256 }
else if (interval_ !=
nullptr) {
2257 interval_->SetEndMin(
value);
2260 void SetEndMax(int64_t
value) {
2261 if (start_ !=
nullptr) {
2263 }
else if (interval_ !=
nullptr) {
2264 interval_->SetEndMax(
value);
2269 IntVar* start_ =
nullptr;
2270 int64_t before_start_;
2271 int64_t after_start_;
2272 IntervalVar* interval_ =
nullptr;
2276 std::vector<TaskTranslator> task_translators_;
2279 DisjunctivePropagator disjunctive_propagator_;
2280 DisjunctivePropagator::Tasks tasks_;
2283 TravelBounds travel_bounds_;
2291 bool CheckVehicle(
int vehicle,
2292 const std::function<int64_t(int64_t)>& next_accessor);
2303 int num_type_added_to_vehicle = 0;
2309 int num_type_removed_from_vehicle = 0;
2314 int position_of_last_type_on_vehicle_up_to_visit = -1;
2321 bool TypeOccursOnRoute(
int type)
const;
2328 bool TypeCurrentlyOnRoute(
int type,
int pos)
const;
2330 void InitializeCheck(
int vehicle,
2331 const std::function<int64_t(int64_t)>& next_accessor);
2341 std::vector<TypePolicyOccurrence> occurrences_of_type_;
2342 std::vector<int64_t> current_route_visits_;
2349 bool check_hard_incompatibilities);
2353 bool HasRegulationsToCheck()
const override;
2354 bool CheckTypeRegulations(
int type, VisitTypePolicy policy,
int pos)
override;
2358 bool check_hard_incompatibilities_;
2369 bool HasRegulationsToCheck()
const override;
2370 void OnInitializeCheck()
override {
2371 types_with_same_vehicle_requirements_on_route_.clear();
2376 bool CheckRequiredTypesCurrentlyOnRoute(
2377 const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2380 bool CheckTypeRegulations(
int type, VisitTypePolicy policy,
int pos)
override;
2381 bool FinalizeCheck()
const override;
2383 absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2430 void Post()
override;
2431 void InitialPropagate()
override;
2434 void PropagateNodeRegulations(
int node);
2435 void CheckRegulationsOnVehicle(
int vehicle);
2440 std::vector<Demon*> vehicle_demons_;
2462 : bound_costs_(num_bounds, default_bound_cost) {}
2465 int Size() {
return bound_costs_.size(); }
2470 std::vector<BoundCost> bound_costs_;
2502 int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2503 int64_t vehicle)
const;
2508 return model_->TransitCallback(class_evaluators_[
vehicle_class])(from_index,
2516 return fixed_transits_[
index];
2520#if !defined(SWIGPYTHON)
2525 const std::vector<IntVar*>&
transits()
const {
return transits_; }
2526 const std::vector<IntVar*>&
slacks()
const {
return slacks_; }
2527#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2530 return forbidden_intervals_;
2534 int64_t
index, int64_t min_value, int64_t max_value)
const;
2538 int64_t min_value)
const {
2541 forbidden_intervals_[
index];
2542 const auto first_forbidden_interval_it =
2544 if (first_forbidden_interval_it != forbidden_intervals.
end() &&
2545 min_value >= first_forbidden_interval_it->start) {
2547 return CapAdd(first_forbidden_interval_it->end, 1);
2557 int64_t max_value)
const {
2560 forbidden_intervals_[
index];
2561 const auto last_forbidden_interval_it =
2563 if (last_forbidden_interval_it != forbidden_intervals.
end() &&
2564 max_value <= last_forbidden_interval_it->end) {
2566 return CapSub(last_forbidden_interval_it->start, 1);
2573 return vehicle_capacities_;
2578 return model_->TransitCallback(
2579 class_evaluators_[vehicle_to_class_[vehicle]]);
2586 const int vehicle = model_->GetVehicleOfClass(
vehicle_class);
2588 return transit_evaluator(vehicle);
2595 int vehicle)
const {
2596 return model_->UnaryTransitCallbackOrNull(
2597 class_evaluators_[vehicle_to_class_[vehicle]]);
2602 return model()->is_transit_evaluator_positive_
2603 [class_evaluators_[vehicle_to_class_[vehicle]]];
2611 void SetSpanUpperBoundForVehicle(int64_t
upper_bound,
int vehicle);
2618 void SetSpanCostCoefficientForVehicle(int64_t
coefficient,
int vehicle);
2619 void SetSpanCostCoefficientForAllVehicles(int64_t
coefficient);
2626 void SetGlobalSpanCostCoefficient(int64_t
coefficient);
2633 void SetCumulVarPiecewiseLinearCost(int64_t
index,
2637 bool HasCumulVarPiecewiseLinearCost(int64_t
index)
const;
2641 int64_t
index)
const;
2656 bool HasCumulVarSoftUpperBound(int64_t
index)
const;
2660 int64_t GetCumulVarSoftUpperBound(int64_t
index)
const;
2664 int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t
index)
const;
2679 bool HasCumulVarSoftLowerBound(int64_t
index)
const;
2683 int64_t GetCumulVarSoftLowerBound(int64_t
index)
const;
2687 int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t
index)
const;
2704#if !defined(SWIGPYTHON)
2705 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks,
int vehicle,
2706 int pre_travel_evaluator,
2707 int post_travel_evaluator);
2711 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks,
int vehicle,
2712 std::vector<int64_t> node_visit_transits);
2718 void SetBreakDistanceDurationOfVehicle(int64_t
distance, int64_t duration,
2722 void InitializeBreaks();
2724 bool HasBreakConstraints()
const;
2725#if !defined(SWIGPYTHON)
2728 void SetBreakIntervalsOfVehicle(
2729 std::vector<IntervalVar*> breaks,
int vehicle,
2730 std::vector<int64_t> node_visit_transits,
2731 std::function<int64_t(int64_t, int64_t)> delays);
2734 const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2739 const std::vector<std::pair<int64_t, int64_t> >&
2740 GetBreakDistanceDurationOfVehicle(
int vehicle)
const;
2743 int GetPreTravelEvaluatorOfVehicle(
int vehicle)
const;
2744 int GetPostTravelEvaluatorOfVehicle(
int vehicle)
const;
2755 int64_t ShortestTransitionSlack(int64_t node)
const;
2758 const std::string&
name()
const {
return name_; }
2763 return path_precedence_graph_;
2778 void SetPickupToDeliveryLimitFunctionForPair(
2781 bool HasPickupToDeliveryLimits()
const;
2783 int64_t GetPickupToDeliveryLimitForPair(
int pair_index,
int pickup,
2784 int delivery)
const;
2793 node_precedences_.push_back(precedence);
2796 return node_precedences_;
2802 AddNodePrecedence({first_node, second_node, offset});
2806 return vehicle_span_upper_bounds_[vehicle];
2810 return vehicle_span_upper_bounds_;
2814 return vehicle_span_cost_coefficients_[vehicle];
2819 const int vehicle = model_->GetVehicleOfClass(
vehicle_class);
2821 return GetSpanCostCoefficientForVehicle(vehicle);
2826 return vehicle_span_cost_coefficients_;
2830 return global_span_cost_coefficient_;
2835 return global_optimizer_offset_;
2838 if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2841 DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2842 return local_optimizer_offset_for_vehicle_[vehicle];
2849 if (!HasSoftSpanUpperBounds()) {
2850 vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2853 vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2856 return vehicle_soft_span_upper_bound_ !=
nullptr;
2859 int vehicle)
const {
2860 DCHECK(HasSoftSpanUpperBounds());
2861 return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2867 if (!HasQuadraticCostSoftSpanUpperBounds()) {
2868 vehicle_quadratic_cost_soft_span_upper_bound_ =
2869 absl::make_unique<SimpleBoundCosts>(
2872 vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2876 return vehicle_quadratic_cost_soft_span_upper_bound_ !=
nullptr;
2879 int vehicle)
const {
2880 DCHECK(HasQuadraticCostSoftSpanUpperBounds());
2881 return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2892 struct PiecewiseLinearCost {
2893 PiecewiseLinearCost() :
var(nullptr),
cost(nullptr) {}
2895 std::unique_ptr<PiecewiseLinearFunction>
cost;
2899 RoutingDimension(RoutingModel*
model, std::vector<int64_t> vehicle_capacities,
2900 const std::string&
name,
2901 const RoutingDimension* base_dimension);
2902 RoutingDimension(RoutingModel*
model, std::vector<int64_t> vehicle_capacities,
2903 const std::string&
name, SelfBased);
2904 void Initialize(
const std::vector<int>& transit_evaluators,
2905 const std::vector<int>& state_dependent_transit_evaluators,
2907 void InitializeCumuls();
2908 void InitializeTransits(
2909 const std::vector<int>& transit_evaluators,
2910 const std::vector<int>& state_dependent_transit_evaluators,
2912 void InitializeTransitVariables(int64_t slack_max);
2914 void SetupCumulVarSoftUpperBoundCosts(
2915 std::vector<IntVar*>* cost_elements)
const;
2917 void SetupCumulVarSoftLowerBoundCosts(
2918 std::vector<IntVar*>* cost_elements)
const;
2919 void SetupCumulVarPiecewiseLinearCosts(
2920 std::vector<IntVar*>* cost_elements)
const;
2923 void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements)
const;
2924 void SetupSlackAndDependentTransitCosts()
const;
2926 void CloseModel(
bool use_light_propagation);
2928 void SetOffsetForGlobalOptimizer(int64_t offset) {
2932 void SetVehicleOffsetsForLocalOptimizer(std::vector<int64_t> offsets) {
2934 std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2935 [](int64_t offset) { return std::max(Zero(), offset); });
2936 local_optimizer_offset_for_vehicle_ = std::move(offsets);
2940 std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2941 std::vector<IntVar*> capacity_vars_;
2942 const std::vector<int64_t> vehicle_capacities_;
2943 std::vector<IntVar*> transits_;
2944 std::vector<IntVar*> fixed_transits_;
2947 std::vector<int> class_evaluators_;
2948 std::vector<int64_t> vehicle_to_class_;
2950 ReverseArcListGraph<int, int> path_precedence_graph_;
2956 std::vector<NodePrecedence> node_precedences_;
2961 const RoutingDimension*
const base_dimension_;
2966 std::vector<int> state_dependent_class_evaluators_;
2967 std::vector<int64_t> state_dependent_vehicle_to_class_;
2972 std::vector<PickupToDeliveryLimitFunction>
2973 pickup_to_delivery_limits_per_pair_index_;
2976 bool break_constraints_are_initialized_ =
false;
2978 std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2979 std::vector<std::vector<std::pair<int64_t, int64_t> > >
2980 vehicle_break_distance_duration_;
2985 std::vector<int> vehicle_pre_travel_evaluators_;
2986 std::vector<int> vehicle_post_travel_evaluators_;
2988 std::vector<IntVar*> slacks_;
2989 std::vector<IntVar*> dependent_transits_;
2990 std::vector<int64_t> vehicle_span_upper_bounds_;
2991 int64_t global_span_cost_coefficient_;
2992 std::vector<int64_t> vehicle_span_cost_coefficients_;
2993 std::vector<SoftBound> cumul_var_soft_upper_bound_;
2994 std::vector<SoftBound> cumul_var_soft_lower_bound_;
2995 std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2996 RoutingModel*
const model_;
2997 const std::string name_;
2998 int64_t global_optimizer_offset_;
2999 std::vector<int64_t> local_optimizer_offset_for_vehicle_;
3001 std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
3002 std::unique_ptr<SimpleBoundCosts>
3003 vehicle_quadratic_cost_soft_span_upper_bound_;
3007 const std::vector<RoutingDimension*>&
dimensions,
3009 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3017 std::vector<IntVar*> variables,
3018 std::vector<int64_t> targets);
std::vector< int > dimensions
#define DCHECK_NE(val1, val2)
#define CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
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...
We call domain any subset of Int64 = [kint64min, kint64max].
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
std::string DebugString() const override
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.
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 * (...
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
const std::vector< IntVar * > & transits() const
IntVar * TransitVar(int64_t index) const
const std::vector< int64_t > & vehicle_span_upper_bounds() const
const std::string & name() const
Returns the name of the dimension.
int64_t GetSpanCostCoefficientForVehicleClass(RoutingVehicleClassIndex vehicle_class) const
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
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 * (...
const std::vector< int64_t > & vehicle_capacities() const
Returns the capacities for all vehicles.
int64_t GetGlobalOptimizerOffset() const
IntVar * CumulVar(int64_t index) const
Get the cumul, transit and slack variables for the given node (given as int64_t var index).
IntVar * SlackVar(int64_t index) const
int64_t GetSpanCostCoefficientForVehicle(int vehicle) const
int64_t global_span_cost_coefficient() const
const RoutingModel::TransitCallback2 & transit_evaluator(int vehicle) const
Returns the callback evaluating the transit value between two node indices for a given vehicle.
const std::vector< IntVar * > & slacks() const
int64_t GetSpanUpperBoundForVehicle(int vehicle) const
const std::vector< int64_t > & vehicle_span_cost_coefficients() const
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
void AddNodePrecedence(int64_t first_node, int64_t second_node, int64_t offset)
IntVar * FixedTransitVar(int64_t index) const
std::function< int64_t(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
void AddNodePrecedence(NodePrecedence precedence)
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...
const RoutingModel::TransitCallback1 & GetUnaryTransitEvaluator(int vehicle) const
Returns the unary callback evaluating the transit value between two node indices for a given vehicle.
bool HasQuadraticCostSoftSpanUpperBounds() const
RoutingModel * model() const
Returns the model on which the dimension was created.
const std::vector< NodePrecedence > & GetNodePrecedences() const
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
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.
int vehicle_to_class(int vehicle) const
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...
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 ...
int64_t GetLocalOptimizerOffsetForVehicle(int vehicle) const
const std::vector< IntVar * > & fixed_transits() const
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
bool HasSoftSpanUpperBounds() const
SimpleBoundCosts::BoundCost GetQuadraticCostSoftSpanUpperBoundForVehicle(int vehicle) const
Manager for any NodeIndex <-> variable index conversion.
Attributes for a dimension.
const Domain & start_domain() const
const Domain & end_domain() const
A Resource sets attributes (costs/constraints) for a set of dimensions.
const Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
const std::vector< Resource > & GetResources() const
void AddResource(Attributes attributes, const RoutingDimension *dimension)
Add a Resource with the given attributes for the corresponding dimension.
ResourceGroup(const RoutingModel *model)
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
Solver * solver() const
Returns the underlying constraint solver.
const TransitCallback2 & TransitCallback(int callback_index) const
std::function< std::vector< operations_research::IntVar * >(RoutingModel *)> GetTabuVarsCallback
Sets the callback returning the variable to use for the Tabu Search metaheuristic.
int nodes() const
Sizes and indices Returns the number of nodes in the model.
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.
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64_t vehicle) const
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 ...
RoutingIndexPair IndexPair
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...
RoutingTransitCallback1 TransitCallback1
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...
int GetNumberOfVisitTypes() const
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
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; ...
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulMPOptimizers() const
bool CheckLimit()
Returns true if the search limit has been crossed.
const IndexPairs & GetImplicitUniquePickupAndDeliveryPairs() const
Returns implicit pickup and delivery pairs currently in the model.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
IntVar * VehicleVar(int64_t index) const
Returns the vehicle variable of the node corresponding to index.
VisitTypePolicy
Set the node visit types and incompatibilities/requirements between the types (see below).
@ TYPE_ADDED_TO_VEHICLE
When visited, the number of types 'T' on the vehicle increases by one.
@ ADDED_TYPE_REMOVED_FROM_VEHICLE
When visited, one instance of type 'T' previously added to the route (TYPE_ADDED_TO_VEHICLE),...
@ TYPE_ON_VEHICLE_UP_TO_VISIT
With the following policy, the visit enforces that type 'T' is considered on the route from its start...
GlobalDimensionCumulOptimizer * GetMutableGlobalCumulMPOptimizer(const RoutingDimension &dimension) const
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
int64_t GetHomogeneousCost(int64_t from_index, int64_t to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
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...
int64_t Size() const
Returns the number of next variables in the model.
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulMPOptimizers() const
bool HasTemporalTypeRequirements() const
IntVar * NextVar(int64_t index) const
!defined(SWIGPYTHON)
static const int64_t kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
RoutingTransitCallback2 TransitCallback2
IntVar * ActiveVehicleVar(int vehicle) const
Returns the active variable of the vehicle.
int64_t GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
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...
Status
Status of the search.
@ ROUTING_SUCCESS
Problem solved successfully after calling RoutingModel::Solve().
@ ROUTING_FAIL
No solution found to the problem after calling RoutingModel::Solve().
@ ROUTING_NOT_SOLVED
Problem not solved yet (before calling RoutingModel::Solve()).
@ ROUTING_INVALID
Model, model parameters or flags are not valid.
@ ROUTING_FAIL_TIMEOUT
Time limit reached before finding a solution with RoutingModel::Solve().
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
RoutingIndexPairs IndexPairs
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
bool IsVehicleAllowedForIndex(int vehicle, int64_t index)
Returns true if a vehicle is allowed to visit a given node.
const VehicleTypeContainer & GetVehicleTypeContainer() const
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
void SetMaximumNumberOfActiveVehicles(int max_active_vehicles)
Constrains the maximum number of active vehicles, aka the number of vehicles which do not have an emp...
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.
const std::vector< std::vector< int > > & GetTopologicallySortedVisitTypes() const
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
int RegisterTransitCallback(TransitCallback2 callback)
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
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...
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64_t index) const
Returns the indices of the disjunctions to which an index belongs.
const std::vector< int64_t > & GetAmortizedLinearCostFactorOfVehicles() const
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
RoutingDimensionIndex DimensionIndex
Assignment * MutablePreAssignment()
const std::vector< std::unique_ptr< LocalDimensionCumulOptimizer > > & GetLocalDimensionCumulOptimizers() const
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)
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
int RegisterPositiveTransitCallback(TransitCallback2 callback)
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
@ PICKUP_AND_DELIVERY_LIFO
Deliveries must be performed in reverse order of pickups.
@ PICKUP_AND_DELIVERY_NO_ORDER
Any precedence is accepted.
@ PICKUP_AND_DELIVERY_FIFO
Deliveries must be performed in the same order as pickups.
int64_t Start(int vehicle) const
Model inspection.
int vehicles() const
Returns the number of vehicle routes in the model.
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
IntVar * ActiveVar(int64_t index) const
Returns the active variable of the node corresponding to index.
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
RoutingVehicleClassIndex VehicleClassIndex
std::function< StateDependentTransit(int64_t, int64_t)> VariableIndexEvaluator2
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
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.
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
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.
int RegisterUnaryTransitCallback(TransitCallback1 callback)
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
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)
RoutingCostClassIndex CostClassIndex
bool HasTemporalTypeIncompatibilities() const
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
const std::vector< int64_t > & GetAmortizedQuadraticCostFactorOfVehicles() const
operations_research::FirstSolutionStrategy::Value GetAutomaticFirstSolutionStrategy() const
Returns the automatic first solution strategy selected.
absl::Duration RemainingTime() const
Returns the time left in the search limit.
Status status() const
Returns the current status of the routing model.
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
int RegisterTransitMatrix(std::vector< std::vector< int64_t > > values)
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
const std::vector< std::unique_ptr< ResourceGroup > > & GetResourceGroups() const
CostClassIndex GetCostClassIndexOfVehicle(int64_t vehicle) const
Get the cost class index of the given vehicle.
static const DisjunctionIndex kNoDisjunction
Constant used to express the "no disjunction" index, returned when a node does not appear in any disj...
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
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...
const std::vector< std::unique_ptr< GlobalDimensionCumulOptimizer > > & GetGlobalDimensionCumulOptimizers() const
Returns [global|local]_dimension_optimizers_, which are empty if the model has not been closed.
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
int GetVehicleOfClass(VehicleClassIndex vehicle_class) const
Returns a vehicle of the given vehicle class, and -1 if there are no vehicles for this class.
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty string if it is unset.
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
ResourceGroup *const AddResourceGroup()
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
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
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.
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'.
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.
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
BoundCost & bound_cost(int element)
BoundCost bound_cost(int element) const
SimpleBoundCosts(const SimpleBoundCosts &)=delete
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
std::function< int64_t(int64_t, int64_t)> IndexEvaluator2
This class represents a sorted list of disjoint, closed intervals.
Iterator LastIntervalLessOrEqual(int64_t value) const
ConstIterator end() const
Iterator FirstIntervalGreaterOrEqual(int64_t value) const
Returns an iterator to either:
Class to arrange indices by by their distance and their angles from the depot.
Checker for type incompatibilities.
~TypeIncompatibilityChecker() override
virtual bool HasRegulationsToCheck() const =0
virtual ~TypeRegulationsChecker()
virtual bool CheckTypeRegulations(int type, VisitTypePolicy policy, int pos)=0
virtual void OnInitializeCheck()
virtual bool FinalizeCheck() const
const RoutingModel & model_
The following constraint ensures that incompatibilities and requirements between types are respected.
Checker for type requirements.
~TypeRequirementChecker() override
TypeRequirementChecker(const RoutingModel &model)
const std::vector< IntVar * > cumuls_
static const int64_t kint64max
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
std::function< int64_t(const Model &)> Value(IntegerVariable v)
CpSolverResponse SolveWithParameters(const CpModelProto &model_proto, const SatParameters ¶ms)
Solves the given CpModelProto with the given parameters.
CpSolverResponse Solve(const CpModelProto &model_proto)
Solves the given CpModelProto and returns an instance of CpSolverResponse.
Collection of objects used to extend the Constraint Solver library.
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 AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters ¶meters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
int64_t CapAdd(int64_t x, int64_t y)
std::function< int64_t(int64_t, int64_t)> RoutingTransitCallback2
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
FirstSolutionStrategy_Value
int64_t CapSub(int64_t x, int64_t y)
std::pair< std::vector< int64_t >, std::vector< int64_t > > RoutingIndexPair
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
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...
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
void FillPathEvaluation(const std::vector< int64_t > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64_t > *values)
void FillTravelBoundsOfVehicle(int vehicle, const std::vector< int64_t > &path, const RoutingDimension &dimension, TravelBounds *travel_bounds)
std::vector< RoutingIndexPair > RoutingIndexPairs
A structure to hold tasks described by their features.
std::vector< std::pair< int64_t, int64_t > > distance_duration
std::vector< int64_t > end_min
std::vector< int64_t > start_min
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
std::vector< bool > is_preemptible
std::vector< int64_t > end_max
std::vector< int64_t > duration_max
std::vector< int64_t > start_max
std::vector< int64_t > duration_min
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
const RoutingDimension * dimension
bool operator<(const DimensionCost &cost) const
int64_t transit_evaluator_class
CostClass(int evaluator_index)
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
What follows is relevant for models with time/state dependent transits.
RangeIntToIntFunction * transit
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_max
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
int start_equivalence_class
Vehicle start and end equivalence classes.
int end_equivalence_class
absl::StrongVector< DimensionIndex, int64_t > dimension_capacities
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
absl::StrongVector< DimensionIndex, int64_t > dimension_end_cumuls_min
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.
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
absl::StrongVector< DimensionIndex, int64_t > dimension_start_cumuls_max
CostClassIndex cost_class_index
The cost class of the vehicle.
bool operator<(const VehicleClassEntry &other) const
Struct used to sort and store vehicles by their type.
std::vector< int > type_index_of_vehicle
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type
int Type(int vehicle) const
std::vector< std::deque< int > > vehicles_per_vehicle_class
std::vector< int64_t > post_travels
std::vector< int64_t > max_travels
std::vector< int64_t > pre_travels
std::vector< int64_t > min_travels