OR-Tools  9.1
routing_flags.cc
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
15
16#include <cstdint>
17#include <limits>
18#include <map>
19#include <vector>
20
21#include "absl/status/status.h"
22#include "absl/time/time.h"
29
30// --- Routing search flags ---
31
32// Neighborhood activation/deactivation
33ABSL_FLAG(bool, routing_no_lns, false,
34 "Routing: forbids use of Large Neighborhood Search.");
35ABSL_FLAG(bool, routing_no_fullpathlns, true,
36 "Routing: forbids use of Full-path Large Neighborhood Search.");
37ABSL_FLAG(bool, routing_no_relocate, false,
38 "Routing: forbids use of Relocate neighborhood.");
39ABSL_FLAG(bool, routing_no_relocate_neighbors, true,
40 "Routing: forbids use of RelocateNeighbors neighborhood.");
41ABSL_FLAG(bool, routing_no_relocate_subtrip, false,
42 "Routing: forbids use of RelocateSubtrips neighborhood.");
43ABSL_FLAG(bool, routing_no_exchange, false,
44 "Routing: forbids use of Exchange neighborhood.");
45ABSL_FLAG(bool, routing_no_exchange_subtrip, false,
46 "Routing: forbids use of ExchangeSubtrips neighborhood.");
47ABSL_FLAG(bool, routing_no_cross, false,
48 "Routing: forbids use of Cross neighborhood.");
49ABSL_FLAG(bool, routing_no_2opt, false,
50 "Routing: forbids use of 2Opt neighborhood.");
51ABSL_FLAG(bool, routing_no_oropt, false,
52 "Routing: forbids use of OrOpt neighborhood.");
53ABSL_FLAG(bool, routing_no_make_active, false,
54 "Routing: forbids use of MakeActive/SwapActive/MakeInactive "
55 "neighborhoods.");
56ABSL_FLAG(bool, routing_no_lkh, false,
57 "Routing: forbids use of LKH neighborhood.");
58ABSL_FLAG(bool, routing_no_relocate_expensive_chain, false,
59 "Routing: forbids use of RelocateExpensiveChain operator.");
60ABSL_FLAG(bool, routing_no_tsp, true,
61 "Routing: forbids use of TSPOpt neighborhood.");
62ABSL_FLAG(bool, routing_no_tsplns, true,
63 "Routing: forbids use of TSPLNS neighborhood.");
64ABSL_FLAG(bool, routing_use_chain_make_inactive, false,
65 "Routing: use chain version of MakeInactive neighborhood.");
66ABSL_FLAG(bool, routing_use_extended_swap_active, false,
67 "Routing: use extended version of SwapActive neighborhood.");
68
69// Meta-heuristics
70ABSL_FLAG(bool, routing_guided_local_search, false, "Routing: use GLS.");
71ABSL_FLAG(double, routing_guided_local_search_lambda_coefficient, 0.1,
72 "Lambda coefficient in GLS.");
73ABSL_FLAG(bool, routing_simulated_annealing, false,
74 "Routing: use simulated annealing.");
75ABSL_FLAG(bool, routing_tabu_search, false, "Routing: use tabu search.");
76ABSL_FLAG(bool, routing_generic_tabu_search, false,
77 "Routing: use tabu search based on a list of values.");
78
79// Search limits
80ABSL_FLAG(int64_t, routing_solution_limit, std::numeric_limits<int64_t>::max(),
81 "Routing: number of solutions limit.");
82ABSL_FLAG(int64_t, routing_time_limit, std::numeric_limits<int64_t>::max(),
83 "Routing: time limit in ms.");
84ABSL_FLAG(int64_t, routing_lns_time_limit, 100,
85 "Routing: time limit in ms for LNS sub-decisionbuilder.");
86
87// Search control
88ABSL_FLAG(std::string, routing_first_solution, "",
89 "Routing first solution heuristic. See SetupParametersFromFlags "
90 "in the code to get a full list.");
91ABSL_FLAG(bool, routing_use_filtered_first_solutions, true,
92 "Use filtered version of first solution heuristics if available.");
93ABSL_FLAG(double, savings_neighbors_ratio, 1,
94 "Ratio of neighbors to consider for each node when "
95 "constructing the savings.");
96ABSL_FLAG(bool, savings_add_reverse_arcs, false,
97 "Add savings related to reverse arcs when finding the nearest "
98 "neighbors of the nodes.");
99ABSL_FLAG(double, savings_arc_coefficient, 1.0,
100 "Coefficient of the cost of the arc for which the saving value "
101 "is being computed.");
102ABSL_FLAG(double, cheapest_insertion_farthest_seeds_ratio, 0,
103 "Ratio of available vehicles in the model on which farthest "
104 "nodes of the model are inserted as seeds.");
105ABSL_FLAG(double, cheapest_insertion_first_solution_neighbors_ratio, 1.0,
106 "Ratio of nodes considered as neighbors in the "
107 "GlobalCheapestInsertion first solution heuristic.");
108ABSL_FLAG(bool, routing_dfs, false,
109 "Routing: use a complete depth-first search.");
110ABSL_FLAG(double, routing_optimization_step, 0.0, "Optimization step.");
111ABSL_FLAG(int, routing_number_of_solutions_to_collect, 1,
112 "Number of solutions to collect.");
113ABSL_FLAG(int, routing_relocate_expensive_chain_num_arcs_to_consider, 4,
114 "Number of arcs to consider in the RelocateExpensiveChain "
115 "neighborhood operator.");
116
117// Propagation control
118ABSL_FLAG(bool, routing_use_light_propagation, true,
119 "Use constraints with light propagation in routing model.");
120
121// Cache settings.
122ABSL_FLAG(bool, routing_cache_callbacks, false, "Cache callback calls.");
123ABSL_FLAG(int64_t, routing_max_cache_size, 1000,
124 "Maximum cache size when callback caching is on.");
125
126// Misc
127ABSL_FLAG(bool, routing_trace, false, "Routing: trace search.");
128ABSL_FLAG(bool, routing_profile, false, "Routing: profile search.");
129
130// --- Routing model flags ---
131ABSL_FLAG(bool, routing_use_homogeneous_costs, true,
132 "Routing: use homogeneous cost model when possible.");
133ABSL_FLAG(bool, routing_gzip_compress_trail, false,
134 "Use gzip to compress the trail, zippy otherwise.");
135
136namespace operations_research {
137
139 CHECK(parameters != nullptr);
140 const std::map<std::string, FirstSolutionStrategy::Value>
141 first_solution_string_to_parameters = {
142 {"PathCheapestArc", FirstSolutionStrategy::PATH_CHEAPEST_ARC},
143 {"PathMostConstrainedArc",
145 {"EvaluatorStrategy", FirstSolutionStrategy::EVALUATOR_STRATEGY},
148 {"Christofides", FirstSolutionStrategy::CHRISTOFIDES},
149 {"AllUnperformed", FirstSolutionStrategy::ALL_UNPERFORMED},
150 {"BestInsertion", FirstSolutionStrategy::BEST_INSERTION},
151 {"GlobalCheapestInsertion",
153 {"SequentialGlobalCheapestInsertion",
155 {"LocalCheapestInsertion",
157 {"GlobalCheapestArc", FirstSolutionStrategy::GLOBAL_CHEAPEST_ARC},
158 {"LocalCheapestArc", FirstSolutionStrategy::LOCAL_CHEAPEST_ARC},
162 if (gtl::FindCopy(first_solution_string_to_parameters,
163 absl::GetFlag(FLAGS_routing_first_solution), &strategy)) {
164 parameters->set_first_solution_strategy(strategy);
165 }
166 parameters->set_use_unfiltered_first_solution_strategy(
167 !absl::GetFlag(FLAGS_routing_use_filtered_first_solutions));
168 parameters->set_savings_neighbors_ratio(
169 absl::GetFlag(FLAGS_savings_neighbors_ratio));
170 parameters->set_savings_max_memory_usage_bytes(6e9);
171 parameters->set_savings_add_reverse_arcs(
172 absl::GetFlag(FLAGS_savings_add_reverse_arcs));
173 parameters->set_savings_arc_coefficient(
174 absl::GetFlag(FLAGS_savings_arc_coefficient));
175 parameters->set_cheapest_insertion_farthest_seeds_ratio(
176 absl::GetFlag(FLAGS_cheapest_insertion_farthest_seeds_ratio));
177 parameters->set_cheapest_insertion_first_solution_neighbors_ratio(
178 absl::GetFlag(FLAGS_cheapest_insertion_first_solution_neighbors_ratio));
179 parameters->set_cheapest_insertion_first_solution_min_neighbors(1);
180}
181
183 CHECK(parameters != nullptr);
184 if (absl::GetFlag(FLAGS_routing_tabu_search)) {
185 parameters->set_local_search_metaheuristic(
187 } else if (absl::GetFlag(FLAGS_routing_generic_tabu_search)) {
188 parameters->set_local_search_metaheuristic(
190 } else if (absl::GetFlag(FLAGS_routing_simulated_annealing)) {
191 parameters->set_local_search_metaheuristic(
193 } else if (absl::GetFlag(FLAGS_routing_guided_local_search)) {
194 parameters->set_local_search_metaheuristic(
196 }
197 parameters->set_guided_local_search_lambda_coefficient(
198 absl::GetFlag(FLAGS_routing_guided_local_search_lambda_coefficient));
199}
200
201namespace {
202OptionalBoolean ToOptionalBoolean(bool x) { return x ? BOOL_TRUE : BOOL_FALSE; }
203} // namespace
204
207 CHECK(parameters != nullptr);
208 parameters->set_cheapest_insertion_ls_operator_neighbors_ratio(1.0);
209 parameters->set_cheapest_insertion_ls_operator_min_neighbors(1);
211 local_search_operators = parameters->mutable_local_search_operators();
212
213 // TODO(user): Remove these overrides: they should be set by the caller, via
214 // a baseline RoutingSearchParameters obtained from DefaultSearchParameters().
215 local_search_operators->set_use_relocate_pair(BOOL_TRUE);
216 local_search_operators->set_use_light_relocate_pair(BOOL_TRUE);
217 local_search_operators->set_use_exchange_pair(BOOL_TRUE);
218 local_search_operators->set_use_relocate_and_make_active(BOOL_FALSE);
219 local_search_operators->set_use_node_pair_swap_active(BOOL_FALSE);
220 local_search_operators->set_use_cross_exchange(BOOL_FALSE);
223 local_search_operators
225 BOOL_TRUE);
227 BOOL_FALSE);
229 BOOL_FALSE);
231 BOOL_FALSE);
233 BOOL_FALSE);
234
235 local_search_operators->set_use_relocate(
236 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_relocate)));
237 local_search_operators->set_use_relocate_neighbors(
238 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_relocate_neighbors)));
239 local_search_operators->set_use_relocate_subtrip(
240 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_relocate_subtrip)));
241 local_search_operators->set_use_exchange_subtrip(
242 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_exchange_subtrip)));
243 local_search_operators->set_use_exchange(
244 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_exchange)));
245 local_search_operators->set_use_cross(
246 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_cross)));
247 local_search_operators->set_use_two_opt(
248 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_2opt)));
249 local_search_operators->set_use_or_opt(
250 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_oropt)));
251 local_search_operators->set_use_lin_kernighan(
252 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_lkh)));
253 local_search_operators->set_use_relocate_expensive_chain(ToOptionalBoolean(
254 !absl::GetFlag(FLAGS_routing_no_relocate_expensive_chain)));
255 local_search_operators->set_use_tsp_opt(
256 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_tsp)));
257 local_search_operators->set_use_make_active(
258 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_make_active)));
259 local_search_operators->set_use_make_inactive(
260 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_use_chain_make_inactive) &&
261 !absl::GetFlag(FLAGS_routing_no_make_active)));
262 local_search_operators->set_use_make_chain_inactive(
263 ToOptionalBoolean(absl::GetFlag(FLAGS_routing_use_chain_make_inactive) &&
264 !absl::GetFlag(FLAGS_routing_no_make_active)));
265 local_search_operators->set_use_swap_active(ToOptionalBoolean(
266 !absl::GetFlag(FLAGS_routing_use_extended_swap_active) &&
267 !absl::GetFlag(FLAGS_routing_no_make_active)));
268 local_search_operators->set_use_extended_swap_active(
269 ToOptionalBoolean(absl::GetFlag(FLAGS_routing_use_extended_swap_active) &&
270 !absl::GetFlag(FLAGS_routing_no_make_active)));
271 local_search_operators->set_use_path_lns(
272 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_lns)));
273 local_search_operators->set_use_inactive_lns(
274 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_lns)));
275 local_search_operators->set_use_full_path_lns(
276 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_fullpathlns)));
277 local_search_operators->set_use_tsp_lns(
278 ToOptionalBoolean(!absl::GetFlag(FLAGS_routing_no_tsplns)));
279}
280
282 CHECK(parameters != nullptr);
283 parameters->set_use_depth_first_search(absl::GetFlag(FLAGS_routing_dfs));
284 parameters->set_use_cp(BOOL_TRUE);
285 parameters->set_use_cp_sat(BOOL_FALSE);
286 parameters->set_optimization_step(
287 absl::GetFlag(FLAGS_routing_optimization_step));
288 parameters->set_number_of_solutions_to_collect(
289 absl::GetFlag(FLAGS_routing_number_of_solutions_to_collect));
290 parameters->set_solution_limit(absl::GetFlag(FLAGS_routing_solution_limit));
291 if (absl::GetFlag(FLAGS_routing_time_limit) !=
294 absl::Milliseconds(absl::GetFlag(FLAGS_routing_time_limit)),
295 parameters->mutable_time_limit()));
296 }
297 if (absl::GetFlag(FLAGS_routing_lns_time_limit) !=
300 absl::Milliseconds(absl::GetFlag(FLAGS_routing_lns_time_limit)),
301 parameters->mutable_lns_time_limit()));
302 }
303}
304
306 CHECK(parameters != nullptr);
307 parameters->set_use_full_propagation(
308 !absl::GetFlag(FLAGS_routing_use_light_propagation));
309 parameters->set_log_search(absl::GetFlag(FLAGS_routing_trace));
310 parameters->set_log_cost_scaling_factor(1.0);
311 parameters->set_relocate_expensive_chain_num_arcs_to_consider(absl::GetFlag(
312 FLAGS_routing_relocate_expensive_chain_num_arcs_to_consider));
313 parameters->set_heuristic_expensive_chain_lns_num_arcs_to_consider(4);
314 parameters->set_heuristic_close_nodes_lns_num_nodes(5);
315 parameters->set_continuous_scheduling_solver(RoutingSearchParameters::GLOP);
316 parameters->set_mixed_integer_scheduling_solver(
318}
319
327 const std::string error = FindErrorInRoutingSearchParameters(parameters);
328 LOG_IF(DFATAL, !error.empty())
329 << "Error in the routing search parameters built from flags: " << error;
330 return parameters;
331}
332
335 ConstraintSolverParameters* const solver_parameters =
336 parameters.mutable_solver_parameters();
337 *solver_parameters = Solver::DefaultSolverParameters();
338 parameters.set_reduce_vehicle_cost_model(
339 absl::GetFlag(FLAGS_routing_use_homogeneous_costs));
340 if (absl::GetFlag(FLAGS_routing_cache_callbacks)) {
341 parameters.set_max_callback_cache_size(
342 absl::GetFlag(FLAGS_routing_max_cache_size));
343 }
344 solver_parameters->set_profile_local_search(
345 absl::GetFlag(FLAGS_routing_profile));
346 return parameters;
347}
348
349} // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
#define LOG_IF(severity, condition)
Definition: base/logging.h:475
#define CHECK(condition)
Definition: base/logging.h:491
#define CHECK_OK(x)
Definition: base/logging.h:42
static constexpr Value PARALLEL_CHEAPEST_INSERTION
static constexpr Value SEQUENTIAL_CHEAPEST_INSERTION
void set_use_node_pair_swap_active(::operations_research::OptionalBoolean value)
void set_use_make_chain_inactive(::operations_research::OptionalBoolean value)
void set_use_light_relocate_pair(::operations_research::OptionalBoolean value)
void set_use_local_cheapest_insertion_expensive_chain_lns(::operations_research::OptionalBoolean value)
void set_use_relocate_path_global_cheapest_insertion_insert_unperformed(::operations_research::OptionalBoolean value)
void set_use_global_cheapest_insertion_close_nodes_lns(::operations_research::OptionalBoolean value)
void set_use_global_cheapest_insertion_expensive_chain_lns(::operations_research::OptionalBoolean value)
void set_use_global_cheapest_insertion_path_lns(::operations_research::OptionalBoolean value)
void set_use_extended_swap_active(::operations_research::OptionalBoolean value)
void set_use_relocate_expensive_chain(::operations_research::OptionalBoolean value)
void set_use_local_cheapest_insertion_path_lns(::operations_research::OptionalBoolean value)
void set_use_relocate_and_make_active(::operations_research::OptionalBoolean value)
void set_use_relocate_neighbors(::operations_research::OptionalBoolean value)
void set_use_local_cheapest_insertion_close_nodes_lns(::operations_research::OptionalBoolean value)
static ConstraintSolverParameters DefaultSolverParameters()
Create a ConstraintSolverParameters proto with all the default values.
SatParameters parameters
bool FindCopy(const Collection &collection, const Key &key, Value *const value)
Definition: map_util.h:185
Collection of objects used to extend the Constraint Solver library.
void SetLocalSearchMetaheuristicFromFlags(RoutingSearchParameters *parameters)
std::string FindErrorInRoutingSearchParameters(const RoutingSearchParameters &search_parameters)
Returns an empty std::string if the routing search parameters are valid, and a non-empty,...
RoutingSearchParameters BuildSearchParametersFromFlags()
Builds routing search parameters from flags.
void SetSearchLimitsFromFlags(RoutingSearchParameters *parameters)
void SetFirstSolutionStrategyFromFlags(RoutingSearchParameters *parameters)
void AddLocalSearchNeighborhoodOperatorsFromFlags(RoutingSearchParameters *parameters)
void SetMiscellaneousParametersFromFlags(RoutingSearchParameters *parameters)
RoutingModelParameters BuildModelParametersFromFlags()
Builds routing search parameters from flags.
inline ::absl::StatusOr< google::protobuf::Duration > EncodeGoogleApiProto(absl::Duration d)
Definition: protoutil.h:27
ABSL_FLAG(bool, routing_no_lns, false, "Routing: forbids use of Large Neighborhood Search.")