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"
183#include "ortools/constraint_solver/routing_enums.pb.h"
185#include "ortools/constraint_solver/routing_parameters.pb.h"
197class GlobalDimensionCumulOptimizer;
198class LocalDimensionCumulOptimizer;
199class LocalSearchPhaseParameters;
201class IndexNeighborFinder;
202class IntVarFilteredDecisionBuilder;
204class RoutingDimension;
307 std::vector<DimensionCost>
315 if (
a.evaluator_index !=
b.evaluator_index) {
316 return a.evaluator_index <
b.evaluator_index;
318 return a.dimension_transit_evaluator_class_and_cost_coefficient <
319 b.dimension_transit_evaluator_class_and_cost_coefficient;
432 absl::flat_hash_map<DimensionIndex, ResourceGroup::Attributes>
433 dimension_attributes_;
451 return vehicles_requiring_resource_;
455 return vehicle_requires_resource_[vehicle];
458 const std::vector<Resource>&
GetResources()
const {
return resources_; }
460 DCHECK_LT(resource_index, resources_.size());
461 return resources_[resource_index];
465 return affected_dimension_indices_;
467 int Size()
const {
return resources_.size(); }
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_;
504 std::vector<std::vector<int64_t> > values);
510 CHECK_LT(callback_index, transit_evaluators_.size());
511 return transit_evaluators_[callback_index];
514 CHECK_LT(callback_index, unary_transit_evaluators_.size());
515 return unary_transit_evaluators_[callback_index];
518 int callback_index)
const {
519 CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
520 return state_dependent_transit_evaluators_[callback_index];
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);
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);
568 bool fix_start_cumul_to_zero,
const std::string&
name);
570 bool fix_start_cumul_to_zero,
571 const std::string&
name) {
573 fix_start_cumul_to_zero,
name);
586 bool fix_start_cumul_to_zero,
587 const std::string&
name);
598 std::vector<std::vector<int64_t> > 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,
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);
620 int64_t slack_max, std::vector<int64_t> vehicle_capacities,
621 bool fix_start_cumul_to_zero,
const std::string&
name);
625 int64_t vehicle_capacity,
bool fix_start_cumul_to_zero,
626 const std::string&
name);
628 int pure_transit,
int dependent_transit,
630 int64_t vehicle_capacity,
bool fix_start_cumul_to_zero,
631 const std::string&
name);
635 const std::function<int64_t(int64_t)>& f, int64_t domain_start,
648 std::vector<IntVar*> spans,
649 std::vector<IntVar*> total_slacks);
656 return dimensions_.get();
663 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
665 return global_dimension_optimizers_;
667 const std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >&
669 return global_dimension_mp_optimizers_;
671 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
673 return local_dimension_optimizers_;
675 const std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >&
677 return local_dimension_mp_optimizers_;
693 bool HasDimension(
const std::string& dimension_name)
const;
696 const std::string& dimension_name)
const;
700 const std::string& dimension_name)
const;
707 primary_constrained_dimension_ = dimension_name;
711 return primary_constrained_dimension_;
721 return resource_groups_;
725 DCHECK_LT(rg_index, resource_groups_.size());
726 return resource_groups_[rg_index].get();
760 int64_t max_cardinality = 1);
763 int64_t
index)
const {
764 return index_to_disjunctions_[
index];
769 template <
typename F>
771 int64_t
index, int64_t max_cardinality, F f)
const {
773 if (disjunctions_[disjunction].
value.max_cardinality == max_cardinality) {
774 for (
const int64_t d_index : disjunctions_[disjunction].indices) {
780#if !defined(SWIGPYTHON)
785 return disjunctions_[
index].indices;
789 int64_t GetDisjunctionPenalty(DisjunctionIndex index) const {
790 return disjunctions_[
index].value.penalty;
795 return disjunctions_[
index].value.max_cardinality;
801 bool HasMandatoryDisjunctions()
const;
804 bool HasMaxCardinalityConstrainedDisjunctions()
const;
809 std::vector<std::pair<int64_t, int64_t>> GetPerfectBinaryDisjunctions()
const;
815 void IgnoreDisjunctionsAlreadyForcedToZero();
820 void AddSoftSameVehicleConstraint(
const std::vector<int64_t>& indices,
827 void SetAllowedVehiclesForIndex(
const std::vector<int>& vehicles,
832 return allowed_vehicles_[
index].empty() ||
833 allowed_vehicles_[
index].find(vehicle) !=
834 allowed_vehicles_[
index].end();
852 void AddPickupAndDelivery(int64_t pickup, int64_t delivery);
856 void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction,
857 DisjunctionIndex delivery_disjunction);
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;
871 void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy);
872 void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy,
874 PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(
879 int GetNumOfSingletonNodes()
const;
884 return pickup_delivery_pairs_;
886 const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
888 return pickup_delivery_disjunctions_;
896 return implicit_pickup_delivery_pairs_without_alternatives_;
910 enum VisitTypePolicy {
925 TYPE_SIMULTANEOUSLY_ADDED_AND_REMOVED
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;
932 VisitTypePolicy GetVisitTypePolicy(int64_t
index)
const;
937 void CloseVisitTypes();
943 return topologically_sorted_visit_types_;
950 void AddHardTypeIncompatibility(int type1, int type2);
951 void AddTemporalTypeIncompatibility(
int type1,
int type2);
953 const absl::flat_hash_set<int>& GetHardTypeIncompatibilitiesOfType(
955 const absl::flat_hash_set<int>& GetTemporalTypeIncompatibilitiesOfType(
960 return has_hard_type_incompatibilities_;
963 return has_temporal_type_incompatibilities_;
975 void AddSameVehicleRequiredTypeAlternatives(
976 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
981 void AddRequiredTypeAlternativesWhenAddingType(
982 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
988 void AddRequiredTypeAlternativesWhenRemovingType(
989 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
993 const std::vector<absl::flat_hash_set<int> >&
994 GetSameVehicleRequiredTypeAlternativesOfType(
int type)
const;
996 const std::vector<absl::flat_hash_set<int> >&
997 GetRequiredTypeAlternativesWhenAddingType(
int type)
const;
999 const std::vector<absl::flat_hash_set<int> >&
1000 GetRequiredTypeAlternativesWhenRemovingType(
int type)
const;
1005 return has_same_vehicle_type_requirements_;
1008 return has_temporal_type_requirements_;
1014 return HasTemporalTypeIncompatibilities() ||
1015 HasHardTypeIncompatibilities() || HasSameVehicleTypeRequirements() ||
1016 HasTemporalTypeRequirements();
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;
1039 max_active_vehicles_ = 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;
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,
1082 return linear_cost_factor_of_vehicle_;
1086 return quadratic_cost_factor_of_vehicle_;
1091 vehicle_used_when_empty_[vehicle] = is_used;
1096 return vehicle_used_when_empty_[vehicle];
1103 return first_solution_evaluator_;
1108 first_solution_evaluator_ = std::move(evaluator);
1118 void AddAtSolutionCallback(std::function<
void()>
callback);
1123 void AddVariableMinimizedByFinalizer(
IntVar*
var);
1126 void AddVariableMaximizedByFinalizer(
IntVar*
var);
1129 void AddWeightedVariableMinimizedByFinalizer(
IntVar*
var, int64_t
cost);
1132 void AddWeightedVariableMaximizedByFinalizer(
IntVar*
var, int64_t
cost);
1135 void AddVariableTargetToFinalizer(
IntVar*
var, int64_t target);
1138 void AddWeightedVariableTargetToFinalizer(
IntVar*
var, int64_t target,
1149 void CloseModelWithParameters(
1150 const RoutingSearchParameters& search_parameters);
1166 const RoutingSearchParameters& search_parameters,
1167 std::vector<const Assignment*>* solutions =
nullptr);
1170 const Assignment* SolveFromAssignmentWithParameters(
1172 const RoutingSearchParameters& search_parameters,
1173 std::vector<const Assignment*>* solutions =
nullptr);
1176 const Assignment* SolveFromAssignmentsWithParameters(
1177 const std::vector<const Assignment*>& assignments,
1178 const RoutingSearchParameters& search_parameters,
1179 std::vector<const Assignment*>* solutions =
nullptr);
1185 void SetAssignmentFromOtherModelAssignment(
1194 int64_t ComputeLowerBound();
1205 IntVar* ApplyLocks(
const std::vector<int64_t>& locks);
1214 bool ApplyLocksToAllVehicles(
const std::vector<std::vector<int64_t>>& locks,
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,
1263 void AssignmentToRoutes(
1265 std::vector<std::vector<int64_t>>*
const routes)
const;
1271 std::vector<std::vector<int64_t>> GetRoutesFromAssignment(
1297 void AddToAssignment(
IntVar*
const var);
1309 const Assignment* PackCumulsOfOptimizerDimensionsFromAssignment(
1310 const Assignment* original_assignment, absl::Duration duration_limit);
1323 CHECK(filter !=
nullptr);
1325 LOG(
WARNING) <<
"Model is closed, filter addition will be ignored.";
1327 extra_filters_.push_back({filter, LocalSearchFilterManager::kRelax});
1328 extra_filters_.push_back({filter, LocalSearchFilterManager::kAccept});
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;
1348 bool IsVehicleUsed(
const Assignment& assignment,
int vehicle)
const;
1350#if !defined(SWIGPYTHON)
1353 const std::vector<IntVar*>&
Nexts()
const {
return nexts_; }
1356 const std::vector<IntVar*>&
VehicleVars()
const {
return vehicle_vars_; }
1361 return resource_vars_[resource_group];
1372 return vehicle_active_[vehicle];
1378 return vehicle_route_considered_[vehicle];
1387 DCHECK_LT(resource_group, resource_vars_.size());
1388 DCHECK_LT(vehicle, resource_vars_[resource_group].size());
1389 return resource_vars_[resource_group][vehicle];
1396 int64_t GetArcCostForVehicle(int64_t from_index, int64_t to_index,
1397 int64_t vehicle)
const;
1400 return costs_are_homogeneous_across_vehicles_;
1405 return GetArcCostForVehicle(from_index, to_index, 0);
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 cost_class_index)
const;
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];
1431 if (cost_class_index == kCostClassIndexOfZeroCost) {
1432 return has_vehicle_with_zero_cost_class_;
1434 return cost_class_index < cost_classes_.size();
1440 return std::max(0, GetCostClassesCount() - 1);
1444 return vehicle_class_index_of_vehicle_[vehicle];
1451 GetVehicleTypeContainer();
1457 return vehicle_type_container
1466 return same_vehicle_groups_[same_vehicle_group_[node]];
1471 return vehicle_type_container_;
1492 bool ArcIsMoreConstrainedThanArc(int64_t from, int64_t to1, int64_t to2);
1497 std::string DebugOutputAssignment(
1499 const std::string& dimension_to_print)
const;
1506 std::vector<std::vector<std::pair<int64_t, int64_t>>> GetCumulBounds(
1522 return limit_->AbsoluteSolverDeadline() - solver_->Now();
1531 int64_t
Size()
const {
return nodes_ + vehicles_ - start_end_count_; }
1535 int64_t GetNumberOfDecisionsInFirstSolution(
1536 const RoutingSearchParameters& search_parameters)
const;
1537 int64_t GetNumberOfRejectsInFirstSolution(
1538 const RoutingSearchParameters& search_parameters)
const;
1542 return automatic_first_solution_strategy_;
1546 bool IsMatchingModel()
const;
1552 std::function<std::vector<operations_research::IntVar*>(
RoutingModel*)>;
1572 std::function<int64_t(int64_t)> initializer);
1579 static std::unique_ptr<LocalSearchOperator> MakeGreedyDescentLSOperator(
1580 std::vector<IntVar*> variables);
1604 enum RoutingLocalSearchOperator {
1607 LIGHT_RELOCATE_PAIR,
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,
1626 RELOCATE_AND_MAKE_ACTIVE,
1627 MAKE_ACTIVE_AND_RELOCATE,
1629 MAKE_CHAIN_INACTIVE,
1631 EXTENDED_SWAP_ACTIVE,
1637 EXCHANGE_RELOCATE_PAIR,
1640 LOCAL_SEARCH_OPERATOR_COUNTER
1646 template <
typename T>
1647 struct ValuedNodes {
1648 std::vector<int64_t> indices;
1651 struct DisjunctionValues {
1653 int64_t max_cardinality;
1655 typedef ValuedNodes<DisjunctionValues> Disjunction;
1659 struct CostCacheElement {
1666 CostClassIndex cost_class_index;
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;
1717 void StoreDimensionCumulOptimizers(
const RoutingSearchParameters&
parameters);
1719 void ComputeCostClasses(
const RoutingSearchParameters&
parameters);
1720 void ComputeVehicleClasses();
1728 void ComputeVehicleTypes();
1738 void FinalizeVisitTypes();
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,
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 {
1752 return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle)
1753 : kCostClassIndexOfZeroCost)
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;
1772 bool RouteCanBeUsedByVehicle(
const Assignment& assignment,
int start_index,
1781 bool ReplaceUnusedVehicle(
int unused_vehicle,
int active_vehicle,
1782 Assignment* compact_assignment)
const;
1784 void QuietCloseModel();
1785 void QuietCloseModelWithParameters(
1793 bool SolveMatchingModel(Assignment* assignment,
1797 bool AppendAssignmentIfFeasible(
1798 const Assignment& assignment,
1799 std::vector<std::unique_ptr<Assignment>>* assignments);
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);
1819 Assignment* GetOrCreateAssignment();
1820 Assignment* GetOrCreateTmpAssignment();
1821 RegularLimit* GetOrCreateLimit();
1822 RegularLimit* GetOrCreateLocalSearchLimit();
1823 RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1824 RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1825 LocalSearchOperator* CreateInsertionOperator();
1826 LocalSearchOperator* CreateMakeInactiveOperator();
1828 LocalSearchOperator* CreateCPOperator(
const T& operator_factory) {
1829 return operator_factory(solver_.get(), nexts_,
1830 CostsAreHomogeneousAcrossVehicles()
1831 ? std::vector<IntVar*>()
1833 vehicle_start_class_callback_);
1836 LocalSearchOperator* CreateCPOperator() {
1837 return CreateCPOperator(MakeLocalSearchOperator<T>);
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*>()
1845 vehicle_start_class_callback_, arg));
1848 LocalSearchOperator* CreatePairOperator() {
1849 return CreateOperator<T>(pickup_delivery_pairs_);
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;
1858 struct FilterOptions {
1859 bool filter_objective;
1860 bool filter_with_cp_solver;
1862 bool operator==(
const FilterOptions& other)
const {
1863 return other.filter_objective == filter_objective &&
1864 other.filter_with_cp_solver == filter_with_cp_solver;
1866 template <
typename H>
1868 return H::combine(std::move(h), options.filter_objective,
1869 options.filter_with_cp_solver);
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_;
1904 void DetectImplicitPickupAndDeliveries();
1906 int GetVehicleStartClass(int64_t
start)
const;
1908 void InitSameVehicleGroups(
int number_of_groups) {
1909 same_vehicle_group_.assign(Size(), 0);
1910 same_vehicle_groups_.assign(number_of_groups, {});
1912 void SetSameVehicleGroup(
int index,
int group) {
1913 same_vehicle_group_[
index] = group;
1914 same_vehicle_groups_[group].push_back(
index);
1918 std::unique_ptr<Solver> solver_;
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_;
1930 std::vector<std::vector<IntVar*> > resource_vars_;
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_;
1949 std::vector<std::unique_ptr<ResourceGroup> > resource_groups_;
1952 dimension_resource_group_indices_;
1957 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1958 global_dimension_optimizers_;
1959 std::vector<std::unique_ptr<GlobalDimensionCumulOptimizer> >
1960 global_dimension_mp_optimizers_;
1962 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1963 local_dimension_optimizers_;
1964 std::vector<std::unique_ptr<LocalDimensionCumulOptimizer> >
1965 local_dimension_mp_optimizers_;
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_;
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_;
2000 VehicleTypeContainer vehicle_type_container_;
2001 std::function<int(int64_t)> vehicle_start_class_callback_;
2004 std::vector<std::vector<DisjunctionIndex> > index_to_disjunctions_;
2006 std::vector<ValuedNodes<int64_t> > same_vehicle_costs_;
2009 std::vector<absl::flat_hash_set<int>> allowed_vehicles_;
2012 IndexPairs pickup_delivery_pairs_;
2013 IndexPairs implicit_pickup_delivery_pairs_without_alternatives_;
2014 std::vector<std::pair<DisjunctionIndex, DisjunctionIndex> >
2015 pickup_delivery_disjunctions_;
2020 std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
2022 std::vector<std::vector<std::pair<int, int> > >
2023 index_to_delivery_index_pairs_;
2025 std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
2027 std::vector<int> same_vehicle_group_;
2029 std::vector<std::vector<int>> same_vehicle_groups_;
2032 std::vector<int> index_to_visit_type_;
2034 std::vector<VisitTypePolicy> index_to_type_policy_;
2036 std::vector<std::vector<int> > single_nodes_of_type_;
2037 std::vector<std::vector<int> > pair_indices_of_type_;
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_;
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<int, absl::flat_hash_set<VisitTypePolicy> >
2055 trivially_infeasible_visit_types_to_policies_;
2072 std::vector<std::vector<int> > topologically_sorted_visit_types_;
2074 int num_visit_types_;
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_;
2083 RoutingIndexManager manager_;
2084 int start_end_count_;
2086 bool closed_ =
false;
2087 Status status_ = ROUTING_NOT_SOLVED;
2088 bool enable_deep_serialization_ =
true;
2091 std::vector<DecisionBuilder*> first_solution_decision_builders_;
2092 std::vector<IntVarFilteredDecisionBuilder*>
2093 first_solution_filtered_decision_builders_;
2094 Solver::IndexEvaluator2 first_solution_evaluator_;
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_;
2117 VarTarget(IntVar* v, int64_t t) :
var(v), target(t) {}
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_;
2130 RegularLimit*
limit_ =
nullptr;
2131 RegularLimit* ls_limit_ =
nullptr;
2132 RegularLimit* lns_limit_ =
nullptr;
2133 RegularLimit* first_solution_lns_limit_ =
nullptr;
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;
2140 std::vector<TransitCallback1> unary_transit_evaluators_;
2141 std::vector<TransitCallback2> transit_evaluators_;
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_;
2168 static const char kLightElement[];
2169 static const char kLightElement2[];
2170 static const char kRemoveValues[];
2184 int num_chain_tasks = 0;
2194 int64_t span_min = 0;
2200 duration_min.clear();
2201 duration_max.clear();
2204 is_preemptible.clear();
2205 forbidden_intervals.clear();
2206 distance_duration.clear();
2209 num_chain_tasks = 0;
2215 bool Propagate(Tasks* tasks);
2218 bool Precedences(Tasks* tasks);
2221 bool MirrorTasks(Tasks* tasks);
2223 bool EdgeFinding(Tasks* tasks);
2226 bool DetectablePrecedencesWithChain(Tasks* tasks);
2228 bool ForbiddenIntervals(Tasks* tasks);
2230 bool DistanceDuration(Tasks* tasks);
2233 bool ChainSpanMin(Tasks* tasks);
2238 bool ChainSpanMinDynamic(Tasks* tasks);
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_;
2268 std::vector<int64_t>* values);
2288 return "GlobalVehicleBreaksConstraint";
2291 void Post()
override;
2292 void InitialPropagate()
override;
2295 void PropagateNode(
int node);
2296 void PropagateVehicle(
int vehicle);
2297 void PropagateMaxBreakDistance(
int vehicle);
2301 std::vector<Demon*> vehicle_demons_;
2302 std::vector<int64_t> path_;
2308 void FillPartialPathOfVehicle(
int vehicle);
2309 void FillPathTravels(
const std::vector<int64_t>& path);
2321 class TaskTranslator {
2323 TaskTranslator(
IntVar*
start, int64_t before_start, int64_t after_start)
2325 before_start_(before_start),
2326 after_start_(after_start) {}
2330 void SetStartMin(int64_t
value) {
2331 if (start_ !=
nullptr) {
2333 }
else if (interval_ !=
nullptr) {
2334 interval_->SetStartMin(
value);
2337 void SetStartMax(int64_t
value) {
2338 if (start_ !=
nullptr) {
2340 }
else if (interval_ !=
nullptr) {
2341 interval_->SetStartMax(
value);
2344 void SetDurationMin(int64_t
value) {
2345 if (interval_ !=
nullptr) {
2346 interval_->SetDurationMin(
value);
2349 void SetEndMin(int64_t
value) {
2350 if (start_ !=
nullptr) {
2352 }
else if (interval_ !=
nullptr) {
2353 interval_->SetEndMin(
value);
2356 void SetEndMax(int64_t
value) {
2357 if (start_ !=
nullptr) {
2359 }
else if (interval_ !=
nullptr) {
2360 interval_->SetEndMax(
value);
2365 IntVar* start_ =
nullptr;
2366 int64_t before_start_;
2367 int64_t after_start_;
2368 IntervalVar* interval_ =
nullptr;
2372 std::vector<TaskTranslator> task_translators_;
2375 DisjunctivePropagator disjunctive_propagator_;
2376 DisjunctivePropagator::Tasks tasks_;
2379 TravelBounds travel_bounds_;
2387 bool CheckVehicle(
int vehicle,
2388 const std::function<int64_t(int64_t)>& next_accessor);
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;
2417 bool TypeOccursOnRoute(
int type)
const;
2424 bool TypeCurrentlyOnRoute(
int type,
int pos)
const;
2426 void InitializeCheck(
int vehicle,
2427 const std::function<int64_t(int64_t)>& next_accessor);
2437 std::vector<TypePolicyOccurrence> occurrences_of_type_;
2438 std::vector<int64_t> current_route_visits_;
2445 bool check_hard_incompatibilities);
2449 bool HasRegulationsToCheck()
const override;
2450 bool CheckTypeRegulations(
int type, VisitTypePolicy policy,
int pos)
override;
2454 bool check_hard_incompatibilities_;
2465 bool HasRegulationsToCheck()
const override;
2466 void OnInitializeCheck()
override {
2467 types_with_same_vehicle_requirements_on_route_.clear();
2472 bool CheckRequiredTypesCurrentlyOnRoute(
2473 const std::vector<absl::flat_hash_set<int> >& required_type_alternatives,
2476 bool CheckTypeRegulations(
int type, VisitTypePolicy policy,
int pos)
override;
2477 bool FinalizeCheck()
const override;
2479 absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
2526 void Post()
override;
2527 void InitialPropagate()
override;
2530 void PropagateNodeRegulations(
int node);
2531 void CheckRegulationsOnVehicle(
int vehicle);
2536 std::vector<Demon*> vehicle_demons_;
2558 : bound_costs_(num_bounds, default_bound_cost) {}
2561 int Size() {
return bound_costs_.size(); }
2566 std::vector<BoundCost> bound_costs_;
2598 int64_t GetTransitValue(int64_t from_index, int64_t to_index,
2599 int64_t vehicle)
const;
2604 return model_->TransitCallback(class_evaluators_[
vehicle_class])(from_index,
2612 return fixed_transits_[
index];
2616#if !defined(SWIGPYTHON)
2621 const std::vector<IntVar*>&
transits()
const {
return transits_; }
2622 const std::vector<IntVar*>&
slacks()
const {
return slacks_; }
2623#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
2626 return forbidden_intervals_;
2630 int64_t
index, int64_t min_value, int64_t max_value)
const;
2634 int64_t min_value)
const {
2637 forbidden_intervals_[
index];
2638 const auto first_forbidden_interval_it =
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);
2653 int64_t max_value)
const {
2656 forbidden_intervals_[
index];
2657 const auto last_forbidden_interval_it =
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);
2669 return vehicle_capacities_;
2674 return model_->TransitCallback(
2675 class_evaluators_[vehicle_to_class_[vehicle]]);
2682 const int vehicle = model_->GetVehicleOfClass(
vehicle_class);
2684 return transit_evaluator(vehicle);
2691 int vehicle)
const {
2692 return model_->UnaryTransitCallbackOrNull(
2693 class_evaluators_[vehicle_to_class_[vehicle]]);
2698 return model()->is_transit_evaluator_positive_
2699 [class_evaluators_[vehicle_to_class_[vehicle]]];
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);
2729 void SetCumulVarPiecewiseLinearCost(int64_t
index,
2733 bool HasCumulVarPiecewiseLinearCost(int64_t
index)
const;
2737 int64_t
index)
const;
2752 bool HasCumulVarSoftUpperBound(int64_t
index)
const;
2756 int64_t GetCumulVarSoftUpperBound(int64_t
index)
const;
2760 int64_t GetCumulVarSoftUpperBoundCoefficient(int64_t
index)
const;
2775 bool HasCumulVarSoftLowerBound(int64_t
index)
const;
2779 int64_t GetCumulVarSoftLowerBound(int64_t
index)
const;
2783 int64_t GetCumulVarSoftLowerBoundCoefficient(int64_t
index)
const;
2800#if !defined(SWIGPYTHON)
2801 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks,
int vehicle,
2802 int pre_travel_evaluator,
2803 int post_travel_evaluator);
2807 void SetBreakIntervalsOfVehicle(std::vector<IntervalVar*> breaks,
int vehicle,
2808 std::vector<int64_t> node_visit_transits);
2814 void SetBreakDistanceDurationOfVehicle(int64_t
distance, int64_t duration,
2818 void InitializeBreaks();
2820 bool HasBreakConstraints()
const;
2821#if !defined(SWIGPYTHON)
2824 void SetBreakIntervalsOfVehicle(
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);
2830 const std::vector<IntervalVar*>& GetBreakIntervalsOfVehicle(
2835 const std::vector<std::pair<int64_t, int64_t> >&
2836 GetBreakDistanceDurationOfVehicle(
int vehicle)
const;
2839 int GetPreTravelEvaluatorOfVehicle(
int vehicle)
const;
2840 int GetPostTravelEvaluatorOfVehicle(
int vehicle)
const;
2851 int64_t ShortestTransitionSlack(int64_t node)
const;
2854 const std::string&
name()
const {
return name_; }
2859 return path_precedence_graph_;
2874 void SetPickupToDeliveryLimitFunctionForPair(
2877 bool HasPickupToDeliveryLimits()
const;
2879 int64_t GetPickupToDeliveryLimitForPair(
int pair_index,
int pickup,
2880 int delivery)
const;
2889 node_precedences_.push_back(precedence);
2892 return node_precedences_;
2898 AddNodePrecedence({first_node, second_node, offset});
2902 return vehicle_span_upper_bounds_[vehicle];
2906 return vehicle_span_upper_bounds_;
2910 return vehicle_span_cost_coefficients_[vehicle];
2915 const int vehicle = model_->GetVehicleOfClass(
vehicle_class);
2917 return GetSpanCostCoefficientForVehicle(vehicle);
2922 return vehicle_span_cost_coefficients_;
2926 return global_span_cost_coefficient_;
2931 return global_optimizer_offset_;
2934 if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2937 DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2938 return local_optimizer_offset_for_vehicle_[vehicle];
2945 if (!HasSoftSpanUpperBounds()) {
2946 vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2949 vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2952 return vehicle_soft_span_upper_bound_ !=
nullptr;
2955 int vehicle)
const {
2956 DCHECK(HasSoftSpanUpperBounds());
2957 return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2963 if (!HasQuadraticCostSoftSpanUpperBounds()) {
2964 vehicle_quadratic_cost_soft_span_upper_bound_ =
2965 absl::make_unique<SimpleBoundCosts>(
2968 vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle) =
2972 return vehicle_quadratic_cost_soft_span_upper_bound_ !=
nullptr;
2975 int vehicle)
const {
2976 DCHECK(HasQuadraticCostSoftSpanUpperBounds());
2977 return vehicle_quadratic_cost_soft_span_upper_bound_->bound_cost(vehicle);
2988 struct PiecewiseLinearCost {
2989 PiecewiseLinearCost() :
var(nullptr),
cost(nullptr) {}
2991 std::unique_ptr<PiecewiseLinearFunction>
cost;
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,
3003 void InitializeCumuls();
3004 void InitializeTransits(
3005 const std::vector<int>& transit_evaluators,
3006 const std::vector<int>& state_dependent_transit_evaluators,
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);
3024 void SetOffsetForGlobalOptimizer(int64_t offset) {
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);
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_;
3046 ReverseArcListGraph<int, int> path_precedence_graph_;
3052 std::vector<NodePrecedence> node_precedences_;
3057 const RoutingDimension*
const base_dimension_;
3062 std::vector<int> state_dependent_class_evaluators_;
3063 std::vector<int64_t> state_dependent_vehicle_to_class_;
3068 std::vector<PickupToDeliveryLimitFunction>
3069 pickup_to_delivery_limits_per_pair_index_;
3072 bool break_constraints_are_initialized_ =
false;
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_;
3081 std::vector<int> vehicle_pre_travel_evaluators_;
3082 std::vector<int> vehicle_post_travel_evaluators_;
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_;
3103 const std::vector<RoutingDimension*>&
dimensions,
3104 const RoutingSearchParameters&
parameters,
bool filter_objective_cost,
3105 std::vector<LocalSearchFilterManager::FilterEvent>* filters);
3113 std::vector<IntVar*> variables,
3114 std::vector<int64_t> targets);
3121 const RoutingSearchParameters& search_parameters,
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)
#define DCHECK_EQ(val1, val2)
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
friend void AppendDimensionCumulFilters(const std::vector< RoutingDimension * > &dimensions, const RoutingSearchParameters ¶meters, bool filter_objective_cost, std::vector< LocalSearchFilterManager::FilterEvent > *filters)
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 ResourceGroup::Attributes & GetDimensionAttributes(const RoutingDimension *dimension) const
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
const std::vector< int > & GetVehiclesRequiringAResource() const
bool VehicleRequiresAResource(int vehicle) const
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
const std::vector< Resource > & GetResources() const
ResourceGroup(const RoutingModel *model)
const absl::flat_hash_set< DimensionIndex > & GetAffectedDimensionIndices() const
void NotifyVehicleRequiresAResource(int vehicle)
Notifies that the given vehicle index requires a resource from this group if the vehicle is used (i....
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
IntVar * ResourceVar(int vehicle, int resource_group) const
Returns the resource variable for the given vehicle index in the given resource group.
ResourceGroup * GetResourceGroup(int rg_index) const
const std::vector< SearchMonitor * > & GetSearchMonitors() 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.
bool IsVehicleUsedWhenEmpty(int vehicle) const
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)
int GetDimensionResourceGroupIndex(const RoutingDimension *dimension) const
Returns the index of the resource group attached to the dimension.
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_INFEASIBLE
Problem proven to be infeasible.
@ 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
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< IntVar * > & ResourceVars(int resource_group) const
Returns vehicle resource variables for a given resource group, such that ResourceVars(r_g)[v] is the ...
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 AddResourceGroup()
Adds a resource group to the routing model.
int GetMaximumNumberOfActiveVehicles() const
Returns the maximum number of active vehicles.
RoutingDimensionIndex DimensionIndex
void SetVehicleUsedWhenEmpty(bool is_used, int vehicle)
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...
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.
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.
IntVar * VehicleRouteConsideredVar(int vehicle) const
Returns the variable specifying whether or not the given vehicle route is considered for costs and co...
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 their distance and their angle 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)
absl::StatusOr< SolveResult > Solve(const Model &model, const SolverType solver_type, const SolveArguments &solve_args, const SolverInitArguments &init_args)
H AbslHashValue(H h, const LinearConstraint &linear_constraint)
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.
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.
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)
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 * MakeRestoreDimensionValuesForUnchangedRoutes(RoutingModel *model)
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)
LinearRange operator==(const LinearExpr &lhs, const LinearExpr &rhs)
std::vector< RoutingIndexPair > RoutingIndexPairs
std::optional< int64_t > end
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
std::vector< int > required_resource_group_indices
Sorted set of resource groups for which the vehicle requires a resource.
uint64_t unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
bool used_when_empty
Whether or not the vehicle is used when empty.
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