14 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ 15 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ 27 #include "absl/container/flat_hash_set.h" 41 class IntVarFilteredHeuristic;
43 class VehicleTypeCurator {
50 : vehicle_type_container_(&vehicle_type_container) {}
54 int Type(
int vehicle)
const {
return vehicle_type_container_->
Type(vehicle); }
58 void Reset(
const std::function<
bool(
int)>& store_vehicle);
62 void Update(
const std::function<
bool(
int)>& remove_vehicle);
66 const std::set<VehicleClassEntry>& vehicle_classes =
67 sorted_vehicle_classes_per_type_[type];
68 if (vehicle_classes.empty()) {
78 std::vector<int>& vehicles = vehicles_per_vehicle_class_[
vehicle_class];
79 if (vehicles.empty()) {
82 std::set<VehicleClassEntry>& vehicle_classes =
83 sorted_vehicle_classes_per_type_[
Type(vehicle)];
84 const auto& insertion =
88 vehicles.push_back(vehicle);
100 int type, std::function<
bool(
int)> vehicle_is_compatible,
101 std::function<
bool(
int)> stop_and_return_vehicle);
104 using VehicleClassEntry =
108 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
109 std::vector<std::vector<int> > vehicles_per_vehicle_class_;
117 bool has_node_precedences,
118 bool has_single_vehicle_node);
139 std::unique_ptr<IntVarFilteredHeuristic> heuristic);
152 const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
172 virtual std::string
DebugString()
const {
return "IntVarFilteredHeuristic"; }
190 if (!is_in_delta_[
index]) {
192 delta_indices_.push_back(
index);
193 is_in_delta_[
index] =
true;
209 int Size()
const {
return vars_.size(); }
223 const std::vector<IntVar*> vars_;
225 std::vector<int> delta_indices_;
226 std::vector<bool> is_in_delta_;
230 int64_t number_of_decisions_;
231 int64_t number_of_rejects_;
242 const std::function<int64_t(int64_t)>& next_accessor);
269 bool InitializeSolution()
override;
272 std::vector<int64_t> start_chain_ends_;
273 std::vector<int64_t> end_chain_starts_;
281 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
282 std::function<int64_t(int64_t)> penalty_evaluator,
305 std::vector<std::vector<StartEndValue> >
312 template <
class Queue>
314 std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
315 Queue* priority_queue);
322 void InsertBetween(int64_t node, int64_t predecessor, int64_t successor);
328 int64_t node_to_insert, int64_t start, int64_t next_after_start,
329 int64_t vehicle, std::vector<ValuedPosition>* valued_positions);
337 int64_t insert_after,
338 int64_t insert_before,
344 std::function<int64_t(int64_t, int64_t, int64_t)>
evaluator_;
385 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
386 std::function<int64_t(int64_t)> penalty_evaluator,
392 return "GlobalCheapestInsertionFilteredHeuristic";
399 typedef absl::flat_hash_set<PairEntry*> PairEntries;
400 typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
408 void InsertPairsAndNodesByRequirementTopologicalOrder();
416 void InsertPairs(
const std::vector<int>& pair_indices);
424 bool InsertPairEntryUsingEmptyVehicleTypeCurator(
425 const std::vector<int>& pair_indices, PairEntry*
const pair_entry,
427 std::vector<PairEntries>* pickup_to_entries,
428 std::vector<PairEntries>* delivery_to_entries);
437 void InsertNodesOnRoutes(
const std::vector<int>&
nodes,
438 const absl::flat_hash_set<int>& vehicles);
447 bool InsertNodeEntryUsingEmptyVehicleTypeCurator(
448 const std::vector<int>&
nodes,
bool all_vehicles,
449 NodeEntry*
const node_entry,
451 std::vector<NodeEntries>* position_to_node_entries);
458 void SequentialInsertNodes(
const std::vector<int>&
nodes);
463 void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
464 std::vector<int>* unused_vehicles,
465 absl::flat_hash_set<int>* used_vehicles);
470 void InsertFarthestNodesAsSeeds();
480 template <
class Queue>
482 std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
483 Queue* priority_queue, std::vector<bool>* is_vehicle_used);
488 void InitializePairPositions(
489 const std::vector<int>& pair_indices,
491 std::vector<PairEntries>* pickup_to_entries,
492 std::vector<PairEntries>* delivery_to_entries);
498 void InitializeInsertionEntriesPerformingPair(
499 int64_t pickup, int64_t delivery,
501 std::vector<PairEntries>* pickup_to_entries,
502 std::vector<PairEntries>* delivery_to_entries);
506 void UpdateAfterPairInsertion(
507 const std::vector<int>& pair_indices,
int vehicle, int64_t pickup,
508 int64_t pickup_position, int64_t delivery, int64_t delivery_position,
510 std::vector<PairEntries>* pickup_to_entries,
511 std::vector<PairEntries>* delivery_to_entries);
514 void UpdatePairPositions(
const std::vector<int>& pair_indices,
int vehicle,
515 int64_t insert_after,
517 std::vector<PairEntries>* pickup_to_entries,
518 std::vector<PairEntries>* delivery_to_entries) {
519 UpdatePickupPositions(pair_indices, vehicle, insert_after, priority_queue,
520 pickup_to_entries, delivery_to_entries);
521 UpdateDeliveryPositions(pair_indices, vehicle, insert_after, priority_queue,
522 pickup_to_entries, delivery_to_entries);
526 void UpdatePickupPositions(
const std::vector<int>& pair_indices,
int vehicle,
527 int64_t pickup_insert_after,
529 std::vector<PairEntries>* pickup_to_entries,
530 std::vector<PairEntries>* delivery_to_entries);
533 void UpdateDeliveryPositions(
534 const std::vector<int>& pair_indices,
int vehicle,
535 int64_t delivery_insert_after,
537 std::vector<PairEntries>* pickup_to_entries,
538 std::vector<PairEntries>* delivery_to_entries);
541 void DeletePairEntry(PairEntry* entry,
543 std::vector<PairEntries>* pickup_to_entries,
544 std::vector<PairEntries>* delivery_to_entries);
549 void AddPairEntry(int64_t pickup, int64_t pickup_insert_after,
550 int64_t delivery, int64_t delivery_insert_after,
553 std::vector<PairEntries>* pickup_entries,
554 std::vector<PairEntries>* delivery_entries)
const;
557 void UpdatePairEntry(
558 PairEntry*
const pair_entry,
563 int64_t GetInsertionValueForPairAtPositions(int64_t pickup,
564 int64_t pickup_insert_after,
566 int64_t delivery_insert_after,
571 void InitializePositions(
const std::vector<int>&
nodes,
572 const absl::flat_hash_set<int>& vehicles,
574 std::vector<NodeEntries>* position_to_node_entries);
580 void InitializeInsertionEntriesPerformingNode(
581 int64_t node,
const absl::flat_hash_set<int>& vehicles,
583 std::vector<NodeEntries>* position_to_node_entries);
586 void UpdatePositions(
const std::vector<int>&
nodes,
int vehicle,
587 int64_t insert_after,
bool all_vehicles,
589 std::vector<NodeEntries>* node_entries);
592 void DeleteNodeEntry(NodeEntry* entry,
594 std::vector<NodeEntries>* node_entries);
599 void AddNodeEntry(int64_t node, int64_t insert_after,
int vehicle,
602 std::vector<NodeEntries>* node_entries)
const;
605 void UpdateNodeEntry(
606 NodeEntry*
const node_entry,
611 void ComputeNeighborhoods();
615 bool IsNeighborForCostClass(
int cost_class, int64_t node_index,
616 int64_t neighbor_index)
const;
619 const std::vector<int64_t>& GetNeighborsOfNodeForCostClass(
620 int cost_class, int64_t node_index)
const {
623 : node_index_to_neighbors_by_cost_class_[node_index][cost_class]
624 ->PositionsSetAtLeastOnce();
627 int64_t NumNonStartEndNodes()
const {
631 int64_t NumNeighbors()
const {
634 NumNonStartEndNodes()));
637 void ResetVehicleIndices()
override {
638 node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
641 void SetVehicleIndex(int64_t node,
int vehicle)
override {
642 DCHECK_LT(node, node_index_to_vehicle_.size());
643 node_index_to_vehicle_[node] = vehicle;
648 bool CheckVehicleIndices()
const;
650 GlobalCheapestInsertionParameters gci_params_;
652 std::vector<int> node_index_to_vehicle_;
655 std::vector<std::vector<std::unique_ptr<SparseBitset<int64_t> > > >
656 node_index_to_neighbors_by_cost_class_;
659 std::unique_ptr<VehicleTypeCurator> empty_vehicle_type_curator_;
664 std::vector<int64_t> all_nodes_;
678 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
683 return "LocalCheapestInsertionFilteredHeuristic";
692 void ComputeEvaluatorSortedPositions(int64_t node,
693 std::vector<int64_t>* sorted_positions);
698 void ComputeEvaluatorSortedPositionsOnRouteAfter(
699 int64_t node, int64_t start, int64_t next_after_start,
700 std::vector<int64_t>* sorted_positions);
702 std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
715 class PartialRoutesAndLargeVehicleIndicesFirst {
717 explicit PartialRoutesAndLargeVehicleIndicesFirst(
719 : builder_(builder) {}
720 bool operator()(
int vehicle1,
int vehicle2)
const;
726 template <
typename Iterator>
727 std::vector<int64_t> GetPossibleNextsFromIterator(int64_t node,
729 Iterator end)
const {
731 std::vector<int64_t> nexts;
732 for (Iterator it = start; it != end; ++it) {
733 const int64_t
next = *it;
735 nexts.push_back(
next);
741 virtual void SortSuccessors(int64_t node,
742 std::vector<int64_t>* successors) = 0;
743 virtual int64_t FindTopSuccessor(int64_t node,
744 const std::vector<int64_t>& successors) = 0;
758 return "EvaluatorCheapestAdditionFilteredHeuristic";
763 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
764 int64_t FindTopSuccessor(int64_t node,
765 const std::vector<int64_t>& successors)
override;
767 std::function<int64_t(int64_t, int64_t)> evaluator_;
781 return "ComparatorCheapestAdditionFilteredHeuristic";
786 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
787 int64_t FindTopSuccessor(int64_t node,
788 const std::vector<int64_t>& successors)
override;
826 typedef std::pair< int64_t, int64_t>
Saving;
828 template <
typename S>
837 return saving.second / size_squared_;
841 return (saving.second % size_squared_) /
Size();
845 return (saving.second % size_squared_) %
Size();
873 void AddSymmetricArcsToAdjacencyLists(
874 std::vector<std::vector<int64_t> >* adjacency_lists);
885 bool ComputeSavings();
887 Saving BuildSaving(int64_t saving,
int vehicle_type,
int before_node,
888 int after_node)
const {
889 return std::make_pair(saving, vehicle_type * size_squared_ +
890 before_node *
Size() + after_node);
896 int64_t MaxNumNeighborsPerNode(
int num_vehicle_types)
const;
899 const SavingsParameters savings_params_;
900 int64_t size_squared_;
914 return "SequentialSavingsFilteredHeuristic";
922 void BuildRoutesFromSavings()
override;
923 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 1.0; }
935 return "ParallelSavingsFilteredHeuristic";
949 void BuildRoutesFromSavings()
override;
951 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 2.0; }
957 void MergeRoutes(
int first_vehicle,
int second_vehicle, int64_t before_node,
961 std::vector<int64_t> first_node_on_route_;
962 std::vector<int64_t> last_node_on_route_;
966 std::vector<int> vehicle_of_first_or_last_node_;
977 bool use_minimum_matching);
981 return "ChristofidesFilteredHeuristic";
985 const bool use_minimum_matching_;
993 const std::vector<std::pair<int64_t, int64_t>>& points);
999 std::vector<int> coordinates_;
1009 bool check_assignment);
1016 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_ bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
int Type(int vehicle) const
int64_t GetInsertionCostForNodeAtPosition(int64_t node_to_insert, int64_t insert_after, int64_t insert_before, int vehicle) const
Returns the cost of inserting 'node_to_insert' between 'insert_after' and 'insert_before' on the 'veh...
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
int64_t Value(int64_t index) const
Returns the value of the variable of index 'index' in the last committed solution.
std::string DebugString() const override
~LocalCheapestInsertionFilteredHeuristic() override
CheapestAdditionFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
std::string DebugString() const override
~RoutingFilteredHeuristic() override
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
std::unique_ptr< VehicleTypeCurator > vehicle_type_curator_
std::unique_ptr< SavingsContainer< Saving > > savings_container_
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
~SavingsFilteredHeuristic() override
Manager for any NodeIndex <-> variable index conversion.
int64_t GetUnperformedValue(int64_t node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
bool Contains(int64_t index) const
Returns true if the variable of index 'index' is in the current solution.
void SetValue(const IntVar *const var, int64_t value)
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
virtual ~IntVarFilteredHeuristic()
Filter-based heuristic dedicated to routing.
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64_t fixed_cost)
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.
int64_t GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
IntVar * Var(int64_t index) const
Returns the variable of index 'index'.
RoutingModel * model() const
std::string DebugString() const override
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, std::function< int64_t(int64_t)> penalty_evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
int64_t number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
int64_t GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
std::function< int64_t(int64_t)> penalty_evaluator_
void Reset(const std::function< bool(int)> &store_vehicle)
Resets the vehicles stored, storing only vehicles from the vehicle_type_container_ for which store_ve...
const E & Element(const V *const var) const
static int64_t FastInt64Round(double x)
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
A DecisionBuilder is responsible for creating the search tree.
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
const Assignment * BuildSolutionFromRoutes(const std::function< int64_t(int64_t)> &next_accessor)
Builds a solution starting from the routes formed by the next accessor.
std::string DebugString() const override
bool StopSearch() override
Returns true if the search must be stopped.
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
Generic filter-based heuristic applied to IntVars.
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
Christofides addition heuristic.
void ResetSolution()
Resets the data members for a new solution.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
int64_t number_of_rejects() const
RoutingFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
std::pair< int64_t, int64_t > Saving
~CheapestAdditionFilteredHeuristic() override
~CheapestInsertionFilteredHeuristic() override
virtual void ResetVehicleIndices()
~IntVarFilteredDecisionBuilder() override
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
bool VehicleIsEmpty(int vehicle) const
double max_memory_usage_bytes
The number of neighbors considered for each node is also adapted so that the stored Savings don't use...
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,...
friend class SavingsFilteredHeuristicTestPeer
virtual bool StopSearch()
Returns true if the search must be stopped.
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
void InsertBetween(int64_t node, int64_t predecessor, int64_t successor)
Inserts 'node' just after 'predecessor', and just before 'successor', resulting in the following subs...
~ComparatorCheapestAdditionFilteredHeuristic() override
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
std::string DebugString() const override
void Update(const std::function< bool(int)> &remove_vehicle)
Goes through all the currently stored vehicles and removes vehicles for which remove_vehicle() return...
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
bool operator<(const StartEndValue &other) const
void MakePartiallyPerformedPairsUnperformed()
Make all partially performed pickup and delivery pairs unperformed.
An Assignment is a variable -> domains mapping, used to report solutions to the user.
The class IntVar is a subset of IntExpr.
void SetValue(int64_t index, int64_t value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
Assignment *const assignment_
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
FirstSolutionStrategy_Value
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
std::string DebugString() const override
#define DCHECK(condition)
GlobalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, std::function< int64_t(int64_t)> penalty_evaluator, LocalSearchFilterManager *filter_manager, GlobalCheapestInsertionParameters parameters)
Takes ownership of evaluators.
std::pair< StartEndValue, int > Seed
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
~ParallelSavingsFilteredHeuristic() override
int64_t GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
ChristofidesFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
int vehicles() const
Returns the number of vehicle routes in the model.
SavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
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...
void ArrangeIndices(std::vector< int64_t > *indices)
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
A Decision represents a choice point in the search tree.
~SequentialSavingsFilteredHeuristic() override
int StartNewRouteWithBestVehicleOfType(int type, int64_t before_node, int64_t after_node)
Finds the best available vehicle of type "type" to start a new route to serve the arc before_node-->a...
virtual void SetVehicleIndex(int64_t node, int vehicle)
bool add_unperformed_entries
If true, entries are created for making the nodes/pairs unperformed, and when the cost of making a no...
Struct used to sort and store vehicles by their type.
Collection of objects used to extend the Constraint Solver library.
std::pair< int, int > GetCompatibleVehicleOfType(int type, std::function< bool(int)> vehicle_is_compatible, std::function< bool(int)> stop_and_return_vehicle)
Searches for the best compatible vehicle of the given type, i.e.
void SetSectors(int sectors)
SweepArranger(const std::vector< std::pair< int64_t, int64_t >> &points)
DecisionBuilder * MakeAllUnperformed(RoutingModel *model)
int GetLowestFixedCostVehicleOfType(int type) const
int64_t Size() const
Returns the number of next variables in the model.
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
void MakeDisjunctionNodesUnperformed(int64_t node)
Make nodes in the same disjunction as 'node' unperformed.
virtual void BuildRoutesFromSavings()=0
std::string DebugString() const override
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
virtual bool InitializeSolution()
Virtual method to initialize the solution.
std::function< int64_t(int64_t, int64_t, int64_t)> evaluator_
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio and min_neighbors) are considered as insertion p...
bool CheckLimit()
Returns true if the search limit has been crossed.
FirstSolutionStrategy::Value AutomaticFirstSolutionStrategy(bool has_pickup_deliveries, bool has_node_precedences, bool has_single_vehicle_node)
Returns the best value for the automatic first solution strategy, based on the given model parameters...
~EvaluatorCheapestAdditionFilteredHeuristic() override
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
const IntContainer & IntVarContainer() const
Assignment *const BuildSolution()
Builds a solution.
int Type(int vehicle) const
std::pair< int64_t, int64_t > ValuedPosition
void AppendEvaluatedPositionsAfter(int64_t node_to_insert, int64_t start, int64_t next_after_start, int64_t vehicle, std::vector< ValuedPosition > *valued_positions)
Helper method to the ComputeEvaluatorSortedPositions* methods.
std::string DebugString() const override
Class to arrange indices by by their distance and their angles from the depot.
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
#define DCHECK_LT(val1, val2)
~ChristofidesFilteredHeuristic() override
int64_t GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
~GlobalCheapestInsertionFilteredHeuristic() override
DecisionBuilder * MakeSweepDecisionBuilder(RoutingModel *model, bool check_assignment)
virtual std::string DebugString() const
int64_t number_of_rejects() const
int64_t number_of_decisions() const
Returns statistics from its underlying heuristic.