Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
routing_ils.proto
Go to the documentation of this file.
1// Copyright 2010-2025 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
14// Protocol buffer used to parametrize an iterated local search (ILS) approach.
15// ILS is an iterative metaheuristic in which every iteration consists in
16// performing a perturbation followed by an improvement step on a reference
17// solution to generate a neighbor solution.
18// The neighbor solution is accepted as the new reference solution according
19// to an acceptance criterion.
20// The best found solution is eventually returned.
21
22syntax = "proto3";
23
24option java_package = "com.google.ortools.constraintsolver";
25option java_multiple_files = true;
26option csharp_namespace = "Google.OrTools.ConstraintSolver";
27
28import "ortools/constraint_solver/routing_enums.proto";
29import "ortools/constraint_solver/routing_heuristic_parameters.proto";
30
31package operations_research;
32
33// Ruin strategy that removes a number of spatially close routes.
34message SpatiallyCloseRoutesRuinStrategy {
35 // Number of spatially close routes ruined at each ruin application.
36 optional uint32 num_ruined_routes = 3;
37}
38
39// Ruin strategy that removes a number of nodes by performing a random walk
40// on the underlying routing solution. More precisely, starting from a randomly
41// selected seed visit, the walk is extended by either moving within the
42// same route or by jumping to a visit served by a different neighboring
43// route. Every active visit encountered along this random walk is made
44// unperformed.
45message RandomWalkRuinStrategy {
46 // Number of visits removed during a ruin application defined on visits.
47 // Note that pickup and delivery pairs are considered as a single entity,
48 // i.e., the removal of a pickup (respectively delivery) causes the removal of
49 // the associated delivery (respectively pickup) and it counts as a single
50 // removal.
51 optional uint32 num_removed_visits = 7;
52}
53
54// Ruin strategy based on the "Slack Induction by String Removals for Vehicle
55// Routing Problems" by Jan Christiaens and Greet Vanden Berghe, Transportation
56// Science 2020.
57//
58// Note that, in this implementation, the notion of "string" is replaced by
59// "sequence".
60//
61// The main idea of this ruin is to remove a number of geographically close
62// sequences of nodes. In particular, at every ruin application, a maximum
63// number max_ruined_routes of routes are disrupted. The value for
64// max_ruined_routes is defined as
65// (4 * avg_num_removed_visits) / (1 + max_sequence_size) + 1
66// with
67// - avg_num_removed_visits: user-defined parameter ruling the average number of
68// visits that are removed in face of several ruin applications (see also the
69// proto message below)
70// - max_sequence_size is defined as
71// min{max_removed_sequence_size, average_route_size}
72// with
73// - max_removed_sequence_size: user-defined parameter that specifies
74// the maximum number of visits removed from a single route (see also the
75// proto message below)
76// - average_route_size: the average size of a non-empty route in the current
77// solution
78//
79// The actual number of ruined routes is then obtained as
80// floor(U(1, max_ruined_routes + 1))
81// where U is a continuous uniform distribution of real values in the given
82// interval.
83//
84// The routes affected by the ruin procedure are selected as follows.
85// First, a non start/end seed node is randomly selected. The route serving this
86// node is the first ruined route. Then, until the required number of routes has
87// been ruined, neighbor nodes of the initial seed node are scanned and the
88// associated not yet ruined routes are disrupted. Nodes defining the selected
89// routes are designated as seed nodes for the "sequence" and "split sequence"
90// removal procedures described below.
91//
92// For every selected route, a maximum number route_max_sequence_size of nodes
93// are removed. In particular, route_max_sequence_size is defined as
94// min{route_size, max_sequence_size}
95// with route_size being the size of the current route.
96//
97// Then, the actual number of removed nodes num_removed_nodes is defined as
98// floor(U(1, route_max_sequence_size + 1))
99// where U is a continuous uniform distribution of real values in the given
100// interval.
101//
102// As mentioned above, the selected num_removed_nodes number of nodes is removed
103// either via the "sequence" removal or "split sequence" removal procedures. The
104// two removal procedures are executed with equal probabilities.
105//
106// The "sequence" removal procedure removes a randomly selected sequence of size
107// num_removed_nodes that includes the seed node.
108//
109// The "split sequence" removal procedure also removes a randomly selected
110// sequence of size num_removed_nodes that includes the seed node, but it can
111// possibly preserve a subsequence of contiguous nodes.
112// In particular, the procedure first selects a sequence of size
113// num_removed_nodes + num_bypassed, then num_bypassed contiguous nodes in the
114// selected sequence are preserved while the others removed.
115//
116// The definition of num_bypassed is as follows. First num_bypassed = 1. The
117// current value of num_bypassed is maintaned if
118// U(0, 1) < bypass_factor * U(0, 1)
119// or the maximum value for num_bypassed, equal to
120// route_size - num_removed_nodes
121// is reached. The value is incremented of a unit otherwise,
122// and the process is repeated. The value assigned to bypass_factor affects the
123// number of preserved visits (see also the proto message below).
124message SISRRuinStrategy {
125 // Maximum number of removed visits per sequence. The parameter name in the
126 // paper is L^{max} and the suggested value is 10.
127 optional uint32 max_removed_sequence_size = 1;
128
129 // Number of visits that are removed on average. The parameter name in the
130 // paper is \bar{c} and the suggested value is 10.
131 optional uint32 avg_num_removed_visits = 2;
132
133 // Value in [0, 1] ruling the number of preserved nodes in the split
134 // sequence removal. The parameter name in the paper is \alpha and the
135 // suggested value is 0.01.
136 optional double bypass_factor = 3;
137}
138
139// Ruin strategies, used in perturbation based on ruin and recreate approaches.
140message RuinStrategy {
141 oneof strategy {
142 SpatiallyCloseRoutesRuinStrategy spatially_close_routes = 1;
143 RandomWalkRuinStrategy random_walk = 2;
144 SISRRuinStrategy sisr = 3;
145 }
146}
147
148// Parameters to customize a recreate strategy.
149message RecreateParameters {
150 oneof parameters {
151 LocalCheapestInsertionParameters local_cheapest_insertion = 1;
152 SavingsParameters savings = 2;
153 GlobalCheapestInsertionParameters global_cheapest_insertion = 3;
154 }
155}
156
157// Strategy defining how a solution is recreated.
158message RecreateStrategy {
159 optional FirstSolutionStrategy.Value heuristic = 1;
160 // The selected parameters should match the chosen recreate heuristic.
161 // If not set, the default parameters from the RoutingModel are used.
162 optional RecreateParameters parameters = 2;
163}
164
165// The ruin composition strategies specifies how ruin are selected at every ILS
166// iteration.
167message RuinCompositionStrategy {
168 enum Value {
169 // Unspecified value.
170 UNSET = 0;
171
172 // Execute all ruin strategies sequentially in the same order provided in
173 // input.
174 RUN_ALL_SEQUENTIALLY = 1;
175
176 // Execute all ruin strategies in a random order.
177 RUN_ALL_RANDOMLY = 2;
178
179 // Execute a randomly selected ruin.
180 RUN_ONE_RANDOMLY = 3;
181 }
182}
183
184// Parameters to configure a perturbation based on a ruin and recreate approach.
185message RuinRecreateParameters {
186 // List of ruin strategies determining how a reference solution is ruined.
187 repeated RuinStrategy ruin_strategies = 1;
188
189 // The composition strategy to use when combining the given 'ruin_strategies'.
190 // Has no effect when ruin_strategies is composed of a single strategy.
191 RuinCompositionStrategy.Value ruin_composition_strategy = 2;
192
193 // Strategy defining how a reference solution is recreated.
194 RecreateStrategy recreate_strategy = 3;
195
196 // Ratio in [0, 1] of non start/end nodes to consider as neighbors for the
197 // identification of routes spatially close to a non start/end seed node.
198 //
199 // In particular, given a non start/end seed node s served by route r, we say
200 // that a route r' is spatially close to the seed node s if there is at
201 // least one non start/end node s' among the neighbors of s, such that s' is
202 // served by r'.
203 //
204 // The neighbors_ratio is coupled with the corresponding min_neighbors and
205 // max_neighbors values, defining the minimum and maximum number of neighbor
206 // nodes considered for a given seed node:
207 // num_neighbors = min(max_neighbors,
208 // max(min_neighbors, neighbors_ratio * NUM_NON_START_END_NODES))
209 //
210 // Neighbors ratio, and minimum and maximum number of non start/end neighbor
211 // nodes for the identification of spatially close routes.
212 optional double route_selection_neighbors_ratio = 4;
213 optional uint32 route_selection_min_neighbors = 5;
214 optional uint32 route_selection_max_neighbors = 6;
215}
216
217// Defines how a reference solution is perturbed.
218message PerturbationStrategy {
219 enum Value {
220 // Unspecified value.
221 UNSET = 0;
222
223 // Performs a perturbation in a ruin and recreate fashion.
224 RUIN_AND_RECREATE = 1;
225 }
226}
227
228// The cooling schedule strategy defines how to compute the current simulated
229// annealing temperature t given
230// - the initial temperature t0
231// - the final temperature t1
232// - the current search progress 0 <= p <= 1
233//
234// The value of t0 and t1 is defined by the initial_temperature and
235// final_temperature in SimulatedAnnealingParameters, respectively.
236//
237// The search progress p is derived, at any given time, by the search limits.
238// In particular, p measures how far we are in the search process w.r.t. to the
239// number of explored solutions and the time limit.
240//
241// The temperature t, computed according to one of the strategies defined below,
242// together with the selected AcceptanceStrategy, is used to guide the search
243// trajectory. In particular, given a neighbor solution S', generated by the
244// the application of the perturbation and improvement step to a reference
245// solution S, we have that S will be replaced by S' iff
246// cost(S') + t * log(U(0, 1)) < cost(S)
247// where U(0, 1) is a random number sampled from a uniform distribution of real
248// numbers in [0, 1].
249message CoolingScheduleStrategy {
250 enum Value {
251 // Unspecified value.
252 UNSET = 0;
253
254 // Exponentially decreases the temperature as the search progresses.
255 // More precisely, t = t0 * (t1/t0)^p.
256 EXPONENTIAL = 1;
257
258 // Linearly decreases the temperature as the search progresses.
259 // More precisely, t = t0 - p * (t0 - t1).
260 LINEAR = 2;
261 }
262}
263
264// Acceptance strategy in which only improving solutions are accepted.
265message GreedyDescentAcceptanceStrategy {}
266
267// Acceptance strategy in which solutions are accepted with a probability that
268// depends on its quality and on the current state of the search.
269message SimulatedAnnealingAcceptanceStrategy {
270 // Determines the speed at which the temperature changes from initial to
271 // final.
272 CoolingScheduleStrategy.Value cooling_schedule_strategy = 1;
273
274 // The initial temperature. See CoolingScheduleStrategy for its usage.
275 optional double initial_temperature = 2;
276
277 // The final temperature. See CoolingScheduleStrategy for its usage.
278 optional double final_temperature = 3;
279
280 // Automatically define the value for the temperatures as follows.
281 // First, a reference temperature t is defined as
282 // w1 * c1 + w2 * c2 + ... + wK * cK
283 // where 0 < wJ <= 1 is the fraction of vehicles of cost class J and cJ is the
284 // average arc cost for the cost class J.
285 // The value of cJ is identified by randomly sampling N arc costs for the cost
286 // class J, where N is equal to the number of instance nodes.
287 // The initial and final temperatures are then defined as
288 // - initial_temperature: 0.1 * t
289 // - final_temperature: 0.001 * t
290 optional bool automatic_temperatures = 4;
291}
292
293// Acceptance strategy in which a solution is accepted only if all nodes
294// are performed. Disjunctions are respected when several nodes can be
295// performed.
296message AllNodesPerformedAcceptanceStrategy {}
297
298// Acceptance strategy in which a solution is accepted only if it performs at
299// least one more node than the reference solution.
300message MoreNodesPerformedAcceptanceStrategy {}
301
302// Acceptance strategy in which a solution is accepted only if it has less
303// absences than the reference solution (see Slack Induction by String Removals
304// for Vehicle Routing Problems" Christiaens and Vanden Berghe, Transportation
305// Science 2020).
306//
307// In particular, for each node n, the number of solutions where n was not
308// performed by any route is tracked by a counter absences[n]. A candidate is
309// accepted if
310// sum(absences[n]) < sum(absences[m])
311// with
312// n in unperformed(candidate)
313// m in unperformed(reference)
314//
315// The counter absences is increased after every ILS iteration for the
316// unperformed nodes in the reference solution. In addition, when
317// remove_route_with_lowest_absences is true and a new best found solution is
318// found, the route with the lowest sum of absences is removed from the
319// reference solution.
320message AbsencesBasedAcceptanceStrategy {
321 // If true, when a new best solution is found, the route with the lowest sum
322 // of absences is removed from the reference solution.
323 optional bool remove_route_with_lowest_absences = 1;
324}
325
326// Determines when a candidate solution replaces another one.
327message AcceptanceStrategy {
328 oneof strategy {
329 GreedyDescentAcceptanceStrategy greedy_descent = 1;
330 SimulatedAnnealingAcceptanceStrategy simulated_annealing = 2;
331 AllNodesPerformedAcceptanceStrategy all_nodes_performed = 3;
332 MoreNodesPerformedAcceptanceStrategy more_nodes_performed = 4;
333 AbsencesBasedAcceptanceStrategy absences_based = 5;
334 }
335}
336
337// Specifies the behavior of a search based on ILS.
338message IteratedLocalSearchParameters {
339 // Determines how a reference solution S is perturbed to obtain a neighbor
340 // solution S'.
341 PerturbationStrategy.Value perturbation_strategy = 1;
342
343 // Parameters to customize a ruin and recreate perturbation.
344 RuinRecreateParameters ruin_recreate_parameters = 2;
345
346 // Determines whether solution S', obtained from the perturbation, should be
347 // optimized with a local search application.
348 optional bool improve_perturbed_solution = 3;
349
350 // Determines when the neighbor solution S', possibly improved if
351 // `improve_perturbed_solution` is true, replaces the reference solution S.
352 AcceptanceStrategy reference_solution_acceptance_strategy = 4;
353
354 // Determines when the neighbor solution S' replaces the best solution found
355 // so far.
356 AcceptanceStrategy best_solution_acceptance_strategy = 5;
357}