OR-Tools  9.1
routing_search.h
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
16
17#include <algorithm>
18#include <functional>
19#include <iterator>
20#include <memory>
21#include <set>
22#include <string>
23#include <tuple>
24#include <utility>
25#include <vector>
26
27#include "absl/container/flat_hash_set.h"
31#include "ortools/base/macros.h"
37#include "ortools/util/bitset.h"
38
39namespace operations_research {
40
41class IntVarFilteredHeuristic;
42#ifndef SWIG
47 public:
49 const RoutingModel::VehicleTypeContainer& vehicle_type_container)
50 : vehicle_type_container_(&vehicle_type_container) {}
51
52 int NumTypes() const { return vehicle_type_container_->NumTypes(); }
53
54 int Type(int vehicle) const { return vehicle_type_container_->Type(vehicle); }
55
58 void Reset(const std::function<bool(int)>& store_vehicle);
59
62 void Update(const std::function<bool(int)>& remove_vehicle);
63
64 int GetLowestFixedCostVehicleOfType(int type) const {
65 DCHECK_LT(type, NumTypes());
66 const std::set<VehicleClassEntry>& vehicle_classes =
67 sorted_vehicle_classes_per_type_[type];
68 if (vehicle_classes.empty()) {
69 return -1;
70 }
71 const int vehicle_class = (vehicle_classes.begin())->vehicle_class;
72 DCHECK(!vehicles_per_vehicle_class_[vehicle_class].empty());
73 return vehicles_per_vehicle_class_[vehicle_class][0];
74 }
75
77 int64_t fixed_cost) {
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 =
85 vehicle_classes.insert({vehicle_class, fixed_cost});
86 DCHECK(insertion.second);
87 }
88 vehicles.push_back(vehicle);
89 }
90
99 std::pair<int, int> GetCompatibleVehicleOfType(
100 int type, std::function<bool(int)> vehicle_is_compatible,
101 std::function<bool(int)> stop_and_return_vehicle);
102
103 private:
104 using VehicleClassEntry =
106 const RoutingModel::VehicleTypeContainer* const vehicle_type_container_;
107 // clang-format off
108 std::vector<std::set<VehicleClassEntry> > sorted_vehicle_classes_per_type_;
109 std::vector<std::vector<int> > vehicles_per_vehicle_class_;
110 // clang-format on
111};
112
116AutomaticFirstSolutionStrategy(bool has_pickup_deliveries,
117 bool has_node_precedences,
118 bool has_single_vehicle_node);
119
132
134// TODO(user): Eventually move this to the core CP solver library
137 public:
139 std::unique_ptr<IntVarFilteredHeuristic> heuristic);
140
142
143 Decision* Next(Solver* solver) override;
144
145 std::string DebugString() const override;
146
148 int64_t number_of_decisions() const;
149 int64_t number_of_rejects() const;
150
151 private:
152 const std::unique_ptr<IntVarFilteredHeuristic> heuristic_;
153};
154
157 public:
158 IntVarFilteredHeuristic(Solver* solver, const std::vector<IntVar*>& vars,
159 LocalSearchFilterManager* filter_manager);
160
162
165 Assignment* const BuildSolution();
166
169 int64_t number_of_decisions() const { return number_of_decisions_; }
170 int64_t number_of_rejects() const { return number_of_rejects_; }
171
172 virtual std::string DebugString() const { return "IntVarFilteredHeuristic"; }
173
174 protected:
176 void ResetSolution();
178 virtual bool InitializeSolution() { return true; }
180 virtual bool BuildSolutionInternal() = 0;
184 bool Commit();
186 virtual bool StopSearch() { return false; }
189 void SetValue(int64_t index, int64_t value) {
190 if (!is_in_delta_[index]) {
191 delta_->FastAdd(vars_[index])->SetValue(value);
192 delta_indices_.push_back(index);
193 is_in_delta_[index] = true;
194 } else {
195 delta_->SetValue(vars_[index], value);
196 }
197 }
200 int64_t Value(int64_t index) const {
202 }
204 bool Contains(int64_t index) const {
205 return assignment_->IntVarContainer().Element(index).Var() != nullptr;
206 }
209 int Size() const { return vars_.size(); }
211 IntVar* Var(int64_t index) const { return vars_[index]; }
213 void SynchronizeFilters();
214
216
217 private:
220 bool FilterAccept();
221
222 Solver* solver_;
223 const std::vector<IntVar*> vars_;
224 Assignment* const delta_;
225 std::vector<int> delta_indices_;
226 std::vector<bool> is_in_delta_;
227 Assignment* const empty_;
228 LocalSearchFilterManager* filter_manager_;
230 int64_t number_of_decisions_;
231 int64_t number_of_rejects_;
232};
233
236 public:
238 LocalSearchFilterManager* filter_manager);
242 const std::function<int64_t(int64_t)>& next_accessor);
243 RoutingModel* model() const { return model_; }
245 int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; }
247 int GetEndChainStart(int vehicle) const { return end_chain_starts_[vehicle]; }
250 void MakeDisjunctionNodesUnperformed(int64_t node);
258
259 protected:
260 bool StopSearch() override { return model_->CheckLimit(); }
261 virtual void SetVehicleIndex(int64_t node, int vehicle) {}
262 virtual void ResetVehicleIndices() {}
263 bool VehicleIsEmpty(int vehicle) const {
264 return Value(model()->Start(vehicle)) == model()->End(vehicle);
265 }
266
267 private:
269 bool InitializeSolution() override;
270
271 RoutingModel* const model_;
272 std::vector<int64_t> start_chain_ends_;
273 std::vector<int64_t> end_chain_starts_;
274};
275
277 public:
281 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
282 std::function<int64_t(int64_t)> penalty_evaluator,
283 LocalSearchFilterManager* filter_manager);
285
286 protected:
287 typedef std::pair<int64_t, int64_t> ValuedPosition;
289 int64_t distance;
291
292 bool operator<(const StartEndValue& other) const {
293 return std::tie(distance, vehicle) <
294 std::tie(other.distance, other.vehicle);
295 }
296 };
297 typedef std::pair<StartEndValue, /*seed_node*/ int> Seed;
298
304 // clang-format off
305 std::vector<std::vector<StartEndValue> >
306 ComputeStartEndDistanceForVehicles(const std::vector<int>& vehicles);
307
312 template <class Queue>
314 std::vector<std::vector<StartEndValue> >* start_end_distances_per_node,
315 Queue* priority_queue);
316 // clang-format on
317
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);
334 // TODO(user): Replace 'insert_before' and 'insert_after' by 'predecessor'
335 // and 'successor' in the code.
336 int64_t GetInsertionCostForNodeAtPosition(int64_t node_to_insert,
337 int64_t insert_after,
338 int64_t insert_before,
339 int vehicle) const;
342 int64_t GetUnperformedValue(int64_t node_to_insert) const;
343
344 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator_;
345 std::function<int64_t(int64_t)> penalty_evaluator_;
346};
347
357 public:
380 };
381
385 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
386 std::function<int64_t(int64_t)> penalty_evaluator,
387 LocalSearchFilterManager* filter_manager,
390 bool BuildSolutionInternal() override;
391 std::string DebugString() const override {
392 return "GlobalCheapestInsertionFilteredHeuristic";
393 }
394
395 private:
396 class NodeEntry;
397 class PairEntry;
398
399 typedef absl::flat_hash_set<PairEntry*> PairEntries;
400 typedef absl::flat_hash_set<NodeEntry*> NodeEntries;
401
408 void InsertPairsAndNodesByRequirementTopologicalOrder();
409
416 void InsertPairs(const std::vector<int>& pair_indices);
417
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);
429
437 void InsertNodesOnRoutes(const std::vector<int>& nodes,
438 const absl::flat_hash_set<int>& vehicles);
439
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);
452
458 void SequentialInsertNodes(const std::vector<int>& nodes);
459
463 void DetectUsedVehicles(std::vector<bool>* is_vehicle_used,
464 std::vector<int>* unused_vehicles,
465 absl::flat_hash_set<int>* used_vehicles);
466
470 void InsertFarthestNodesAsSeeds();
471
480 template <class Queue>
481 int InsertSeedNode(
482 std::vector<std::vector<StartEndValue>>* start_end_distances_per_node,
483 Queue* priority_queue, std::vector<bool>* is_vehicle_used);
484 // clang-format on
485
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);
523 }
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,
551 int vehicle,
553 std::vector<PairEntries>* pickup_entries,
554 std::vector<PairEntries>* delivery_entries) const;
557 void UpdatePairEntry(
558 PairEntry* const pair_entry,
559 AdjustablePriorityQueue<PairEntry>* priority_queue) const;
563 int64_t GetInsertionValueForPairAtPositions(int64_t pickup,
564 int64_t pickup_insert_after,
565 int64_t delivery,
566 int64_t delivery_insert_after,
567 int vehicle) const;
568
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);
595
599 void AddNodeEntry(int64_t node, int64_t insert_after, int vehicle,
600 bool all_vehicles,
602 std::vector<NodeEntries>* node_entries) const;
605 void UpdateNodeEntry(
606 NodeEntry* const node_entry,
607 AdjustablePriorityQueue<NodeEntry>* priority_queue) const;
608
611 void ComputeNeighborhoods();
612
615 bool IsNeighborForCostClass(int cost_class, int64_t node_index,
616 int64_t neighbor_index) const;
617
619 const std::vector<int64_t>& GetNeighborsOfNodeForCostClass(
620 int cost_class, int64_t node_index) const {
621 return gci_params_.neighbors_ratio == 1
622 ? all_nodes_
623 : node_index_to_neighbors_by_cost_class_[node_index][cost_class]
624 ->PositionsSetAtLeastOnce();
625 }
626
627 int64_t NumNonStartEndNodes() const {
628 return model()->Size() - model()->vehicles();
629 }
630
631 int64_t NumNeighbors() const {
632 return std::max(gci_params_.min_neighbors,
634 NumNonStartEndNodes()));
635 }
636
637 void ResetVehicleIndices() override {
638 node_index_to_vehicle_.assign(node_index_to_vehicle_.size(), -1);
639 }
640
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;
644 }
645
648 bool CheckVehicleIndices() const;
649
650 GlobalCheapestInsertionParameters gci_params_;
652 std::vector<int> node_index_to_vehicle_;
653
654 // clang-format off
655 std::vector<std::vector<std::unique_ptr<SparseBitset<int64_t> > > >
656 node_index_to_neighbors_by_cost_class_;
657 // clang-format on
658
659 std::unique_ptr<VehicleTypeCurator> empty_vehicle_type_curator_;
660
664 std::vector<int64_t> all_nodes_;
665};
666
674 public:
678 std::function<int64_t(int64_t, int64_t, int64_t)> evaluator,
679 LocalSearchFilterManager* filter_manager);
681 bool BuildSolutionInternal() override;
682 std::string DebugString() const override {
683 return "LocalCheapestInsertionFilteredHeuristic";
684 }
685
686 private:
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);
701
702 std::vector<std::vector<StartEndValue>> start_end_distances_per_node_;
703};
704
708 public:
710 LocalSearchFilterManager* filter_manager);
712 bool BuildSolutionInternal() override;
713
714 private:
715 class PartialRoutesAndLargeVehicleIndicesFirst {
716 public:
717 explicit PartialRoutesAndLargeVehicleIndicesFirst(
719 : builder_(builder) {}
720 bool operator()(int vehicle1, int vehicle2) const;
721
722 private:
723 const CheapestAdditionFilteredHeuristic& builder_;
724 };
726 template <typename Iterator>
727 std::vector<int64_t> GetPossibleNextsFromIterator(int64_t node,
728 Iterator start,
729 Iterator end) const {
730 const int size = model()->Size();
731 std::vector<int64_t> nexts;
732 for (Iterator it = start; it != end; ++it) {
733 const int64_t next = *it;
734 if (next != node && (next >= size || !Contains(next))) {
735 nexts.push_back(next);
736 }
737 }
738 return nexts;
739 }
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;
745};
746
751 public:
754 RoutingModel* model, std::function<int64_t(int64_t, int64_t)> evaluator,
755 LocalSearchFilterManager* filter_manager);
757 std::string DebugString() const override {
758 return "EvaluatorCheapestAdditionFilteredHeuristic";
759 }
760
761 private:
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;
766
767 std::function<int64_t(int64_t, int64_t)> evaluator_;
768};
769
774 public:
778 LocalSearchFilterManager* filter_manager);
780 std::string DebugString() const override {
781 return "ComparatorCheapestAdditionFilteredHeuristic";
782 }
783
784 private:
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;
789
791};
792
802 public:
806 double neighbors_ratio = 1.0;
812 bool add_reverse_arcs = false;
815 double arc_coefficient = 1.0;
816 };
817
819 const RoutingIndexManager* manager,
821 LocalSearchFilterManager* filter_manager);
822 ~SavingsFilteredHeuristic() override;
823 bool BuildSolutionInternal() override;
824
825 protected:
826 typedef std::pair</*saving*/ int64_t, /*saving index*/ int64_t> Saving;
827
828 template <typename S>
829 class SavingsContainer;
830
831 virtual double ExtraSavingsMemoryMultiplicativeFactor() const = 0;
832
833 virtual void BuildRoutesFromSavings() = 0;
834
836 int64_t GetVehicleTypeFromSaving(const Saving& saving) const {
837 return saving.second / size_squared_;
838 }
840 int64_t GetBeforeNodeFromSaving(const Saving& saving) const {
841 return (saving.second % size_squared_) / Size();
842 }
844 int64_t GetAfterNodeFromSaving(const Saving& saving) const {
845 return (saving.second % size_squared_) % Size();
846 }
848 int64_t GetSavingValue(const Saving& saving) const { return saving.first; }
849
859 int StartNewRouteWithBestVehicleOfType(int type, int64_t before_node,
860 int64_t after_node);
861
862 // clang-format off
863 std::unique_ptr<SavingsContainer<Saving> > savings_container_;
864 // clang-format on
865 std::unique_ptr<VehicleTypeCurator> vehicle_type_curator_;
866
867 private:
872 // clang-format off
873 void AddSymmetricArcsToAdjacencyLists(
874 std::vector<std::vector<int64_t> >* adjacency_lists);
875 // clang-format on
876
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);
891 }
892
896 int64_t MaxNumNeighborsPerNode(int num_vehicle_types) const;
897
898 const RoutingIndexManager* const manager_;
899 const SavingsParameters savings_params_;
900 int64_t size_squared_;
901
903};
904
906 public:
908 const RoutingIndexManager* manager,
910 LocalSearchFilterManager* filter_manager)
911 : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
913 std::string DebugString() const override {
914 return "SequentialSavingsFilteredHeuristic";
915 }
916
917 private:
922 void BuildRoutesFromSavings() override;
923 double ExtraSavingsMemoryMultiplicativeFactor() const override { return 1.0; }
924};
925
927 public:
929 const RoutingIndexManager* manager,
931 LocalSearchFilterManager* filter_manager)
932 : SavingsFilteredHeuristic(model, manager, parameters, filter_manager) {}
934 std::string DebugString() const override {
935 return "ParallelSavingsFilteredHeuristic";
936 }
937
938 private:
949 void BuildRoutesFromSavings() override;
950
951 double ExtraSavingsMemoryMultiplicativeFactor() const override { return 2.0; }
952
957 void MergeRoutes(int first_vehicle, int second_vehicle, int64_t before_node,
958 int64_t after_node);
959
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_;
967};
968
972
974 public:
976 LocalSearchFilterManager* filter_manager,
977 bool use_minimum_matching);
979 bool BuildSolutionInternal() override;
980 std::string DebugString() const override {
981 return "ChristofidesFilteredHeuristic";
982 }
983
984 private:
985 const bool use_minimum_matching_;
986};
987
991 public:
992 explicit SweepArranger(
993 const std::vector<std::pair<int64_t, int64_t>>& points);
994 virtual ~SweepArranger() {}
995 void ArrangeIndices(std::vector<int64_t>* indices);
996 void SetSectors(int sectors) { sectors_ = sectors; }
997
998 private:
999 std::vector<int> coordinates_;
1000 int sectors_;
1001
1002 DISALLOW_COPY_AND_ASSIGN(SweepArranger);
1003};
1004#endif // SWIG
1005
1006// Returns a DecisionBuilder building a first solution based on the Sweep
1007// heuristic. Mostly suitable when cost is proportional to distance.
1008DecisionBuilder* MakeSweepDecisionBuilder(RoutingModel* model,
1009 bool check_assignment);
1010
1011// Returns a DecisionBuilder making all nodes unperformed.
1012DecisionBuilder* MakeAllUnperformed(RoutingModel* model);
1013
1014} // namespace operations_research
1015
1016#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_SEARCH_H_
int64_t max
Definition: alldiff_cst.cc:140
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:889
#define DCHECK(condition)
Definition: base/logging.h:885
const E & Element(const V *const var) const
An Assignment is a variable -> domains mapping, used to report solutions to the user.
void SetValue(const IntVar *const var, int64_t value)
const IntContainer & IntVarContainer() const
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, 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...
int64_t GetUnperformedValue(int64_t node_to_insert) const
Returns the cost of unperforming node 'node_to_insert'.
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...
bool BuildSolutionInternal() override
Virtual method to redefine how to build a solution.
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.
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.
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.
Decision builder building a solution using heuristics with local search filters to evaluate its feasi...
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)
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 bool StopSearch()
Returns true if the search must be stopped.
void ResetSolution()
Resets the data members for a new solution.
void SynchronizeFilters()
Synchronizes filters with an assignment (the current solution).
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...
IntVar * Var(int64_t index) const
Returns the variable of index 'index'.
int64_t Value(int64_t index) const
Returns the value of the variable of index 'index' in the last committed solution.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
Assignment *const BuildSolution()
Builds a solution.
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(RoutingModel *model, std::function< int64_t(int64_t, int64_t, int64_t)> evaluator, LocalSearchFilterManager *filter_manager)
Takes ownership of evaluator.
Filter manager: when a move is made, filters are executed to decide whether the solution is feasible ...
static int64_t FastInt64Round(double x)
Definition: mathutil.h:138
ParallelSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
Filter-based heuristic dedicated to routing.
int GetStartChainEnd(int vehicle) const
Returns the end of the start chain of vehicle,.
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.
void MakePartiallyPerformedPairsUnperformed()
Make all partially performed pickup and delivery pairs unperformed.
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.
Definition: routing.h:1443
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1460
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1458
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1279
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::unique_ptr< SavingsContainer< Saving > > savings_container_
virtual double ExtraSavingsMemoryMultiplicativeFactor() const =0
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...
SequentialSavingsFilteredHeuristic(RoutingModel *model, const RoutingIndexManager *manager, SavingsParameters parameters, LocalSearchFilterManager *filter_manager)
std::function< bool(int64_t, int64_t, int64_t)> VariableValueComparator
Class to arrange indices by by their distance and their angles from the depot.
SweepArranger(const std::vector< std::pair< int64_t, int64_t > > &points)
void ArrangeIndices(std::vector< int64_t > *indices)
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...
void ReinjectVehicleOfClass(int vehicle, int vehicle_class, int64_t fixed_cost)
int GetLowestFixedCostVehicleOfType(int type) const
Block * next
SatParameters parameters
int64_t value
GRBmodel * model
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)
int index
Definition: pack.cc:509
int vehicle_class
int nodes
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...
Definition: routing.h:355
Struct used to sort and store vehicles by their type.
Definition: routing.h:354
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.