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