Skip to content

Minimum route stops

Info

This feature is configurable via .json input, without the need for code customization and is available for both the Marketplace app and Platform. You can find a list of all available features.

Field name Required Data type SI Unit Defined on Example Configurable via defaults
min_stops No int NA vehicle {"min_stops": 8}
min_stops_penalty No float NA vehicle {"min_stops_penalty": 1000}

It may be useful to impose a minimum number of stops in a route to avoid routes that may be too short. This encourages higher vehicle utilization. This limit can be set via the min_stops feature on vehicles. The vehicle's starting and ending locations are not counted as stops. For every stop below the min_stops limit set on the vehicle, we incur a penalty as set by the min_stops_penalty.

The penalty is set using the following logic:

penalty_applied = (min_stops - route_stops)^2 * min_stops_penalty

Please note that the difference between the number of stops in the route and the minimum number of stops is squared. This is to ensure that the penalty increases exponentially as the number of stops decreases.

Here is an example defining minimum stops for vehicles. A sample output obtained after solving the problem is also shown.

{
  "options": {
    "min_stops": 1.0
  },
  "defaults": {
    "vehicles": {
      "speed": 20,
      "min_stops": 3,
      "min_stops_penalty": 1000
    },
    "stops": {
      "unplanned_penalty": 200000
    }
  },
  "stops": [
    {
      "id": "Fushimi Inari Taisha",
      "location": {
        "lon": 135.772695,
        "lat": 34.967146
      }
    },
    {
      "id": "Kiyomizu-dera",
      "location": {
        "lon": 135.78506,
        "lat": 34.994857
      }
    },
    {
      "id": "Nijō Castle",
      "location": {
        "lon": 135.748134,
        "lat": 35.014239
      }
    },
    {
      "id": "Kyoto Imperial Palace",
      "location": {
        "lon": 135.762057,
        "lat": 35.025431
      }
    },
    {
      "id": "Gionmachi",
      "location": {
        "lon": 135.775682,
        "lat": 35.002457
      }
    },
    {
      "id": "Kinkaku-ji",
      "location": {
        "lon": 135.728898,
        "lat": 35.039705
      }
    },
    {
      "id": "Arashiyama Bamboo Forest",
      "location": {
        "lon": 135.672009,
        "lat": 35.017209
      }
    }
  ],
  "vehicles": [
    {
      "id": "v1"
    },
    {
      "id": "v2"
    }
  ]
}
{
  "options": {
    "check": {
      "duration": 30000000000,
      "verbosity": "off"
    },
    "format": {
      "disable": {
        "progression": true
      }
    },
    "model": {
      "constraints": {
        "disable": {
          "attributes": false,
          "capacities": null,
          "capacity": false,
          "distance_limit": false,
          "groups": false,
          "maximum_duration": false,
          "maximum_stops": false,
          "maximum_wait_stop": false,
          "maximum_wait_vehicle": false,
          "mixing_items": false,
          "precedence": false,
          "start_time_windows": false,
          "vehicle_end_time": false,
          "vehicle_start_time": false
        },
        "enable": {
          "cluster": false
        }
      },
      "objectives": {
        "capacities": "",
        "cluster": 0,
        "distance": 0,
        "early_arrival_penalty": 1,
        "late_arrival_penalty": 1,
        "min_stops": 1,
        "stop_balance": 0,
        "travel_duration": 0,
        "unplanned_penalty": 1,
        "vehicle_activation_penalty": 1,
        "vehicles_duration": 1
      },
      "properties": {
        "disable": {
          "duration_groups": false,
          "durations": false,
          "initial_solution": false,
          "stop_duration_multipliers": false
        },
        "maximum_time_horizon": 15552000
      },
      "validate": {
        "disable": {
          "resources": false,
          "start_time": false
        },
        "enable": {
          "matrix": false,
          "matrix_asymmetry_tolerance": 20
        }
      }
    },
    "solve": {
      "duration": 10000000000,
      "iterations": 50,
      "parallel_runs": 1,
      "plateau": {
        "absolute_threshold": -1,
        "delay": 0,
        "duration": 0,
        "iterations": 0,
        "relative_threshold": 0
      },
      "run_deterministically": true,
      "solver": {
        "plan_group_size": {
          "delta": 0,
          "delta_after_iterations": 1000000000,
          "max_value": 2,
          "min_value": 2,
          "snap_back_after_improvement": true,
          "start_value": 2,
          "zigzag": true
        },
        "unplan_units": {
          "delta": 2,
          "delta_after_iterations": 125,
          "max_value": -1,
          "min_value": 2,
          "snap_back_after_improvement": true,
          "start_value": 2,
          "zigzag": true
        },
        "unplan_weights": "Vehicle:3,Island:1,Location:293"
      },
      "start_solutions": 1
    }
  },
  "solutions": [
    {
      "objective": {
        "name": "1 * vehicles_duration + 1 * unplanned_penalty + 1 * min_stops",
        "objectives": [
          {
            "base": 909.04663596676,
            "factor": 1,
            "name": "vehicles_duration",
            "value": 909.04663596676
          },
          {
            "factor": 1,
            "name": "unplanned_penalty",
            "value": 0
          },
          {
            "factor": 1,
            "name": "min_stops",
            "value": 0
          }
        ],
        "value": 909.04663596676
      },
      "unplanned": [],
      "vehicles": [
        {
          "id": "v1",
          "route": [],
          "route_duration": 0,
          "route_travel_duration": 0
        },
        {
          "id": "v2",
          "route": [
            {
              "cumulative_travel_duration": 0,
              "stop": {
                "id": "Fushimi Inari Taisha",
                "location": {
                  "lat": 34.967146,
                  "lon": 135.772695
                }
              },
              "travel_duration": 0
            },
            {
              "cumulative_travel_distance": 3280,
              "cumulative_travel_duration": 164,
              "stop": {
                "id": "Kiyomizu-dera",
                "location": {
                  "lat": 34.994857,
                  "lon": 135.78506
                }
              },
              "travel_distance": 3280,
              "travel_duration": 164
            },
            {
              "cumulative_travel_distance": 4481,
              "cumulative_travel_duration": 224,
              "stop": {
                "id": "Gionmachi",
                "location": {
                  "lat": 35.002457,
                  "lon": 135.775682
                }
              },
              "travel_distance": 1201,
              "travel_duration": 60
            },
            {
              "cumulative_travel_distance": 7320,
              "cumulative_travel_duration": 366,
              "stop": {
                "id": "Kyoto Imperial Palace",
                "location": {
                  "lat": 35.025431,
                  "lon": 135.762057
                }
              },
              "travel_distance": 2839,
              "travel_duration": 141
            },
            {
              "cumulative_travel_distance": 9096,
              "cumulative_travel_duration": 454,
              "stop": {
                "id": "Nijō Castle",
                "location": {
                  "lat": 35.014239,
                  "lon": 135.748134
                }
              },
              "travel_distance": 1776,
              "travel_duration": 88
            },
            {
              "cumulative_travel_distance": 12425,
              "cumulative_travel_duration": 621,
              "stop": {
                "id": "Kinkaku-ji",
                "location": {
                  "lat": 35.039705,
                  "lon": 135.728898
                }
              },
              "travel_distance": 3329,
              "travel_duration": 166
            },
            {
              "cumulative_travel_distance": 18177,
              "cumulative_travel_duration": 909,
              "stop": {
                "id": "Arashiyama Bamboo Forest",
                "location": {
                  "lat": 35.017209,
                  "lon": 135.672009
                }
              },
              "travel_distance": 5752,
              "travel_duration": 287
            }
          ],
          "route_duration": 909,
          "route_travel_distance": 18177,
          "route_travel_duration": 909
        }
      ]
    }
  ],
  "statistics": {
    "result": {
      "custom": {
        "activated_vehicles": 1,
        "max_duration": 0.123,
        "max_stops_in_vehicle": 7,
        "max_travel_duration": 0.123,
        "min_duration": 0.123,
        "min_stops_in_vehicle": 7,
        "min_travel_duration": 0.123,
        "unplanned_stops": 0
      },
      "duration": 0.123,
      "value": 0.123
    },
    "run": {
      "duration": 0.123,
      "iterations": 50
    },
    "schema": "v1"
  },
  "version": {
    "sdk": "VERSION"
  }
}