Reference

Input/output schema

A reference for the input and output schemas in vehicle routing.

Input

  • The format for timestamps should be RFC3339, e.g.: "2023-01-01T00:00:00Z".

The input schema is a JSON payload defining the vehicles, stops, and features for a given routing problem. Nextmv's tools are designed to operate directly on business data (in JSON) to produce decisions that are actionable by software systems. This makes decisions more interpretable and easier to test. It also makes integration with data warehouses and business intelligence platforms significantly easier. An input contains the following components:

Field nameRequiredData typeSI UnitDescriptionExample
vehiclesYesarray of vehicleNAVehicles to route.See vehicle
stopsYesarray of stopNAStops that will be routed and assigned to the vehicles.See stop
alternate_stopsNoarray of alternate_stopNAAlternate stops which can be serviced.{"alternate_stops": [{"id": "Inafuku","location": { "lon": 123, "lat": 456 }}]}
defaultsNoobjectNADefault properties for vehicles and stops.{"defaults": {"stops": {"duration": 1.23}}}
stop_groupsNoarray of array of stringNAGroup of stops that must be part of the same route.{"stop_groups": [["foo", "bar"], ["baz", "roh"]]}
duration_matrixNoarray of array of floatsecondsMatrix of durations between locations.{"duration_matrix": [[1.23, 4.56], [7.89, 0.12]]}
distance_matrixNoarray of array of floatmetersMatrix of distances between locations.{"distance_matrix": [[1.23, 4.56], [7.89, 0.12]]}
duration_groupsNoarray of duration_groupNADuration added when approaching the group.{"duration_groups": [{"group":["foo", "bar"], "duration": 200}]
custom_dataNoanyNACustom data to be used arbitrarily within the model.{"custom_data": {"foo": "bar"}}
optionsNoobjectNAArbitrary options.{"options": {"foo": "bar"}}

Here you can find a sample .json with the input schema:

{
  "defaults": {
    "vehicles": {
      "capacity": {
        "bunnies": 20,
        "rabbits": 10
      },
      "start_location": {
        "lat": 35.791729813680874,
        "lon": -78.7401685145487
      },
      "end_location": {
        "lat": 35.791729813680874,
        "lon": -78.7401685145487
      },
      "speed": 10
    },
    "stops": {
      "duration": 300,
      "quantity": {
        "bunnies": -1,
        "rabbits": -1
      },
      "unplanned_penalty": 200000,
      "target_arrival_time": "2023-01-01T10:00:00Z",
      "early_arrival_time_penalty": 1.5,
      "late_arrival_time_penalty": 1.5
    }
  },
  "stops": [
    {
      "id": "s1",
      "location": {
        "lon": -78.90919,
        "lat": 35.72389
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s2",
      "location": {
        "lon": -78.813862,
        "lat": 35.75712
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s3",
      "location": {
        "lon": -78.92996,
        "lat": 35.932795
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s4",
      "location": {
        "lon": -78.505745,
        "lat": 35.77772
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s5",
      "location": {
        "lon": -78.75084,
        "lat": 35.732995
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s6",
      "location": {
        "lon": -78.788025,
        "lat": 35.813025
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s7",
      "location": {
        "lon": -78.749391,
        "lat": 35.74261
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s8",
      "location": {
        "lon": -78.94658,
        "lat": 36.039135
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s9",
      "location": {
        "lon": -78.64972,
        "lat": 35.64796
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s10",
      "location": {
        "lon": -78.747955,
        "lat": 35.672955
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s11",
      "location": {
        "lon": -78.83403,
        "lat": 35.77013
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s12",
      "location": {
        "lon": -78.864465,
        "lat": 35.782855
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s13",
      "location": {
        "lon": -78.952142,
        "lat": 35.88029
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s14",
      "location": {
        "lon": -78.52748,
        "lat": 35.961465
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s15",
      "location": {
        "lon": -78.89832,
        "lat": 35.83202
      }
    },
    {
      "id": "s16",
      "location": {
        "lon": -78.63216,
        "lat": 35.83458
      }
    },
    {
      "id": "s17",
      "location": {
        "lon": -78.76063,
        "lat": 35.67337
      }
    },
    {
      "id": "s18",
      "location": {
        "lon": -78.911485,
        "lat": 36.009015
      }
    },
    {
      "id": "s19",
      "location": {
        "lon": -78.522705,
        "lat": 35.93663
      }
    },
    {
      "id": "s20",
      "location": {
        "lon": -78.995162,
        "lat": 35.97414
      }
    },
    {
      "id": "s21",
      "location": {
        "lon": -78.50509,
        "lat": 35.7606
      }
    },
    {
      "id": "s22",
      "location": {
        "lon": -78.828547,
        "lat": 35.962635
      },
      "precedes": ["s16", "s23"]
    },
    {
      "id": "s23",
      "location": {
        "lon": -78.60914,
        "lat": 35.84616
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ]
    },
    {
      "id": "s24",
      "location": {
        "lon": -78.65521,
        "lat": 35.740605
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ],
      "succeeds": "s25"
    },
    {
      "id": "s25",
      "location": {
        "lon": -78.92051,
        "lat": 35.887575
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ],
      "precedes": "s26"
    },
    {
      "id": "s26",
      "location": {
        "lon": -78.84058,
        "lat": 35.823865
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ]
    }
  ],
  "vehicles": [
    {
      "id": "vehicle-0",
      "start_time": "2023-01-01T06:00:00-06:00",
      "end_time": "2023-01-01T10:00:00-06:00",
      "activation_penalty": 4000,
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "vehicle-1",
      "start_time": "2023-01-01T10:00:00-06:00",
      "end_time": "2023-01-01T16:00:00-06:00",
      "max_duration": 21000,
      "compatibility_attributes": ["basic"]
    }
  ]
}
Copy

Alternate stop

An alternate stop has all the same fields as a stop excluding the following:

  • precedes
  • succeeds
  • compatibility_attributes

The id of the alternate stop is used as part of the alternate_stops field in the vehicle schema.

Defaults

The defaults schema defines the default values for all the vehicles and stops. Please go to each section to determine which fields are configurable as defaults.

Field nameRequiredData typeDescriptionExample
vehiclesNovehicleDefault values for the vehicle.{"vehicle": {"capacity": 5}}
stopsNostopDefault values for the stop.{"stop": {"duration": 123}}

Duration Group

A duration groups is used in the input schema.

Field nameRequiredData typeSI UnitDescriptionExample
groupYesarray of stringNAStop IDs contained in the group.{"group": ["foo", "bar"]}
durationYesintsecondsDuration to add when visiting the group.{"duration": 4}

Location

A location is used in the vehicle and stop schemas.

Field nameRequiredData typeDescriptionExample
lonYesfloatLongitude of the location.{"lon": 1.23}
latYesfloatLatitude of the location.{"lat": 4.56}

Stop

The target_arrival_time is used in the early_arrival_time_penalty and late_arrival_time_penalty features.

Field nameRequiredData typeSI UnitDescriptionExampleConfigurable via defaults
idYesstringNAUnique identifier for the stop.{"id": "foo"}
locationYeslocationNALocation of the stop.{"location": {"lon": 1.23, "lat": 4.56}}
precedesNoarray of string or stringNAStops that must be visited after this one on the same route.{"precedes": ["foo", "bar"]}
succeedsNoarray of string or stringNAStops that must be visited before this one on the same route.{"succeeds": ["foo", "bar"]}
quantityNoobject (string to int) or intNAQuantity of the stop.{"quantity": -1}
target_arrival_timeNotimestampNATarget arrival time at the stop.{"target_arrival_time": "2023-01-01T00:00:00Z"}
start_time_windowNoarray of timestamp or array of array of timestampNATime window in which the stop can start service.{"start_time_window": [["2023-01-01T12:00:00Z", "2023-01-01T12:05:00Z"], ["2023-01-01T12:30:00Z", "2023-01-01T13:35:00Z"]]}
max_waitNointsecondsMaximum waiting time at the stop.{"max_wait": 123}
durationNointsecondsDuration of the service time at the stop.{"duration": 123}
unplanned_penaltyNointNAPenalty for not planning the stop.{"unplanned_penalty": 123}
early_arrival_time_penaltyNofloatNAPenalty for arriving at the stop before the target arrival time.{"early_arrival_time_penalty": 1.23}
late_arrival_time_penaltyNofloatNAPenalty for arriving at the stop after the target arrival time.{"late_arrival_time_penalty": 1.23}
compatibility_attributesNoarray of stringNAAttributes that the stop is compatible with.{"compatibility_attributes": ["foo", "bar"]}
custom_dataNoanyNACustom data to be used arbitrarily within the model.{"custom_data": {"foo": "bar"}}

Vehicle

  • If the duration_matrix is not specified in the input, the speed must be present.
Field nameRequiredData typeSI UnitDescriptionExampleConfigurable via defaults
idYesstringNAUnique identifier for the vehicle.{"id": "foo"}
capacityNoobject (string to int) or intNACapacity of the vehicle.{"capacity": {"bar": 2}}
start_levelNoobject (string to int) or intNAInitial capacity of the vehicle.{"start_level": {"bar": 2}}
start_locationNolocationNALocation where the vehicle starts.{"start_location": {"lon": 1.23, "lat": 4.56}}
end_locationNolocationNALocation where the vehicle ends.{"end_location": {"lon": 1.23, "lat": 4.56}}
min_stopsNointNAMinimum stops that a vehicle should visit.{"min_stops": 8}
min_stops_penaltyNofloatNAPenalty for not complying with minimum stops.{"min_stops_penalty": 1000}
speedNofloatmeters/secondSpeed of the vehicle.{"speed": 1.23}
start_timeNotimestampNATime when the vehicle starts its route.{"start_time": "2023-01-01T00:00:00Z"}
end_timeNotimestampNALatest time at which the vehicle ends its route.{"end_time": "2023-01-01T00:00:00Z"}
compatibility_attributesNoarray of stringNAAttributes that the vehicle is compatible with.{"compatibility_attributes": ["foo", "bar"]}
max_stopsNointNAMaximum number of stops that the vehicle can visit.{"max_stops": 2}
max_distanceNointmetersMaximum distance that the vehicle can travel.{"max_distance": 123}
max_durationNointsecondsMaximum duration that the vehicle can travel.{"max_duration": 123}
max_waitNointsecondsMaximum aggregated waiting time that the vehicle can wait across route stops.{"max_wait": 123}
stop_duration_multiplierNofloatNAMultiplier on a stop's duration.{"stop_duration_multiplier": 1.23}
activation_penaltyNointNACost of using the vehicle.{"activation_penalty": 1.23}
alternate_stopsNoarray of stringNAAlternate stops IDs to service for the vehicle.{"alternate_stops": ["foo", "bar"]}
initial_stopsNoarray of initial_stopNAInitial stops planned on the vehicle.{"initial_stops": [{"id": "bar"}]}
custom_dataNoanyNACustom data to be used arbitrarily within the model.{"custom_data": {"foo": "bar"}}

Here you can find additional definitions used in the vehicle schema:

  • initial_stop

    Field nameRequiredData typeDescriptionExample
    idYesstringUnique identifier for the stop.{"id": "foo"}
    fixedNoboolWhether the stop is fixed or not.{"fixed": true}

Input schema Validation

The Nextmv SDK runner implements automatic schema validation for:

  • correctly named fields,
  • unknown fields,
  • invalid data types.

This validation applies to any input passed to the runner including custom input.

If you prefer to turn off schema validation, you can add the run.InputValidate argument.

    runner := run.CLI(solver.Solver, run.InputValidate[run.CLIRunnerConfig, schema.Input, solver.Options, schema.Output](nil))
Copy

Output

The output schema defines the solution to the routing problem, in addition to the options that were used and summary statistics, all in JSON format. The output schema contains the following components.

Field nameAlways presentData typeSI UnitDescriptionExample
optionsYesoptionsNAOptions used to generate the solution.{"options": {"solve": {"iterations": 50}}}
solutionsYesarray of solutionNASolutions to the routing problem.{"solutions": []}
statisticsYesstatisticsNASummary statistics of the solution.{"statistics": {"total_cost": 123}}
versionYesobjectNAVersion of the Nextmv SDK used to generate the solution.{"version": {"sdk": "v1.2.3"}}

Here you can find a sample .json with the output schema:

{
  "options": {
    "format": {
      "disable": {
        "progression": true
      }
    },
    "model": {
      "constraints": {
        "disable": {
          "attributes": false,
          "capacity": false,
          "distance_limit": false,
          "groups": false,
          "maximum_duration": false,
          "maximum_stops": false,
          "maximum_wait_stop": false,
          "maximum_wait_vehicle": false,
          "precedence": false,
          "start_time_windows": false,
          "vehicle_end_time": false,
          "vehicle_start_time": false
        },
        "enable": {
          "cluster": false
        }
      },
      "objectives": {
        "cluster": 0,
        "early_arrival_penalty": 1,
        "late_arrival_penalty": 1,
        "min_stops": 1,
        "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
        }
      },
      "validate": {
        "disable": {
          "resources": false,
          "start_time": false
        },
        "enable": {
          "matrix": false,
          "matrix_asymmetry_tolerance": 20
        }
      }
    },
    "solve": {
      "duration": 10000000000,
      "iterations": 50,
      "parallel_runs": 1,
      "run_deterministically": true,
      "start_solutions": 1
    }
  },
  "solutions": [
    {
      "objective": {
        "name": "1 * vehicle_activation_penalty + 1 * vehicles_duration + 1 * unplanned_penalty + 1 * early_arrival_penalty + 1 * late_arrival_penalty",
        "objectives": [
          {
            "base": 4000,
            "factor": 1,
            "name": "vehicle_activation_penalty",
            "value": 4000
          },
          {
            "base": 34394.3133084774,
            "factor": 1,
            "name": "vehicles_duration",
            "value": 34394.3133084774
          },
          {
            "base": 1400000,
            "factor": 1,
            "name": "unplanned_penalty",
            "value": 1400000
          },
          {
            "factor": 1,
            "name": "early_arrival_penalty",
            "value": 0
          },
          {
            "base": 621271.1251366138,
            "factor": 1,
            "name": "late_arrival_penalty",
            "value": 621271.1251366138
          }
        ],
        "value": 2059665.4384450912
      },
      "unplanned": [
        {
          "id": "s22",
          "location": {
            "lat": 35.962635,
            "lon": -78.828547
          }
        },
        {
          "id": "s16",
          "location": {
            "lat": 35.83458,
            "lon": -78.63216
          }
        },
        {
          "id": "s23",
          "location": {
            "lat": 35.84616,
            "lon": -78.60914
          }
        },
        {
          "id": "s25",
          "location": {
            "lat": 35.887575,
            "lon": -78.92051
          }
        },
        {
          "id": "s24",
          "location": {
            "lat": 35.740605,
            "lon": -78.65521
          }
        },
        {
          "id": "s26",
          "location": {
            "lat": 35.823865,
            "lon": -78.84058
          }
        },
        {
          "id": "s4",
          "location": {
            "lat": 35.77772,
            "lon": -78.505745
          }
        }
      ],
      "vehicles": [
        {
          "id": "vehicle-0",
          "route": [
            {
              "arrival_time": "2023-01-01T06:00:00-06:00",
              "cumulative_travel_duration": 0,
              "end_time": "2023-01-01T06:00:00-06:00",
              "start_time": "2023-01-01T06:00:00-06:00",
              "stop": {
                "id": "vehicle-0-start",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_duration": 0
            },
            {
              "arrival_time": "2023-01-01T06:09:12-06:00",
              "cumulative_travel_distance": 5524,
              "cumulative_travel_duration": 552,
              "duration": 300,
              "end_time": "2023-01-01T06:14:12-06:00",
              "late_arrival_duration": 7752,
              "start_time": "2023-01-01T06:09:12-06:00",
              "stop": {
                "id": "s7",
                "location": {
                  "lat": 35.74261,
                  "lon": -78.749391
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 5524,
              "travel_duration": 552
            },
            {
              "arrival_time": "2023-01-01T06:28:29-06:00",
              "cumulative_travel_distance": 14094,
              "cumulative_travel_duration": 1409,
              "duration": 300,
              "end_time": "2023-01-01T06:33:29-06:00",
              "late_arrival_duration": 8909,
              "start_time": "2023-01-01T06:28:29-06:00",
              "stop": {
                "id": "s6",
                "location": {
                  "lat": 35.813025,
                  "lon": -78.788025
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8570,
              "travel_duration": 857
            },
            {
              "arrival_time": "2023-01-01T06:49:20-06:00",
              "cumulative_travel_distance": 23604,
              "cumulative_travel_duration": 2360,
              "duration": 300,
              "end_time": "2023-01-01T06:54:20-06:00",
              "late_arrival_duration": 10160,
              "start_time": "2023-01-01T06:49:20-06:00",
              "stop": {
                "id": "s5",
                "location": {
                  "lat": 35.732995,
                  "lon": -78.75084
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9510,
              "travel_duration": 951
            },
            {
              "arrival_time": "2023-01-01T07:05:29-06:00",
              "cumulative_travel_distance": 30292,
              "cumulative_travel_duration": 3029,
              "duration": 300,
              "end_time": "2023-01-01T07:10:29-06:00",
              "late_arrival_duration": 11129,
              "start_time": "2023-01-01T07:05:29-06:00",
              "stop": {
                "id": "s17",
                "location": {
                  "lat": 35.67337,
                  "lon": -78.76063
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 6688,
              "travel_duration": 668
            },
            {
              "arrival_time": "2023-01-01T07:34:43-06:00",
              "cumulative_travel_distance": 44835,
              "cumulative_travel_duration": 4483,
              "duration": 300,
              "end_time": "2023-01-01T07:39:43-06:00",
              "late_arrival_duration": 12883,
              "start_time": "2023-01-01T07:34:43-06:00",
              "stop": {
                "id": "s1",
                "location": {
                  "lat": 35.72389,
                  "lon": -78.90919
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 14543,
              "travel_duration": 1454
            },
            {
              "arrival_time": "2023-01-01T07:55:20-06:00",
              "cumulative_travel_distance": 54198,
              "cumulative_travel_duration": 5420,
              "duration": 300,
              "end_time": "2023-01-01T08:00:20-06:00",
              "late_arrival_duration": 14120,
              "start_time": "2023-01-01T07:55:20-06:00",
              "stop": {
                "id": "s2",
                "location": {
                  "lat": 35.75712,
                  "lon": -78.813862
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9363,
              "travel_duration": 936
            },
            {
              "arrival_time": "2023-01-01T08:19:08-06:00",
              "cumulative_travel_distance": 65484,
              "cumulative_travel_duration": 6548,
              "duration": 300,
              "end_time": "2023-01-01T08:24:08-06:00",
              "late_arrival_duration": 15548,
              "start_time": "2023-01-01T08:19:08-06:00",
              "stop": {
                "id": "s15",
                "location": {
                  "lat": 35.83202,
                  "lon": -78.89832
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11286,
              "travel_duration": 1128
            },
            {
              "arrival_time": "2023-01-01T08:43:25-06:00",
              "cumulative_travel_distance": 77046,
              "cumulative_travel_duration": 7705,
              "duration": 300,
              "end_time": "2023-01-01T08:48:25-06:00",
              "late_arrival_duration": 17005,
              "start_time": "2023-01-01T08:43:25-06:00",
              "stop": {
                "id": "s3",
                "location": {
                  "lat": 35.932795,
                  "lon": -78.92996
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11562,
              "travel_duration": 1156
            },
            {
              "arrival_time": "2023-01-01T09:02:48-06:00",
              "cumulative_travel_distance": 85682,
              "cumulative_travel_duration": 8568,
              "duration": 300,
              "end_time": "2023-01-01T09:07:48-06:00",
              "late_arrival_duration": 18168,
              "start_time": "2023-01-01T09:02:48-06:00",
              "stop": {
                "id": "s18",
                "location": {
                  "lat": 36.009015,
                  "lon": -78.911485
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8636,
              "travel_duration": 863
            },
            {
              "arrival_time": "2023-01-01T09:55:35-06:00",
              "cumulative_travel_distance": 114350,
              "cumulative_travel_duration": 11435,
              "end_time": "2023-01-01T09:55:35-06:00",
              "start_time": "2023-01-01T09:55:35-06:00",
              "stop": {
                "id": "vehicle-0-end",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_distance": 28668,
              "travel_duration": 2866
            }
          ],
          "route_duration": 14135,
          "route_stops_duration": 2700,
          "route_travel_distance": 114350,
          "route_travel_duration": 11435
        },
        {
          "id": "vehicle-1",
          "route": [
            {
              "arrival_time": "2023-01-01T10:00:00-06:00",
              "cumulative_travel_duration": 0,
              "end_time": "2023-01-01T10:00:00-06:00",
              "start_time": "2023-01-01T10:00:00-06:00",
              "stop": {
                "id": "vehicle-1-start",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_duration": 0
            },
            {
              "arrival_time": "2023-01-01T10:14:40-06:00",
              "cumulative_travel_distance": 8801,
              "cumulative_travel_duration": 880,
              "duration": 300,
              "end_time": "2023-01-01T10:19:40-06:00",
              "late_arrival_duration": 22480,
              "start_time": "2023-01-01T10:14:40-06:00",
              "stop": {
                "id": "s11",
                "location": {
                  "lat": 35.77013,
                  "lon": -78.83403
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8801,
              "travel_duration": 880
            },
            {
              "arrival_time": "2023-01-01T10:24:48-06:00",
              "cumulative_travel_distance": 11889,
              "cumulative_travel_duration": 1188,
              "duration": 300,
              "end_time": "2023-01-01T10:29:48-06:00",
              "late_arrival_duration": 23088,
              "start_time": "2023-01-01T10:24:48-06:00",
              "stop": {
                "id": "s12",
                "location": {
                  "lat": 35.782855,
                  "lon": -78.864465
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 3088,
              "travel_duration": 308
            },
            {
              "arrival_time": "2023-01-01T10:56:41-06:00",
              "cumulative_travel_distance": 28011,
              "cumulative_travel_duration": 2801,
              "duration": 300,
              "end_time": "2023-01-01T11:01:41-06:00",
              "late_arrival_duration": 25001,
              "start_time": "2023-01-01T10:56:41-06:00",
              "stop": {
                "id": "s10",
                "location": {
                  "lat": 35.672955,
                  "lon": -78.747955
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 16122,
              "travel_duration": 1612
            },
            {
              "arrival_time": "2023-01-01T11:17:11-06:00",
              "cumulative_travel_distance": 37310,
              "cumulative_travel_duration": 3731,
              "duration": 300,
              "end_time": "2023-01-01T11:22:11-06:00",
              "late_arrival_duration": 26231,
              "start_time": "2023-01-01T11:17:11-06:00",
              "stop": {
                "id": "s9",
                "location": {
                  "lat": 35.64796,
                  "lon": -78.64972
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9299,
              "travel_duration": 929
            },
            {
              "arrival_time": "2023-01-01T11:52:20-06:00",
              "cumulative_travel_distance": 55404,
              "cumulative_travel_duration": 5540,
              "duration": 300,
              "end_time": "2023-01-01T11:57:20-06:00",
              "late_arrival_duration": 28340,
              "start_time": "2023-01-01T11:52:20-06:00",
              "stop": {
                "id": "s21",
                "location": {
                  "lat": 35.7606,
                  "lon": -78.50509
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 18094,
              "travel_duration": 1809
            },
            {
              "arrival_time": "2023-01-01T12:34:43-06:00",
              "cumulative_travel_distance": 77830,
              "cumulative_travel_duration": 7783,
              "duration": 300,
              "end_time": "2023-01-01T12:39:43-06:00",
              "late_arrival_duration": 30883,
              "start_time": "2023-01-01T12:34:43-06:00",
              "stop": {
                "id": "s14",
                "location": {
                  "lat": 35.961465,
                  "lon": -78.52748
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 22426,
              "travel_duration": 2242
            },
            {
              "arrival_time": "2023-01-01T12:44:22-06:00",
              "cumulative_travel_distance": 80624,
              "cumulative_travel_duration": 8062,
              "duration": 300,
              "end_time": "2023-01-01T12:49:22-06:00",
              "late_arrival_duration": 31462,
              "start_time": "2023-01-01T12:44:22-06:00",
              "stop": {
                "id": "s19",
                "location": {
                  "lat": 35.93663,
                  "lon": -78.522705
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 2794,
              "travel_duration": 279
            },
            {
              "arrival_time": "2023-01-01T13:54:40-06:00",
              "cumulative_travel_distance": 119804,
              "cumulative_travel_duration": 11980,
              "duration": 300,
              "end_time": "2023-01-01T13:59:40-06:00",
              "late_arrival_duration": 35680,
              "start_time": "2023-01-01T13:54:40-06:00",
              "stop": {
                "id": "s13",
                "location": {
                  "lat": 35.88029,
                  "lon": -78.952142
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 39180,
              "travel_duration": 3918
            },
            {
              "arrival_time": "2023-01-01T14:18:14-06:00",
              "cumulative_travel_distance": 130935,
              "cumulative_travel_duration": 13094,
              "duration": 300,
              "end_time": "2023-01-01T14:23:14-06:00",
              "late_arrival_duration": 37094,
              "start_time": "2023-01-01T14:18:14-06:00",
              "stop": {
                "id": "s20",
                "location": {
                  "lat": 35.97414,
                  "lon": -78.995162
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11131,
              "travel_duration": 1113
            },
            {
              "arrival_time": "2023-01-01T14:37:18-06:00",
              "cumulative_travel_distance": 139380,
              "cumulative_travel_duration": 13938,
              "duration": 300,
              "end_time": "2023-01-01T14:42:18-06:00",
              "late_arrival_duration": 38238,
              "start_time": "2023-01-01T14:37:18-06:00",
              "stop": {
                "id": "s8",
                "location": {
                  "lat": 36.039135,
                  "lon": -78.94658
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8445,
              "travel_duration": 844
            },
            {
              "arrival_time": "2023-01-01T15:37:38-06:00",
              "cumulative_travel_distance": 172581,
              "cumulative_travel_duration": 17258,
              "end_time": "2023-01-01T15:37:38-06:00",
              "start_time": "2023-01-01T15:37:38-06:00",
              "stop": {
                "id": "vehicle-1-end",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_distance": 33201,
              "travel_duration": 3320
            }
          ],
          "route_duration": 20258,
          "route_stops_duration": 3000,
          "route_travel_distance": 172581,
          "route_travel_duration": 17258
        }
      ]
    }
  ],
  "statistics": {
    "result": {
      "custom": {
        "activated_vehicles": 2,
        "max_duration": 20258,
        "max_stops_in_vehicle": 10,
        "max_travel_duration": 17258,
        "min_duration": 14135,
        "min_stops_in_vehicle": 9,
        "min_travel_duration": 11435,
        "unplanned_stops": 3
      },
      "duration": 0.123200958,
      "value": 2059665.4384450912
    },
    "run": {
      "duration": 0.124943291,
      "iterations": 50
    },
    "schema": "v1"
  },
  "version": {
    "sdk": "VERSION"
  }
}
Copy

Objective

Field nameAlways presentData typeSI UnitDescriptionExample
nameYesstringNAName of the objective.{"name": "foo"}
objectivesNoarray of objectiveNATerms of the main objective.{"objectives": [{"name": "foo"}, {"name": "bar"}]}
factorYesfloatNAFactor of the objective.{"factor": 1.23}
baseYesfloatNABase value of the objective.{"base": 1.23}
valueYesfloatNAValue of the objective, equivalent to factor * base.{"value": 1.23}

Output stop

Field nameAlways presentData typeSI UnitDescriptionExample
idYesstringNAUnique identifier for the stop.{"id": "foo"}
locationYeslocationNALocation of the stop.{"location": {"lon": 1.23, "lat": 4.56}}
custom_dataNo, only if defined on the input stopanyNACustom data to be used arbitrarily within the model.{"custom_data": {"foo": "bar"}}

Output vehicle

Field nameAlways presentData typeSI UnitDescriptionExample
idYesstringNAUnique identifier for the vehicle.{"id": "foo"}
routeYesarray of planned_stopNAPlanned stops for the vehicle.See planned_stop
route_travel_durationYesintsecondsTotal travel duration of the route.{"route_travel_duration": 123}
route_durationYesintsecondsTotal duration of the route, including waiting times.{"route_duration": 123}
route_stops_durationNo, only if greater than zero.intsecondsTotal duration of the service times across all stops.{"route_stops_duration": 123}
route_waiting_durationNo, only if greater than zero.intsecondsTotal waiting time across all stops.{"route_waiting_duration": 123}
custom_dataNo, only if defined on the input vehicleanyNACustom data to be used arbitrarily within the model.{"custom_data": {"foo": "bar"}}

Planned stop

Field nameAlways presentData typeSI UnitDescriptionExample
stopYesoutput_stopNAStop that was planned.See output_stop
cumulative_travel_durationYesintsecondsCumulative travel duration of the route up to the stop.{"cumulative_travel_duration": 123}
travel_durationYesintsecondsTravel duration from the previous stop to the current stop.{"travel_duration": 123}
target_arrival_timeNo, only if defined on the input stoptimestampNATarget arrival time at the stop.{"target_arrival_time": "2023-01-01T00:00:00Z"}
arrival_timeNo, only if the input vehicle has start_timetimestampNAArrival time at the stop.{"arrival_time": "2023-01-01T00:00:00Z"}
start_timeNo, only if the input vehicle has start_timetimestampNATime at which the stop starts service.{"start_time": "2023-01-01T00:00:00Z"}
end_timeNo, only if the input vehicle has start_timetimestampNATime at which the stop ends service.{"end_time": "2023-01-01T00:00:00Z"}
waiting_durationNo, only if greater than zero.intsecondsWaiting time at the stop.{"waiting_duration": 123}
durationNo, only if greater than zero.intsecondsDuration of the service time at the stop.{"duration": 123}
early_arrival_durationNo, only if greater than zero.intsecondsDuration by which the vehicle arrived early at the stop.{"early_arrival_duration": 123}
late_arrival_durationNo, only if greater than zero.intsecondsDuration by which the vehicle arrived late at the stop.{"late_arrival_duration": 123}

Solution

Field nameAlways presentData typeSI UnitDescriptionExample
objectiveYesobjectiveNAObjective value of the solution.See objective
unplannedYesarray of output_stopNAUnplanned stops.See output_stop
vehiclesYesarray of output_vehicleNAVehicles with planned stops.See output_vehicle

Statistics

By default, all fields in statistics are always present. The -format.disable.progression option can be used to disable the result and series_data fields.

Field nameAlways presentData typeSI UnitDescriptionExample
resultNoresultNAFinal result of the solutions.See result
runYesrunNAInformation of the run.See run
schemaYesstringNASchema of the statistics.{"schema": "v1"}
series_dataNoseries_dataNAData series of solution values.See series_data

Here you can find additional definitions used in the statistics schema:

  • result

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration to get to the final result.{"duration": 0.123}
    valueYesfloatNAValue of the final result.{"value": 0.123}
    `customNoanyNACustom metrics specified in the custom app (see below).{"custom": {"activated_vehicles": 2,"unplanned_stops": 4}}
  • run

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration of the run.{"duration": 0.123}
  • series_data

    Field nameAlways presentData typeSI UnitDescriptionExample
    valueYesseriesNAValue of the data series.See series
    customNo, only if specifiedarray of seriesNACustom data in the series.See series
  • series

    Field nameAlways presentData typeSI UnitDescriptionExample
    nameYesstringNAName of the series.{"name": "foo"}
    data_pointsYesarray of data_pointNAData points of the series.See data_point
  • data_point

    Field nameAlways presentData typeSI UnitDescriptionExample
    xYesfloatNAX value of the data point.{"x": 0.123}
    yYesfloatNAY value of the data point.{"y": 0.123}

Add custom statistics

If you have a custom app, you may wish to add custom statistics to your result. You can do this by passing a computed statistic in to output.Statistics.Result.Custom. For example, if you want to add unplanned stop count as a custom statistic, you can:

  1. format the output using the nextroute factory formatter.
  2. Add custom unplanned stop count to the formatted solution output.

An example is shown below:

    output := factory.Format(ctx, options, solver, last)
    solution := output.Solutions[0].(schema.SolutionOutput)
    output.Statistics.Result.Custom = map[string]any{"unplanned": len(solution.Unplanned)}
Copy

Page last updated

Go to on-page nav menu