OR-Tools  9.0
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"
30 #include "ortools/base/logging.h"
31 #include "ortools/base/macros.h"
32 #include "ortools/base/mathutil.h"
37 #include "ortools/util/bitset.h"
38 
39 namespace operations_research {
40 
41 class 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 
76  void ReinjectVehicleOfClass(int vehicle, int vehicle_class,
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 
116 AutomaticFirstSolutionStrategy(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;
288  struct StartEndValue {
289  int64_t distance;
290  int vehicle;
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:
370  int64_t min_neighbors;
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,
426  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
450  AdjustablePriorityQueue<NodeEntry>* priority_queue,
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,
490  AdjustablePriorityQueue<PairEntry>* priority_queue,
491  std::vector<PairEntries>* pickup_to_entries,
492  std::vector<PairEntries>* delivery_to_entries);
498  void InitializeInsertionEntriesPerformingPair(
499  int64_t pickup, int64_t delivery,
500  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
509  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
516  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
528  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
536  AdjustablePriorityQueue<PairEntry>* priority_queue,
537  std::vector<PairEntries>* pickup_to_entries,
538  std::vector<PairEntries>* delivery_to_entries);
541  void DeletePairEntry(PairEntry* entry,
542  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
552  AdjustablePriorityQueue<PairEntry>* priority_queue,
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,
573  AdjustablePriorityQueue<NodeEntry>* priority_queue,
574  std::vector<NodeEntries>* position_to_node_entries);
580  void InitializeInsertionEntriesPerformingNode(
581  int64_t node, const absl::flat_hash_set<int>& vehicles,
582  AdjustablePriorityQueue<NodeEntry>* priority_queue,
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,
588  AdjustablePriorityQueue<NodeEntry>* priority_queue,
589  std::vector<NodeEntries>* node_entries);
592  void DeleteNodeEntry(NodeEntry* entry,
593  AdjustablePriorityQueue<NodeEntry>* priority_queue,
594  std::vector<NodeEntries>* node_entries);
595 
599  void AddNodeEntry(int64_t node, int64_t insert_after, int vehicle,
600  bool all_vehicles,
601  AdjustablePriorityQueue<NodeEntry>* priority_queue,
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(
718  const CheapestAdditionFilteredHeuristic& builder)
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.
1008 DecisionBuilder* MakeSweepDecisionBuilder(RoutingModel* model,
1009  bool check_assignment);
1010 
1011 // Returns a DecisionBuilder making all nodes unperformed.
1012 DecisionBuilder* 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:896
#define DCHECK(condition)
Definition: base/logging.h:892
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, 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...
int64_t Value(int64_t index) const
Returns the value of the variable of index 'index' in the last committed solution.
IntVar * Var(int64_t index) const
Returns the variable of index 'index'.
IntVarFilteredHeuristic(Solver *solver, const std::vector< IntVar * > &vars, LocalSearchFilterManager *filter_manager)
Assignment *const BuildSolution()
Builds a solution.
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:1335
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1352
int vehicles() const
Returns the number of vehicle routes in the model.
Definition: routing.h:1350
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
Definition: routing.h:1186
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.
void ArrangeIndices(std::vector< int64_t > *indices)
SweepArranger(const std::vector< std::pair< int64_t, int64_t >> &points)
Helper class that manages vehicles.
void Update(const std::function< bool(int)> &remove_vehicle)
Goes through all the currently stored vehicles and removes vehicles for which remove_vehicle() return...
std::pair< int, int > GetCompatibleVehicleOfType(int type, std::function< bool(int)> vehicle_is_compatible, std::function< bool(int)> stop_and_return_vehicle)
Searches for the best compatible vehicle of the given type, i.e.
VehicleTypeCurator(const RoutingModel::VehicleTypeContainer &vehicle_type_container)
void Reset(const std::function< bool(int)> &store_vehicle)
Resets the vehicles stored, storing only vehicles from the vehicle_type_container_ for which store_ve...
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
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1492
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:354
Struct used to sort and store vehicles by their type.
Definition: routing.h:353
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.