OR-Tools  9.0
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"
23 #include "ortools/base/map_util.h"
24 #include "ortools/base/protoutil.h"
29 
30 // --- Routing search flags ---
31 
32 // Neighborhood activation/deactivation
33 ABSL_FLAG(bool, routing_no_lns, false,
34  "Routing: forbids use of Large Neighborhood Search.");
35 ABSL_FLAG(bool, routing_no_fullpathlns, true,
36  "Routing: forbids use of Full-path Large Neighborhood Search.");
37 ABSL_FLAG(bool, routing_no_relocate, false,
38  "Routing: forbids use of Relocate neighborhood.");
39 ABSL_FLAG(bool, routing_no_relocate_neighbors, true,
40  "Routing: forbids use of RelocateNeighbors neighborhood.");
41 ABSL_FLAG(bool, routing_no_relocate_subtrip, false,
42  "Routing: forbids use of RelocateSubtrips neighborhood.");
43 ABSL_FLAG(bool, routing_no_exchange, false,
44  "Routing: forbids use of Exchange neighborhood.");
45 ABSL_FLAG(bool, routing_no_exchange_subtrip, false,
46  "Routing: forbids use of ExchangeSubtrips neighborhood.");
47 ABSL_FLAG(bool, routing_no_cross, false,
48  "Routing: forbids use of Cross neighborhood.");
49 ABSL_FLAG(bool, routing_no_2opt, false,
50  "Routing: forbids use of 2Opt neighborhood.");
51 ABSL_FLAG(bool, routing_no_oropt, false,
52  "Routing: forbids use of OrOpt neighborhood.");
53 ABSL_FLAG(bool, routing_no_make_active, false,
54  "Routing: forbids use of MakeActive/SwapActive/MakeInactive "
55  "neighborhoods.");
56 ABSL_FLAG(bool, routing_no_lkh, false,
57  "Routing: forbids use of LKH neighborhood.");
58 ABSL_FLAG(bool, routing_no_relocate_expensive_chain, false,
59  "Routing: forbids use of RelocateExpensiveChain operator.");
60 ABSL_FLAG(bool, routing_no_tsp, true,
61  "Routing: forbids use of TSPOpt neighborhood.");
62 ABSL_FLAG(bool, routing_no_tsplns, true,
63  "Routing: forbids use of TSPLNS neighborhood.");
64 ABSL_FLAG(bool, routing_use_chain_make_inactive, false,
65  "Routing: use chain version of MakeInactive neighborhood.");
66 ABSL_FLAG(bool, routing_use_extended_swap_active, false,
67  "Routing: use extended version of SwapActive neighborhood.");
68 
69 // Meta-heuristics
70 ABSL_FLAG(bool, routing_guided_local_search, false, "Routing: use GLS.");
71 ABSL_FLAG(double, routing_guided_local_search_lambda_coefficient, 0.1,
72  "Lambda coefficient in GLS.");
73 ABSL_FLAG(bool, routing_simulated_annealing, false,
74  "Routing: use simulated annealing.");
75 ABSL_FLAG(bool, routing_tabu_search, false, "Routing: use tabu search.");
76 ABSL_FLAG(bool, routing_generic_tabu_search, false,
77  "Routing: use tabu search based on a list of values.");
78 
79 // Search limits
80 ABSL_FLAG(int64_t, routing_solution_limit, std::numeric_limits<int64_t>::max(),
81  "Routing: number of solutions limit.");
82 ABSL_FLAG(int64_t, routing_time_limit, std::numeric_limits<int64_t>::max(),
83  "Routing: time limit in ms.");
84 ABSL_FLAG(int64_t, routing_lns_time_limit, 100,
85  "Routing: time limit in ms for LNS sub-decisionbuilder.");
86 
87 // Search control
88 ABSL_FLAG(std::string, routing_first_solution, "",
89  "Routing first solution heuristic. See SetupParametersFromFlags "
90  "in the code to get a full list.");
91 ABSL_FLAG(bool, routing_use_filtered_first_solutions, true,
92  "Use filtered version of first solution heuristics if available.");
93 ABSL_FLAG(double, savings_neighbors_ratio, 1,
94  "Ratio of neighbors to consider for each node when "
95  "constructing the savings.");
96 ABSL_FLAG(bool, savings_add_reverse_arcs, false,
97  "Add savings related to reverse arcs when finding the nearest "
98  "neighbors of the nodes.");
99 ABSL_FLAG(double, savings_arc_coefficient, 1.0,
100  "Coefficient of the cost of the arc for which the saving value "
101  "is being computed.");
102 ABSL_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.");
105 ABSL_FLAG(double, cheapest_insertion_first_solution_neighbors_ratio, 1.0,
106  "Ratio of nodes considered as neighbors in the "
107  "GlobalCheapestInsertion first solution heuristic.");
108 ABSL_FLAG(bool, routing_dfs, false,
109  "Routing: use a complete depth-first search.");
110 ABSL_FLAG(double, routing_optimization_step, 0.0, "Optimization step.");
111 ABSL_FLAG(int, routing_number_of_solutions_to_collect, 1,
112  "Number of solutions to collect.");
113 ABSL_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
118 ABSL_FLAG(bool, routing_use_light_propagation, true,
119  "Use constraints with light propagation in routing model.");
120 
121 // Cache settings.
122 ABSL_FLAG(bool, routing_cache_callbacks, false, "Cache callback calls.");
123 ABSL_FLAG(int64_t, routing_max_cache_size, 1000,
124  "Maximum cache size when callback caching is on.");
125 
126 // Misc
127 ABSL_FLAG(bool, routing_trace, false, "Routing: trace search.");
128 ABSL_FLAG(bool, routing_profile, false, "Routing: profile search.");
129 
130 // --- Routing model flags ---
131 ABSL_FLAG(bool, routing_use_homogeneous_costs, true,
132  "Routing: use homogeneous cost model when possible.");
133 ABSL_FLAG(bool, routing_gzip_compress_trail, false,
134  "Use gzip to compress the trail, zippy otherwise.");
135 
136 namespace operations_research {
137 
138 void SetFirstSolutionStrategyFromFlags(RoutingSearchParameters* parameters) {
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",
144  FirstSolutionStrategy::PATH_MOST_CONSTRAINED_ARC},
145  {"EvaluatorStrategy", FirstSolutionStrategy::EVALUATOR_STRATEGY},
146  {"Savings", FirstSolutionStrategy::SAVINGS},
147  {"Sweep", FirstSolutionStrategy::SWEEP},
148  {"Christofides", FirstSolutionStrategy::CHRISTOFIDES},
149  {"AllUnperformed", FirstSolutionStrategy::ALL_UNPERFORMED},
150  {"BestInsertion", FirstSolutionStrategy::BEST_INSERTION},
151  {"GlobalCheapestInsertion",
152  FirstSolutionStrategy::PARALLEL_CHEAPEST_INSERTION},
153  {"SequentialGlobalCheapestInsertion",
154  FirstSolutionStrategy::SEQUENTIAL_CHEAPEST_INSERTION},
155  {"LocalCheapestInsertion",
156  FirstSolutionStrategy::LOCAL_CHEAPEST_INSERTION},
157  {"GlobalCheapestArc", FirstSolutionStrategy::GLOBAL_CHEAPEST_ARC},
158  {"LocalCheapestArc", FirstSolutionStrategy::LOCAL_CHEAPEST_ARC},
159  {"DefaultStrategy", FirstSolutionStrategy::FIRST_UNBOUND_MIN_VALUE},
160  {"", FirstSolutionStrategy::FIRST_UNBOUND_MIN_VALUE}};
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 
182 void SetLocalSearchMetaheuristicFromFlags(RoutingSearchParameters* parameters) {
183  CHECK(parameters != nullptr);
184  if (absl::GetFlag(FLAGS_routing_tabu_search)) {
185  parameters->set_local_search_metaheuristic(
186  LocalSearchMetaheuristic::TABU_SEARCH);
187  } else if (absl::GetFlag(FLAGS_routing_generic_tabu_search)) {
188  parameters->set_local_search_metaheuristic(
189  LocalSearchMetaheuristic::GENERIC_TABU_SEARCH);
190  } else if (absl::GetFlag(FLAGS_routing_simulated_annealing)) {
191  parameters->set_local_search_metaheuristic(
192  LocalSearchMetaheuristic::SIMULATED_ANNEALING);
193  } else if (absl::GetFlag(FLAGS_routing_guided_local_search)) {
194  parameters->set_local_search_metaheuristic(
195  LocalSearchMetaheuristic::GUIDED_LOCAL_SEARCH);
196  }
197  parameters->set_guided_local_search_lambda_coefficient(
198  absl::GetFlag(FLAGS_routing_guided_local_search_lambda_coefficient));
199 }
200 
201 namespace {
202 OptionalBoolean ToOptionalBoolean(bool x) { return x ? BOOL_TRUE : BOOL_FALSE; }
203 } // namespace
204 
206  RoutingSearchParameters* parameters) {
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);
210  RoutingSearchParameters::LocalSearchNeighborhoodOperators* const
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);
221  local_search_operators->set_use_global_cheapest_insertion_path_lns(BOOL_TRUE);
222  local_search_operators->set_use_local_cheapest_insertion_path_lns(BOOL_TRUE);
223  local_search_operators
224  ->set_use_relocate_path_global_cheapest_insertion_insert_unperformed(
225  BOOL_TRUE);
226  local_search_operators->set_use_global_cheapest_insertion_expensive_chain_lns(
227  BOOL_FALSE);
228  local_search_operators->set_use_local_cheapest_insertion_expensive_chain_lns(
229  BOOL_FALSE);
230  local_search_operators->set_use_global_cheapest_insertion_close_nodes_lns(
231  BOOL_FALSE);
232  local_search_operators->set_use_local_cheapest_insertion_close_nodes_lns(
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 
281 void SetSearchLimitsFromFlags(RoutingSearchParameters* parameters) {
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 
305 void SetMiscellaneousParametersFromFlags(RoutingSearchParameters* parameters) {
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(
317  RoutingSearchParameters::CP_SAT);
318 }
319 
320 RoutingSearchParameters BuildSearchParametersFromFlags() {
321  RoutingSearchParameters parameters;
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 
333 RoutingModelParameters BuildModelParametersFromFlags() {
334  RoutingModelParameters parameters;
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:482
#define CHECK(condition)
Definition: base/logging.h:498
#define CHECK_OK(x)
Definition: base/logging.h:42
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
std::function< int64_t(const Model &)> Value(IntegerVariable v)
Definition: integer.h:1492
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.")