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