157 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ 158 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ 161 #include <functional> 168 #include "absl/container/flat_hash_map.h" 169 #include "absl/container/flat_hash_set.h" 170 #include "absl/hash/hash.h" 171 #include "absl/time/time.h" 172 #include "ortools/base/adjustable_priority_queue-inl.h" 173 #include "ortools/base/adjustable_priority_queue.h" 174 #include "ortools/base/commandlineflags.h" 175 #include "ortools/base/hash.h" 176 #include "ortools/base/int_type_indexed_vector.h" 177 #include "ortools/base/logging.h" 178 #include "ortools/base/macros.h" 184 #include "ortools/glop/lp_solver.h" 185 #include "ortools/glop/parameters.pb.h" 186 #include "ortools/graph/graph.h" 187 #include "ortools/lp_data/lp_data.h" 188 #include "ortools/lp_data/lp_types.h" 189 #include "ortools/sat/theta_tree.h" 190 #include "ortools/util/range_query_function.h" 191 #include "ortools/util/sorted_interval_list.h" 195 class IntVarFilteredDecisionBuilder;
196 class LocalSearchOperator;
197 class RoutingDimension;
199 using util::ReverseArcListGraph;
299 std::vector<DimensionCost>
344 #endif // defined(SWIG) 372 CHECK_LT(callback_index, transit_evaluators_.size());
373 return transit_evaluators_[callback_index];
376 CHECK_LT(callback_index, unary_transit_evaluators_.size());
377 return unary_transit_evaluators_[callback_index];
380 int callback_index)
const {
381 CHECK_LT(callback_index, state_dependent_transit_evaluators_.size());
382 return state_dependent_transit_evaluators_[callback_index];
407 bool AddDimension(
int evaluator_index, int64 slack_max, int64 capacity,
408 bool fix_start_cumul_to_zero,
const std::string& name);
410 const std::vector<int>& evaluator_indices, int64 slack_max,
411 int64 capacity,
bool fix_start_cumul_to_zero,
const std::string& name);
413 std::vector<int64> vehicle_capacities,
414 bool fix_start_cumul_to_zero,
415 const std::string& name);
417 const std::vector<int>& evaluator_indices, int64 slack_max,
418 std::vector<int64> vehicle_capacities,
bool fix_start_cumul_to_zero,
419 const std::string& name);
428 bool fix_start_cumul_to_zero,
429 const std::string& name);
431 bool fix_start_cumul_to_zero,
432 const std::string& name) {
434 fix_start_cumul_to_zero, name);
444 bool fix_start_cumul_to_zero,
445 const std::string& name);
454 int64 capacity,
bool fix_start_cumul_to_zero,
455 const std::string& name);
463 const std::vector<int>& pure_transits,
464 const std::vector<int>& dependent_transits,
466 std::vector<int64> vehicle_capacities,
bool fix_start_cumul_to_zero,
467 const std::string& name) {
468 return AddDimensionDependentDimensionWithVehicleCapacityInternal(
469 pure_transits, dependent_transits, base_dimension, slack_max,
470 std::move(vehicle_capacities), fix_start_cumul_to_zero, name);
475 int64 slack_max, std::vector<int64> vehicle_capacities,
476 bool fix_start_cumul_to_zero,
const std::string& name);
480 int64 vehicle_capacity,
bool fix_start_cumul_to_zero,
481 const std::string& name);
483 int pure_transit,
int dependent_transit,
485 int64 vehicle_capacity,
bool fix_start_cumul_to_zero,
486 const std::string& name);
490 const std::function<int64(int64)>& f, int64 domain_start,
503 std::vector<IntVar*> spans,
504 std::vector<IntVar*> total_slacks);
511 return dimensions_.get();
519 return dimensions_for_global_optimizer_;
523 return dimensions_for_local_optimizer_;
526 bool HasDimension(
const std::string& dimension_name)
const;
529 const std::string& dimension_name)
const;
533 const std::string& dimension_name)
const;
539 DCHECK(dimension_name.empty() ||
HasDimension(dimension_name));
540 primary_constrained_dimension_ = dimension_name;
545 return primary_constrained_dimension_;
565 int64 max_cardinality = 1);
569 return index_to_disjunctions_[index];
574 template <
typename F>
576 int64 index, int64 max_cardinality, F f)
const {
578 if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) {
579 for (
const int64 d_index : disjunctions_[disjunction].indices) {
585 #if !defined(SWIGPYTHON) 590 return disjunctions_[index].indices;
592 #endif // !defined(SWIGPYTHON) 595 return disjunctions_[index].value.penalty;
600 return disjunctions_[index].value.max_cardinality;
631 return allowed_vehicles_[index].empty() ||
632 allowed_vehicles_[index].find(vehicle) !=
633 allowed_vehicles_[index].end();
661 const std::vector<std::pair<int, int> >&
664 const std::vector<std::pair<int, int> >&
683 return pickup_delivery_pairs_;
685 const std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>&
687 return pickup_delivery_disjunctions_;
728 return has_hard_type_incompatibilities_;
731 return has_temporal_type_incompatibilities_;
744 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
749 int dependent_type, absl::flat_hash_set<int> required_type_alternatives);
753 const std::vector<absl::flat_hash_set<int> >&
755 const std::vector<absl::flat_hash_set<int> >&
761 return has_same_vehicle_type_requirements_;
764 return has_temporal_type_requirements_;
821 int64 quadratic_cost_factor);
824 int64 quadratic_cost_factor,
828 return linear_cost_factor_of_vehicle_;
831 return quadratic_cost_factor_of_vehicle_;
835 DCHECK_LT(vehicle, vehicles_);
836 consider_empty_route_costs_[vehicle] = consider_costs;
840 DCHECK_LT(vehicle, vehicles_);
841 return consider_empty_route_costs_[vehicle];
848 return first_solution_evaluator_;
853 first_solution_evaluator_ = std::move(evaluator);
888 const RoutingSearchParameters& search_parameters);
895 const Assignment*
Solve(
const Assignment* assignment =
nullptr);
904 const RoutingSearchParameters& search_parameters,
905 std::vector<const Assignment*>* solutions =
nullptr);
907 const Assignment* assignment,
908 const RoutingSearchParameters& search_parameters,
909 std::vector<const Assignment*>* solutions =
nullptr);
916 Assignment* target_assignment,
const RoutingModel* source_model,
917 const Assignment* source_assignment);
969 const std::vector<std::vector<int64>>& routes,
970 bool ignore_inactive_indices);
988 bool ignore_inactive_indices,
bool close_routes,
994 std::vector<std::vector<int64>>*
const routes)
const;
1030 const Assignment* original_assignment, absl::Duration duration_limit);
1045 CHECK(filter !=
nullptr);
1047 LOG(WARNING) <<
"Model is closed, filter addition will be ignored.";
1049 extra_filters_.push_back(filter);
1054 int64
Start(
int vehicle)
const {
return starts_[vehicle]; }
1056 int64
End(
int vehicle)
const {
return ends_[vehicle]; }
1058 bool IsStart(int64 index)
const;
1071 #if !defined(SWIGPYTHON) 1072 const std::vector<IntVar*>&
Nexts()
const {
return nexts_; }
1077 const std::vector<IntVar*>&
VehicleVars()
const {
return vehicle_vars_; }
1079 IntVar* NextVar(int64 index) const { return nexts_[index]; } 1087 return vehicle_costs_considered_[vehicle];
1098 int64 vehicle)
const;
1101 return costs_are_homogeneous_across_vehicles_;
1118 int64 cost_class_index)
const;
1122 return cost_class_index_of_vehicle_[vehicle];
1128 if (cost_class_index == kCostClassIndexOfZeroCost) {
1129 return has_vehicle_with_zero_cost_class_;
1131 return cost_class_index < cost_classes_.size();
1141 return vehicle_class_index_of_vehicle_[vehicle];
1148 return same_vehicle_groups_[same_vehicle_group_[node]];
1175 const std::string& dimension_to_print)
const;
1183 DCHECK(limit_ !=
nullptr);
1184 return limit_->
Check();
1189 DCHECK(limit_ !=
nullptr);
1199 int64
Size()
const {
return nodes_ + vehicles_ - start_end_count_; }
1235 std::function<int64(int64)> initializer);
1243 std::vector<IntVar*> variables);
1245 DecisionBuilder* MakeSelfDependentDimensionFinalizer( 1263 enum RoutingLocalSearchOperator {
1266 LIGHT_RELOCATE_PAIR,
1274 RELOCATE_EXPENSIVE_CHAIN,
1278 RELOCATE_AND_MAKE_ACTIVE,
1279 MAKE_ACTIVE_AND_RELOCATE,
1281 MAKE_CHAIN_INACTIVE,
1283 EXTENDED_SWAP_ACTIVE,
1289 EXCHANGE_RELOCATE_PAIR,
1292 LOCAL_SEARCH_OPERATOR_COUNTER
1298 template <
typename T>
1299 struct ValuedNodes {
1300 std::vector<int64> indices;
1303 struct DisjunctionValues {
1305 int64 max_cardinality;
1307 typedef ValuedNodes<DisjunctionValues> Disjunction;
1311 struct CostCacheElement {
1323 void AddNoCycleConstraintInternal();
1324 bool AddDimensionWithCapacityInternal(
1325 const std::vector<int>& evaluator_indices, int64 slack_max,
1326 std::vector<int64> vehicle_capacities,
bool fix_start_cumul_to_zero,
1327 const std::string& name);
1328 bool AddDimensionDependentDimensionWithVehicleCapacityInternal(
1329 const std::vector<int>& pure_transits,
1330 const std::vector<int>& dependent_transits,
1332 std::vector<int64> vehicle_capacities,
bool fix_start_cumul_to_zero,
1333 const std::string& name);
1334 bool InitializeDimensionInternal(
1335 const std::vector<int>& evaluator_indices,
1336 const std::vector<int>& state_dependent_evaluator_indices,
1337 int64 slack_max,
bool fix_start_cumul_to_zero,
1339 DimensionIndex GetDimensionIndex(
const std::string& dimension_name)
const;
1367 void StoreDimensionsForDimensionCumulOptimizers();
1369 void ComputeCostClasses(
const RoutingSearchParameters& parameters);
1370 void ComputeVehicleClasses();
1371 int64 GetArcCostForClassInternal(int64 from_index, int64 to_index,
1373 void AppendHomogeneousArcCosts(
const RoutingSearchParameters& parameters,
1375 std::vector<IntVar*>* cost_elements);
1376 void AppendArcCosts(
const RoutingSearchParameters& parameters,
int node_index,
1377 std::vector<IntVar*>* cost_elements);
1378 Assignment* DoRestoreAssignment();
1380 int64 SafeGetCostClassInt64OfVehicle(int64 vehicle)
const {
1381 DCHECK_LT(0, vehicles_);
1383 : kCostClassIndexOfZeroCost)
1386 int64 GetDimensionTransitCostSum(int64 i, int64 j,
1387 const CostClass& cost_class)
const;
1391 void AddPickupAndDeliverySetsInternal(
const std::vector<int64>& pickups,
1392 const std::vector<int64>& deliveries);
1395 IntVar* CreateSameVehicleCost(
int vehicle_index);
1398 int FindNextActive(
int index,
const std::vector<int64>& indices)
const;
1402 bool RouteCanBeUsedByVehicle(
const Assignment& assignment,
int start_index,
1411 bool ReplaceUnusedVehicle(
int unused_vehicle,
int active_vehicle,
1412 Assignment* compact_assignment)
const;
1414 void QuietCloseModel();
1415 void QuietCloseModelWithParameters(
1416 const RoutingSearchParameters& parameters) {
1423 bool SolveMatchingModel(Assignment* assignment);
1425 bool AppendAssignmentIfFeasible(
1427 const Assignment& assignment,
1428 std::vector<std::unique_ptr<Assignment>>* assignments);
1430 void LogSolution(
const RoutingSearchParameters& parameters,
1432 const std::string& description, int64 solution_cost,
1433 int64 start_time_ms);
1436 Assignment* CompactAssignmentInternal(
const Assignment& assignment,
1437 bool check_compact_assignment)
const;
1442 std::string FindErrorInSearchParametersForModel(
1443 const RoutingSearchParameters& search_parameters)
const;
1445 void SetupSearch(
const RoutingSearchParameters& search_parameters);
1448 Assignment* GetOrCreateAssignment();
1449 Assignment* GetOrCreateTmpAssignment();
1450 RegularLimit* GetOrCreateLimit();
1451 RegularLimit* GetOrCreateLocalSearchLimit();
1452 RegularLimit* GetOrCreateLargeNeighborhoodSearchLimit();
1453 RegularLimit* GetOrCreateFirstSolutionLargeNeighborhoodSearchLimit();
1454 LocalSearchOperator* CreateInsertionOperator();
1455 LocalSearchOperator* CreateMakeInactiveOperator();
1456 void CreateNeighborhoodOperators(
const RoutingSearchParameters& parameters);
1457 LocalSearchOperator* GetNeighborhoodOperators(
1458 const RoutingSearchParameters& search_parameters)
const;
1459 const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters();
1460 const std::vector<LocalSearchFilter*>& GetOrCreateFeasibilityFilters();
1461 DecisionBuilder* CreateSolutionFinalizer(SearchLimit* lns_limit);
1462 DecisionBuilder* CreateFinalizerForMinimizedAndMaximizedVariables();
1463 void CreateFirstSolutionDecisionBuilders(
1464 const RoutingSearchParameters& search_parameters);
1465 DecisionBuilder* GetFirstSolutionDecisionBuilder(
1466 const RoutingSearchParameters& search_parameters)
const;
1467 IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull(
1468 const RoutingSearchParameters& parameters)
const;
1469 LocalSearchPhaseParameters* CreateLocalSearchParameters(
1470 const RoutingSearchParameters& search_parameters);
1471 DecisionBuilder* CreateLocalSearchDecisionBuilder(
1472 const RoutingSearchParameters& search_parameters);
1473 void SetupDecisionBuilders(
const RoutingSearchParameters& search_parameters);
1474 void SetupMetaheuristics(
const RoutingSearchParameters& search_parameters);
1475 void SetupAssignmentCollector(
1476 const RoutingSearchParameters& search_parameters);
1477 void SetupTrace(
const RoutingSearchParameters& search_parameters);
1478 void SetupSearchMonitors(
const RoutingSearchParameters& search_parameters);
1479 bool UsesLightPropagation(
1480 const RoutingSearchParameters& search_parameters)
const;
1483 int GetVehicleStartClass(int64 start)
const;
1485 void InitSameVehicleGroups(
int number_of_groups) {
1486 same_vehicle_group_.assign(
Size(), 0);
1487 same_vehicle_groups_.assign(number_of_groups, {});
1489 void SetSameVehicleGroup(
int index,
int group) {
1490 same_vehicle_group_[index] = group;
1491 same_vehicle_groups_[group].push_back(index);
1495 std::unique_ptr<Solver> solver_;
1498 Constraint* no_cycle_constraint_ =
nullptr;
1500 std::vector<IntVar*> nexts_;
1501 std::vector<IntVar*> vehicle_vars_;
1502 std::vector<IntVar*> active_;
1503 std::vector<IntVar*> vehicle_costs_considered_;
1508 std::vector<IntVar*> is_bound_to_end_;
1509 mutable RevSwitch is_bound_to_end_ct_added_;
1511 absl::flat_hash_map<std::string, DimensionIndex> dimension_name_to_index_;
1512 gtl::ITIVector<DimensionIndex, RoutingDimension*> dimensions_;
1513 std::vector<RoutingDimension*> dimensions_for_global_optimizer_;
1514 std::vector<RoutingDimension*> dimensions_for_local_optimizer_;
1515 std::string primary_constrained_dimension_;
1517 IntVar* cost_ =
nullptr;
1518 std::vector<int> vehicle_to_transit_cost_;
1519 std::vector<int64> fixed_cost_of_vehicle_;
1520 std::vector<CostClassIndex> cost_class_index_of_vehicle_;
1521 bool has_vehicle_with_zero_cost_class_;
1522 std::vector<int64> linear_cost_factor_of_vehicle_;
1523 std::vector<int64> quadratic_cost_factor_of_vehicle_;
1524 bool vehicle_amortized_cost_factors_set_;
1535 std::vector<bool> consider_empty_route_costs_;
1537 gtl::ITIVector<CostClassIndex, CostClass> cost_classes_;
1539 bool costs_are_homogeneous_across_vehicles_;
1540 bool cache_callbacks_;
1541 mutable std::vector<CostCacheElement> cost_cache_;
1542 std::vector<VehicleClassIndex> vehicle_class_index_of_vehicle_;
1544 gtl::ITIVector<VehicleClassIndex, VehicleClass> vehicle_classes_;
1546 std::function<int(int64)> vehicle_start_class_callback_;
1548 gtl::ITIVector<DisjunctionIndex, Disjunction> disjunctions_;
1549 std::vector<std::vector<DisjunctionIndex>> index_to_disjunctions_;
1551 std::vector<ValuedNodes<int64>> same_vehicle_costs_;
1554 std::vector<std::unordered_set<int>> allowed_vehicles_;
1558 std::vector<std::pair<DisjunctionIndex, DisjunctionIndex>>
1559 pickup_delivery_disjunctions_;
1564 std::vector<std::vector<std::pair<int, int> > > index_to_pickup_index_pairs_;
1566 std::vector<std::vector<std::pair<int, int> > >
1567 index_to_delivery_index_pairs_;
1569 std::vector<PickupAndDeliveryPolicy> vehicle_pickup_delivery_policy_;
1571 std::vector<int> same_vehicle_group_;
1573 std::vector<std::vector<int>> same_vehicle_groups_;
1576 std::vector<int> index_to_visit_type_;
1578 std::vector<absl::flat_hash_set<int> >
1579 hard_incompatible_types_per_type_index_;
1580 bool has_hard_type_incompatibilities_;
1581 std::vector<absl::flat_hash_set<int> >
1582 temporal_incompatible_types_per_type_index_;
1583 bool has_temporal_type_incompatibilities_;
1585 std::vector<std::vector<absl::flat_hash_set<int> > >
1586 same_vehicle_required_type_alternatives_per_type_index_;
1587 bool has_same_vehicle_type_requirements_;
1588 std::vector<std::vector<absl::flat_hash_set<int> > >
1589 temporal_required_type_alternatives_per_type_index_;
1590 bool has_temporal_type_requirements_;
1591 absl::flat_hash_set<int> trivially_infeasible_visit_types_;
1593 int num_visit_types_;
1596 std::vector<int> index_to_equivalence_class_;
1597 std::vector<int> index_to_vehicle_;
1598 std::vector<int64> starts_;
1599 std::vector<int64> ends_;
1602 RoutingIndexManager manager_;
1603 int start_end_count_;
1605 bool closed_ =
false;
1607 bool enable_deep_serialization_ =
true;
1610 std::vector<DecisionBuilder*> first_solution_decision_builders_;
1611 std::vector<IntVarFilteredDecisionBuilder*>
1612 first_solution_filtered_decision_builders_;
1614 std::vector<LocalSearchOperator*> local_search_operators_;
1615 std::vector<SearchMonitor*> monitors_;
1616 SolutionCollector* collect_assignments_ =
nullptr;
1617 SolutionCollector* collect_one_assignment_ =
nullptr;
1618 SolutionCollector* packed_dimensions_assignment_collector_ =
nullptr;
1619 DecisionBuilder* solve_db_ =
nullptr;
1620 DecisionBuilder* improve_db_ =
nullptr;
1621 DecisionBuilder* restore_assignment_ =
nullptr;
1622 DecisionBuilder* restore_tmp_assignment_ =
nullptr;
1623 Assignment* assignment_ =
nullptr;
1624 Assignment* preassignment_ =
nullptr;
1625 Assignment* tmp_assignment_ =
nullptr;
1626 std::vector<IntVar*> extra_vars_;
1627 std::vector<IntervalVar*> extra_intervals_;
1628 std::vector<LocalSearchOperator*> extra_operators_;
1629 std::vector<LocalSearchFilter*> filters_;
1630 std::vector<LocalSearchFilter*> feasibility_filters_;
1631 std::vector<LocalSearchFilter*> extra_filters_;
1633 std::vector<std::pair<IntVar*, int64>> finalizer_variable_cost_pairs_;
1634 std::vector<std::pair<IntVar*, int64>> finalizer_variable_target_pairs_;
1635 absl::flat_hash_map<IntVar*, int> finalizer_variable_cost_index_;
1636 absl::flat_hash_set<IntVar*> finalizer_variable_target_set_;
1637 std::unique_ptr<SweepArranger> sweep_arranger_;
1640 RegularLimit* limit_ =
nullptr;
1641 RegularLimit* ls_limit_ =
nullptr;
1642 RegularLimit* lns_limit_ =
nullptr;
1643 RegularLimit* first_solution_lns_limit_ =
nullptr;
1645 typedef std::pair<int64, int64> CacheKey;
1646 typedef absl::flat_hash_map<CacheKey, int64> TransitCallbackCache;
1647 typedef absl::flat_hash_map<CacheKey, StateDependentTransit>
1648 StateDependentTransitCallbackCache;
1650 std::vector<TransitCallback1> unary_transit_evaluators_;
1651 std::vector<TransitCallback2> transit_evaluators_;
1662 std::vector<bool> is_transit_evaluator_positive_;
1663 std::vector<VariableIndexEvaluator2> state_dependent_transit_evaluators_;
1664 std::vector<std::unique_ptr<StateDependentTransitCallbackCache>>
1665 state_dependent_transit_evaluators_cache_;
1738 sat::ThetaLambdaTree<int64> theta_lambda_tree_;
1740 std::vector<int> tasks_by_start_min_;
1741 std::vector<int> tasks_by_end_max_;
1742 std::vector<int> event_of_task_;
1743 std::vector<int> nonchain_tasks_by_start_max_;
1747 const std::vector<int64>& min_travels,
1748 const std::vector<int64>& max_travels,
1749 const std::vector<int64>& pre_travels,
1750 const std::vector<int64>& post_travels,
1751 const RoutingDimension& dimension,
1752 DisjunctivePropagator::Tasks* tasks);
1754 DisjunctivePropagator::Tasks* tasks);
1757 std::vector<int64>* values);
1758 #endif // !defined(SWIG) 1774 void Post()
override;
1778 void PropagateNode(
int node);
1779 void PropagateVehicle(
int vehicle);
1780 void PropagateMaxBreakDistance(
int vehicle);
1784 std::vector<Demon*> vehicle_demons_;
1785 std::vector<int64> path_;
1791 void FillPartialPathOfVehicle(
int vehicle);
1792 void FillPathTravels(
const std::vector<int64>& path);
1804 class TaskTranslator {
1806 TaskTranslator(
IntVar* start, int64 before_start, int64 after_start)
1808 before_start_(before_start),
1809 after_start_(after_start) {}
1810 explicit TaskTranslator(
IntervalVar* interval) : interval_(interval) {}
1813 void SetStartMin(int64 value) {
1814 if (start_ !=
nullptr) {
1815 start_->SetMin(CapAdd(before_start_, value));
1816 }
else if (interval_ !=
nullptr) {
1817 interval_->SetStartMin(value);
1820 void SetStartMax(int64 value) {
1821 if (start_ !=
nullptr) {
1822 start_->SetMax(CapAdd(before_start_, value));
1823 }
else if (interval_ !=
nullptr) {
1824 interval_->SetStartMax(value);
1827 void SetDurationMin(int64 value) {
1828 if (interval_ !=
nullptr) {
1829 interval_->SetDurationMin(value);
1832 void SetEndMin(int64 value) {
1833 if (start_ !=
nullptr) {
1834 start_->SetMin(CapSub(value, after_start_));
1835 }
else if (interval_ !=
nullptr) {
1836 interval_->SetEndMin(value);
1839 void SetEndMax(int64 value) {
1840 if (start_ !=
nullptr) {
1841 start_->SetMax(CapSub(value, after_start_));
1842 }
else if (interval_ !=
nullptr) {
1843 interval_->SetEndMax(value);
1848 IntVar* start_ =
nullptr;
1849 int64 before_start_;
1855 std::vector<TaskTranslator> task_translators_;
1862 std::vector<int64> min_travel_;
1863 std::vector<int64> max_travel_;
1864 std::vector<int64> pre_travel_;
1865 std::vector<int64> post_travel_;
1874 const std::function<int64(int64)>& next_accessor);
1898 std::vector<PickupDeliveryStatus> pickup_delivery_status_of_node_;
1899 std::vector<NodeCount> counts_of_type_;
1906 bool check_hard_incompatibilities);
1910 bool HasRegulationsToCheck()
const override;
1911 bool CheckTypeRegulations(
int type)
override;
1915 bool check_hard_incompatibilities_;
1926 bool HasRegulationsToCheck()
const override;
1927 void InitializeCheck()
override {
1928 types_with_same_vehicle_requirements_on_route_.clear();
1930 bool CheckTypeRegulations(
int type)
override;
1931 bool FinalizeCheck()
const override;
1933 absl::flat_hash_set<int> types_with_same_vehicle_requirements_on_route_;
1959 void Post()
override;
1963 void PropagateNodeRegulations(
int node);
1964 void CheckRegulationsOnVehicle(
int vehicle);
1969 std::vector<Demon*> vehicle_demons_;
1991 : bound_costs_(num_bounds, default_bound_cost) {}
1994 int Size() {
return bound_costs_.size(); }
1999 std::vector<BoundCost> bound_costs_;
2001 #endif // !defined SWIG 2031 int64
GetTransitValue(int64 from_index, int64 to_index, int64 vehicle)
const;
2035 int64 vehicle_class)
const {
2036 return model_->
TransitCallback(class_evaluators_[vehicle_class])(from_index,
2046 #if !defined(SWIGPYTHON) 2047 const std::vector<IntVar*>&
cumuls()
const {
return cumuls_; }
2051 const std::vector<IntVar*>&
transits()
const {
return transits_; }
2052 const std::vector<IntVar*>&
slacks()
const {
return slacks_; }
2053 #if !defined(SWIGCSHARP) && !defined(SWIGJAVA) 2056 return forbidden_intervals_;
2060 return vehicle_capacities_;
2066 class_evaluators_[vehicle_to_class_[vehicle]]);
2072 int vehicle)
const {
2074 class_evaluators_[vehicle_to_class_[vehicle]]);
2079 return model()->is_transit_evaluator_positive_
2080 [class_evaluators_[vehicle_to_class_[vehicle]]];
2085 void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle); 2111 const PiecewiseLinearFunction& cost);
2184 #if !defined(SWIGPYTHON) 2186 int pre_travel_evaluator,
2187 int post_travel_evaluator);
2188 #endif // !defined(SWIGPYTHON) 2192 std::vector<int64> node_visit_transits);
2205 #if !defined(SWIGPYTHON) 2209 std::vector<IntervalVar*> breaks,
int vehicle,
2210 std::vector<int64> node_visit_transits,
2211 std::function<int64(int64, int64)> group_delays);
2219 const std::vector<std::pair<int64, int64> >&
2223 int GetPreTravelEvaluatorOfVehicle(int vehicle) const; 2238 const std::string&
name()
const {
return name_; }
2243 return path_precedence_graph_;
2264 int delivery)
const;
2273 node_precedences_.push_back(precedence);
2276 return node_precedences_;
2285 return vehicle_span_upper_bounds_[vehicle];
2289 return vehicle_span_upper_bounds_;
2293 return vehicle_span_cost_coefficients_[vehicle];
2297 return vehicle_span_cost_coefficients_;
2301 return global_span_cost_coefficient_;
2305 DCHECK_GE(global_optimizer_offset_, 0);
2306 return global_optimizer_offset_;
2309 if (vehicle >= local_optimizer_offset_for_vehicle_.size()) {
2312 DCHECK_GE(local_optimizer_offset_for_vehicle_[vehicle], 0);
2313 return local_optimizer_offset_for_vehicle_[vehicle];
2321 vehicle_soft_span_upper_bound_ = absl::make_unique<SimpleBoundCosts>(
2324 vehicle_soft_span_upper_bound_->bound_cost(vehicle) = bound_cost;
2327 return vehicle_soft_span_upper_bound_ !=
nullptr;
2330 int vehicle)
const {
2332 return vehicle_soft_span_upper_bound_->bound_cost(vehicle);
2343 struct PiecewiseLinearCost {
2344 PiecewiseLinearCost() : var(nullptr), cost(nullptr) {}
2346 std::unique_ptr<PiecewiseLinearFunction> cost;
2351 const std::string&
name,
2354 const std::string&
name, SelfBased);
2355 void Initialize(
const std::vector<int>& transit_evaluators,
2356 const std::vector<int>& state_dependent_transit_evaluators,
2358 void InitializeCumuls();
2359 void InitializeTransits(
2360 const std::vector<int>& transit_evaluators,
2361 const std::vector<int>& state_dependent_transit_evaluators,
2363 void InitializeTransitVariables(int64 slack_max);
2365 void SetupCumulVarSoftUpperBoundCosts(
2366 std::vector<IntVar*>* cost_elements)
const;
2368 void SetupCumulVarSoftLowerBoundCosts(
2369 std::vector<IntVar*>* cost_elements)
const;
2370 void SetupCumulVarPiecewiseLinearCosts(
2371 std::vector<IntVar*>* cost_elements)
const;
2374 void SetupGlobalSpanCost(std::vector<IntVar*>* cost_elements)
const;
2375 void SetupSlackAndDependentTransitCosts()
const;
2377 void CloseModel(
bool use_light_propagation);
2379 void SetOffsetForGlobalOptimizer(int64 offset) {
2380 global_optimizer_offset_ = std::max(
Zero(), offset);
2383 void SetVehicleOffsetsForLocalOptimizer(std::vector<int64> offsets) {
2385 std::transform(offsets.begin(), offsets.end(), offsets.begin(),
2386 [](int64 offset) {
return std::max(
Zero(), offset); });
2387 local_optimizer_offset_for_vehicle_ = std::move(offsets);
2390 std::vector<IntVar*> cumuls_;
2391 std::vector<SortedDisjointIntervalList> forbidden_intervals_;
2392 std::vector<IntVar*> capacity_vars_;
2393 const std::vector<int64> vehicle_capacities_;
2394 std::vector<IntVar*> transits_;
2395 std::vector<IntVar*> fixed_transits_;
2398 std::vector<int> class_evaluators_;
2399 std::vector<int64> vehicle_to_class_;
2401 ReverseArcListGraph<int, int> path_precedence_graph_;
2407 std::vector<NodePrecedence> node_precedences_;
2412 const RoutingDimension*
const base_dimension_;
2417 std::vector<int> state_dependent_class_evaluators_;
2418 std::vector<int64> state_dependent_vehicle_to_class_;
2423 std::vector<PickupToDeliveryLimitFunction>
2424 pickup_to_delivery_limits_per_pair_index_;
2427 bool break_constraints_are_initialized_ =
false;
2429 std::vector<std::vector<IntervalVar*> > vehicle_break_intervals_;
2430 std::vector<std::vector<std::pair<int64, int64> > >
2431 vehicle_break_distance_duration_;
2436 std::vector<int> vehicle_pre_travel_evaluators_;
2437 std::vector<int> vehicle_post_travel_evaluators_;
2439 std::vector<IntVar*> slacks_;
2440 std::vector<IntVar*> dependent_transits_;
2441 std::vector<int64> vehicle_span_upper_bounds_;
2442 int64 global_span_cost_coefficient_;
2443 std::vector<int64> vehicle_span_cost_coefficients_;
2444 std::vector<SoftBound> cumul_var_soft_upper_bound_;
2445 std::vector<SoftBound> cumul_var_soft_lower_bound_;
2446 std::vector<PiecewiseLinearCost> cumul_var_piecewise_linear_cost_;
2448 const std::string name_;
2449 int64 global_optimizer_offset_;
2450 std::vector<int64> local_optimizer_offset_for_vehicle_;
2452 std::unique_ptr<SimpleBoundCosts> vehicle_soft_span_upper_bound_;
2464 explicit SweepArranger(
const std::vector<std::pair<int64, int64>>& points);
2470 std::vector<int> coordinates_;
2480 std::vector<IntVar*> variables,
2481 std::vector<int64> targets);
2501 const std::vector<IntVar*>& vars,
2502 const std::vector<LocalSearchFilter*>& filters);
2524 if (!is_in_delta_[index]) {
2526 delta_indices_.push_back(index);
2527 is_in_delta_[index] =
true;
2529 delta_->
SetValue(vars_[index], value);
2543 int Size()
const {
return vars_.size(); }
2549 void SynchronizeFilters();
2552 bool FilterAccept();
2554 const std::vector<IntVar*> vars_;
2557 std::vector<int> delta_indices_;
2558 std::vector<bool> is_in_delta_;
2562 int64 number_of_decisions_;
2563 int64 number_of_rejects_;
2588 bool InitializeSolution()
override;
2591 std::vector<int64> start_chain_ends_;
2592 std::vector<int64> end_chain_starts_;
2601 std::function<int64(int64)> penalty_evaluator,
2602 const std::vector<LocalSearchFilter*>& filters);
2624 std::vector<std::vector<StartEndValue> >
2631 template <
class Queue>
2633 std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
2634 Queue* priority_queue);
2641 void InsertBetween(int64 node, int64 predecessor, int64 successor);
2647 int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle,
2648 std::vector<ValuedPosition>* valued_positions);
2670 std::function<int64(int64)> penalty_evaluator,
2671 const std::vector<LocalSearchFilter*>& filters,
bool is_sequential,
2672 double farthest_seeds_ratio,
double neighbors_ratio);
2676 return "GlobalCheapestInsertionFilteredDecisionBuilder";
2682 typedef absl::flat_hash_set<PairEntry*> PairEntries;
2683 typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
2700 void InsertNodesOnRoutes(
const std::vector<int>& nodes,
2701 const std::vector<int>& vehicles);
2708 void SequentialInsertNodes(
const std::vector<int>& nodes);
2713 void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
2714 std::vector<int>* used_vehicles,
2715 std::vector<int>* unused_vehicles);
2720 void InsertFarthestNodesAsSeeds();
2730 template <
class Queue>
2732 std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
2733 Queue* priority_queue, std::vector<bool>* is_vehicle_used);
2738 void InitializePairPositions(
2739 AdjustablePriorityQueue<PairEntry>* priority_queue,
2740 std::vector<PairEntries>* pickup_to_entries,
2741 std::vector<PairEntries>* delivery_to_entries);
2744 void UpdatePairPositions(
int vehicle, int64 insert_after,
2745 AdjustablePriorityQueue<PairEntry>* priority_queue,
2746 std::vector<PairEntries>* pickup_to_entries,
2747 std::vector<PairEntries>* delivery_to_entries) {
2748 UpdatePickupPositions(vehicle, insert_after, priority_queue,
2749 pickup_to_entries, delivery_to_entries);
2750 UpdateDeliveryPositions(vehicle, insert_after, priority_queue,
2751 pickup_to_entries, delivery_to_entries);
2755 void UpdatePickupPositions(
int vehicle, int64 pickup_insert_after,
2756 AdjustablePriorityQueue<PairEntry>* priority_queue,
2757 std::vector<PairEntries>* pickup_to_entries,
2758 std::vector<PairEntries>* delivery_to_entries);
2761 void UpdateDeliveryPositions(
2762 int vehicle, int64 delivery_insert_after,
2763 AdjustablePriorityQueue<PairEntry>* priority_queue,
2764 std::vector<PairEntries>* pickup_to_entries,
2765 std::vector<PairEntries>* delivery_to_entries);
2768 void DeletePairEntry(PairEntry* entry,
2769 AdjustablePriorityQueue<PairEntry>* priority_queue,
2770 std::vector<PairEntries>* pickup_to_entries,
2771 std::vector<PairEntries>* delivery_to_entries);
2774 void InitializePositions(
const std::vector<int>& nodes,
2775 AdjustablePriorityQueue<NodeEntry>* priority_queue,
2776 std::vector<NodeEntries>* position_to_node_entries,
2777 const std::vector<int>& vehicles);
2780 void UpdatePositions(
const std::vector<int>& nodes,
int vehicle,
2782 AdjustablePriorityQueue<NodeEntry>* priority_queue,
2783 std::vector<NodeEntries>* node_entries);
2786 void DeleteNodeEntry(NodeEntry* entry,
2787 AdjustablePriorityQueue<NodeEntry>* priority_queue,
2788 std::vector<NodeEntries>* node_entries);
2794 void AddNeighborForCostClass(
int cost_class, int64 node_index,
2795 int64 neighbor_index,
bool neighbor_is_pickup,
2796 bool neighbor_is_delivery);
2800 bool IsNeighborForCostClass(
int cost_class, int64 node_index,
2801 int64 neighbor_index)
const;
2804 const absl::flat_hash_set<int64>& GetPickupNeighborsOfNodeForCostClass(
2805 int cost_class, int64 node_index) {
2806 if (neighbors_ratio_ == 1) {
2807 return pickup_nodes_;
2809 return node_index_to_pickup_neighbors_by_cost_class_[node_index]
2814 const absl::flat_hash_set<int64>& GetDeliveryNeighborsOfNodeForCostClass(
2815 int cost_class, int64 node_index) {
2816 if (neighbors_ratio_ == 1) {
2817 return delivery_nodes_;
2819 return node_index_to_delivery_neighbors_by_cost_class_[node_index]
2823 const bool is_sequential_;
2824 const double farthest_seeds_ratio_;
2825 const double neighbors_ratio_;
2828 std::vector<std::vector<absl::flat_hash_set<int64> > >
2829 node_index_to_single_neighbors_by_cost_class_;
2830 std::vector<std::vector<absl::flat_hash_set<int64> > >
2831 node_index_to_pickup_neighbors_by_cost_class_;
2832 std::vector<std::vector<absl::flat_hash_set<int64> > >
2833 node_index_to_delivery_neighbors_by_cost_class_;
2839 absl::flat_hash_set<int64> pickup_nodes_;
2840 absl::flat_hash_set<int64> delivery_nodes_;
2854 const std::vector<LocalSearchFilter*>& filters);
2858 return "LocalCheapestInsertionFilteredDecisionBuilder";
2867 void ComputeEvaluatorSortedPositions(int64 node,
2868 std::vector<int64>* sorted_positions);
2873 void ComputeEvaluatorSortedPositionsOnRouteAfter(
2874 int64 node, int64 start, int64 next_after_start,
2875 std::vector<int64>* sorted_positions);
2889 class PartialRoutesAndLargeVehicleIndicesFirst {
2891 explicit PartialRoutesAndLargeVehicleIndicesFirst(
2893 : builder_(builder) {}
2894 bool operator()(
int vehicle1,
int vehicle2)
const;
2900 template <
typename Iterator>
2901 std::vector<int64> GetPossibleNextsFromIterator(int64 node, Iterator start,
2902 Iterator end)
const {
2904 std::vector<int64> nexts;
2905 for (Iterator it = start; it != end; ++it) {
2906 const int64 next = *it;
2907 if (next != node && (next >= size || !
Contains(next))) {
2908 nexts.push_back(next);
2914 virtual void SortSuccessors(int64 node, std::vector<int64>* successors) = 0;
2915 virtual int64 FindTopSuccessor(int64 node,
2916 const std::vector<int64>& successors) = 0;
2927 const std::vector<LocalSearchFilter*>& filters);
2930 return "EvaluatorCheapestAdditionFilteredDecisionBuilder";
2935 void SortSuccessors(int64 node, std::vector<int64>* successors)
override;
2936 int64 FindTopSuccessor(int64 node,
2937 const std::vector<int64>& successors)
override;
2939 std::function<int64(int64, int64)> evaluator_;
2950 const std::vector<LocalSearchFilter*>& filters);
2953 return "ComparatorCheapestAdditionFilteredDecisionBuilder";
2958 void SortSuccessors(int64 node, std::vector<int64>* successors)
override;
2959 int64 FindTopSuccessor(int64 node,
2960 const std::vector<int64>& successors)
override;
2993 const std::vector<LocalSearchFilter*>& filters);
3000 template <
typename S>
3019 return saving.second / size_squared_;
3023 return (saving.second % size_squared_) /
Size();
3027 return (saving.second % size_squared_) %
Size();
3056 void AddSymetricArcsToAdjacencyLists(
3057 std::vector<std::vector<int64>>* adjacency_lists);
3066 void ComputeSavings();
3068 Saving BuildSaving(int64 saving,
int vehicle_type,
int before_node,
3069 int after_node)
const {
3070 return std::make_pair(saving, vehicle_type * size_squared_ +
3071 before_node *
Size() + after_node);
3081 void ComputeVehicleTypes();
3086 int64 MaxNumNeighborsPerNode(
int num_vehicle_types)
const;
3089 const SavingsParameters savings_params_;
3090 int64 size_squared_;
3101 const std::vector<LocalSearchFilter*>& filters)
3105 return "SequentialSavingsFilteredDecisionBuilder";
3113 void BuildRoutesFromSavings()
override;
3114 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 1.0; }
3123 const std::vector<LocalSearchFilter*>& filters)
3127 return "ParallelSavingsFilteredDecisionBuilder";
3141 void BuildRoutesFromSavings()
override;
3143 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 2.0; }
3149 void MergeRoutes(
int first_vehicle,
int second_vehicle, int64 before_node,
3153 std::vector<int64> first_node_on_route_;
3154 std::vector<int64> last_node_on_route_;
3158 std::vector<int> vehicle_of_first_or_last_node_;
3173 return "ChristofidesFilteredDecisionBuilder";
3182 const Assignment* initial_solution,
3183 Assignment* solution);
3189 BasePathFilter(
const std::vector<IntVar*>& nexts,
int next_domain_size,
3190 std::function<
void(int64)> objective_callback);
3204 int64
Start(
int i)
const {
return starts_[i]; }
3205 int GetPath(int64 node)
const {
return paths_[node]; }
3206 int Rank(int64 node)
const {
return ranks_[node]; }
3209 return new_synchronized_unperformed_nodes_.PositionsSetAtLeastOnce();
3213 enum Status { UNKNOWN, ENABLED, DISABLED };
3215 virtual bool DisableFiltering()
const {
return false; }
3216 virtual void OnBeforeSynchronizePaths() {}
3217 virtual void OnAfterSynchronizePaths() {}
3218 virtual void OnSynchronizePathFromStart(int64 start) {}
3219 virtual void InitializeAcceptPath() {}
3220 virtual bool AcceptPath(int64 path_start, int64 chain_start,
3221 int64 chain_end) = 0;
3222 virtual bool FinalizeAcceptPath(Assignment* delta) {
return true; }
3224 void ComputePathStarts(std::vector<int64>* path_starts,
3225 std::vector<int>* index_to_path);
3226 bool HavePathsChanged();
3227 void SynchronizeFullAssignment();
3228 void UpdateAllRanks();
3229 void UpdatePathRanksFromStart(
int start);
3231 std::vector<int64> node_path_starts_;
3232 std::vector<int64> starts_;
3233 std::vector<int> paths_;
3234 SparseBitset<int64> new_synchronized_unperformed_nodes_;
3235 std::vector<int64> new_nexts_;
3236 std::vector<int> delta_touched_;
3237 SparseBitset<> touched_paths_;
3238 SparseBitset<> touched_path_nodes_;
3239 std::vector<int> ranks_;
3259 std::string
DebugString()
const override {
return "CPFeasibilityFilter"; }
3266 static const int64 kUnassigned;
3276 const RoutingModel& routing_model,
3277 std::function<
void(int64)> objective_callback);
3279 const RoutingModel& routing_model,
3282 const RoutingModel& routing_model);
3284 const RoutingDimension& dimension,
3287 const RoutingDimension& dimension,
3289 bool propagate_own_objective_value,
bool filter_objective_cost);
3291 const RoutingDimension& dimension,
3295 const std::vector<RoutingModel::PickupAndDeliveryPolicy>& vehicle_policies);
3297 const RoutingModel& routing_model);
3299 const RoutingModel& routing_model,
const RoutingDimension& dimension);
3301 const RoutingModel* routing_model);
3305 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_
bool CheckLimit()
Returns true if the search limit has been crossed.
static std::unique_ptr< LocalSearchOperator > MakeGreedyDescentLSOperator(std::vector< IntVar * > variables)
Perhaps move it to constraint_solver.h.
~GlobalCheapestInsertionFilteredDecisionBuilder() override
const std::vector< IntVar * > & transits() const
int64 GetCumulVarSoftLowerBound(int64 index) const
Returns the soft lower bound of a cumul variable for a given variable index.
~CheapestAdditionFilteredDecisionBuilder() override
void OnSynchronize(const Assignment *delta) override
std::string DebugString() const override
int nodes() const
Sizes and indices Returns the number of nodes in the model.
int vehicle_to_class(int vehicle) const
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_min
Bounds of cumul variables at start and end vehicle nodes.
bool AddConstantDimension(int64 value, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
std::vector< RoutingDimension * > GetDimensionsWithSoftOrSpanCosts() const
Returns dimensions with soft or vehicle span costs.
gtl::ITIVector< DimensionIndex, int64 > dimension_start_cumuls_max
bool HasBreakConstraints() const
Returns true if any break interval or break distance was defined.
SUBTLE: The vehicle's fixed cost is skipped on purpose here, because we can afford to do so:
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
std::function< int64(int64)> penalty_evaluator_
bool IsVehicleAllowedForIndex(int vehicle, int64 index)
Returns true if a vehicle is allowed to visit a given node.
std::vector< IntVarLocalSearchFilter * > MakeCumulFilters(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost)
int64 GetDepot() const
Returns the variable index of the first starting or ending node of all routes.
static const char kLightElement[]
Constraint types.
void AddNodePrecedence(int64 first_node, int64 second_node, int64 offset)
Assignment * CompactAssignment(const Assignment &assignment) const
Returns a compacted version of the given assignment, in which all vehicles with id lower or equal to ...
CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const
Get the cost class index of the given vehicle.
Any precedence is accepted.
DecisionBuilder * MakeSetValuesFromTargets(Solver *solver, std::vector< IntVar * > variables, std::vector< int64 > targets)
A decision builder which tries to assign values to variables as close as possible to target values fi...
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
IntVarLocalSearchFilter * MakePathCumulFilter(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool propagate_own_objective_value, bool filter_objective_cost)
std::vector< int64 > start_min
const std::vector< IntervalVar * > & GetBreakIntervalsOfVehicle(int vehicle) const
Returns the break intervals set by SetBreakIntervalsOfVehicle().
bool BuildSolution() override
Virtual method to redefine to build a solution.
bool HasHardTypeIncompatibilities() const
Returns true iff any hard (resp.
int64 GetSpanUpperBoundForVehicle(int vehicle) const
const std::vector< RoutingDimension * > & GetDimensions() const
Returns all dimensions of the model.
bool Accept(Assignment *delta, Assignment *deltadelta) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
int64 GetNumberOfRejectsInFirstSolution(const RoutingSearchParameters &search_parameters) const
void InsertBetween(int64 node, int64 predecessor, int64 successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
bool IsEnd(int64 index) const
Returns true if 'index' represents the last node of a route.
void CloseModel()
Closes the current routing model; after this method is called, no modification to the model can be do...
void SetFixedCostOfVehicle(int64 cost, int vehicle)
Sets the fixed cost of one vehicle route.
int64 GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
const std::vector< DisjunctionIndex > & GetDisjunctionIndices(int64 index) const
Returns the indices of the disjunctions to which an index belongs.
int RegisterStateDependentTransitCallback(VariableIndexEvaluator2 callback)
const std::vector< IntVar * > & fixed_transits() const
std::string DebugString() const override
int GetPath(int64 node) const
bool AddDimensionWithVehicleCapacity(int evaluator_index, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
bool AreVehicleTransitsPositive(int vehicle) const
Returns true iff the transit evaluator of 'vehicle' is positive for all arcs.
IntVarLocalSearchFilter * MakeGlobalLPCumulFilter(const RoutingDimension &dimension, Solver::ObjectiveWatcher objective_callback, bool filter_objective_cost)
void MakeDisjunctionNodesUnperformed(int64 node)
Make nodes in the same disjunction as 'node' unperformed.
const RoutingModel::TransitCallback2 & transit_evaluator(int vehicle) const
Returns the callback evaluating the transit value between two node indices for a given vehicle.
void AddLocalSearchFilter(LocalSearchFilter *filter)
Adds a custom local search filter to the list of filters used to speed up local search by pruning unf...
gtl::ITIVector< DimensionIndex, int64 > dimension_evaluator_classes
dimension_evaluators[d]->Run(from, to) is the transit value of arc from->to for a dimension d.
int64 ComputeLowerBound()
Computes a lower bound to the routing problem solving a linear assignment problem.
bool IsStart(int64 index) const
Returns true if 'index' represents the first node of a route.
friend class RoutingDimension
RoutingIndexPair IndexPair
int Rank(int64 node) const
void AddIntervalToAssignment(IntervalVar *const interval)
virtual bool InitializeSolution()
Virtual method to initialize the solution.
CheapestAdditionFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
GlobalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters, bool is_sequential, double farthest_seeds_ratio, double neighbors_ratio)
Takes ownership of evaluators.
const Assignment *const PreAssignment() const
Returns an assignment used to fix some of the variables of the problem.
std::pair< StartEndValue, int > Seed
bool HasDimension(const std::string &dimension_name) const
Returns true if a dimension exists for a given dimension name.
std::function< StateDependentTransit(int64, int64)> VariableIndexEvaluator2
void AddAtSolutionCallback(std::function< void()> callback)
Adds a callback called each time a solution is found during the search.
const std::vector< IntVar * > & slacks() const
SimpleBoundCosts operator=(const SimpleBoundCosts &)=delete
virtual bool StopSearch()
Returns true if the search must be stopped.
void CloseVisitTypes()
This function should be called once all node visit types have been set and prior to adding any incomp...
int64 GetTransitValueFromClass(int64 from_index, int64 to_index, int64 vehicle_class) const
Same as above but taking a vehicle class of the dimension instead of a vehicle (the class of a vehicl...
int GetNonDeliveryCount(int type) const
Returns the number of pickups and fixed nodes from counts_of_type_["type"].
int64 Start(int vehicle) const
Model inspection.
bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2)
Returns whether the arc from->to1 is more constrained than from->to2, taking into account,...
bool MirrorTasks(Tasks *tasks)
Transforms the problem with a time symmetry centered in 0.
virtual bool CheckTypeRegulations(int type)=0
EvaluatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const IndexPairs & GetPickupAndDeliveryPairs() const
Returns pickup and delivery pairs currently in the model.
This class acts like a CP propagator: it takes a set of tasks given by their start/duration/end featu...
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
void SetAmortizedCostFactorsOfVehicle(int64 linear_cost_factor, int64 quadratic_cost_factor, int vehicle)
Sets the linear and quadratic cost factor of the given vehicle.
bool IsVarSynced(int index) const
void AddSameVehicleRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
Requirements: NOTE: As of 2019-04, cycles in the requirement graph are not supported,...
void IgnoreDisjunctionsAlreadyForcedToZero()
SPECIAL: Makes the solver ignore all the disjunctions whose active variables are all trivially zero (...
Dimensions represent quantities accumulated at nodes along the routes.
void FillPathEvaluation(const std::vector< int64 > &path, const RoutingModel::TransitCallback2 &evaluator, std::vector< int64 > *values)
int64 GetLocalOptimizerOffsetForVehicle(int vehicle) const
int GetNonDeliveredCount(int type) const
Same as above, but substracting the number of deliveries of "type".
void SetSectors(int sectors)
SimpleBoundCosts::BoundCost GetSoftSpanUpperBoundForVehicle(int vehicle) const
void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex(int64 index, int64 max_cardinality, F f) const
Calls f for each variable index of indices in the same disjunctions as the node corresponding to the ...
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
void AssignmentToRoutes(const Assignment &assignment, std::vector< std::vector< int64 >> *const routes) const
Converts the solution in the given assignment to routes for all vehicles.
bool SolveModelWithSat(const RoutingModel &model, const Assignment *initial_solution, Assignment *solution)
Attempts to solve the model using the cp-sat solver.
std::function< int64(int64, int64)> RoutingTransitCallback2
bool Accept(Assignment *delta, Assignment *deltadelta) override
Accepts a "delta" given the assignment with which the filter has been synchronized; the delta holds t...
const std::vector< int64 > & GetNewSynchronizedUnperformedNodes() const
bool RoutesToAssignment(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices, bool close_routes, Assignment *const assignment) const
Fills an assignment from a specification of the routes of the vehicles.
void SetPrimaryConstrainedDimension(const std::string &dimension_name)
Set the given dimension as "primary constrained".
void SetValue(const IntVar *const var, int64 value)
void SetCumulVarPiecewiseLinearCost(int64 index, const PiecewiseLinearFunction &cost)
Sets a piecewise linear cost on the cumul variable of a given variable index.
std::pair< int64, int64 > Saving
~ComparatorCheapestAdditionFilteredDecisionBuilder() override
const std::vector< absl::flat_hash_set< int > > & GetSameVehicleRequiredTypeAlternativesOfType(int type) const
Returns the sets of same-vehicle/temporal requirement alternatives for the given type.
Assignment * ReadAssignment(const std::string &file_name)
Reads an assignment from a file and returns the current solution.
int64 GetArcCostForClass(int64 from_index, int64 to_index, int64 cost_class_index) const
Returns the cost of the segment between two nodes for a given cost class.
int vehicles() const
Returns the number of vehicle routes in the model.
void AddSoftSameVehicleConstraint(const std::vector< int64 > &indices, int64 cost)
Adds a soft contraint to force a set of variable indices to be on the same vehicle.
double max_memory_usage_bytes
The number of neighbors considered for each node is also adapted so that the stored Savings don't use...
const std::vector< SortedDisjointIntervalList > & forbidden_intervals() const
Returns forbidden intervals for each node.
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
bool AddDimensionDependentDimensionWithVehicleCapacity(const std::vector< int > &pure_transits, const std::vector< int > &dependent_transits, const RoutingDimension *base_dimension, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension with transits depending on the cumuls of another dimension.
int GetNumOfSingletonNodes() const
Returns the number of non-start/end nodes which do not appear in a pickup/delivery pair.
IntVar * CumulVar(int64 index) const
Get the cumul, transit and slack variables for the given node (given as int64 var index).
bool AreEmptyRouteCostsConsideredForVehicle(int vehicle) const
std::function< int64(int, int)> PickupToDeliveryLimitFunction
Limits, in terms of maximum difference between the cumul variables, between the pickup and delivery a...
Filter-based decision builder dedicated to routing.
int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index) const
Returns the cost of the arc in the context of the first solution strategy.
friend class RoutingModelInspector
RoutingModel(const RoutingIndexManager &index_manager)
Constructor taking an index manager.
int64 Value(int64 index) const
Returns the value of the variable of index 'index' in the last committed solution.
int64 GetNext(int64 node) const
Checker for type requirements.
std::function< bool(int64, int64, int64)> VariableValueComparator
bool BuildSolution() override
Virtual method to redefine to build a solution.
int64 GetGlobalOptimizerOffset() const
gtl::ITIVector< DimensionIndex, int64 > dimension_capacities
RoutingCostClassIndex CostClassIndex
int VehicleIndex(int index) const
Returns the vehicle of the given start/end index, and -1 if the given index is not a vehicle start/en...
void SetSpanCostCoefficientForAllVehicles(int64 coefficient)
const VariableIndexEvaluator2 & StateDependentTransitCallback(int callback_index) const
Status
Status of the search.
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 RoutingModel::TransitCallback1 & GetUnaryTransitEvaluator(int vehicle) const
Returns the unary callback evaluating the transit value between two node indices for a given vehicle.
int64 GetFixedCostOfVehicle(int vehicle) const
Returns the route fixed cost taken into account if the route of the vehicle is not empty,...
void AddWeightedVariableMinimizedByFinalizer(IntVar *var, int64 cost)
Adds a variable to minimize in the solution finalizer, with a weighted priority: the higher the more ...
bool HasSoftSpanUpperBounds() const
RoutingIndexPairs IndexPairs
const std::vector< std::pair< int, int > > & GetPickupIndexPairs(int64 node_index) const
Returns pairs for which the node is a pickup; the first element of each pair is the index in the pick...
void InitializePriorityQueue(std::vector< std::vector< StartEndValue > > *start_end_distances_per_node, Queue *priority_queue)
Initializes the priority_queue by inserting the best entry corresponding to each node,...
bool BuildSolution() override
Virtual method to redefine to build a solution.
const std::vector< int64 > & GetAmortizedLinearCostFactorOfVehicles() const
bool EdgeFinding(Tasks *tasks)
Does edge-finding deductions on all tasks.
int64 global_span_cost_coefficient() const
Assignment * ReadAssignmentFromRoutes(const std::vector< std::vector< int64 >> &routes, bool ignore_inactive_indices)
Restores the routes as the current solution.
RoutingTransitCallback2 TransitCallback2
bool operator<(const DimensionCost &cost) const
void SetTabuVarsCallback(GetTabuVarsCallback tabu_var_callback)
static RoutingModel::StateDependentTransit MakeStateDependentTransit(const std::function< int64(int64)> &f, int64 domain_start, int64 domain_end)
Creates a cached StateDependentTransit from an std::function.
void AddVariableMaximizedByFinalizer(IntVar *var)
Adds a variable to maximize in the solution finalizer (see above for information on the solution fina...
bool ApplyLocksToAllVehicles(const std::vector< std::vector< int64 >> &locks, bool close_routes)
Applies lock chains to all vehicles to the next search, such that locks[p] is the lock chain for rout...
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
std::function< std::vector< operations_research::IntVar * >(RoutingModel *)> GetTabuVarsCallback
Sets the callback returning the variable to use for the Tabu Search metaheuristic.
void SetArcCostEvaluatorOfVehicle(int evaluator_index, int vehicle)
Sets the cost function for a given vehicle route.
bool operator<(const StartEndValue &other) const
Assignment * CompactAndCheckAssignment(const Assignment &assignment) const
Same as CompactAssignment() but also checks the validity of the final compact solution; if it is not ...
Problem solved successfully after calling RoutingModel::Solve().
IntVarLocalSearchFilter * MakeTypeRegulationsFilter(const RoutingModel &routing_model)
const Assignment * PackCumulsOfOptimizerDimensionsFromAssignment(const Assignment *original_assignment, absl::Duration duration_limit)
For every dimension in the model's dimensions_for_local/global_optimizer_, this method tries to pack ...
int64 GetDisjunctionPenalty(DisjunctionIndex index) const
Returns the penalty of the node disjunction of index 'index'.
static const char kLightElement2[]
int64 GetPickupToDeliveryLimitForPair(int pair_index, int pickup, int delivery) const
const absl::flat_hash_set< int > & GetHardTypeIncompatibilitiesOfType(int type) const
Returns visit types incompatible with a given type.
friend class RoutingModel
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
const TransitCallback1 & UnaryTransitCallbackOrNull(int callback_index) const
const std::vector< int64 > & vehicle_span_upper_bounds() const
int64 Next(const Assignment &assignment, int64 index) const
Assignment inspection Returns the variable index of the node directly after the node corresponding to...
ComparatorCheapestAdditionFilteredDecisionBuilder(RoutingModel *model, Solver::VariableValueComparator comparator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
The following constraint ensures that incompatibilities and requirements between types are respected.
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
int RegisterPositiveUnaryTransitCallback(TransitCallback1 callback)
int64 Value(int index) const
bool IsMatchingModel() const
Returns true if a vehicle/node matching problem is detected.
void AddSearchMonitor(SearchMonitor *const monitor)
Adds a search monitor to the search used to solve the routing model.
std::vector< int64 > start_max
void SetAmortizedCostFactorsOfAllVehicles(int64 linear_cost_factor, int64 quadratic_cost_factor)
The following methods set the linear and quadratic cost factors of vehicles (must be positive values)...
bool CheckVehicle(int vehicle, const std::function< int64(int64)> &next_accessor)
int start_equivalence_class
Vehicle start and end equivalence classes.
void AddPickupAndDelivery(int64 pickup, int64 delivery)
Notifies that index1 and index2 form a pair of nodes which should belong to the same route.
int64 number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
void InitializeBreaks()
Sets up vehicle_break_intervals_, vehicle_break_distance_duration_, pre_travel_evaluators and post_tr...
const std::string & name() const
Returns the name of the dimension.
static bool LessThan(const VehicleClass &a, const VehicleClass &b)
Comparator for STL containers and algorithms.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_max
const Assignment * SolveFromAssignmentWithParameters(const Assignment *assignment, const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
bool AddConstantDimensionWithSlack(int64 value, int64 capacity, int64 slack_max, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'value'; 'capacity' is t...
void ConsiderEmptyRouteCostsForVehicle(bool consider_costs, int vehicle)
const IntContainer & IntVarContainer() const
friend class SavingsFilteredDecisionBuilderTestPeer
IntVarLocalSearchFilter * MakeCPFeasibilityFilter(const RoutingModel *routing_model)
bool HasTemporalTypeRequirements() const
void AddTemporalRequiredTypeAlternatives(int dependent_type, absl::flat_hash_set< int > required_type_alternatives)
If type_D temporally depends on type_R, any non-delivery node_D of type_D requires at least one non-d...
void Post() override
This method is called when the constraint is processed by the solver.
What follows is relevant for models with time/state dependent transits.
std::pair< int64, int64 > ValuedPosition
std::function< int64(int64)> RoutingTransitCallback1
bool HasCumulVarPiecewiseLinearCost(int64 index) const
Returns true if a piecewise linear cost has been set for a given variable index.
Time limit reached before finding a solution with RoutingModel::Solve().
PickupAndDeliveryPolicy
Types of precedence policy applied to pickup and delivery pairs.
void SetBreakDistanceDurationOfVehicle(int64 distance, int64 duration, int vehicle)
With breaks supposed to be consecutive, this forces the distance between breaks of size at least mini...
std::string DebugString() const override
const std::vector< RoutingDimension * > & GetDimensionsForLocalCumulOptimizers() const
int64 End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
const std::vector< IntVar * > & cumuls() const
Like CumulVar(), TransitVar(), SlackVar() but return the whole variable vectors instead (indexed by i...
Class to arrange indices by by their distance and their angles from the depot.
IntVarLocalSearchFilter * MakeVehicleBreaksFilter(const RoutingModel &routing_model, const RoutingDimension &dimension)
bool ForbiddenIntervals(Tasks *tasks)
Tasks might have holes in their domain, this enforces such holes.
A structure to hold tasks described by their features.
bool HasCumulVarSoftUpperBound(int64 index) const
Returns true if a soft upper bound has been set for a given variable index.
IntVar * CostVar() const
Returns the global cost variable which is being minimized.
friend class RoutingModelInspector
void AppendTasksFromIntervals(const std::vector< IntervalVar * > &intervals, DisjunctivePropagator::Tasks *tasks)
Deliveries must be performed in the same order as pickups.
std::string DebugString() const override
RoutingVehicleClassIndex VehicleClassIndex
RoutingModel * model() const
bool CostsAreHomogeneousAcrossVehicles() const
Whether costs are homogeneous across all vehicles.
void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle)
Sets a cost proportional to the dimension span on a given vehicle, or on all vehicles at once.
~LocalCheapestInsertionFilteredDecisionBuilder() override
virtual void InitializeCheck()
~CheapestInsertionFilteredDecisionBuilder() override
int GetVehicleClassesCount() const
Returns the number of different vehicle classes in the model.
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
void AppendEvaluatedPositionsAfter(int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, std::vector< ValuedPosition > *valued_positions)
Helper method to the ComputeEvaluatorSortedPositions* methods.
ParallelSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
bool DetectablePrecedencesWithChain(Tasks *tasks)
Does detectable precedences deductions on tasks in the chain precedence, taking the time windows of n...
IntVarFilteredDecisionBuilder(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< LocalSearchFilter * > &filters)
A DecisionBuilder is responsible for creating the search tree.
GlobalVehicleBreaksConstraint(const RoutingDimension *dimension)
void AddLocalSearchOperator(LocalSearchOperator *ls_operator)
Adds a local search operator to the set of operators used to solve the vehicle routing problem.
gtl::ITIVector< DimensionIndex, int64 > dimension_end_cumuls_min
CostClass(int evaluator_index)
const Solver::IndexEvaluator2 & first_solution_evaluator() const
Gets/sets the evaluator used during the search.
std::string DebugString() const override
~RoutingFilteredDecisionBuilder() override
DecisionBuilder * MakeGuidedSlackFinalizer(const RoutingDimension *dimension, std::function< int64(int64)> initializer)
The next few members are in the public section only for testing purposes.
void SetSweepArranger(SweepArranger *sweep_arranger)
uint64 unvisitable_nodes_fprint
Fingerprint of unvisitable non-start/end nodes.
bool HasVehicleWithCostClassIndex(CostClassIndex cost_class_index) const
Returns true iff the model contains a vehicle with the given cost_class_index.
bool AddMatrixDimension(std::vector< std::vector< int64 >> values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i][next(i)]' for...
CostClassIndex cost_class_index
The cost class of the vehicle.
void SetCumulVarSoftUpperBound(int64 index, int64 upper_bound, int64 coefficient)
Sets a soft upper bound to the cumul variable of a given variable index.
void SetCumulVarSoftLowerBound(int64 index, int64 lower_bound, int64 coefficient)
Sets a soft lower bound to the cumul variable of a given variable index.
int evaluator_index
Index of the arc cost evaluator, registered in the RoutingModel class.
const std::vector< RoutingDimension * > & GetDimensionsForGlobalCumulOptimizers() const
Returns dimensions_for_[global|local]_optimizer_ if the model has been closed, and empty vectors othe...
~CPFeasibilityFilter() override
int64 GetCumulVarSoftUpperBound(int64 index) const
Returns the soft upper bound of a cumul variable for a given variable index.
~TypeIncompatibilityChecker() override
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
std::vector< const SortedDisjointIntervalList * > forbidden_intervals
BoundCost & bound_cost(int element)
std::function< int64(int64, int64, int64)> evaluator_
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc evalua...
Local Search Filters are used for fast neighbor pruning.
IntVar * ActiveVar(int64 index) const
Returns the active variable of the node corresponding to index.
const std::vector< NodePrecedence > & GetNodePrecedences() const
int64 GetSpanCostCoefficientForVehicle(int vehicle) const
~ChristofidesFilteredDecisionBuilder() override
bool AddVectorDimension(std::vector< int64 > values, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Creates a dimension where the transit variable is constrained to be equal to 'values[i]' for node i; ...
bool IsVehicleUsed(const Assignment &assignment, int vehicle) const
Returns true if the route of 'vehicle' is non empty in 'assignment'.
bool BuildSolution() override
Virtual method to redefine to build a solution.
Status status() const
Returns the current status of the routing model.
std::string DebugString() const override
A constraint is the main modeling object.
Deliveries must be performed in reverse order of pickups.
void SetPickupAndDeliveryPolicyOfAllVehicles(PickupAndDeliveryPolicy policy)
Sets the Pickup and delivery policy of all vehicles.
RoutingModel * model() const
Returns the model on which the dimension was created.
int64 GetHomogeneousCost(int64 from_index, int64 to_index) const
Returns the cost of the segment between two nodes supposing all vehicle costs are the same (returns t...
A structure meant to store soft bounds and associated violation constants.
Decision builders building a solution using local search filters to evaluate its feasibility.
static bool LessThan(const CostClass &a, const CostClass &b)
Comparator for STL containers and algorithms.
const E & Element(const V *const var) const
RoutingFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
int64 GetCumulVarSoftUpperBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft upper bound of a cumul variable for a given variable index.
TypeIncompatibilityChecker(const RoutingModel &model, bool check_hard_incompatibilities)
std::vector< std::pair< int64, int64 > > GetPerfectBinaryDisjunctions() const
Returns the list of all perfect binary disjunctions, as pairs of variable indices: a disjunction is "...
const RoutingModel & model_
int RegisterUnaryTransitCallback(TransitCallback1 callback)
Registers 'callback' and returns its index.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
IntVar * SlackVar(int64 index) const
IntVar * FixedTransitVar(int64 index) const
std::vector<::std::string > GetAllDimensionNames() const
Outputs the names of all dimensions added to the routing engine.
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
TypeRegulationsChecker(const RoutingModel &model)
IntVar * Var(int64 index) const
Returns the variable of index 'index'.
Constraint * MakePathSpansAndTotalSlacks(const RoutingDimension *dimension, std::vector< IntVar * > spans, std::vector< IntVar * > total_slacks)
For every vehicle of the routing model:
std::vector< int64 > duration_max
~TypeRequirementChecker() override
int RegisterTransitCallback(TransitCallback2 callback)
bool HasPickupToDeliveryLimits() const
int64 number_of_rejects() const
void SetValue(int64 index, int64 value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const
Returns the transition value for a given pair of nodes (as var index); this value is the one taken by...
IntVarLocalSearchFilter * MakeVehicleAmortizedCostFilter(const RoutingModel &routing_model, Solver::ObjectiveWatcher objective_callback)
bool Propagate(Tasks *tasks)
Computes new bounds for all tasks, returns false if infeasible.
No solution found to the problem after calling RoutingModel::Solve().
Checker for type incompatibilities.
static const int64 kUnassigned
const std::vector< int64 > & vehicle_span_cost_coefficients() const
const std::vector< std::pair< int, int > > & GetDeliveryIndexPairs(int64 node_index) const
Same as above for deliveries.
bool HasTypeRegulations() const
Returns true iff the model has any incompatibilities or requirements set on node types.
bool BuildSolution() override
Virtual method to redefine to build a solution.
absl::Duration RemainingTime() const
Returns the time left in the search limit.
int GetVisitType(int64 index) const
void ArrangeIndices(std::vector< int64 > *indices)
IntVarLocalSearchFilter * MakeNodeDisjunctionFilter(const RoutingModel &routing_model, std::function< void(int64)> objective_callback)
bool HasCumulVarSoftLowerBound(int64 index) const
Returns true if a soft lower bound has been set for a given variable index.
BoundCost bound_cost(int element) const
Manager for any NodeIndex <-> variable index conversion.
void InitialPropagate() override
This method performs the initial propagation of the constraint.
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
std::vector< int64 > end_max
const std::vector< IntVar * > & VehicleVars() const
Returns all vehicle variables of the model, such that VehicleVars(i) is the vehicle variable of the n...
Model, model parameters or flags are not valid.
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
void SetArcCostEvaluatorOfAllVehicles(int evaluator_index)
Sets the cost function of the model such that the cost of a segment of a route between node 'from' an...
GlobalVehicleBreaksConstraint ensures breaks constraints are enforced on all vehicles in the dimensio...
std::unique_ptr< SavingsContainer< Saving > > savings_container_
IntVar * VehicleCostsConsideredVar(int vehicle) const
Returns the variable specifying whether or not costs are considered for vehicle.
void AddHardTypeIncompatibility(int type1, int type2)
Incompatibilities: Two nodes with "hard" incompatible types cannot share the same route at all,...
SweepArranger * sweep_arranger() const
Returns the sweep arranger to be used by routing heuristics.
const std::vector< int > & GetSameVehicleIndicesOfIndex(int node) const
Returns variable indices of nodes constrained to be on the same route.
This filter accepts deltas for which the assignment satisfies the constraints of the Solver.
void Post() override
This method is called when the constraint is processed by the solver.
bool AddDimensionWithVehicleTransitAndCapacity(const std::vector< int > &evaluator_indices, int64 slack_max, std::vector< int64 > vehicle_capacities, bool fix_start_cumul_to_zero, const std::string &name)
Assignment * RestoreAssignment(const Assignment &solution)
Restores an assignment as a solution in the routing model and returns the new solution.
DisjunctionIndex AddDisjunction(const std::vector< int64 > &indices, int64 penalty=kNoPenalty, int64 max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
RoutingTransitCallback1 TransitCallback1
int64 Size() const
Returns the number of next variables in the model.
int GetNumberOfDisjunctions() const
Returns the number of node disjunctions in the model.
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...
std::vector< DimensionCost > dimension_transit_evaluator_class_and_cost_coefficient
SequentialSavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
PickupAndDeliveryPolicy GetPickupAndDeliveryPolicyOfVehicle(int vehicle) const
A BaseObject is the root of all reversibly allocated objects.
const PiecewiseLinearFunction * GetCumulVarPiecewiseLinearCost(int64 index) const
Returns the piecewise linear cost of a cumul variable for a given variable index.
~SavingsFilteredDecisionBuilder() override
int64 ShortestTransitionSlack(int64 node) const
It makes sense to use the function only for self-dependent dimension.
bool StopSearch() override
Returns true if the search must be stopped.
BasePathFilter(const std::vector< IntVar * > &nexts, int next_domain_size, std::function< void(int64)> objective_callback)
RangeIntToIntFunction * transit
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
IntVar * TransitVar(int64 index) const
void CloseModelWithParameters(const RoutingSearchParameters &search_parameters)
Same as above taking search parameters (as of 10/2015 some the parameters have to be set when closing...
static const DisjunctionIndex kNoDisjunction
Constant used to express the "no disjunction" index, returned when a node does not appear in any disj...
void OnSynchronize(const Assignment *delta) override
bool WriteAssignment(const std::string &file_name) const
Writes the current solution to a file containing an AssignmentProto.
static const char kRemoveValues[]
TypeRequirementChecker(const RoutingModel &model)
const Assignment * Solve(const Assignment *assignment=nullptr)
Solves the current routing model; closes the current model.
void SetFixedCostOfAllVehicles(int64 cost)
Sets the fixed cost of all vehicle routes.
void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator)
Takes ownership of evaluator.
void AppendTasksFromPath(const std::vector< int64 > &path, const std::vector< int64 > &min_travels, const std::vector< int64 > &max_travels, const std::vector< int64 > &pre_travels, const std::vector< int64 > &post_travels, const RoutingDimension &dimension, DisjunctivePropagator::Tasks *tasks)
IntVarLocalSearchFilter * MakePickupDeliveryFilter(const RoutingModel &routing_model, const RoutingModel::IndexPairs &pairs, const std::vector< RoutingModel::PickupAndDeliveryPolicy > &vehicle_policies)
std::function< void(int64)> ObjectiveWatcher
void AddTemporalTypeIncompatibility(int type1, int type2)
The class IntVar is a subset of IntExpr.
std::vector< int > type_index_of_vehicle_
const std::vector< std::pair< int64, int64 > > & GetBreakDistanceDurationOfVehicle(int vehicle) const
Returns the pairs (distance, duration) specified by break distance constraints.
IntVar * ApplyLocks(const std::vector< int64 > &locks)
Applies a lock chain to the next search.
static const DimensionIndex kNoDimension
Constant used to express the "no dimension" index, returned when a dimension name does not correspond...
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Christofides addition heuristic.
const std::vector< int64 > & vehicle_capacities() const
Returns the capacities for all vehicles.
const std::vector< std::pair< DisjunctionIndex, DisjunctionIndex > > & GetPickupAndDeliveryDisjunctions() const
RoutingDimensionIndex DimensionIndex
void InitialPropagate() override
This method performs the initial propagation of the constraint.
SimpleBoundCosts(int num_bounds, BoundCost default_bound_cost)
void AddVariableTargetToFinalizer(IntVar *var, int64 target)
Add a variable to set the closest possible to the target value in the solution finalizer.
int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const
Same as above except that it returns default_value instead of 0 when penalty is not well defined (def...
int GetCostClassesCount() const
Returns the number of different cost classes in the model.
IntVarLocalSearchFilter * MakeVehicleVarFilter(const RoutingModel &routing_model)
Solver * solver() const
Returns the underlying constraint solver.
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
CPFeasibilityFilter(const RoutingModel *routing_model)
bool DistanceDuration(Tasks *tasks)
int64 GetArcCostForVehicle(int64 from_index, int64 to_index, int64 vehicle) const
Returns the cost of the transit arc between two nodes for a given vehicle.
int64 transit_evaluator_class
int64 GetUnperformedValue(int64 node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
bool AddDimensionWithVehicleTransits(const std::vector< int > &evaluator_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
int end_equivalence_class
std::vector< int64 > end_min
Generic path-based filter class.
std::vector< int64 > duration_min
bool HasSameVehicleTypeRequirements() const
Returns true iff any same-route (resp.
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
absl::Time AbsoluteSolverDeadline() const
virtual bool FinalizeCheck() const
const RoutingDimension * dimension
int64 GetCumulVarSoftLowerBoundCoefficient(int64 index) const
Returns the cost coefficient of the soft lower bound of a cumul variable for a given variable index.
VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const
virtual bool HasRegulationsToCheck() const =0
~BasePathFilter() override
int64 UnperformedPenalty(int64 var_index) const
Get the "unperformed" penalty of a node.
static const int64 kNoPenalty
Constant used to express a hard constraint instead of a soft penalty.
virtual void BuildRoutesFromSavings()=0
Problem not solved yet (before calling RoutingModel::Solve()).
int StartNewRouteWithBestVehicleOfType(int type, int64 before_node, int64 after_node)
Finds the best available vehicle of type "type" to start a new route to serve the arc before_node-->a...
std::vector< std::set< VehicleClassEntry > > sorted_vehicle_classes_per_type_
int GetNonZeroCostClassesCount() const
Ditto, minus the 'always zero', built-in cost class.
int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const
Returns the maximum number of possible active nodes of the node disjunction of index 'index'.
int RegisterPositiveTransitCallback(TransitCallback2 callback)
bool Contains(int64 index) const
Returns true if the variable of index 'index' is in the current solution.
const std::vector< absl::flat_hash_set< int > > & GetTemporalRequiredTypeAlternativesOfType(int type) const
ChristofidesFilteredDecisionBuilder(RoutingModel *model, const std::vector< LocalSearchFilter * > &filters)
A Decision represents a choice point in the search tree.
std::vector< RoutingIndexPair > RoutingIndexPairs
void AddNodePrecedence(NodePrecedence precedence)
Assignment * MutablePreAssignment()
int64 GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
CheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, std::function< int64(int64)> penalty_evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
std::function< int64(int64, int64)> IndexEvaluator2
const std::string & GetPrimaryConstrainedDimension() const
Get the primary constrained dimension, or an empty std::string if it is unset.
Interval variables are often used in scheduling.
bool Precedences(Tasks *tasks)
Propagates the deductions from the chain of precedences, if there is one.
void SetAssignmentFromOtherModelAssignment(Assignment *target_assignment, const RoutingModel *source_model, const Assignment *source_assignment)
Given a "source_model" and its "source_assignment", resets "target_assignment" with the IntVar variab...
RangeMinMaxIndexFunction * transit_plus_identity
f(x)
int GetPostTravelEvaluatorOfVehicle(int vehicle) const
virtual ~TypeRegulationsChecker()
TypeRegulationsConstraint(const RoutingModel &model)
RoutingDisjunctionIndex DisjunctionIndex
int64 GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' comes from an arc compar...
void SetVisitType(int64 index, int type)
Set the node visit types and incompatibilities/requirements between the types (see below).
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
std::vector< bool > is_preemptible
std::string DebugOutputAssignment(const Assignment &solution_assignment, const std::string &dimension_to_print) const
Print some debugging information about an assignment, including the feasible intervals of the CumulVa...
int64 fixed_cost
Contrarily to CostClass, here we need strict equivalence.
bool operator<(const VehicleClassEntry &other) const
bool Check() override
This method is called to check the status of the limit.
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
~SequentialSavingsFilteredDecisionBuilder() override
SweepArranger(const std::vector< std::pair< int64, int64 >> &points)
~IntVarFilteredDecisionBuilder() override
bool AddDimension(int evaluator_index, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
IntVar * VehicleVar(int64 index) const
Returns the vehicle variable of the node corresponding to index.
std::vector< std::pair< int64, int64 > > distance_duration
std::vector< std::deque< int > > vehicles_per_vehicle_class_
std::pair< std::vector< int64 >, std::vector< int64 > > RoutingIndexPair
int GetNumberOfVisitTypes() const
int64 GetNumberOfDecisionsInFirstSolution(const RoutingSearchParameters &search_parameters) const
Returns statistics on first solution search, number of decisions sent to filters, number of decisions...
~EvaluatorCheapestAdditionFilteredDecisionBuilder() override
const RoutingDimension * base_dimension() const
Returns the parent in the dependency tree if any or nullptr otherwise.
virtual bool BuildSolution()=0
Virtual method to redefine to build a solution.
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
LocalCheapestInsertionFilteredDecisionBuilder(RoutingModel *model, std::function< int64(int64, int64, int64)> evaluator, const std::vector< LocalSearchFilter * > &filters)
Takes ownership of evaluator.
const std::vector< int64 > & GetAmortizedQuadraticCostFactorOfVehicles() const
SavingsFilteredDecisionBuilder(RoutingModel *model, RoutingIndexManager *manager, SavingsParameters parameters, const std::vector< LocalSearchFilter * > &filters)
void SetPickupAndDeliveryPolicyOfVehicle(PickupAndDeliveryPolicy policy, int vehicle)
const absl::flat_hash_set< int > & GetTemporalTypeIncompatibilitiesOfType(int type) const
const TransitCallback2 & TransitCallback(int callback_index) const
bool HasTemporalTypeIncompatibilities() const
void SetPickupToDeliveryLimitFunctionForPair(PickupToDeliveryLimitFunction limit_function, int pair_index)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
std::vector< std::vector< StartEndValue > > ComputeStartEndDistanceForVehicles(const std::vector< int > &vehicles)
Computes and returns the distance of each uninserted node to every vehicle in "vehicles" as a std::ve...
std::string DebugString() const override
std::string DebugString() const override
const ReverseArcListGraph< int, int > & GetPathPrecedenceGraph() const
Accessors.
int64 GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
~ParallelSavingsFilteredDecisionBuilder() override
void AddPickupAndDeliverySets(DisjunctionIndex pickup_disjunction, DisjunctionIndex delivery_disjunction)
Same as AddPickupAndDelivery but notifying that the performed node from the disjunction of index 'pic...
void SetGlobalSpanCostCoefficient(int64 coefficient)
Sets a cost proportional to the global dimension span, that is the difference between the largest val...
void SetAllowedVehiclesForIndex(const std::vector< int > &vehicles, int64 index)
Sets the vehicles which can visit a given node.