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
 
    6//     http://www.apache.org/licenses/LICENSE-2.0
 
    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.
 
   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.
 
   24option java_package = "com.google.ortools.constraintsolver";
 
   25option java_multiple_files = true;
 
   26option csharp_namespace = "Google.OrTools.ConstraintSolver";
 
   28import "ortools/constraint_solver/routing_enums.proto";
 
   30package operations_research;
 
   32// Ruin strategy that removes a number of spatially close routes.
 
   33message SpatiallyCloseRoutesRuinStrategy {
 
   34  // Number of spatially close routes ruined at each ruin application.
 
   35  optional uint32 num_ruined_routes = 3;
 
   38// Ruin strategy that removes a number of customers by performing a random walk
 
   39// on the underlying routing solution. More precisely, starting from a randomly
 
   40// selected seed visit, the walk is extended by either moving within the
 
   41// same route or by jumping to a visit served by a different neighboring
 
   42// route. Every active visit encountered along this random walk is made
 
   44message RandomWalkRuinStrategy {
 
   45  // Number of visits removed during a ruin application defined on visits.
 
   46  // Note that pickup and delivery pairs are considered as a single entity,
 
   47  // i.e., the removal of a pickup (respectively delivery) causes the removal of
 
   48  // the associated delivery (respectively pickup) and it counts as a single
 
   50  optional uint32 num_removed_visits = 7;
 
   53// Ruin strategy based on the "Slack Induction by String Removals for Vehicle
 
   54// Routing Problems" by Jan Christiaens and Greet Vanden Berghe, Transportation
 
   57// https://kuleuven.limo.libis.be/discovery/fulldisplay?docid=lirias1988666&context=SearchWebhook&vid=32KUL_KUL:Lirias&lang=en&search_scope=lirias_profile&adaptor=SearchWebhook&tab=LIRIAS&query=any,contains,LIRIAS1988666&offset=0
 
   59// Note that, in this implementation, the notion of "string" is replaced by
 
   62// The main idea of this ruin is to remove a number of geographically close
 
   63// sequences of nodes. In particular, at every ruin application, a maximum
 
   64// number max_ruined_routes of routes are disrupted. The value for
 
   65// max_ruined_routes is defined as
 
   66//       (4 * avg_num_removed_visits) / (1 + max_sequence_size) + 1
 
   68// - avg_num_removed_visits: user-defined parameter ruling the average number of
 
   69//   visits that are removed in face of several ruin applications (see also the
 
   70//   proto message below)
 
   71// - max_sequence_size is defined as
 
   72//        min{max_removed_sequence_size, average_route_size}
 
   74//   - max_removed_sequence_size: user-defined parameter that specifies
 
   75//     the maximum number of visits removed from a single route (see also the
 
   76//     proto message below)
 
   77//   - average_route_size: the average size of a non-empty route in the current
 
   80// The actual number of ruined routes is then obtained as
 
   81//                  floor(U(1, max_ruined_routes + 1))
 
   82// where U is a continuous uniform distribution of real values in the given
 
   85// The routes affected by the ruin procedure are selected as follows.
 
   86// First, a non start/end seed node is randomly selected. The route serving this
 
   87// node is the first ruined route. Then, until the required number of routes has
 
   88// been ruined, neighbor nodes of the initial seed node are scanned and the
 
   89// associated not yet ruined routes are disrupted. Nodes defining the selected
 
   90// routes are designated as seed nodes for the "sequence" and "split sequence"
 
   91// removal procedures described below.
 
   93// For every selected route, a maximum number route_max_sequence_size of nodes
 
   94// are removed. In particular, route_max_sequence_size is defined as
 
   95//                min{route_size, max_sequence_size}
 
   96// with route_size being the size of the current route.
 
   98// Then, the actual number of removed nodes num_removed_nodes is defined as
 
   99//              floor(U(1, route_max_sequence_size + 1))
 
  100// where U is a continuous uniform distribution of real values in the given
 
  103// As mentioned above, the selected num_removed_nodes number of nodes is removed
 
  104// either via the "sequence" removal or "split sequence" removal procedures. The
 
  105// two removal procedures are executed with equal probabilities.
 
  107// The "sequence" removal procedure removes a randomly selected sequence of size
 
  108// num_removed_nodes that includes the seed node.
 
  110// The "split sequence" removal procedure also removes a randomly selected
 
  111// sequence of size num_removed_nodes that includes the seed node, but it can
 
  112// possibly preserve a subsequence of contiguous nodes.
 
  113// In particular, the procedure first selects a sequence of size
 
  114// num_removed_nodes + num_bypassed, then num_bypassed contiguous nodes in the
 
  115// selected sequence are preserved while the others removed.
 
  117// The definition of num_bypassed is as follows. First num_bypassed = 1. The
 
  118// current value of num_bypassed is maintaned if
 
  119//          U(0, 1) < bypass_factor * U(0, 1)
 
  120// or the maximum value for num_bypassed, equal to
 
  121//           route_size - num_removed_nodes
 
  122// is reached. The value is incremented of a unit otherwise,
 
  123// and the process is repeated. The value assigned to bypass_factor affects the
 
  124// number of preserved visits (see also the proto message below).
 
  125message SISRRuinStrategy {
 
  126  // Maximum number of removed visits per sequence. The parameter name in the
 
  127  // paper is L^{max} and the suggested value is 10.
 
  128  optional uint32 max_removed_sequence_size = 1;
 
  130  // Number of visits that are removed on average. The parameter name in the
 
  131  // paper is \bar{c} and the suggested value is 10.
 
  132  optional uint32 avg_num_removed_visits = 2;
 
  134  // Value in [0, 1] ruling the number of preserved customers in the split
 
  135  // sequence removal. The parameter name in the paper is \alpha and the
 
  136  // suggested value is 0.01.
 
  137  optional double bypass_factor = 3;
 
  140// Ruin strategies, used in perturbation based on ruin and recreate approaches.
 
  141message RuinStrategy {
 
  143    SpatiallyCloseRoutesRuinStrategy spatially_close_routes = 1;
 
  144    RandomWalkRuinStrategy random_walk = 2;
 
  145    SISRRuinStrategy sisr = 3;
 
  149// The ruin composition strategies specifies how ruin are selected at every ILS
 
  151message RuinCompositionStrategy {
 
  153    // Unspecified value.
 
  156    // Execute all ruin strategies sequentially in the same order provided in
 
  158    RUN_ALL_SEQUENTIALLY = 1;
 
  160    // Execute all ruin strategies in a random order.
 
  161    RUN_ALL_RANDOMLY = 2;
 
  163    // Execute a randomly selected ruin.
 
  164    RUN_ONE_RANDOMLY = 3;
 
  168// Parameters to configure a perturbation based on a ruin and recreate approach.
 
  169message RuinRecreateParameters {
 
  170  // List of ruin strategies determining how a reference solution is ruined.
 
  171  repeated RuinStrategy ruin_strategies = 1;
 
  173  // The composition strategy to use when combining the given 'ruin_strategies'.
 
  174  // Has no effect when ruin_strategies is composed of a single strategy.
 
  175  RuinCompositionStrategy.Value ruin_composition_strategy = 2;
 
  177  // Strategy defining how a reference solution is recreated.
 
  178  FirstSolutionStrategy.Value recreate_strategy = 3;
 
  180  // Ratio in [0, 1] of non start/end nodes to consider as neighbors for the
 
  181  // identification of routes spatially close to a non start/end seed node.
 
  183  // In particular, given a non start/end seed node s served by route r, we say
 
  184  // that a route r' is spatially close to the seed node s if there is at
 
  185  // least one non start/end node s' among the neighbors of s, such that s' is
 
  188  // The neighbors_ratio is coupled with the corresponding min_neighbors and
 
  189  // max_neighbors values, defining the minimum and maximum number of neighbor
 
  190  // nodes considered for a given seed node:
 
  191  // num_neighbors = min(max_neighbors,
 
  192  //          max(min_neighbors, neighbors_ratio * NUM_NON_START_END_NODES))
 
  194  // Neighbors ratio, and minimum and maximum number of non start/end neighbor
 
  195  // nodes for the identification of spatially close routes.
 
  196  optional double route_selection_neighbors_ratio = 4;
 
  197  optional uint32 route_selection_min_neighbors = 5;
 
  198  optional uint32 route_selection_max_neighbors = 6;
 
  201// Defines how a reference solution is perturbed.
 
  202message PerturbationStrategy {
 
  204    // Unspecified value.
 
  207    // Performs a perturbation in a ruin and recreate fashion.
 
  208    RUIN_AND_RECREATE = 1;
 
  212// The cooling schedule strategy defines how to compute the current simulated
 
  213// annealing temperature t given
 
  214// - the initial temperature t0
 
  215// - the final temperature t1
 
  216// - the current search progress 0 <= p <= 1
 
  218// The value of t0 and t1 is defined by the initial_temperature and
 
  219// final_temperature in SimulatedAnnealingParameters, respectively.
 
  221// The search progress p is derived, at any given time, by the search limits.
 
  222// In particular, p measures how far we are in the search process w.r.t. to the
 
  223// number of explored solutions and the time limit.
 
  225// The temperature t, computed according to one of the strategies defined below,
 
  226// together with the selected AcceptanceStrategy, is used to guide the search
 
  227// trajectory. In particular, given a neighbor solution S', generated by the
 
  228// the application of the perturbation and improvement step to a reference
 
  229// solution S, we have that S will be replaced by S' iff
 
  230//                  cost(S') + t * log(U(0, 1)) < cost(S)
 
  231// where U(0, 1) is a random number sampled from a uniform distribution of real
 
  233message CoolingScheduleStrategy {
 
  235    // Unspecified value.
 
  238    // Exponentially decreases the temperature as the search progresses.
 
  239    // More precisely, t = t0 * (t1/t0)^p.
 
  242    // Linearly decreases the temperature as the search progresses.
 
  243    // More precisely, t = t0 - p * (t0 - t1).
 
  248// Specifies the behavior of a simulated annealing acceptance strategy.
 
  249message SimulatedAnnealingParameters {
 
  250  // Determines the speed at which the temperature changes from initial to
 
  252  CoolingScheduleStrategy.Value cooling_schedule_strategy = 1;
 
  254  // The initial temperature. See CoolingScheduleStrategy for its usage.
 
  255  optional double initial_temperature = 2;
 
  257  // The final temperature. See CoolingScheduleStrategy for its usage.
 
  258  optional double final_temperature = 3;
 
  260  // Automatically define the value for the temperatures as follows.
 
  261  // First, a  reference temperature t is defined as
 
  262  //           w1 * c1 + w2 * c2 + ... + wK * cK
 
  263  // where 0 < wJ <= 1 is the fraction of vehicles of cost class J and cJ is the
 
  264  // average arc cost for the cost class J.
 
  265  // The value of cJ is identified by randomly sampling N arc costs for the cost
 
  266  // class J, where N is equal to the number of instance nodes.
 
  267  // The initial and final temperatures are then defined as
 
  268  // - initial_temperature: 0.1 * t
 
  269  // - final_temperature: 0.001 * t
 
  270  optional bool automatic_temperatures = 4;
 
  273// Determines when a neighbor solution, obtained by the application of a
 
  274// perturbation and improvement step to a reference solution, is used to
 
  275// replace the reference solution.
 
  276message AcceptanceStrategy {
 
  278    // Unspecified value.
 
  281    // Accepts only solutions that are improving with respect to the reference
 
  285    // Accepts a candidate solution with a probability that depends on its
 
  286    // quality and on the current state of the search.
 
  287    SIMULATED_ANNEALING = 2;
 
  291// Specifies the behavior of a search based on ILS.
 
  292message IteratedLocalSearchParameters {
 
  293  // Determines how a reference solution S is perturbed to obtain a neighbor
 
  295  PerturbationStrategy.Value perturbation_strategy = 1;
 
  297  // Parameters to customize a ruin and recreate perturbation.
 
  298  RuinRecreateParameters ruin_recreate_parameters = 2;
 
  300  // Determines whether solution S', obtained from the perturbation, should be
 
  301  // optimized with a local search application.
 
  302  optional bool improve_perturbed_solution = 3;
 
  304  // Determines when the neighbor solution S', possibly improved if
 
  305  // `improve_perturbed_solution` is true, replaces the reference solution S.
 
  306  AcceptanceStrategy.Value acceptance_strategy = 4;
 
  308  // Parameters to customize a simulated annealing acceptance strategy. These
 
  309  // parameters are required iff the acceptance_strategy is SIMULATED_ANNEALING.
 
  310  SimulatedAnnealingParameters simulated_annealing_parameters = 5;