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;
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);
#define DCHECK_LT(val1, val2)
#define DCHECK(condition)
const E & Element(const V *const var) const
An Assignment is a variable -> domains mapping, used to report solutions to the user.
const IntContainer & IntVarContainer() const
void SetValue(const IntVar *const var, int64_t value)
IntVarElement * FastAdd(IntVar *const var)
Adds without checking if variable has been previously added.
Filtered-base decision builder based on the addition heuristic, extending a path from its start node ...
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
~CheapestAdditionFilteredHeuristic() override
CheapestAdditionFilteredHeuristic(RoutingModel *model, 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 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::function< int64_t(int64_t, int64_t, int64_t)> evaluator_
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,...
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::pair< int64_t, int64_t > ValuedPosition
~CheapestInsertionFilteredHeuristic() override
int64_t GetUnperformedValue(int64_t node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
std::function< int64_t(int64_t)> penalty_evaluator_
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.
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...
std::pair< StartEndValue, int > Seed
Christofides addition heuristic.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
~ChristofidesFilteredHeuristic() override
std::string DebugString() const override
ChristofidesFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
~ComparatorCheapestAdditionFilteredHeuristic() override
std::string DebugString() const override
A DecisionBuilder is responsible for creating the search tree.
A Decision represents a choice point in the search tree.
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc evaluator.
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
~EvaluatorCheapestAdditionFilteredHeuristic() override
std::string DebugString() const override
Filter-based decision builder which builds a solution by inserting nodes at their cheapest position o...
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
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.
~GlobalCheapestInsertionFilteredHeuristic() override
std::string DebugString() const override
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
~IntVarFilteredDecisionBuilder() override
Decision * Next(Solver *solver) override
This is the main method of the decision builder class.
int64_t number_of_decisions() const
Returns statistics from its underlying heuristic.
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
std::string DebugString() const override
int64_t number_of_rejects() const
Generic filter-based heuristic applied to IntVars.
void SetValue(int64_t index, int64_t value)
Modifies the current solution by setting the variable of index 'index' to value 'value'.
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
int Size() const
Returns the number of variables the decision builder is trying to instantiate.
bool Contains(int64_t index) const
Returns true if the variable of index 'index' is in the current solution.
bool Commit()
Commits the modifications to the current solution if these modifications are "filter-feasible",...
virtual ~IntVarFilteredHeuristic()
virtual bool StopSearch()
Returns true if the search must be stopped.
Assignment *const assignment_
void ResetSolution()
Resets the data members for a new solution.
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).
virtual std::string DebugString() const
virtual bool InitializeSolution()
Virtual method to initialize the solution.
int64_t number_of_decisions() const
Returns statistics on search, number of decisions sent to filters, number of decisions rejected by fi...
int64_t Value(int64_t index) const
Returns the value of the variable of index 'index' in the last committed solution.
IntVar * Var(int64_t index) const
Returns the variable of index 'index'.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
Assignment *const BuildSolution()
Builds a solution.
int64_t number_of_rejects() const
The class IntVar is a subset of IntExpr.
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
~LocalCheapestInsertionFilteredHeuristic() override
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
std::string DebugString() const override
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
static int64_t FastInt64Round(double x)
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
~ParallelSavingsFilteredHeuristic() override
std::string DebugString() const override
Filter-based heuristic dedicated to routing.
~RoutingFilteredHeuristic() override
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
RoutingModel * model() const
virtual void SetVehicleIndex(int64_t node, int vehicle)
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
void MakeDisjunctionNodesUnperformed(int64_t node)
Make nodes in the same disjunction as 'node' unperformed.
bool StopSearch() override
Returns true if the search must be stopped.
void MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed.
virtual void ResetVehicleIndices()
void MakePartiallyPerformedPairsUnperformed()
Make all partially performed pickup and delivery pairs unperformed.
bool VehicleIsEmpty(int vehicle) const
const Assignment * BuildSolutionFromRoutes(const std::function< int64_t(int64_t)> &next_accessor)
Builds a solution starting from the routes formed by the next accessor.
RoutingFilteredHeuristic(RoutingModel *model, LocalSearchFilterManager *filter_manager)
Manager for any NodeIndex <-> variable index conversion.
bool CheckLimit()
Returns true if the search limit has been crossed.
int64_t Size() const
Returns the number of next variables in the model.
int vehicles() const
Returns the number of vehicle routes in the model.
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Filter-based decision builder which builds a solution by using Clarke & Wright's Savings heuristic.
int64_t GetVehicleTypeFromSaving(const Saving &saving) const
Returns the cost class from a saving.
std::unique_ptr< VehicleTypeCurator > vehicle_type_curator_
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
int64_t GetAfterNodeFromSaving(const Saving &saving) const
Returns the "after node" from a saving.
int64_t GetSavingValue(const Saving &saving) const
Returns the saving value from a saving.
std::pair< int64_t, int64_t > Saving
std::unique_ptr< SavingsContainer< Saving > > savings_container_
~SavingsFilteredHeuristic() override
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
friend class SavingsFilteredHeuristicTestPeer
int64_t GetBeforeNodeFromSaving(const Saving &saving) const
Returns the "before node" from a saving.
SavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
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 BuildRoutesFromSavings()=0
~SequentialSavingsFilteredHeuristic() override
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
std::string DebugString() const override
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
Class to arrange indices by by their distance and their angles from the depot.
void ArrangeIndices(std::vector< int64_t > *indices)
void SetSectors(int sectors)
SweepArranger(const std::vector< std::pair< int64_t, int64_t >> &points)
Helper class that manages vehicles.
void Update(const std::function< bool(int)> &remove_vehicle)
Goes through all the currently stored vehicles and removes vehicles for which remove_vehicle() return...
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.
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
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...
int Type(int vehicle) const
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64_t fixed_cost)
int GetLowestFixedCostVehicleOfType(int type) const
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Collection of objects used to extend the Constraint Solver library.
DecisionBuilder * MakeAllUnperformed(RoutingModel *model)
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...
DecisionBuilder * MakeSweepDecisionBuilder(RoutingModel *model, bool check_assignment)
bool operator<(const StartEndValue &other) const
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
double farthest_seeds_ratio
The ratio of routes on which to insert farthest nodes as seeds before starting the cheapest insertion...
bool use_neighbors_ratio_for_initialization
If true, only closest neighbors (see neighbors_ratio and min_neighbors) are considered as insertion p...
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.
int Type(int vehicle) const
double neighbors_ratio
If neighbors_ratio < 1 then for each node only this ratio of its neighbors leading to the smallest ar...
double arc_coefficient
arc_coefficient is a strictly positive parameter indicating the coefficient of the arc being consider...
double max_memory_usage_bytes
The number of neighbors considered for each node is also adapted so that the stored Savings don't use...
bool add_reverse_arcs
If add_reverse_arcs is true, the neighborhood relationships are considered symmetrically.