14 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
15 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
17 #include <sys/types.h>
30 #include <type_traits>
34 #include "absl/container/flat_hash_set.h"
48 class IntVarFilteredHeuristic;
57 : vehicle_type_container_(&vehicle_type_container) {}
61 int Type(
int vehicle)
const {
return vehicle_type_container_->
Type(vehicle); }
65 void Reset(
const std::function<
bool(
int)>& store_vehicle);
69 void Update(
const std::function<
bool(
int)>& remove_vehicle);
73 const std::set<VehicleClassEntry>& vehicle_classes =
74 sorted_vehicle_classes_per_type_[type];
75 if (vehicle_classes.empty()) {
85 std::vector<int>& vehicles = vehicles_per_vehicle_class_[
vehicle_class];
86 if (vehicles.empty()) {
89 std::set<VehicleClassEntry>& vehicle_classes =
90 sorted_vehicle_classes_per_type_[
Type(vehicle)];
91 const auto& insertion =
93 DCHECK(insertion.second);
95 vehicles.push_back(vehicle);
101 int type,
const std::function<
bool(
int)>& vehicle_is_compatible)
const;
111 int type,
const std::function<
bool(
int)>& vehicle_is_compatible,
112 const std::function<
bool(
int)>& stop_and_return_vehicle);
115 using VehicleClassEntry =
119 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
120 std::vector<std::vector<int> > vehicles_per_vehicle_class_;
128 bool has_node_precedences,
129 bool has_single_vehicle_node);
154 std::unique_ptr<IntVarFilteredHeuristic> heuristic);
167 const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
174 const std::vector<IntVar*>& secondary_vars,
188 virtual std::string
DebugString()
const {
return "IntVarFilteredHeuristic"; }
206 std::optional<int64_t>
Evaluate(
bool commit);
212 if (!is_in_delta_[
index]) {
214 delta_indices_.push_back(
index);
215 is_in_delta_[
index] =
true;
231 int Size()
const {
return vars_.size(); }
237 return index + base_vars_size_;
254 std::vector<IntVar*> vars_;
255 const int base_vars_size_;
257 std::vector<int> delta_indices_;
258 std::vector<bool> is_in_delta_;
261 int64_t objective_upper_bound_;
263 int64_t number_of_decisions_;
264 int64_t number_of_rejects_;
271 std::function<
bool()> stop_search,
273 bool omit_secondary_vars =
true);
277 const std::function<int64_t(int64_t)>& next_accessor);
304 bool InitializeSolution()
override;
307 std::function<bool()> stop_search_;
308 std::vector<int64_t> start_chain_ends_;
309 std::vector<int64_t> end_chain_starts_;
317 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
318 std::function<int64_t(int64_t)> penalty_evaluator,
352 std::vector<std::vector<StartEndValue> >
359 template <
class Queue>
361 std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
362 Queue* priority_queue);
370 void InsertBetween(int64_t node, int64_t predecessor, int64_t successor,
377 int64_t node_to_insert, int64_t
start, int64_t next_after_start,
378 int vehicle,
bool ignore_cost,
379 std::vector<NodeInsertion>* node_insertions);
387 int64_t insert_after,
388 int64_t insert_before,
394 std::function<int64_t(int64_t, int64_t, int64_t)>
evaluator_;
435 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
436 std::function<int64_t(int64_t)> penalty_evaluator,
442 return "GlobalCheapestInsertionFilteredHeuristic";
447 class NodeEntryQueue;
452 PairEntry(
int pickup_to_insert,
int pickup_insert_after,
453 int delivery_to_insert,
int delivery_insert_after,
int vehicle,
455 : value_(std::numeric_limits<int64_t>::
max()),
457 pickup_to_insert_(pickup_to_insert),
458 pickup_insert_after_(pickup_insert_after),
459 delivery_to_insert_(delivery_to_insert),
460 delivery_insert_after_(delivery_insert_after),
465 bool operator<(
const PairEntry& other)
const {
467 if (bucket_ != other.bucket_) {
468 return bucket_ > other.bucket_;
472 if (value_ != other.value_) {
473 return value_ > other.value_;
475 if ((vehicle_ == -1) ^ (other.vehicle_ == -1)) {
476 return vehicle_ == -1;
478 return std::tie(pickup_insert_after_, pickup_to_insert_,
479 delivery_insert_after_, delivery_to_insert_, vehicle_) >
480 std::tie(other.pickup_insert_after_, other.pickup_to_insert_,
481 other.delivery_insert_after_, other.delivery_to_insert_,
484 void SetHeapIndex(
int h) { heap_index_ = h; }
485 int GetHeapIndex()
const {
return heap_index_; }
486 void set_value(int64_t
value) { value_ =
value; }
487 int pickup_to_insert()
const {
return pickup_to_insert_; }
488 int pickup_insert_after()
const {
return pickup_insert_after_; }
489 void set_pickup_insert_after(
int pickup_insert_after) {
490 pickup_insert_after_ = pickup_insert_after;
492 int delivery_to_insert()
const {
return delivery_to_insert_; }
493 int delivery_insert_after()
const {
return delivery_insert_after_; }
494 int vehicle()
const {
return vehicle_; }
495 void set_vehicle(
int vehicle) { vehicle_ = vehicle; }
500 int pickup_to_insert_;
501 int pickup_insert_after_;
502 int delivery_to_insert_;
503 int delivery_insert_after_;
508 typedef absl::flat_hash_set<PairEntry*> PairEntries;
511 template <
typename T>
512 class EntryAllocator {
517 free_entries_.clear();
519 template <
typename... Args>
520 T* NewEntry(
const Args&... args) {
521 if (!free_entries_.empty()) {
522 auto* entry = free_entries_.back();
523 free_entries_.pop_back();
527 entries_.emplace_back(args...);
528 return &entries_.back();
531 void FreeEntry(T* entry) { free_entries_.push_back(entry); }
535 std::deque<T> entries_;
536 std::vector<T*> free_entries_;
545 bool InsertPairsAndNodesByRequirementTopologicalOrder();
554 const std::map<int64_t, std::vector<int>>& pair_indices_by_bucket);
559 bool UseEmptyVehicleTypeCuratorForVehicle(
int vehicle,
560 bool all_vehicles =
true) {
570 bool InsertPairEntryUsingEmptyVehicleTypeCurator(
571 const absl::flat_hash_set<int>& pair_indices, PairEntry*
const pair_entry,
573 std::vector<PairEntries>* pickup_to_entries,
574 std::vector<PairEntries>* delivery_to_entries);
583 bool InsertNodesOnRoutes(
584 const std::map<int64_t, std::vector<int>>& nodes_by_bucket,
585 const absl::flat_hash_set<int>& vehicles);
594 bool InsertNodeEntryUsingEmptyVehicleTypeCurator(
595 const std::vector<bool>&
nodes,
bool all_vehicles, NodeEntryQueue* queue);
602 bool SequentialInsertNodes(
603 const std::map<int64_t, std::vector<int>>& nodes_by_bucket);
608 void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
609 std::vector<int>* unused_vehicles,
610 absl::flat_hash_set<int>* used_vehicles);
615 void InsertFarthestNodesAsSeeds();
625 template <
class Queue>
627 std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
628 Queue* priority_queue, std::vector<bool>* is_vehicle_used);
633 bool InitializePairPositions(
634 const absl::flat_hash_set<int>& pair_indices,
636 std::vector<PairEntries>* pickup_to_entries,
637 std::vector<PairEntries>* delivery_to_entries);
643 void InitializeInsertionEntriesPerformingPair(
644 int64_t pickup, int64_t delivery,
646 std::vector<PairEntries>* pickup_to_entries,
647 std::vector<PairEntries>* delivery_to_entries);
651 bool UpdateAfterPairInsertion(
652 const absl::flat_hash_set<int>& pair_indices,
int vehicle, int64_t pickup,
653 int64_t pickup_position, int64_t delivery, int64_t delivery_position,
655 std::vector<PairEntries>* pickup_to_entries,
656 std::vector<PairEntries>* delivery_to_entries);
660 bool UpdateExistingPairEntriesOnChain(
661 int64_t insert_after_start, int64_t insert_after_end,
663 std::vector<PairEntries>* pickup_to_entries,
664 std::vector<PairEntries>* delivery_to_entries);
670 bool AddPairEntriesAfter(
const absl::flat_hash_set<int>& pair_indices,
671 int vehicle, int64_t insert_after,
672 int64_t skip_entries_inserting_delivery_after,
674 std::vector<PairEntries>* pickup_to_entries,
675 std::vector<PairEntries>* delivery_to_entries) {
676 return AddPairEntriesWithDeliveryAfter(pair_indices, vehicle, insert_after,
677 priority_queue, pickup_to_entries,
678 delivery_to_entries) &&
679 AddPairEntriesWithPickupAfter(pair_indices, vehicle, insert_after,
680 skip_entries_inserting_delivery_after,
681 priority_queue, pickup_to_entries,
682 delivery_to_entries);
690 bool AddPairEntriesWithPickupAfter(
691 const absl::flat_hash_set<int>& pair_indices,
int vehicle,
692 int64_t insert_after, int64_t skip_entries_inserting_delivery_after,
694 std::vector<PairEntries>* pickup_to_entries,
695 std::vector<PairEntries>* delivery_to_entries);
699 bool AddPairEntriesWithDeliveryAfter(
700 const absl::flat_hash_set<int>& pair_indices,
int vehicle,
702 std::vector<PairEntries>* pickup_to_entries,
703 std::vector<PairEntries>* delivery_to_entries);
706 void DeletePairEntry(PairEntry* entry,
708 std::vector<PairEntries>* pickup_to_entries,
709 std::vector<PairEntries>* delivery_to_entries);
714 void AddPairEntry(int64_t pickup, int64_t pickup_insert_after,
715 int64_t delivery, int64_t delivery_insert_after,
718 std::vector<PairEntries>* pickup_entries,
719 std::vector<PairEntries>* delivery_entries)
const;
722 void UpdatePairEntry(
723 PairEntry*
const pair_entry,
728 int64_t GetInsertionValueForPairAtPositions(int64_t pickup,
729 int64_t pickup_insert_after,
731 int64_t delivery_insert_after,
736 bool InitializePositions(
const std::vector<bool>&
nodes,
737 const absl::flat_hash_set<int>& vehicles,
738 NodeEntryQueue* queue);
744 void InitializeInsertionEntriesPerformingNode(
745 int64_t node,
const absl::flat_hash_set<int>& vehicles,
746 NodeEntryQueue* queue);
749 bool UpdateAfterNodeInsertion(
const std::vector<bool>&
nodes,
int vehicle,
750 int64_t node, int64_t insert_after,
751 bool all_vehicles, NodeEntryQueue* queue);
755 bool UpdateExistingNodeEntriesOnChain(
const std::vector<bool>&
nodes,
756 int vehicle, int64_t insert_after_start,
757 int64_t insert_after_end,
759 NodeEntryQueue* queue);
762 bool AddNodeEntriesAfter(
const std::vector<bool>&
nodes,
int vehicle,
763 int64_t insert_after,
bool all_vehicles,
764 NodeEntryQueue* queue);
769 void AddNodeEntry(int64_t node, int64_t insert_after,
int vehicle,
770 bool all_vehicles, NodeEntryQueue* queue)
const;
772 int64_t NumNonStartEndNodes()
const {
776 int64_t NumNeighbors()
const {
779 NumNonStartEndNodes()));
782 void ResetVehicleIndices()
override {
783 node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
786 void SetVehicleIndex(int64_t node,
int vehicle)
override {
787 DCHECK_LT(node, node_index_to_vehicle_.size());
788 node_index_to_vehicle_[node] = vehicle;
793 bool CheckVehicleIndices()
const;
796 int64_t GetBucketOfNode(
int node)
const {
802 int64_t max_pickup_bucket = 0;
803 for (int64_t pickup : index_pair.first) {
804 max_pickup_bucket =
std::max(max_pickup_bucket, GetBucketOfNode(pickup));
806 int64_t max_delivery_bucket = 0;
807 for (int64_t delivery : index_pair.second) {
808 max_delivery_bucket =
809 std::max(max_delivery_bucket, GetBucketOfNode(delivery));
811 return std::min(max_pickup_bucket, max_delivery_bucket);
816 template <
typename T>
819 if constexpr (std::is_same_v<T, PairEntry>) {
820 pair_entry_allocator_.Clear();
822 priority_queue->
Clear();
826 GlobalCheapestInsertionParameters gci_params_;
828 std::vector<int> node_index_to_vehicle_;
830 const RoutingModel::NodeNeighborsByCostClass*
831 node_index_to_neighbors_by_cost_class_;
833 std::unique_ptr<VehicleTypeCurator> empty_vehicle_type_curator_;
835 mutable EntryAllocator<PairEntry> pair_entry_allocator_;
874 int pickup,
const std::vector<int>& path,
875 const std::vector<bool>& node_is_pickup,
876 const std::vector<bool>& node_is_delivery,
877 std::vector<PickupDeliveryInsertion>& insertions);
881 std::vector<int> next_decrease_;
882 std::vector<int> next_increase_;
883 std::vector<int> prev_decrease_;
884 std::vector<int> prev_increase_;
898 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
899 RoutingSearchParameters::PairInsertionStrategy pair_insertion_strategy,
904 return "LocalCheapestInsertionFilteredHeuristic";
914 std::vector<NodeInsertion> ComputeEvaluatorSortedPositions(int64_t node);
919 std::vector<NodeInsertion> ComputeEvaluatorSortedPositionsOnRouteAfter(
920 int64_t node, int64_t
start, int64_t next_after_start,
int vehicle);
925 std::optional<std::vector<InsertionGenerator::PickupDeliveryInsertion>>
926 ComputeEvaluatorSortedPairPositions(int64_t pickup, int64_t delivery);
938 const std::vector<bool>& node_is_pickup,
939 const std::vector<bool>& node_is_delivery);
941 bool InsertPair(int64_t pickup, int64_t insert_pickup_after, int64_t delivery,
942 int64_t insert_delivery_after,
int vehicle);
946 bool update_start_end_distances_per_node_;
947 std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
948 const RoutingSearchParameters::PairInsertionStrategy pair_insertion_strategy_;
952 std::vector<bool> visited_;
960 std::function<
bool()> stop_search,
966 class PartialRoutesAndLargeVehicleIndicesFirst {
968 explicit PartialRoutesAndLargeVehicleIndicesFirst(
970 : builder_(builder) {}
971 bool operator()(
int vehicle1,
int vehicle2)
const;
977 template <
typename Iterator>
978 std::vector<int64_t> GetPossibleNextsFromIterator(int64_t node,
980 Iterator
end)
const {
982 std::vector<int64_t> nexts;
983 for (Iterator it =
start; it !=
end; ++it) {
984 const int64_t
next = *it;
986 nexts.push_back(
next);
992 virtual void SortSuccessors(int64_t node,
993 std::vector<int64_t>* successors) = 0;
994 virtual int64_t FindTopSuccessor(int64_t node,
995 const std::vector<int64_t>& successors) = 0;
1006 std::function<int64_t(int64_t, int64_t)> evaluator,
1010 return "EvaluatorCheapestAdditionFilteredHeuristic";
1015 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
1016 int64_t FindTopSuccessor(int64_t node,
1017 const std::vector<int64_t>& successors)
override;
1019 std::function<int64_t(int64_t, int64_t)> evaluator_;
1034 return "ComparatorCheapestAdditionFilteredHeuristic";
1039 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
1040 int64_t FindTopSuccessor(int64_t node,
1041 const std::vector<int64_t>& successors)
override;
1072 std::function<
bool()> stop_search,
1081 template <
typename S>
1090 return saving.second / size_squared_;
1094 return (saving.second % size_squared_) /
Size();
1098 return (saving.second % size_squared_) %
Size();
1113 int64_t after_node);
1126 void AddSymmetricArcsToAdjacencyLists(
1127 std::vector<std::vector<int64_t> >* adjacency_lists);
1138 bool ComputeSavings();
1140 Saving BuildSaving(int64_t saving,
int vehicle_type,
int before_node,
1141 int after_node)
const {
1142 return std::make_pair(saving, vehicle_type * size_squared_ +
1143 before_node *
Size() + after_node);
1149 int64_t MaxNumNeighborsPerNode(
int num_vehicle_types)
const;
1151 const SavingsParameters savings_params_;
1152 int64_t size_squared_;
1160 std::function<
bool()> stop_search,
1167 return "SequentialSavingsFilteredHeuristic";
1175 void BuildRoutesFromSavings()
override;
1176 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 1.0; }
1182 std::function<
bool()> stop_search,
1189 return "ParallelSavingsFilteredHeuristic";
1203 void BuildRoutesFromSavings()
override;
1205 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 2.0; }
1211 void MergeRoutes(
int first_vehicle,
int second_vehicle, int64_t before_node,
1212 int64_t after_node);
1215 std::vector<int64_t> first_node_on_route_;
1216 std::vector<int64_t> last_node_on_route_;
1220 std::vector<int> vehicle_of_first_or_last_node_;
1230 std::function<
bool()> stop_search,
1232 bool use_minimum_matching);
1236 return "ChristofidesFilteredHeuristic";
1240 const bool use_minimum_matching_;
1248 const std::vector<std::pair<int64_t, int64_t>>& points);
1254 std::vector<int> coordinates_;
1264 bool check_assignment);
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(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager)
~CheapestAdditionFilteredHeuristic() override=default
void AppendInsertionPositionsAfter(int64_t node_to_insert, int64_t start, int64_t next_after_start, int vehicle, bool ignore_cost, std::vector< NodeInsertion > *node_insertions)
Helper method to the ComputeEvaluatorSortedPositions* methods.
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...
CheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, 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.
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...
~CheapestInsertionFilteredHeuristic() override=default
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_
void InsertBetween(int64_t node, int64_t predecessor, int64_t successor, int vehicle=-1)
Inserts 'node' just after 'predecessor', and just before 'successor' on the route of 'vehicle',...
std::pair< StartEndValue, int > Seed
Christofides addition heuristic.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
ChristofidesFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
~ChristofidesFilteredHeuristic() override=default
std::string DebugString() const override
A CheapestAdditionFilteredHeuristic where the notion of 'cheapest arc' comes from an arc comparator.
~ComparatorCheapestAdditionFilteredHeuristic() override=default
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
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< bool()> stop_search, std::function< int64_t(int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
std::string DebugString() const override
~EvaluatorCheapestAdditionFilteredHeuristic() override=default
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< bool()> stop_search, 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=default
std::string DebugString() const override
void AppendPickupDeliveryMultitourInsertions(int pickup, const std::vector< int > &path, const std::vector< bool > &node_is_pickup, const std::vector< bool > &node_is_delivery, std::vector< PickupDeliveryInsertion > &insertions)
Generates insertions for a pickup and delivery pair in a multitour path:
InsertionGenerator()=default
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.
int64_t SecondaryVarIndex(int64_t index) const
Returns the index of a secondary var.
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.
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 ~IntVarFilteredHeuristic()=default
bool HasSecondaryVars() const
Returns true if there are secondary variables.
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...
virtual void Initialize()
Initialize the heuristic; called before starting to build a new solution.
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'.
bool IsSecondaryVar(int64_t index) const
Returns true if 'index' is a secondary variable index.
std::optional< int64_t > Evaluate(bool commit)
Evaluates the modifications to the current solution.
Assignment *const BuildSolution()
Builds a solution.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, LocalSearchFilterManager *filter_manager)
int64_t number_of_rejects() const
The class IntVar is a subset of IntExpr.
virtual uint64_t Size() const =0
This method returns the number of values in the domain of the variable.
Filter-base decision builder which builds a solution by inserting nodes at their cheapest position.
void Initialize() override
Initialize the heuristic; called before starting to build a new solution.
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
LocalCheapestInsertionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, RoutingSearchParameters::PairInsertionStrategy pair_insertion_strategy, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
~LocalCheapestInsertionFilteredHeuristic() override=default
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() override=default
std::string DebugString() const override
ParallelSavingsFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Filter-based heuristic dedicated to routing.
bool MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed, always returns true.
RoutingFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager, bool omit_secondary_vars=true)
~RoutingFilteredHeuristic() override=default
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
RoutingModel * model() const
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.
virtual void ResetVehicleIndices()
void MakePartiallyPerformedPairsUnperformed()
Make all partially performed pickup and delivery pairs unperformed.
virtual void SetVehicleIndex(int64_t, int)
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.
RoutingIndexPair IndexPair
IntVar * VehicleVar(int64_t index) const
Returns the vehicle variable of the node corresponding to index.
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, std::function< bool()> stop_search, 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(RoutingModel *model, std::function< bool()> stop_search, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
~SequentialSavingsFilteredHeuristic() override=default
std::string DebugString() const override
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
Class to arrange indices by their distance and their angle 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...
bool HasCompatibleVehicleOfType(int type, const std::function< bool(int)> &vehicle_is_compatible) const
Searches a compatible vehicle of the given type; returns false if none was found.
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...
std::pair< int, int > GetCompatibleVehicleOfType(int type, const std::function< bool(int)> &vehicle_is_compatible, const std::function< bool(int)> &stop_and_return_vehicle)
Searches for the best compatible vehicle of the given type, i.e.
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)
std::vector< int64_t > ComputeVehicleEndChainStarts(const RoutingModel &model)
Computes and returns the first node in the end chain of each vehicle in the model,...
std::optional< int64_t > end
bool operator<(const NodeInsertion &other) const
bool operator<(const StartEndValue &other) const
int64_t num_allowed_vehicles
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...
int64_t insert_delivery_after
int64_t insert_pickup_after
bool operator<(const PickupDeliveryInsertion &other) const
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.