Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
routing_insertion_lns.h
Go to the documentation of this file.
1// Copyright 2010-2024 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_INSERTION_LNS_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_INSERTION_LNS_H_
16
17#include <cstdint>
18#include <functional>
19#include <memory>
20#include <string>
21#include <utility>
22#include <vector>
23
24#include "absl/log/check.h"
25#include "absl/strings/str_cat.h"
31#include "ortools/util/bitset.h"
32
33namespace operations_research {
34
37// TODO(user): Put these methods in an object with helper methods instead
38// of adding a layer to the class hierarchy.
40 public:
42 std::unique_ptr<RoutingFilteredHeuristic> heuristic,
43 bool keep_inverse_values = false);
45
46 protected:
47 virtual bool IncrementPosition() = 0;
51 virtual std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() = 0;
52
53 std::string HeuristicName() const {
54 std::string heuristic_name = heuristic_->DebugString();
55 const int erase_pos = heuristic_name.find("FilteredHeuristic");
56 if (erase_pos != std::string::npos) {
57 const int expected_name_size = heuristic_name.size() - 17;
58 heuristic_name.erase(erase_pos);
59 // NOTE: Verify that the "FilteredHeuristic" string was at the end of the
60 // heuristic name.
61 DCHECK_EQ(heuristic_name.size(), expected_name_size);
62 }
63 return heuristic_name;
64 }
65
66 // TODO(user): Remove the dependency from RoutingModel by storing an
67 // IntVarFilteredHeuristic here instead and storing information on path
68 // start/ends like PathOperator does (instead of relying on the model).
69 RoutingModel* const model_;
72
73 private:
74 bool MakeOneNeighbor() override;
75 bool MakeChangesAndInsertNodes();
76
77 int64_t VehicleVarIndex(int64_t node) const { return model_->Size() + node; }
78
79 const std::unique_ptr<RoutingFilteredHeuristic> heuristic_;
80 const bool consider_vehicle_vars_;
81};
82
87 public:
89 std::unique_ptr<RoutingFilteredHeuristic> heuristic);
91
92 std::string DebugString() const override {
93 return absl::StrCat("HeuristicPathLNS(", HeuristicName(), ")");
94 }
95
96 private:
97 void OnStart() override;
98
99 bool IncrementPosition() override;
100 bool CurrentRouteIsEmpty() const;
101 void IncrementCurrentRouteToNextNonEmpty();
102
103 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
104
105 int current_route_;
106 int last_route_;
107 bool just_started_;
108};
109
115 public:
117 std::unique_ptr<RoutingFilteredHeuristic> heuristic);
119
120 std::string DebugString() const override {
121 return absl::StrCat("RelocatePathAndHeuristicInsertUnperformed(",
122 HeuristicName(), ")");
123 }
124
125 private:
126 void OnStart() override;
127
128 bool IncrementPosition() override;
129 bool IncrementRoutes();
130
131 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
132
133 int route_to_relocate_index_;
134 int last_route_to_relocate_index_;
135 int empty_route_index_;
136 int last_empty_route_index_;
137 std::vector<int> routes_to_relocate_;
138 std::vector<int> empty_routes_;
139 std::vector<int64_t> last_node_on_route_;
140 bool has_unperformed_nodes_;
141 bool just_started_;
142};
143
149 public:
151 std::unique_ptr<RoutingFilteredHeuristic> heuristic,
152 int num_arcs_to_consider,
153 std::function<int64_t(int64_t, int64_t, int64_t)>
154 arc_cost_for_route_start);
156
157 std::string DebugString() const override {
158 return absl::StrCat("HeuristicExpensiveChainLNS(", HeuristicName(), ")");
159 }
160
161 private:
162 void OnStart() override;
163
164 bool IncrementPosition() override;
165 bool IncrementRoute();
166 bool IncrementCurrentArcIndices();
167 bool FindMostExpensiveChainsOnRemainingRoutes();
168
169 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
170
171 int current_route_;
172 int last_route_;
173
174 const int num_arcs_to_consider_;
175 std::vector<std::pair<int64_t, int>> most_expensive_arc_starts_and_ranks_;
178 std::pair</*first_arc_index*/ int, /*second_arc_index*/ int>
179 current_expensive_arc_indices_;
180 std::function<int64_t(/*before_node*/ int64_t, /*after_node*/ int64_t,
181 /*path_start*/ int64_t)>
182 arc_cost_for_route_start_;
183
184 bool just_started_;
185};
186
192 public:
194 std::unique_ptr<RoutingFilteredHeuristic> heuristic, int num_close_nodes);
196
197 std::string DebugString() const override {
198 return absl::StrCat("HeuristicCloseNodesLNS(", HeuristicName(), ")");
199 }
200
201 private:
202 void Initialize();
203
204 void OnStart() override;
205
206 bool IncrementPosition() override;
207
208 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
209
210 void RemoveNode(int64_t node);
211 void RemoveNodeAndActiveSibling(int64_t node);
212
213 bool IsActive(int64_t node) const {
214 DCHECK_LT(node, model_->Size());
215 return Value(node) != node && !removed_nodes_[node];
216 }
217
218 int64_t Prev(int64_t node) const {
219 DCHECK_EQ(Value(InverseValue(node)), node);
220 DCHECK_LT(node, new_prevs_.size());
221 return changed_prevs_[node] ? new_prevs_[node] : InverseValue(node);
222 }
223 int64_t Next(int64_t node) const {
224 DCHECK(!model_->IsEnd(node));
225 return changed_nexts_[node] ? new_nexts_[node] : Value(node);
226 }
227
228 std::vector<int64_t> GetActiveSiblings(int64_t node) const;
229
230 const std::vector<PickupDeliveryPair>& pickup_delivery_pairs_;
231
232 int current_node_;
233 int last_node_;
234 bool just_started_;
235 bool initialized_;
236
237 std::vector<std::vector<int64_t>> close_nodes_;
238 const int num_close_nodes_;
240 std::vector<int64_t> new_nexts_;
241 SparseBitset<> changed_nexts_;
242 std::vector<int64_t> new_prevs_;
243 SparseBitset<> changed_prevs_;
244};
245
246} // namespace operations_research
247
248#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_INSERTION_LNS_H_
FilteredHeuristicCloseNodesLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, int num_close_nodes)
FilteredHeuristicCloseNodesLNSOperator.
FilteredHeuristicExpensiveChainLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, int num_arcs_to_consider, std::function< int64_t(int64_t, int64_t, int64_t)> arc_cost_for_route_start)
FilteredHeuristicExpensiveChainLNSOperator.
SparseBitset removed_nodes_
Keeps track of removed nodes when making a neighbor.
virtual std::function< int64_t(int64_t)> SetupNextAccessorForNeighbor()=0
FilteredHeuristicLocalSearchOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, bool keep_inverse_values=false)
FilteredHeuristicLocalSearchOperator.
FilteredHeuristicPathLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic)
FilteredHeuristicPathLNSOperator.
RelocatePathAndHeuristicInsertUnperformedOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic)
RelocatePathAndHeuristicInsertUnperformedOperator.
In SWIG mode, we don't want anything besides these top-level includes.
bool Next()