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