14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
23#include <initializer_list>
36#include "absl/container/flat_hash_map.h"
37#include "absl/container/flat_hash_set.h"
38#include "absl/log/check.h"
39#include "absl/types/span.h"
44#include "ortools/constraint_solver/routing_enums.pb.h"
45#include "ortools/constraint_solver/routing_parameters.pb.h"
51class IntVarFilteredHeuristic;
59 const RoutingModel::VehicleTypeContainer& vehicle_type_container)
60 : vehicle_type_container_(&vehicle_type_container) {}
62 int NumTypes()
const {
return vehicle_type_container_->NumTypes(); }
64 int Type(
int vehicle)
const {
return vehicle_type_container_->Type(vehicle); }
68 void Reset(
const std::function<
bool(
int)>& store_vehicle);
72 void Update(
const std::function<
bool(
int)>& remove_vehicle);
76 const std::set<VehicleClassEntry>& vehicle_classes =
77 sorted_vehicle_classes_per_type_[type];
78 if (vehicle_classes.empty()) {
81 const int vehicle_class = (vehicle_classes.begin())->vehicle_class;
88 std::vector<int>& vehicles = vehicles_per_vehicle_class_[
vehicle_class];
89 if (vehicles.empty()) {
92 std::set<VehicleClassEntry>& vehicle_classes =
93 sorted_vehicle_classes_per_type_[
Type(vehicle)];
94 const auto& insertion =
96 DCHECK(insertion.second);
98 vehicles.push_back(vehicle);
104 int type,
const std::function<
bool(
int)>& vehicle_is_compatible)
const;
114 int type,
const std::function<
bool(
int)>& vehicle_is_compatible,
115 const std::function<
bool(
int)>& stop_and_return_vehicle);
118 using VehicleClassEntry =
119 RoutingModel::VehicleTypeContainer::VehicleClassEntry;
120 const RoutingModel::VehicleTypeContainer*
const vehicle_type_container_;
122 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
123 std::vector<std::vector<int> > vehicles_per_vehicle_class_;
129operations_research::FirstSolutionStrategy::Value
131 bool has_node_precedences,
132 bool has_single_vehicle_node);
157 std::unique_ptr<IntVarFilteredHeuristic> heuristic);
170 const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
177 const std::vector<IntVar*>& secondary_vars,
191 virtual std::string
DebugString()
const {
return "IntVarFilteredHeuristic"; }
209 std::optional<int64_t>
Evaluate(
bool commit);
215 DCHECK_LT(
index, is_in_delta_.size());
216 if (!is_in_delta_[
index]) {
218 delta_indices_.push_back(
index);
219 is_in_delta_[
index] =
true;
240 return index + base_vars_size_;
257 std::vector<IntVar*> vars_;
258 const int base_vars_size_;
260 std::vector<int> delta_indices_;
261 std::vector<bool> is_in_delta_;
264 int64_t objective_upper_bound_;
266 int64_t number_of_decisions_;
267 int64_t number_of_rejects_;
274 std::function<
bool()> stop_search,
279 const std::function<int64_t(int64_t)>& next_accessor);
280 RoutingModel*
model()
const {
return model_; }
310 bool InitializeSolution()
override;
312 RoutingModel*
const model_;
313 std::function<bool()> stop_search_;
314 std::vector<int64_t> start_chain_ends_;
315 std::vector<int64_t> end_chain_starts_;
322 RoutingModel*
model, std::function<
bool()> stop_search,
323 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
324 std::function<int64_t(int64_t)> penalty_evaluator,
371 std::priority_queue<Seed, std::vector<Seed>, std::greater<Seed> >
383 std::vector<std::vector<StartEndValue> >
390 std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
397 std::vector<StartEndValue>* start_end_distances,
405 void InsertBetween(int64_t node, int64_t predecessor, int64_t successor,
412 int64_t node_to_insert, int64_t
start, int64_t next_after_start,
413 int vehicle,
bool ignore_cost,
414 std::vector<NodeInsertion>* node_insertions);
422 int64_t insert_after,
423 int64_t insert_before,
429 std::function<int64_t(int64_t, int64_t, int64_t)>
evaluator_;
469 RoutingModel*
model, std::function<
bool()> stop_search,
470 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
471 std::function<int64_t(int64_t)> penalty_evaluator,
477 return "GlobalCheapestInsertionFilteredHeuristic";
482 class NodeEntryQueue;
487 PairEntry(
int pickup_to_insert,
int pickup_insert_after,
488 int delivery_to_insert,
int delivery_insert_after,
int vehicle,
490 : value_(
std::numeric_limits<int64_t>::
max()),
492 pickup_to_insert_(pickup_to_insert),
493 pickup_insert_after_(pickup_insert_after),
494 delivery_to_insert_(delivery_to_insert),
495 delivery_insert_after_(delivery_insert_after),
500 bool operator<(
const PairEntry& other)
const {
502 if (bucket_ != other.bucket_) {
503 return bucket_ > other.bucket_;
507 if (value_ != other.value_) {
508 return value_ > other.value_;
510 if ((vehicle_ == -1) ^ (other.vehicle_ == -1)) {
511 return vehicle_ == -1;
513 return std::tie(pickup_insert_after_, pickup_to_insert_,
514 delivery_insert_after_, delivery_to_insert_, vehicle_) >
515 std::tie(other.pickup_insert_after_, other.pickup_to_insert_,
516 other.delivery_insert_after_, other.delivery_to_insert_,
519 void SetHeapIndex(
int h) { heap_index_ = h; }
520 int GetHeapIndex()
const {
return heap_index_; }
521 void set_value(int64_t
value) { value_ =
value; }
522 int pickup_to_insert()
const {
return pickup_to_insert_; }
523 int pickup_insert_after()
const {
return pickup_insert_after_; }
524 void set_pickup_insert_after(
int pickup_insert_after) {
525 pickup_insert_after_ = pickup_insert_after;
527 int delivery_to_insert()
const {
return delivery_to_insert_; }
528 int delivery_insert_after()
const {
return delivery_insert_after_; }
529 int vehicle()
const {
return vehicle_; }
530 void set_vehicle(
int vehicle) { vehicle_ = vehicle; }
535 int pickup_to_insert_;
536 int pickup_insert_after_;
537 int delivery_to_insert_;
538 int delivery_insert_after_;
543 typedef absl::flat_hash_set<PairEntry*> PairEntries;
546 template <
typename T>
547 class EntryAllocator {
552 free_entries_.clear();
554 template <
typename... Args>
555 T* NewEntry(
const Args&... args) {
556 if (!free_entries_.empty()) {
557 auto* entry = free_entries_.back();
558 free_entries_.pop_back();
562 entries_.emplace_back(args...);
563 return &entries_.back();
566 void FreeEntry(T* entry) { free_entries_.push_back(entry); }
570 std::deque<T> entries_;
571 std::vector<T*> free_entries_;
580 bool InsertPairsAndNodesByRequirementTopologicalOrder();
589 const std::map<int64_t, std::vector<int>>& pair_indices_by_bucket);
594 bool UseEmptyVehicleTypeCuratorForVehicle(
int vehicle,
595 bool all_vehicles =
true) {
605 bool InsertPairEntryUsingEmptyVehicleTypeCurator(
606 const absl::flat_hash_set<int>& pair_indices, PairEntry* pair_entry,
608 std::vector<PairEntries>* pickup_to_entries,
609 std::vector<PairEntries>* delivery_to_entries);
618 bool InsertNodesOnRoutes(
619 const std::map<int64_t, std::vector<int>>& nodes_by_bucket,
620 const absl::flat_hash_set<int>& vehicles);
629 bool InsertNodeEntryUsingEmptyVehicleTypeCurator(
630 const std::vector<bool>&
nodes,
bool all_vehicles, NodeEntryQueue* queue);
637 bool SequentialInsertNodes(
638 const std::map<int64_t, std::vector<int>>& nodes_by_bucket);
643 void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
644 std::vector<int>* unused_vehicles,
645 absl::flat_hash_set<int>* used_vehicles);
649 bool IsCheapestClassRepresentative(
int vehicle)
const;
654 void InsertFarthestNodesAsSeeds();
665 std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
666 SeedQueue* sq, std::vector<bool>* is_vehicle_used);
671 bool InitializePairPositions(
672 const absl::flat_hash_set<int>& pair_indices,
674 std::vector<PairEntries>* pickup_to_entries,
675 std::vector<PairEntries>* delivery_to_entries);
681 void InitializeInsertionEntriesPerformingPair(
682 int64_t pickup, int64_t delivery,
684 std::vector<PairEntries>* pickup_to_entries,
685 std::vector<PairEntries>* delivery_to_entries);
689 bool UpdateAfterPairInsertion(
690 const absl::flat_hash_set<int>& pair_indices,
int vehicle, int64_t pickup,
691 int64_t pickup_position, int64_t delivery, int64_t delivery_position,
693 std::vector<PairEntries>* pickup_to_entries,
694 std::vector<PairEntries>* delivery_to_entries);
698 bool UpdateExistingPairEntriesOnChain(
699 int64_t insert_after_start, int64_t insert_after_end,
701 std::vector<PairEntries>* pickup_to_entries,
702 std::vector<PairEntries>* delivery_to_entries);
708 bool AddPairEntriesAfter(
const absl::flat_hash_set<int>& pair_indices,
709 int vehicle, int64_t insert_after,
710 int64_t skip_entries_inserting_delivery_after,
712 std::vector<PairEntries>* pickup_to_entries,
713 std::vector<PairEntries>* delivery_to_entries) {
714 return AddPairEntriesWithDeliveryAfter(pair_indices, vehicle, insert_after,
715 priority_queue, pickup_to_entries,
716 delivery_to_entries) &&
717 AddPairEntriesWithPickupAfter(pair_indices, vehicle, insert_after,
718 skip_entries_inserting_delivery_after,
719 priority_queue, pickup_to_entries,
720 delivery_to_entries);
728 bool AddPairEntriesWithPickupAfter(
729 const absl::flat_hash_set<int>& pair_indices,
int vehicle,
730 int64_t insert_after, int64_t skip_entries_inserting_delivery_after,
732 std::vector<PairEntries>* pickup_to_entries,
733 std::vector<PairEntries>* delivery_to_entries);
737 bool AddPairEntriesWithDeliveryAfter(
738 const absl::flat_hash_set<int>& pair_indices,
int vehicle,
740 std::vector<PairEntries>* pickup_to_entries,
741 std::vector<PairEntries>* delivery_to_entries);
744 void DeletePairEntry(PairEntry* entry,
746 std::vector<PairEntries>* pickup_to_entries,
747 std::vector<PairEntries>* delivery_to_entries);
752 void AddPairEntry(int64_t pickup, int64_t pickup_insert_after,
753 int64_t delivery, int64_t delivery_insert_after,
756 std::vector<PairEntries>* pickup_entries,
757 std::vector<PairEntries>* delivery_entries)
const;
760 void UpdatePairEntry(
761 PairEntry* pair_entry,
766 int64_t GetInsertionValueForPairAtPositions(int64_t pickup,
767 int64_t pickup_insert_after,
769 int64_t delivery_insert_after,
774 bool InitializePositions(
const std::vector<bool>&
nodes,
775 const absl::flat_hash_set<int>& vehicles,
776 NodeEntryQueue* queue);
782 void InitializeInsertionEntriesPerformingNode(
783 int64_t node,
const absl::flat_hash_set<int>& vehicles,
784 NodeEntryQueue* queue);
787 bool UpdateAfterNodeInsertion(
const std::vector<bool>&
nodes,
int vehicle,
788 int64_t node, int64_t insert_after,
789 bool all_vehicles, NodeEntryQueue* queue);
793 bool UpdateExistingNodeEntriesOnChain(
const std::vector<bool>&
nodes,
794 int vehicle, int64_t insert_after_start,
795 int64_t insert_after_end,
797 NodeEntryQueue* queue);
800 bool AddNodeEntriesAfter(
const std::vector<bool>&
nodes,
int vehicle,
801 int64_t insert_after,
bool all_vehicles,
802 NodeEntryQueue* queue);
807 void AddNodeEntry(int64_t node, int64_t insert_after,
int vehicle,
808 bool all_vehicles, NodeEntryQueue* queue)
const;
810 void ResetVehicleIndices()
override {
811 node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
814 void SetVehicleIndex(int64_t node,
int vehicle)
override {
815 DCHECK_LT(node, node_index_to_vehicle_.size());
816 node_index_to_vehicle_[node] = vehicle;
821 bool CheckVehicleIndices()
const;
824 int64_t GetBucketOfNode(
int node)
const {
825 return model()->VehicleVar(node)->Size();
829 int64_t GetBucketOfPair(
const PickupDeliveryPair& pair)
const {
830 int64_t max_pickup_bucket = 0;
831 for (int64_t pickup : pair.pickup_alternatives) {
832 max_pickup_bucket = std::max(max_pickup_bucket, GetBucketOfNode(pickup));
834 int64_t max_delivery_bucket = 0;
835 for (int64_t delivery : pair.delivery_alternatives) {
836 max_delivery_bucket =
837 std::max(max_delivery_bucket, GetBucketOfNode(delivery));
839 return std::min(max_pickup_bucket, max_delivery_bucket);
844 template <
typename T>
847 if constexpr (std::is_same_v<T, PairEntry>) {
848 pair_entry_allocator_.Clear();
850 priority_queue->
Clear();
854 GlobalCheapestInsertionParameters gci_params_;
856 std::vector<int> node_index_to_vehicle_;
858 const RoutingModel::NodeNeighborsByCostClass*
859 node_index_to_neighbors_by_cost_class_;
861 std::unique_ptr<VehicleTypeCurator> empty_vehicle_type_curator_;
863 mutable EntryAllocator<PairEntry> pair_entry_allocator_;
880 struct InsertionBounds {
885 bool operator<(
const InsertionBounds& other)
const {
886 return std::tie(cost, vehicle, begin) <
887 std::tie(other.cost, other.vehicle, other.begin);
889 size_t Size()
const {
return end - begin; }
906 : data_(data), bounds_(bounds) {}
909 DCHECK_NE(data_, other.data_);
910 return bounds_ != other.bounds_;
915 size_t Size()
const {
return bounds_->Size(); }
916 int Vehicle()
const {
return bounds_->vehicle; }
917 int64_t
Cost()
const {
return bounds_->cost; }
918 int64_t&
Cost() {
return bounds_->cost; }
922 InsertionBounds*
const bounds_;
927 : data_(data), bounds_(bounds) {}
929 DCHECK_EQ(data_, other.data_);
930 return bounds_ != other.bounds_;
940 InsertionBounds* bounds_;
945 return {insertions_.data(), insertion_bounds_.data()};
948 return {insertions_.data(),
949 insertion_bounds_.data() + insertion_bounds_.size()};
952 size_t Size()
const {
return insertion_bounds_.size(); }
958 int vehicle, std::initializer_list<Insertion> insertion_sequence) {
959 insertion_bounds_.push_back(
960 {.begin = insertions_.size(),
961 .end = insertions_.size() + insertion_sequence.size(),
964 insertions_.insert(insertions_.end(), insertion_sequence.begin(),
965 insertion_sequence.end());
970 absl::Span<const Insertion> insertion_sequence) {
971 insertion_bounds_.push_back(
972 {.begin = insertions_.size(),
973 .end = insertions_.size() + insertion_sequence.size(),
976 insertions_.insert(insertions_.end(), insertion_sequence.begin(),
977 insertion_sequence.end());
987 if (!p(sequence)) insertion_bounds_[
to++] = insertion_bounds_[from];
990 insertion_bounds_.resize(
to);
997 void Sort() { std::sort(insertion_bounds_.begin(), insertion_bounds_.end()); }
1001 insertions_.clear();
1002 insertion_bounds_.clear();
1006 std::vector<Insertion> insertions_;
1007 std::vector<InsertionBounds> insertion_bounds_;
1033 int pickup,
int delivery,
int vehicle,
const std::vector<int>& path,
1034 const std::vector<bool>& path_node_is_pickup,
1035 const std::vector<bool>& path_node_is_delivery,
1040 std::vector<int> next_decrease_;
1041 std::vector<int> next_increase_;
1042 std::vector<int> prev_decrease_;
1043 std::vector<int> prev_increase_;
1070 RoutingModel*
model, std::function<
bool()> stop_search,
1071 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
1072 RoutingSearchParameters::PairInsertionStrategy pair_insertion_strategy,
1075 std::function<
bool(
const std::vector<RoutingModel::VariableValuePair>&,
1076 std::vector<RoutingModel::VariableValuePair>*)>
1077 optimize_on_insertion =
nullptr);
1081 return "LocalCheapestInsertionFilteredHeuristic";
1091 void ComputeInsertionOrder();
1095 std::vector<NodeInsertion> ComputeEvaluatorSortedPositions(int64_t node);
1100 std::vector<NodeInsertion> ComputeEvaluatorSortedPositionsOnRouteAfter(
1101 int64_t node, int64_t
start, int64_t next_after_start,
int vehicle);
1106 std::vector<PickupDeliveryInsertion> ComputeEvaluatorSortedPairPositions(
1107 int pickup,
int delivery);
1120 bool InsertPair(int64_t pickup, int64_t insert_pickup_after, int64_t delivery,
1121 int64_t insert_delivery_after,
int vehicle);
1129 bool MustUpdateBinCapacities()
const {
1130 return bin_capacities_ !=
nullptr && optimize_on_insertion_ ==
nullptr;
1133 std::vector<Seed> insertion_order_;
1134 const RoutingSearchParameters::PairInsertionStrategy pair_insertion_strategy_;
1135 InsertionSequenceContainer insertion_container_;
1136 InsertionSequenceGenerator insertion_generator_;
1138 BinCapacities*
const bin_capacities_;
1140 std::function<bool(
const std::vector<RoutingModel::VariableValuePair>&,
1141 std::vector<RoutingModel::VariableValuePair>*)>
1142 optimize_on_insertion_;
1143 bool synchronize_insertion_optimizer_ =
true;
1151 std::function<
bool()> stop_search,
1157 class PartialRoutesAndLargeVehicleIndicesFirst {
1159 explicit PartialRoutesAndLargeVehicleIndicesFirst(
1161 : builder_(builder) {}
1162 bool operator()(
int vehicle1,
int vehicle2)
const;
1168 template <
typename Iterator>
1169 std::vector<int64_t> GetPossibleNextsFromIterator(int64_t node,
1171 Iterator
end)
const {
1173 std::vector<int64_t> nexts;
1174 for (Iterator it =
start; it !=
end; ++it) {
1175 const int64_t
next = *it;
1177 nexts.push_back(
next);
1183 virtual void SortSuccessors(int64_t node,
1184 std::vector<int64_t>* successors) = 0;
1185 virtual int64_t FindTopSuccessor(int64_t node,
1186 const std::vector<int64_t>& successors) = 0;
1196 RoutingModel*
model, std::function<
bool()> stop_search,
1197 std::function<int64_t(int64_t, int64_t)> evaluator,
1201 return "EvaluatorCheapestAdditionFilteredHeuristic";
1206 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
1207 int64_t FindTopSuccessor(int64_t node,
1208 const std::vector<int64_t>& successors)
override;
1210 std::function<int64_t(int64_t, int64_t)> evaluator_;
1220 RoutingModel*
model, std::function<
bool()> stop_search,
1225 return "ComparatorCheapestAdditionFilteredHeuristic";
1230 void SortSuccessors(int64_t node, std::vector<int64_t>* successors)
override;
1231 int64_t FindTopSuccessor(int64_t node,
1232 const std::vector<int64_t>& successors)
override;
1263 std::function<
bool()> stop_search,
1282 template <
typename S>
1299 int64_t after_node);
1312 void AddSymmetricArcsToAdjacencyLists(
1313 std::vector<std::vector<int64_t> >* adjacency_lists);
1324 bool ComputeSavings();
1326 Saving BuildSaving(int64_t saving,
int vehicle_type,
int before_node,
1327 int after_node)
const {
1328 return {saving,
static_cast<unsigned int>(vehicle_type),
1329 static_cast<unsigned int>(before_node),
1330 static_cast<unsigned int>(after_node)};
1336 int64_t MaxNumNeighborsPerNode(
int num_vehicle_types)
const;
1338 const SavingsParameters savings_params_;
1346 std::function<
bool()> stop_search,
1353 return "SequentialSavingsFilteredHeuristic";
1361 void BuildRoutesFromSavings()
override;
1362 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 1.0; }
1368 std::function<
bool()> stop_search,
1375 return "ParallelSavingsFilteredHeuristic";
1389 void BuildRoutesFromSavings()
override;
1391 double ExtraSavingsMemoryMultiplicativeFactor()
const override {
return 2.0; }
1397 void MergeRoutes(
int first_vehicle,
int second_vehicle, int64_t before_node,
1398 int64_t after_node);
1401 std::vector<int64_t> first_node_on_route_;
1402 std::vector<int64_t> last_node_on_route_;
1406 std::vector<int> vehicle_of_first_or_last_node_;
1416 std::function<
bool()> stop_search,
1418 bool use_minimum_matching);
1422 return "ChristofidesFilteredHeuristic";
1426 const bool use_minimum_matching_;
1434 const std::vector<std::pair<int64_t, int64_t>>& points);
1445 std::vector<int> coordinates_;
1453 bool check_assignment);
const E & Element(const V *const var) const
void SetValue(const IntVar *var, int64_t value)
IntVarElement * FastAdd(IntVar *var)
Adds without checking if variable has been previously added.
const IntContainer & IntVarContainer() const
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
~CheapestAdditionFilteredHeuristic() override
CheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager)
CheapestAdditionFilteredHeuristic.
int64_t GetInsertionCostForNodeAtPosition(int64_t node_to_insert, int64_t insert_after, int64_t insert_before, int vehicle) const
std::function< int64_t(int64_t, int64_t, int64_t)> evaluator_
~CheapestInsertionFilteredHeuristic() override
void InitializeSeedQueue(std::vector< std::vector< StartEndValue > > *start_end_distances_per_node, SeedQueue *sq)
std::vector< std::vector< StartEndValue > > ComputeStartEndDistanceForVehicles(const std::vector< int > &vehicles)
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.
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)
int64_t GetUnperformedValue(int64_t node_to_insert) const
void InsertBetween(int64_t node, int64_t predecessor, int64_t successor, int vehicle=-1)
std::function< int64_t(int64_t)> penalty_evaluator_
void AddSeedNodeToQueue(int node, std::vector< StartEndValue > *start_end_distances, SeedQueue *sq)
clang-format on
ChristofidesFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager, bool use_minimum_matching)
ChristofidesFilteredHeuristic.
bool BuildSolutionInternal() override
~ChristofidesFilteredHeuristic() override
std::string DebugString() const override
~ComparatorCheapestAdditionFilteredHeuristic() override
std::string DebugString() const override
ComparatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, Solver::VariableValueComparator comparator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
~EvaluatorCheapestAdditionFilteredHeuristic() override
std::string DebugString() const override
EvaluatorCheapestAdditionFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, std::function< int64_t(int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
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
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
std::string DebugString() const override
InsertionSequenceIterator(Insertion *data, InsertionBounds *bounds)
InsertionSequence operator*() const
bool operator!=(const InsertionSequenceIterator &other) const
InsertionSequenceIterator & operator++()
const Insertion * end() const
const Insertion * begin() const
bool operator!=(const InsertionSequence &other) const
InsertionSequence(Insertion *data, InsertionBounds *bounds)
void RemoveIf(const std::function< bool(const InsertionSequence &)> &p)
void AddInsertionSequence(int vehicle, std::initializer_list< Insertion > insertion_sequence)
InsertionSequenceIterator begin()
InsertionSequenceContainer is a range over insertion sequences.
void Clear()
Removes all sequences.
size_t Size() const
Returns the number of sequences of this container.
InsertionSequenceIterator end()
void AddInsertionSequence(int vehicle, absl::Span< const Insertion > insertion_sequence)
Adds an insertion sequence to the container.
Generates insertion positions respecting structural constraints.
void AppendPickupDeliveryMultitourInsertions(int pickup, int delivery, int vehicle, const std::vector< int > &path, const std::vector< bool > &path_node_is_pickup, const std::vector< bool > &path_node_is_delivery, InsertionSequenceContainer &insertions)
InsertionSequenceGenerator()
int64_t number_of_rejects() const
int64_t number_of_decisions() const
Returns statistics from its underlying heuristic.
std::string DebugString() const override
-------— Decision Builder -------—
IntVarFilteredDecisionBuilder(std::unique_ptr< IntVarFilteredHeuristic > heuristic)
— First solution decision builder —
~IntVarFilteredDecisionBuilder() override
Generic filter-based heuristic applied to IntVars.
bool HasSecondaryVars() const
Returns true if there are secondary variables.
Assignment *const assignment_
virtual std::string DebugString() const
void ResetSolution()
Resets the data members for a new solution.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, LocalSearchFilterManager *filter_manager)
— First solution heuristics —
virtual bool BuildSolutionInternal()=0
Virtual method to redefine how to build a solution.
int64_t number_of_rejects() const
int64_t number_of_decisions() const
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.
virtual void Initialize()
Initialize the heuristic; called before starting to build a new solution.
Assignment * BuildSolution()
int64_t SecondaryVarIndex(int64_t index) const
Returns the index of a secondary var.
int64_t Value(int64_t index) const
void SetValue(int64_t index, int64_t value)
virtual bool InitializeSolution()
Virtual method to initialize the solution.
const std::vector< int > & delta_indices() const
Returns the indices of the nodes currently in the insertion delta.
IntVar * Var(int64_t index) const
Returns the variable of index 'index'.
std::optional< int64_t > Evaluate(bool commit)
virtual ~IntVarFilteredHeuristic()
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).
bool IsSecondaryVar(int64_t index) const
Returns true if 'index' is a secondary variable index.
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, BinCapacities *bin_capacities=nullptr, std::function< bool(const std::vector< RoutingModel::VariableValuePair > &, std::vector< RoutingModel::VariableValuePair > *)> optimize_on_insertion=nullptr)
Takes ownership of evaluator.
void Initialize() override
Initialize the heuristic; called before starting to build a new solution.
~LocalCheapestInsertionFilteredHeuristic() override
std::string DebugString() const override
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
~ParallelSavingsFilteredHeuristic() override
std::string DebugString() const override
ParallelSavingsFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Filter-based heuristic dedicated to routing.
int GetEndChainStart(int vehicle) const
Returns the start of the end chain of vehicle,.
virtual void ResetVehicleIndices()
virtual void SetVehicleIndex(int64_t, int)
Assignment * BuildSolutionFromRoutes(const std::function< int64_t(int64_t)> &next_accessor)
Builds a solution starting from the routes formed by the next accessor.
void SetNext(int64_t node, int64_t next, int vehicle)
bool VehicleIsEmpty(int vehicle) const
void MakeDisjunctionNodesUnperformed(int64_t node)
bool MakeUnassignedNodesUnperformed()
Make all unassigned nodes unperformed, always returns true.
RoutingFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, LocalSearchFilterManager *filter_manager)
RoutingFilteredHeuristic.
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
RoutingModel * model() const
~RoutingFilteredHeuristic() override
bool StopSearch() override
Returns true if the search must be stopped.
void MakePartiallyPerformedPairsUnperformed()
virtual void BuildRoutesFromSavings()=0
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
SavingsFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
SavingsFilteredHeuristic.
~SavingsFilteredHeuristic() override
friend class SavingsFilteredHeuristicTestPeer
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
int StartNewRouteWithBestVehicleOfType(int type, int64_t before_node, int64_t after_node)
std::unique_ptr< SavingsContainer< Saving > > savings_container_
clang-format off
std::unique_ptr< VehicleTypeCurator > vehicle_type_curator_
clang-format on
std::string DebugString() const override
~SequentialSavingsFilteredHeuristic() override
SequentialSavingsFilteredHeuristic(RoutingModel *model, std::function< bool()> stop_search, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
For the time being, Solver is neither MT_SAFE nor MT_HOT.
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
SweepArranger(const SweepArranger &)=delete
This type is neither copyable nor movable.
SweepArranger(const std::vector< std::pair< int64_t, int64_t > > &points)
void ArrangeIndices(std::vector< int64_t > *indices)
void SetSectors(int sectors)
SweepArranger & operator=(const SweepArranger &)=delete
void Update(const std::function< bool(int)> &remove_vehicle)
bool HasCompatibleVehicleOfType(int type, const std::function< bool(int)> &vehicle_is_compatible) const
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64_t fixed_cost)
int GetLowestFixedCostVehicleOfType(int type) const
std::pair< int, int > GetCompatibleVehicleOfType(int type, const std::function< bool(int)> &vehicle_is_compatible, const std::function< bool(int)> &stop_and_return_vehicle)
void Reset(const std::function< bool(int)> &store_vehicle)
— VehicleTypeCurator —
int Type(int vehicle) const
In SWIG mode, we don't want anything besides these top-level includes.
DecisionBuilder * MakeAllUnperformed(RoutingModel *model)
Returns a DecisionBuilder making all nodes unperformed.
FirstSolutionStrategy::Value AutomaticFirstSolutionStrategy(bool has_pickup_deliveries, bool has_node_precedences, bool has_single_vehicle_node)
std::vector< int64_t > ComputeVehicleEndChainStarts(const RoutingModel &model)
DecisionBuilder * MakeSweepDecisionBuilder(RoutingModel *model, bool check_assignment)
trees with all degrees equal to
int64_t fixed_cost
Contrarily to CostClass, here we need strict equivalence.
std::optional< int64_t > end
bool operator<(const NodeInsertion &other) const
const bool prioritize_farthest_nodes
std::priority_queue< Seed, std::vector< Seed >, std::greater< Seed > > priority_queue
SeedQueue(bool prioritize_farthest_nodes)
StartEndValue start_end_value
uint64_t num_allowed_vehicles
bool operator>(const Seed &other) const
bool operator<(const StartEndValue &other) const
bool add_unperformed_entries
bool use_neighbors_ratio_for_initialization
double farthest_seeds_ratio
bool is_sequential
Whether the routes are constructed sequentially or in parallel.
bool operator==(const Insertion &other) const
bool operator<(const PickupDeliveryInsertion &other) const
int64_t insert_pickup_after
int64_t insert_delivery_after
unsigned int vehicle_type
bool operator<(const Saving &other) const
double max_memory_usage_bytes