Vehicle properties
- Vehicle or courier ID
- Vehicle or courier capacity
- Vehicle properties
- Load handling time at depot
- Vehicle started not from the depot
- Start from one of several depots
- Additional loading at an intermediate depot
- Returning to a depot at the end of the route or run
- Start or end of the route as close to the depot as possible
- Vehicle or courier shifts
- Multiple vehicle runs per day
- Limit the number of stops per shift
- Maximum shift duration
- Maximum mileage per shift
- Route grouping
- Vehicle or courier cost
- Advanced cost settings
- Calculation of the courier's payout
- Vehicle tags
- Order incompatibility
- Geofences
- Transportation method
- Courier working mode
- Planned route
- Fixed part of the route
- Adjusting the vehicle's moving time
- Adjusting handling time
- Prompt delivery
- Trailers
- Minimum order weight for a vehicle
Orders in RouteQ can be delivered by regular vehicles or couriers traveling on foot or by public transit. Vehicles and couriers have a common set of properties.
The vehicles
field is used in the request to determine the vehicle or courier.
Vehicle or courier ID
Each vehicle or courier must have a unique numeric or string ID set in the id
field. The ID must be unique within a single service request. When exporting to Track & Trace, this identifier is used as the courier's username.
You can also specify the vehicle's or the courier's numeric or string ID from your tracking system in the ref
field and the courier's mobile phone number in the phone
field so that they can be contacted from Track & Trace.
Vehicle or courier capacity
In RouteQ you can define the vehicle capacity in terms of the maximum weight or cargo the vehicle/courier can transport over a single route.
To determine the vehicle or courier carrying capacity, use the capacity
field (you can specify just one option):
capacity.weight_kg
: Weight in kilograms or bulk weight.The volume, which is measured in cubic meters and set as the product of dimensions:
capacity.volume.width_m
: Width in meters.capacity.volume.depth_m
: Depth in meters.capacity.volume.height_m
: Height in meters.
If you don't know the dimensions, you can set the volume value in one field and enter
1
in the other fields.capacity.units
: Number of units (pallets, boxes, kegs).
For more information about weight determination, see Weight and volume.
Please note that if the order weight is set in kilograms or as a volume weight, the vehicle capacity must be set in the same units. Similarly, if the order weight is set as the number of units, the vehicle capacity must specify the maximum number of units in each vehicle.
Additionally, you can set the maximum load of a vehicle as a percentage of the specified load capacity. To do this, use the limits
request field:
limits.volume_perc
: A percentage of the value specified incapacity.volume.width_m
*capacity.volume.depth_m
*capacity.volume.height_m
.limits.weight_perc
: A percentage of the value specified incapacity.weight_kg
.limits.volume_perc
: A percentage of the value specified incapacity.volume
.
To indicate that overload is allowed relative to a given value, specify a value greater than 100. To leave spare load capacity, for example, to allow for the inaccurate estimation of order dimensions, specify a value less than 100. For example, a value of 110 allows for 10% overload and a value of 90 allows for a maximum load of 90% the specified load capacity.
The vehicle capacity (based on the limits
) is a hard restriction that won't be violated. Note that, when calculating the vehicle load, the system takes into account the orders for pickup and delivery. For more information, see Pickup and delivery.
You can use the vehicle capacity to indirectly manage the number of orders that should be added to it. For example, if you set the volume per order to 1 unit (regardless of the actual size of the order) and the vehicle capacity to 10 units, then each vehicle will be assigned no more than 10 orders.
Example
There are two vehicles with a load capacity of 1.5 tons (Vehicle 1) and 3 tons (Vehicle 2) and three orders for delivery with a weight of 1 ton, 1.2 tons, and 1.4 tons, respectively.
When optimizing routes, the 1.2-ton order is placed in Vehicle 1 and the 1-ton and 1.4-ton orders are placed in Vehicle 2.
Custom capacity units
Vehicle capacity in custom units.
The custom unit is set by two parameters:
capacity.custom.<sequential number>.name
: Name of the custom unit.capacity.custom.<serial number>.size
: Vehicle carrying capacity in custom units.
By default, carrying capacity in the capacity.custom.<sequential number>.size
parameter isn't limited.
You can set multiple custom units and assign any names to them.
The name of the custom unit for the vehicle should be the same as the one given for the order.
If custom capacity units are specified for orders or explicitly specified for some vehicles, but not for others, then the vehicles with unspecified units will be taken to have unlimited carrying capacity in custom units.
Example of filling out Excel file sheets for a custom price
parameter (order cost):
Order cost | |
---|---|
shipment_size.custom.0.name | shipment_size.custom.0.size |
price | 100 |
Order cost | |
---|---|
shipment_size.custom.0.name | shipment_size.custom.0.size |
price | 100 |
Total order cost | |
---|---|
capacity.custom.0.name | capacity.custom.0.size |
price | 1000 |
Total order cost | |
---|---|
capacity.custom.0.name | capacity.custom.0.size |
price | 1000 |
Example 1
This example shows the weight, volume, and number of cargo units. You can also set the order cost and the limit on the total order cost per vehicle using the location.shipment_size.custom
and vehicle.capacity.custom
parameters, respectively.
You can see that there are 2 vehicles transporting 1 order each. However, their weight, volume and number of units is small, because their order cost is close to the vehicle's limit.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The same as example 1, but the maximum number of orders that the courier can transport is also specified. The restriction is described using the parameters location.shipment_size.custom.0
and vehicle.capacity.custom.1
. Each vehicle can now carry no more than 5 orders.
You can see that the number of orders in three cars has changed. Now one vehicle carries one order, and orders cannot be added due to the total cost limit. For the rest, maximum utilization by total cost in each vehicle was achieved, and it was possible to maintain the limit on the number of orders.
Vehicle properties
You can specify vehicle properties in the vehicle.specs
field. The following parameters can be specified:
width
: Vehicle width in meters.height
: Vehicle height in meters.length
: Vehicle length in meters.max_weight
: Maximum vehicle weight in tons.max_weight_kg
: Maximum vehicle weight in kilograms (rounded up to the ton when addressing the planning task).
If you set the vehicle.specs.max_weight
and vehicle.specs.max_weight_kg
parameters simultaneously in the planning task, the solution will use vehicle.specs.max_weight
.
The minimum value is 0
for all the listed properties.
You can specify these parameters only for trucks (routing_mode = truck
).
Load handling time at depot
The loading or unloading time at the depot may depend both on orders and vehicle properties (for example, dimensions or equipment).
To specify the amount of additional time required for loading at the depot, use the vehicle.depot_extra_service_duration_s
parameter. The time is set in seconds.
The time assigned in the vehicle.depot_extra_service_duration_s
parameter is summed up with the depot handling time.
Example
2 vehicles with the same load capacity are delivering 13 large orders. The handling time at the depot depot.service_duration_s
is 5 minutes (300 seconds). Additional time is set for loading orders into a vehicle at the depot vehicle.depot_extra_service_duration_s
: 30 minutes (1800 seconds). As a result of planning, each vehicle will spend 35 minutes at the depot before starting their routes.
Vehicle started not from the depot
By default, vehicles and couriers start from the depot. However, sometimes they need to start the route from another point (for example, from their home or parking spot). That's a usual task in the case of sales representatives, service engineers, and other specialists who don't deliver goods, but provide services.
You can implement this requirement using the property vehicle.start_at
. In this case, the courier or vehicle will start their route from the specified point with the type garage
, rather than from the depot.
Visiting the depot before the start of the working day
At the beginning of the working day, couriers may need to visit the depot to get their orders there. Use the property vehicle.visit_depot_at_start
to enable this. If you specify true
, the courier or the vehicle must visit the depot before starting the delivery (this is default behavior). Otherwise, they can immediately start delivering orders. To learn more, see Start or end of the route at an arbitrary point.
Example 1
Delivery is carried out by three cars:
The first one starts the delivery from the depot.
The second one starts and ends the route without visiting the depot. The starting point for the courier is order 6, which has the
garage
type.The third one starts the route not from the depot, but from order 4 (the
garage
type), but must visit the depot before starting the delivery.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
Delivery is carried out by three cars:
The first one starts the delivery from the depot.
The second and the third vehicles start and end the route without visiting the depot. Orders 1 and 7 have the
pickup
type, and the algorithm selects them as the first route points.
Three separate routes are planned in the solution because of the orders' priorities.
Start from one of several depots
A courier can start from one of several depots. These depots have to be listed in the depot_id
field (depots that the courier can visit) or starting_depot_id
(depots from which the courier can start their route). These lists can overlap. If there are several depots, the algorithm will choose the optimal depot to start from.
If the fields depot_id
and starting_depot_id
are not entered for a courier, they start from the first depot in the depots
list.
If you use the delivery from one of several depots functionality, a courier will be able to pick up orders from any depot they can visit.
You can additionally set the allow_different_depots_in_route
and max_middle_depots
parameters for a courier. For more information, see Choosing the optimal depot to start from.
Additional loading at an intermediate depot
For a courier to be able to visit additional depots for reloading orders while following the route, set the allow_different_depots_in_route
= true
parameter. These depots have to be listed in the depot_id
field (depots that the courier can visit) or middle_depot_id
(depots for reloading). Depot lists can overlap. If there are orders in several depots, the algorithm will select the optimal depot for reloading.
If the courier can stop at intermediate depots for reloading only at the beginning of the route (before completing the first order), set depots_only_at_run_beginning
= true
(the default is false
).
You can additionally set the max_middle_depots
parameter for a courier. For more information, see Visiting an additional depot.
Returning to a depot at the end of the route or run
By default, the courier completes the route at the depot where they started. To allow the courier to visit several depots along the route, set allow_different_depots_in_route
= true
. In this case, the courier can end the route at a depot other than the first one.
Depots where a courier can end their route are specified in the depot_id
field (depots that the courier can visit) or ending_depot_id
field (depots from which the courier can complete their route). These lists can overlap. If there are several depots, the algorithm will choose the optimal depot to complete the route at.
To have the courier end the route at the same depot where they started, set finish_route_in_starting_depot
= true
(the default is false
). If the courier starts the route not from a depot (visit_depot_at_start
= false
), they are to return to the depot they stopped at during the second run of the route.
To have the courier end each run at the same depot where that run started, set finish_run_in_starting_depot
= true
(the default is false
). To allow the courier to change from depots between runs, set can_change_depot_between_runs
= true
(see Start of a new run from a different depot).
Parameters finish_route_in_starting_depot
= true
and finish_run_in_starting_depot
= true
are only viable if allow_different_depots_in_route
= true
.
If the courier doesn't have to return to the depot after all the orders are completed, use the return_to_depot
= false
option.
Example 1.1
Two couriers are to deliver two orders: one is a delivery
order that needs to be picked up from Depot 1, and the other one is a pickup
order to be delivered to Depot 2. The couriers can only make 1 run each, starting at any depot and ending the route at any depot. Both couriers are allowed to stop at different depots during one run, but they cannot stop at intermediate depots.
The solution uses only one courier: they leave Depot 1 after picking up the delivery
order, deliver it, pick up the pickup
order, and deliver it to Depot 2, where they end the route.
API request (JSON) ⋅ API response ⋅ View on map
Example 1.2
The same as in example 1.1, but the couriers need to end the route at the same depot where they started (finish_route_in_starting_depot
= true
).
The solution uses both couriers. Courier 1 leaves Depot 1 after picking up the delivery
order, delivers it, and returns to Depot 1. The second courier leaves Depot 2, picks up the pickup
order, and returns with it to Depot 2.
Returning to any point at the end of the route
If your work scenario needs to take into account the distance of the last order from the courier's parking spot (or home address, for example), you can implement it as follows:
Create a point with the
garage
type (thelocations.type
field). This point will only be used to end the routes.For a courier who needs to return “home” or to the “parking spot” at the end of their working day, enter the ID of this point in the
vehicle.finish_at
field.
In the solution, all vehicles or couriers that have the finish_at
property specified return to the specified point. If the option to return to the depot is enabled (vehicle.return_to_depot = true
), the route will first go the depot and then to the parking spot.
Example
The example below uses two vehicles with different load capacities and four orders with different weights. Two vehicles are used for delivery because of the weight restrictions. Vehicle 2 doesn't have to return to the depot after it delivers the last order.
Note that in the RouteQ response, vehicle 2 completes the route at the last order location.
Start or end of the route as close to the depot as possible
You can plan a route so that the courier starts or finishes on the order that is closest to or furthest from the depot. For example, if you expect to get new orders in the morning, then it would be better to start the route with the orders closest to the depot. That way, it will be easier for the courier to return to the depot to pick them up. On the other hand, by starting the route with the farthest order, the courier would finish closer to the depot in the evening.
If you are not using advanced cost settings, set the following parameters:
first_edges_penalty_factor
: A penalty for the distance from the depot to the first order, the default is0
. If the value is greater than0
, the algorithm minimizes this distance, and if the value is less than0
, it maximizes it.last_edges_penalty_factor
: A penalty for the distance from the depot to the last order, the default is0
. If the value is greater than0
, the algorithm minimizes this distance, and if the value is less than0
, it maximizes it.
If penalty values are high, routes may be suboptimal in terms of mileage. If penalty values are low, then the first or last order of a route may be selected in violation of any requirements provided it saves on mileage.
If you are using advanced cost settings, use the keywords from the Travel from or to the depot group.
Example
In the example below, there is 1 courier and 10 orders. Two penalties are set: first_edges_penalty_factor
= 2
and last_edges_penalty_factor
= -2
. Planning produces a route that begins with the order closest to the depot and ends with the furthest order.
Vehicle or courier shifts
You can define one or more work shifts for a vehicle. Use the vehicle.shifts
field to define the shifts.
A shift is a time range when the vehicle is allowed to operate. Shift time includes the loading time at the depot, traveling time, and handover time at order locations.
You can also restrict the maximum shift duration.
To use one or more shifts in Excel, define the following fields:
shifts.0.time_window
: The time window corresponding to the vehicle's operating hours.shifts.0.hard_window
: The hard time window flag.shifts.0.service_duration_s
: Time between shifts (in seconds). For example, it can be the time needed to replace the driver or exchange documents.
In the case of a soft time window, you can set additional penalties:
- For time window violation:
shifts.0.penalty.out_of_time.fixed
: A fixed penalty for one-time violation of the shift's time window.shifts.0.penalty.out_of_time.minute
: A penalty per minute of the shift's time window violation.
- For early departure:
shifts.0.penalty.early.fixed
: A fixed penalty for one-time start of work before the shift's time window.shifts.0.penalty.out_of_time.minute
: A penalty per minute of work start before the shift's time window.
- For late arrival:
shifts.0.penalty.late.fixed
: A fixed penalty for one-time work completion later than the shift's time window.shifts.0.penalty.late.minute
: A penalty per minute of work end after the shift's time window.
To limit permissible violations of the shift's time window, you can set a hard window around a soft one.
Note that to define multiple shifts, you need multiple Excel fields with an increasing numeric index.
For example, shifts.0.time_window
refers to the first shift, and shifts.1.time_window
refers to the second shift.
Example
The request to RouteQ includes one vehicle with three shifts (morning, afternoon, and evening) and three orders, of which one order has a delivery time in the morning, and two others in the evening.
Note that the RouteQ response will only use the morning and evening shifts, since there are no delivery orders for the day shift.
Multiple vehicle runs per day
By default, a vehicle or courier starts and ends their route at a depot, completing exactly one route during a working day (shift).
If a vehicle can return to the depot anytime during the work shift to pick up additional orders, limit the number of runs using one of the parameters:
vehicle.shifts.N.max_runs
: The maximum number of runs per shift.vehicle.max_runs
: The maximum number of runs for all a vehicle's shifts.
You can limit either the number of runs per shift or the total number of runs, but not both parameters at the same time.
If no shifts are set for a vehicle, then max_runs
is used as a limit on the total number of runs (1 by default).
max_runs
is specified for the vehicle, then this value is used as a limit for each shift (for example, the vehicle can perform all the runs in one shift). The number of vehicle runs can be lower than the number of shifts.max_runs
is specified for shifts, then the total number of runs is added up across shifts.max_runs
is not specified, then the vehicle can make as many runs as it has shifts (one run per shift).
If vehicle.max_runs
= 0
, then the number of shifts (if specified) or 1 (if no shifts are specified) is used instead.
If some shifts aren't used but are defined in the request, they're counted as 1 run.
Example
The example below uses one vehicle with the limited carrying capacity of 2 tons and three orders with a weight of 0.8 tons. The vehicle is allowed to do two runs. This means that after completing two orders, the vehicle can return to the depot to pick up and deliver another order.
Limit the number of stops per shift
When planning a route, you can specify the minimum and maximum number of stops in the route. This can be useful, for example, to limit the maximum vehicle workload per day or, on the contrary, make sure that the vehicle gets on the route with a certain minimum number of stops.
For this, RouteQ uses the minimal_stops
and maximal_stops
shift parameters. You can set the number of stops for each vehicle.
The restriction is not strict and may be violated. If the limit on the minimum number of stops is violated, a penalty applies. The penalty is specified in the following shift fields: penalty.stop_lack.fixed
(for making fewer stops than the minimum number) and penalty.stop_lack.per_stop
(for each stop missing under the minimum number).
In the same way, if the limit on the maximum number of stops is violated, a penalty applies. The penalty is specified in the following shift fields: penalty.stop_excess.fixed
(for making more stops than the maximum number) and penalty.stop_excess.per_stop
(for each stop above the maximum number).
Usually when you restrict the number of stops, the solution metrics degrade since the solution favors restrictions at the cost of the optimal route.
By default, the minimal_stops
limit applies to all specified vehicles. When you specify more vehicles than necessary, and the penalty.stop_lack
penalty value is too high, planning results may be suboptimal.
To limit the minimum number of stops per shift and build an effective route at the same time, use the ignore_min_stops_for_unused
option (see Counting the minimum number of stops only for couriers).
Example 1
In the example, the route is built for 3 vehicles that deliver to 15 points. Since there are no restrictions for the route, the route is built the usual way.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
This example has the same conditions as example 1, but sets the limit of 4 minimum stops per vehicle. As a result, the routes changed so that each vehicle visited at least 4 delivery locations.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
This example has the same conditions as example 1, but sets the limit of 5 maximum stops per vehicle. In the result, orders are distributed evenly among all vehicles, even though several orders are located next to each other and can be completed by one vehicle.
Maximum shift duration
Sometimes you may need to extend the courier's working hours. But you also need to limit the maximum shift length and set the window you want to fit into. Let's day you have a 14-hour time window for courier delivery (for example, from 8:00 to 22:00), but each courier shouldn't work more than 8 hours.
RouteQ helps you schedule shifts with hard time windows and preferred lengths. In this case, the courier's shift length doesn't affect the work start time. It only affects the time that they spend completing orders.
The maximum shift length can be set as a soft restriction shifts.N.max_duration_s
that can be violated for a penalty or as a hard restriction shifts.N.hard_max_duration_s
that can't be violated:
When planning with a soft restriction, the workload that doesn't fit into one courier's preferred shift is distributed among others or to the same courier, but with penalties for violating the shift length. All orders that can't be completed in
max_duration_s
are added to the route with the penalty specified in theshift.penalty.late
field (if applicable) or in theshift.penalty.out_of_time
field all other times. The total route penalty for violating the maximum shift length is shown in the API response in theovertime_penalty
field. If the estimated order cost including penalties is higher than the cost of completing the order by another courier, the order is handed over to another courier.- When planning with a hard restriction, the courier's shift never exceeds the
hard_max_duration_s
value.
If you use both restrictions, the hard one can't be less than the soft one. By default, max_duration_s
is 2 days, and hard_max_duration_s
is 30 days.
Example 1
Let's say the shift window shifts.N.time_window
is from 8:00 to 23:00. By default, routes will be built to use the minimum number of couriers.
If you specify max_duration_s
= 14400
, the load is distributed between couriers, and each of them works for approximately 4 hours (the shift length is set in seconds). Some couriers may still work more than 4 hours, because it's less costly to pay for extra hours than to hand over the order to another courier.
As a result of planning, orders are distributed among three couriers. One courier's shift went over 4 hours. The penalty amount is shown in the API response in the overtime_penalty
field.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The same as in Example 1, but with hard restrictions on the maximum shift length: hard_max_duration_s
= 14400
. When planning, all couriers are given shifts that are 4 hours or less. As a result, the number of couriers increased to 4.
Maximum mileage per shift
In some cases, you need to limit the mileage per vehicle. For example:
The planning includes hired cars, and their rate implies limited mileage.
You can assign specific vehicles for far-away points. Then you can limit the mileage for other vehicles.
The shifts.max_mileage_km
parameter determines the maximum vehicle mileage per shift. The entire mileage is taken into account, including:
Traveling from the depot or starting point to the first point from the order list.
Returning to the depot or end point of the route from the last point in the order list.
The restriction is soft: the algorithm may violate it. Penalties are set in the fields:
shifts.penalty.max_mileage.fixed
: A fixed penalty for exceeding the maximum mileage (1000 by default).shifts.penalty.max_mileage.km
: A penalty per each kilometer in excess of the maximum mileage (100 by default).
If the maximum mileage per run is critical to you, and the vehicle can do several runs per shift, create multiple identical shifts (see Example 2).
If the courier uses public transit, only the walking part of the route is returned as the mileage.
Example 1
The mileage limit per courier is 50 km. A big penalty is applied in case of violation. In the result, the planned mileage on any route doesn't exceed 50 km.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
There is one courier and each their run must be limited by 50 km. For this, the courier must have several shifts with the same time windows and mileage restrictions. The result includes 3 routes, each one less than 50 km long.
Route grouping
To set the preferred area of work for a vehicle so that the route includes orders near a certain location, use the global_proximity_attraction_point
parameter. In the parameter value, specify the location id
with the garage
type. This is used as a “hotspot”: the algorithm aims to reduce the total distance between orders on the route and this location.
The proximity of routes to the hotspot is determined by the options.global_proximity_factor
option: the greater its value, the denser the grouping. For more information about this option, see Grouped routes.
The maximum distance from the route locations to the “hotspot” is stored in the max_distance_to_attraction_point_m
parameter, which can be used to calculate the cost of the route. The total sum of distances from all orders to the “hotspot” on the route affects the penalty for insufficient route grouping.
- You can use the
global_proximity_factor
option to build grouped routes without setting a “hotspot”. This option only works for vehicles that don't have theglobal_proximity_attraction_point
parameter set. - By using geofences for vehicles, you can set restrictions on delivery zones. The geofence restriction can't be violated. In contrast, the route grouping settings are a more flexible tool.
Example 1
Three vehicles have to deliver 15 orders. The route is calculated based on the order weight and vehicle capacity. There are no other restrictions on the route.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The same as in example 1, but each courier has a set “hotspot” that shows their preferred area of work. As a result, the routes are more grouped. The maximum distance from the order to the “hotspot” on the route is 20,663 m.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
The same as in example 2, but one of the couriers has a different “hotspot”. Because orders are regrouped, the location of routes on the map has changed. The maximum distance from the order to the “hotspot” increased to 28,528 m.
Vehicle or courier cost
You can specify different cost-of-use components for each vehicle in the query to RouteQ. To set the cost-of-use for the vehicle or courier, use the optional vehicle.cost
field.
RouteQ lets you define the following main cost components:
cost.fixed
: The fixed cost-of-use for the vehicle.cost.hour
: The cost per hour of work.cost.km
: The cost per kilometer of mileage.cost.location
: The cost per visit of one order.cost.run
: The cost per run.cost.tonne_km
: The cost per ton-kilometer of transport work.
In this case, the cost at which the algorithm selects the optimal routing option is used. That's not the actual rate for using the vehicle, but rather the algorithm's settings.
You can also set the cost-of-use for the vehicle or courier as an arithmetic expression. For more information, see Advanced cost settings.
Cost values
Please note that some components of vehicle cost are already set by default:
cost.fixed = 3000
cost.hour = 100
cost.km = 8
They apply in the following cases:
If you use Excel and leave these fields blank.
If you make an API request and don't fill in the
vehicle.cost
field.
The default values often need to be adjusted. For example, adjust them in the following business cases:
Always set cost.hour
and cost.km
to values other than 0
, otherwise, the routes will be chaotic. That happens because the algorithm optimizes the total cost. If the cost per hour or kilometer equals 0
, the route will cost the same with any mileage.
The cost of a ton-kilometer of transport work
Heavily loaded vehicles use more fuel and wear out faster. That's why routes for transporting heavy goods need to be built in such a way that the vehicle travels the minimal possible distance while heavily loaded.
RouteQ uses the cost.tonne_km
property to do this. It determines the cost of one kilometer for each ton of cargo in the vehicle. Default value: 0
.
The total amount of transport work in ton-kilometers is returned to the total_transport_work_tonne_km
field of the API response, and its total cost is in the total_transport_work_cost
field.
Example 1
You need to deliver 3 cargos weighing 100
, 200
, and 2000
kg. The cost.tonne_km
cost per ton-kilometer is set to zero. As a result, the heaviest order was delivered last: the vehicle load wasn't taken into account when building the route, and based on other criteria, this option was optimal.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The source data is the same, but cost.tonne_km
= 8
. The resulting solution is optimized, taking the load into account: the heaviest order is unloaded first.
Advanced cost settings
You can set the cost-of-use for the vehicle or courier as an arithmetic expression. When planning, you can calculate the cost with one expression in the vehicles.cost
field or use multiple expressions in nested fields:
cost.route
: For a route.cost.shift
: For a shift.cost.run
: For a run.
If the vehicle.cost
field has formulas, then the algorithm calculates the cost-of-use for the vehicle or courier based only on these formulas. Standard cost components are included in the calculation only if they are explicitly specified in the formulas.
The expression can use keywords and mathematical notation given in the tables below. To check the expression, use an HTTP request.
Keywords for route parameters
Group | Keyword and explanation |
---|---|
Runs |
|
Shifts |
|
Orders |
|
Duration |
|
Distance |
|
Transport work | transport_work_tonne_km : The transport work, in ton-kilometers. |
Stops |
|
Depots | middle_depots : The number of intermediate depots on the route. |
Start and end of the route |
|
Travel from or to the depot |
These parameters are used to implement the same scenarios as those found in penalties for the start or end of the route as close to the depot as possible. |
Travel between orders |
|
Travel with and without orders |
|
Capacity |
|
Trailer |
|
Walking routes |
|
Group | Keyword and explanation |
---|---|
Runs |
|
Shifts |
|
Orders |
|
Duration |
|
Distance |
|
Transport work | transport_work_tonne_km : The transport work, in ton-kilometers. |
Stops |
|
Depots | middle_depots : The number of intermediate depots on the route. |
Start and end of the route |
|
Travel from or to the depot |
These parameters are used to implement the same scenarios as those found in penalties for the start or end of the route as close to the depot as possible. |
Travel between orders |
|
Travel with and without orders |
|
Capacity |
|
Trailer |
|
Walking routes |
|
Route metrics are calculated using the following formulas:
- total route duration
transit_duration_h
=walking_transit_duration_h
+driving_transit_duration_h
- total route length
distance_km
=walking_distance_km
+driving_distance_km
The calculation of variables that are used in routes with walking parts is influenced by the transportation method:
walking
: The entire route is traveled on foot, and the distancedriving_distance_km
and durationdriving_transit_duration_h
equal 0.transit
:driving_distance_km
=0
: It's assumed that the courier visited all orders on foot (there isn't enough data to calculate the distance traveled by public transport).driving_transit_duration_h
is calculated based on other data received when solving the problem (it may be non-zero).
Mathematical notation and functions
Mathematical notations | Explanation |
---|---|
Numbers | Integers (positive, negative), rational. Use a dot as a separator for decimals. |
Arithmetic operations | + , - , * , / |
Parentheses | (…) |
Mathematical functions |
|
Logical functions | bool() : Converts any nonzero real number to 1.0 , and zero number to 0.0 . |
Comparison operations | < , > , = |
Logical operations |
|
Functions |
|
Function conditions | The following functions can only be used inside the
|
Mathematical notations | Explanation |
---|---|
Numbers | Integers (positive, negative), rational. Use a dot as a separator for decimals. |
Arithmetic operations | + , - , * , / |
Parentheses | (…) |
Mathematical functions |
|
Logical functions | bool() : Converts any nonzero real number to 1.0 , and zero number to 0.0 . |
Comparison operations | < , > , = |
Logical operations |
|
Functions |
|
Function conditions | The following functions can only be used inside the
|
500 + 500 * has_location(in_zone('West'))
: If the route has a stop in theWest
zone, then the expression will return1000
, otherwise,500
.450 * location_count(in_zone('West') | in_zone('North'))
: Counts the number of stops in at least one of the two zones (West
,North
) and returns that number multiplied by450
.1000 + has_location(in_zone('West') & has_load_type('Freeze')) * 500
: If there's at least one stop in the route that's in theWest
zone and has theFreeze
load type at the same time, the expression returns1500
, otherwise,1000
.100 * (has_location(in_zone('West')) & has_location(in_zone('North')))
: If there's at least one stop in theWest
zone and at least one stop in theNorth
zone (there can be one stop in both zones or two different ones), the expression returns100
.100 * has_location(in_zone('West') & in_zone('North'))
: If there's a stop that's in theWest
andNorth
zones at the same time, the expression returns100
.100 * location_count(is_pickup() & in_zone('West') & !has_tag('Return'))
: The expression counts the number ofpickup
orders that are in theWest
zone and at the same time don't have theReturn
tag, and returns their number multiplied by100
.
Solution metrics
If the vehicle or courier have advanced cost settings set, you'll see the following fields in the solution metrics:
run_custom_cost
: The cost of the run calculated using thecost.run
formula.shift_custom_cost
: The cost of the shift calculated using thecost.shift
formula. Shown only for the first run of the shift.shift_total_custom_cost
: The total cost of the shift. It includes the cost of the shift calculated using the formula plus the cost of all the shift's runs. Shown only for the first run of the shift.route_custom_cost
: The cost of the route calculated using thecost.route
formula. Shown only for the first run of the route.total_custom_cost
: The full cost of the route, including the cost of the route calculated using the formula plus the cost of all the shifts. Shown only for the first run of the route, the other runs have it as0
.
Example 1
The task uses the following pricing plan:
The basic cost of one multi-order is 170 units.
The cost of a multi-order increases by 20 units every 100 kilometers.
The courier receives at least 4000 units per shift even if the number of orders is insufficient.
This pricing corresponds to the following cost: 100 * duration_h + 8 * distance_km + max(4000, (170 + 20 * Floor(distance_km / 100)) * unique_stops)
.
As a result, the cost of using each vehicle is at least 4000
. The cost in excess of the shift payment (or delivered orders) is formed based on the total time and route length.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
You need to plan a route, provided that the cost depends on the mileage and is determined using the formula:
<vehicle cost> = maximum {<minimum route cost>, <number of points on the route> * <cost of delivery to the point>}
The minimum route cost and cost of delivery to the point are indicated in the table:
Mileage | The cost of one multi-order (rubles) | The minimum route cost (rubles) |
---|---|---|
no more than 150 km | 510 | 6000 |
no more than 450 km | 530 | 7000 |
no more than 750 km | 550 | 8500 |
over 750 km | 570 | 11000 |
Mileage | The cost of one multi-order (rubles) | The minimum route cost (rubles) |
---|---|---|
no more than 150 km | 510 | 6000 |
no more than 450 km | 530 | 7000 |
no more than 750 km | 550 | 8500 |
over 750 km | 570 | 11000 |
When planning, the vehicle cost is calculated using the formula:
max(6000 + (distance_km > 150)*1000 + (distance_km > 450)*1500 + (distance_km > 750)*2500
, stops
*(510 + min(60, Ceil(max(0, distance_km - 150)/300)*20))
)
- The minimum route cost:
6000 + (distance_km > 150)*1000 + (distance_km > 450)*1500 + (distance_km > 750)*2500
- The number of points on the route is determined using the
stops
parameter. - The cost of delivery to the point is determined as follows. The minimum multi-order cost is
510
, the maximum possible addition to it is570 - 510 = 60
. It's important that the cost of multi-orders increases uniformly in increments20
for every 300 km of mileage. This can be represented using the formulaCeil(max(0, distance_km - 150)/300)*20
. Then the cost of delivery to the point, based on the data from the table, is equal to510 + min(60, Ceil(max(0, distance_km - 150)/300)*20))
.
As a result, vehicle 1 has a route length of more than 150 km, the number of stops is 18 (1 multi-order). The final cost is 9540. Vehicle 2 has a route length of no more than 150 km, the number of stops is 21 (1 multi-order). The total cost is 10,710.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
You need to plan the route so as to minimize underloading the vehicle. To do this, you can set an additional vehicle cost in the formula, provided that its load is below a certain limit. For example, when planning vehicles with a load capacity of 3000 kg, load them by at least 80%. Note that we assume that the remaining cost (per hour, per km, for the fact of use) will be set by default. The vehicle cost is calculated using the formula:
3000 + duration_h*100 + distance_km*8 + max(0, 2400 - utilization_kg) * 100
3000
, 100
, 8
in the first three summands are default values of the cost per use, per hour, and per kilometer, respectively. The formula adds the cost of 100 units for each underloaded kilogram from 2400.As a result, the algorithm will aim to load all vehicles by at least 80% (if possible).
API request (JSON) ⋅ API response ⋅ View on map
Example 4
You need to plan a route, which includes some retail chains that open earlier. The task uses the following pricing plan:
The base cost of the route is made up of the time spent and the distance traveled.
Routes should be started earlier to avoid morning traffic. To encourage this, a penalty for departing after 8 AM is added to the cost calculation formula.
This pricing corresponds to the following cost: 100 * duration_h + 8 * distance_km + 50 * (start_route_time_s > 28800)
As a result of planning, all vehicles arrive at the depot before 8 AM.
Calculation of the courier's payout
Calculating the payment the courier receives for completing the route. During planning, you can calculate payouts using one expression in the vehicle.payout
field or use multiple expressions in nested fields:
payout.route
: For a route.payout.shift
: For a shift.payout.run
: For a run.
In the expressions, you can use the same keywords and mathematical notation you use to calculate the cost of the route for the company (the vehicle.cost
field).
The vehicle.payout
field doesn't affect the route optimization, it's calculated after the planning task has been solved.
If the courier has the vehicle.payout
field set, you'll see the following fields in the solution metrics:
run_payout
: Payout for the run calculated using thepayout.run
formula.shift_payout
: Payout for the shift calculated using thepayout.shift
formula. Shown only for the first run of the shift.shift_total_payout
: Total payout for the shift. It includes the payout for the shift calculated using the formula plus the payout for all the shift's runs. Shown only for the first run of the shift.route_payout
: Payout for the route calculated using thepayout.route
formula. Shown only for the first run of the route.total_payout
: Full payout for the route, including the payout for the route calculated using the formula plus the payout for all the shifts. Shown only for the first run of the route, the other runs have it as0
.
If the payout
field is set for at least one courier, the planning results also have the total_payout
metric, which is the total amount to be paid to couriers.
Example 1
Two couriers are delivering 40 orders, each courier makes 2 runs. The couriers' cost for the company is set by the expression in the cost
field. For courier 1, the payout for the completed route is calculated using the expression in the payout
field: this amount is displayed in the metrics of the first run and is equal to 5000 units. For Courier 2, the payout is not calculated, so the total_payout
amount is also equal to 5000 units.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
Two couriers are delivering 40 orders. For Courier 1, the payout calculation is set as follows: starting the shift — 3000 units, each kilometer of the route — 10 units, each delivered order — 50 units. If they deliver more than 10 orders during the shift, they receive a bonus of 500 units. For Courier 2, the payout is not calculated.
As a result of planning, Courier 1 makes two runs and delivers 20 orders. For each run, run_payout
is applied (1232 and 1053 units), as well as shift_total_payout
for the shift (2785 units, including the shift_payout
bonus of 500 units) and route_payout
for the route (3000 units). In total, the courier gets total_payout
of 5785 units.
Excel file ⋅ API request (JSON) ⋅ API response ⋅ View on map
Vehicle tags
When you set up a vehicle or courier in a request to RouteQ, you can define the rules (or tags) for its compatibility with orders.
Compatibility rules may be required if a vehicle has special equipment that's necessary to fulfil a particular order, like an isothermal van for transporting food.
Vehicle and order compatibility rules (vehicle tags) are set in the following fields:
vehicle.tags
: The vehicle properties that can partially match the properties required to fulfill the order.vehicle.excluded_tags
: The vehicle properties that must not match the properties required to fulfill the order.
To set the order tags, use the location.required_tags
field in the request.
The order tags identify the vehicle characteristics that an order requires, whereas vehicle tags define the actual rules for compatibility of a particular vehicle with different orders.
Vehicle tags can be set as strings or regular expressions. Tags can be separated by commas in strings. In this case, the vehicle can deliver the order if at least one of the listed vehicle tags matches the order tag or if the order has no tags. Regular expressions are used to describe the more complex logic and vehicle/order compatibility rules.
RouteQ uses POSIX Extended regular expression syntax. You can test your regular expressions at Regex101.
Let's look at some real-life cases of using tags.
Example 1
Let's take a use case when a transportation company delivers food and drinks in small bulk quantities. Some foodstuff must be delivered in isothermal trucks only. At the same time, all drinks and some foodstuff can be delivered without refrigerators. In addition, some customers can only accept a cargo if a vehicle is equipped with a tail lift.
To set these order restrictions, specify the following tags in the location.required_tags
field:
TAIL_LIFT
: For orders that can only be unloaded if a vehicle is equipped with a tail lift.ISOTHERMAL_TRUCK
: For orders containing goods that require temperature-controlled transportation.NORMAL_TRUCK
: For orders that do not require special conditions of transportation.
To set vehicle features, use the following tags in the vehicle.tags
field:
TAIL_LIFT
: For vehicles equipped with a tail lift.ISOTHERMAL_TRUCK
: For isothermal vehicles.NORMAL_TRUCK
: For regular vehicles without an isothermal van.
A vehicle may have one or more tags, or it may not have any at all, depending on its actual configuration. The same rule applies to order tags.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
Let's take a use case when some orders have a restriction on the vehicle body height due to different height of unloading zones.
For example, there are orders with the restriction on body height of 2 meters, 2.3 meters, and 2.5 meters. Then they should have the appropriate tags: Max_200
, Max_230
, and Max_250
.
For the vehicles, tags are set in a more complex way, since a vehicle up to 2 meters high can deliver any orders, whereas a vehicle up to 2.8 meters high can only deliver some orders. That is, if you only use tags
, then at a vehicle's height:
Up to 2 meters, the
vehicle.tags
field will contain allMax_200
,Max_230
, andMax_250
values.From 2 to 2.3 meters, the
vehicle.tags
field will contain theMax_230
andMax_250
values.From 2 to 2.3 meters, the
vehicle.tags
field will contain theMax_250
value.More than 2.5 meters, the
vehicle.required_tags
field will be empty.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
Let's take a use case when some orders have a restriction on the arrival of vehicles with a certain load capacity (the OR condition applies when any of the corresponding vehicles is suitable).
For example, there are vehicles with different load capacity: 1, 3, 9, and 15 tons. Let's fix these characteristics using vehicle.tags
tags. Since you'll have to combine these tags when describing orders, let's set them using regular expressions: .*1TON.*
, .*3TON.*
, .*9TON.*
and .*15TON.*
(.*
means “any substring”).
The vehicle load capacity limit for some orders is from 1 to 15 tons, from 3 to 9 tons, and from 1 to 3 tons. This limit is set for the order by a string with a regular expression that includes tags of all suitable vehicles. That is, the location.required_tags
field will contain the following regular expressions at the required load capacity:
- From 1 to 15 tons:
##1TON##3TON##9TON##15TON##
. - From 3 to 9 tons:
##3TON##9TON##
. - From 1 to 3 tons:
##1TON##3TON##
.
The order tags in example 2 are set by a simple list, because the vehicle must have all the listed tags (AND condition). You have to set at least one of the order tags (OR condition) for the vehicle in example 3. To do this, you can use regular expressions or create separate tags for each possible combination of OR conditions.
Optional tags
When planning, you may sometimes need to consider which vehicles are best to use (or avoid) for certain orders. For example, it's better to give VIP orders to specially trained couriers.
For such requirements, there are optional tags. They're listed in the location.optional_tags
field. If preferences can't be met, they may be violated (for example, because of weight restrictions or delivery time). That's the difference between optional tags and required vehicle characteristics.
If you'd prefer to have vehicles used in a certain zone, set optional geofences for them.
You can use the location.optional_tags.value
tag weight to prioritize your preferences. Its value can be positive or negative. When planning, the optional tag is compared to the tags of the vehicle that is delivering the order. If the tag from location.optional_tags
matches a vehicle tag from the following lists:
vehicle.tags
:value
is deducted from the route cost.vehicle.excluded_tags
:value
is added to the route cost.
The value that optional tags add to the route cost is returned in the result.routes.metrics.total_optional_tags_cost
field (it can be negative).
Example
You need to deliver 10 orders, some of them have the following optional tags:
vip
: 6 orders. Its weight varies from100
to350
at different points.morning
: 3 orders. Its weight at all points is the same —500
.
One of the vehicles has vip
and morning
tags specified in the vehicle.excluded_tags
field. This means that it's best not to give vip
-tagged and morning
-tagged orders to this courier due to the late start time of the route.
As a result, in most cases the requirements aren't violated: five out of six vip orders are delivered by the courier that doesn't have any limits on the vip
tag. There are no violations related to the morning
tag.
But one vip order is scheduled for a vehicle with the vip
tag in excluded_tags
due to capacity restrictions. In the total_optional_tags_cost
field for this route, 100
is returned: using an “unsuitable” vehicle increased the cost by 100 units. The preference was violated for the order with the lowest location.optional_tags.value
weight.
Order incompatibility
Orders may have incompatible types, which you can set using the following parameters:
options.incompatible_load_types
: Sets order incompatibility for all vehicles in the same way. To learn more, see the Order incompatibility section.vehicle.incompatible_load_types
: Sets order incompatibility for a specific vehicle by enabling you to take vehicle features into account.vehicle.onboard_incompatible_load_types
: When this is set tofalse
(by default), order incompatibility remains in effect throughout the entire run, and when the value istrue
, then only while the orders are in the vehicle.
The vehicle.incompatible_load_types
parameter has a higher priority and completely redefines the options.incompatible_load_types
parameters for this vehicle.
For example, different temperature modes are required to transport milk and ice cream. If the vehicle has one compartment, it can transport either milk or ice cream. If the vehicle has two compartments with different temperature modes, it can transport milk and ice cream at the same time in different compartments. In this case, specify the order incompatibility vehicle.incompatible_load_types
for vehicles with one compartment. Don't use this parameter for vehicles with two compartments and don't specify incompatible types options.incompatible_load_types
for orders in general.
If orders are incompatible for reasons other than vehicle characteristics, set vehicle.onboard_incompatible_load_types
= true
. For example, if orders from competing companies shouldn't be transported at the same time, the courier will pick up and deliver each company's orders separately without stopping at a depot. This reduces mileage and time en route.
Example 1
The delivery consists of 4 addresses with the following order types:
Order 1 (
id = 1
):flowers
.Order 2 (
id = 2
):flowers
.Order 3 (
id = 3
):flowers
,sweets
.Order 4 (
id = 4
):flowers
,ice-cream
.
Flowers
and sweets
are incompatible for delivery in the same vehicle. Moreover, simultaneous delivery of flowers
and ice-cream
in vehicle 2 is prohibited, but simultaneous delivery of flowers
and sweets
is permitted. Then the solution will contain delivery of orders 2 and 4 in the first vehicle and delivery of orders 1 and 3 in the second vehicle.
API request (JSON) ⋅ API response ⋅ View on map
Example 2.1
You need to have 3 orders from different companies picked up and delivered. Orders 1 and 2 and orders 2 and 3 cannot be delivered together, because they belong to competing companies.
As a result of planning, the courier picks up and delivers orders 1 and 3, then returns to the depot to load and deliver order 2 as part of a new run.
API request (JSON) ⋅ API response ⋅ View on map
Example 2.2
The same as in example 2.1, but vehicle.onboard_incompatible_load_types
= true
.
As a result of planning, the courier picks up and delivers order 2, and then picks up and delivers orders 1 and 3 without visiting the depot. This means less mileage and time en route.
Geofences
You can set limits for vehicles by delivery zones. You can set zones that the vehicle can deliver orders to using the vehicles.allowed_zones
parameter:
The vehicle can deliver orders in any zone specified in the
allowed_zones
parameter.If you don't specify the availability zones, the vehicle can deliver orders without any limits.
The order can't be delivered if availability zones are specified for all vehicles, and the order location doesn't fall into any of them.
Set the zones forbidden for delivery using the vehicle.forbidden_zones
parameter. The vehicle can't deliver orders to any of the zones specified in the forbidden_zones
parameter.
If the order is located in the intersection of the permitted and forbidden zones, it can't be delivered: the forbidden_zones
parameter has a higher priority than the allowed_zones
parameter.
When orders are being assigned, geofence incompatibility is taken into account: both the global option and the values set for individual couriers. When planning routes, you can also cancel all limits related to geofences.
Example
This example shows 4 orders and 2 vehicles, 4 geofences are set in the interface. Coordinates automatically determine how orders pertain to geofences:
Order 1 — simultaneously in
zone1
andzone2
.Order 2 — in
zone1
.Order 3 — simultaneously in
zone2
andzone3
.Order 4 — in
zone4
.
The availability of geofences for vehicles determined:
vehicle.allowed_zones | vehicle.forbidden_zones | |
---|---|---|
Vehicle 1 | zone1 , zone2 | zone3 |
Vehicle 2 | Zones not determined | zone2 |
vehicle.allowed_zones | vehicle.forbidden_zones | |
---|---|---|
Vehicle 1 | zone1 , zone2 | zone3 |
Vehicle 2 | Zones not determined | zone2 |
As a result, Vehicle 1 delivers Orders 1 and 2, Vehicle 2 delivers Order 4. And Order 3 remains unallocated, because its address is located in the zones forbidden for both vehicles.
Optional geofences
When assigning orders to vehicles, you can make use of optional geofences, which have bonuses or penalties associated with visiting them. You can set one or more such geofences for each vehicle.
Optional geofences represent a soft restriction. They help designate zones that are preferred for delivery (high-priority and low-priority).
Optional geofences are set using the vehicle.optional_zones
array:
optional_zones.N.zone
: Name of the geofence.optional_zones.N.value
: If the value is greater than 0, the vehicle receives a bonus for visiting the specified geofence (the value of the parameter is deducted from the route cost), and if it's less than 0, a penalty (the value is added to the route cost).
Example 1
You need to deliver 10 orders with two vehicles. For the first vehicle, the South
optional geofence is set, and for the second one, North
. Visiting these geofences carries a bonus of 1000
units. As a result, the first vehicle delivers orders in the south, and the second one, in the north. Order 5 is an exception: it belongs to the South
geofence, but was delivered by the Courier north
vehicle.
Excel file ⋅ API request (JSON) ⋅ API response ⋅ View on map
Example 2
4 couriers have to deliver 27 orders. The city is divided into 4 optional geofences: Northwest
, Northeast
, Southwest
, and Southeast
. Each courier has been set one high-priority zone that carries a bonus, two low-priority zones, and one zone that carries a penalty. As a result of planning, couriers end up delivering orders in their high-priority zones. The exceptions are orders 18, 20, and 23 due to vehicle capacity limitations.
Excel file ⋅ API request (JSON) ⋅ API response ⋅ View on map
Incompatible geofences
You can set geofence incompatibility in order to prevent orders belonging to different delivery zones from ending up part of the same courier run.
Using the vehicles.incompatible_zones
parameter, the list of such zones can be set both for the entire solution and for a specific courier. Incompatible zones defined for the courier take precedence over globally defined zones. In order for the global restriction options.incompatible_zones
not to apply to the courier, set an empty list in the vehicles.incompatible_zones
field.
When planning in Excel, for the global zone incompatibility restriction not to apply to the courier, put a space in the incompatible_zones.N
cells for them (it corresponds to an empty list).
Example
Each of the three couriers must deliver 4 orders to different parts of the city: northwest, southwest, northeast, and southeast. These areas correspond to the following geofences defined during planning: Northwest
, Southwest
, Northeast
, Southeast
.
Global geofence incompatibility has been set: southern zones (Southwest
and Southeast
) are incompatible with the northern ones (Northwest
and Northeast
). Additionally, two couriers have the vehicles.incompatible_zones
parameter set for them: for the first courier, it contains an empty list, and for the second, it makes the western zones (Northwest
and Southwest
) incompatible with the eastern ones (Northeast
and Southeast
).
As a result of planning:
Courier 1
is unaffected by the global incompatibility, and all the 4 orders from different zones get included in their run.Courier 2
is subject to the zone incompatibility restrictions set for them in thevehicles.incompatible_zones
parameter: one run includes orders to the eastern zones, and the other, to the western ones.Courier 3
is subject to the global restrictions: orders to the southern and northern zones get assigned to different runs.
Transportation method
When building routes, it is assumed by default that a courier uses a passenger car for delivery (load capacity less than 2.5 tons). To specify delivery on foot, by truck, or by public transit, use the vehicle.routing_mode
parameter. If all couriers have the same delivery method, you can use the routing option options.routing_mode
.
The vehicle.routing_mode
parameter has a higher priority than the options.routing_mode
parameter.
Possible values:
driving
: The default method, routing for vehicles whose load capacity is less than 2.5 tons.truck
: Routing for trucks whose default load capacity starts at 2.5 tons. You can specify additional parameters in vehicle characteristics.walking
: A pedestrian route. The route uses only roads that can be walked.transit
: A route that includes traveling by public transit and walking from the public transit stop to the delivery location.
Example 1
The example below uses the transit
transportation method for all couriers. As a result, couriers deliver orders using public transit with optimal order allocation.
API request (JSON) ⋅ API response ⋅ View on map
For the built routes, the mileage is specified only for the distances that couriers walk. The distances traveled by public transit are taken into account for optimization purposes, but are not counted in metrics.
Example 2
The example below uses the transit
transportation method for one courier and the driving
method for another courier. Orders are distributed among couriers so that the vehicle delivers to locations situated further away from public transit stops or from each other.
Courier working mode
By default, the service plans a route only with stops that are necessary for cargo delivery. However, couriers often can't work without stopping: they need to have lunch breaks, and you must take these into account when you build routes. Moreover, on long-distance runs, drivers are required to make stops at certain intervals to meet the work and rest requirements.
To control the couriers' working mode, use the vehicle.rest_schedule.breaks
object. You can describe simple or complex patterns of rest and maintenance breaks and other activities.
Schedule templates
You can describe breaks separately for each courier or create templates for multiple couriers. Moreover, you can combine individual and template schedules.
To create a template, add the template_rest_schedules
parameter to options
and specify an array of schedules in it: [{"id": string, "breaks": [...]}]
.
To use the template, add the rest_schedule_id
parameter to vehicles
and specify id
of the schedule template from options
in it.
Break duration
You can set the break duration using the rest_duration_s
parameter mandatory for every break.
Parameter | Value | Example |
---|---|---|
rest_duration_s | Break duration in seconds. |
The break should last 10 minutes (600 seconds). |
Parameter | Value | Example |
---|---|---|
rest_duration_s | Break duration in seconds. |
The break should last 10 minutes (600 seconds). |
Break start conditions
The break start is indicated by the time range (from and to). You can set the break start in several ways that are indicated in the table below.
Parameter | Value | Example |
---|---|---|
work_time_range_from_start | Working hours from the start of the route. Includes: travel time, waiting time, and handling time at order locations and at the depots. The presence and duration of other breaks don't matter. |
Start the break no earlier than in 1 hour and no later than 3 hours after the start of the route. |
work_time_range_till_rest | Working hours from the last break (or from the start of the route if it's the first break). Includes: travel time, waiting time, and handling time at order locations and at the depots. |
Start the break no earlier than 2 hours and no later than 4 hours after the shift start (including arrival at the depot, handling time, periods of travel and waiting). |
travel_time_range | Travel time and waiting time from the start of the route. Handling time is not taken into account. |
Start the break no earlier than 1 hour and no later than 3 hours after the start of the route, taking into account periods and travel and waiting and without taking into account handling time at order locations and at the depots. |
continuous_travel_time_range | Travel time and waiting time from the completion of the previous order. Handling time is not taken into account. |
Start the break no earlier than in 2 hours and not later than after 3 hours of continuous travel. |
driving_time_range | Travel time from the start of the route. Waiting time and handling time are not taken into account. |
Start the break no earlier than 1 hour and no later than 3 hours from the start of the continuous travel. |
exact_time_range | Break start time. The break can't be repeated. The work start time, the presence and duration of other breaks don't matter. The break won't start if the route ends before the break start time. |
Start a break from 17:00 to 20:00. |
Parameter | Value | Example |
---|---|---|
work_time_range_from_start | Working hours from the start of the route. Includes: travel time, waiting time, and handling time at order locations and at the depots. The presence and duration of other breaks don't matter. |
Start the break no earlier than in 1 hour and no later than 3 hours after the start of the route. |
work_time_range_till_rest | Working hours from the last break (or from the start of the route if it's the first break). Includes: travel time, waiting time, and handling time at order locations and at the depots. |
Start the break no earlier than 2 hours and no later than 4 hours after the shift start (including arrival at the depot, handling time, periods of travel and waiting). |
travel_time_range | Travel time and waiting time from the start of the route. Handling time is not taken into account. |
Start the break no earlier than 1 hour and no later than 3 hours after the start of the route, taking into account periods and travel and waiting and without taking into account handling time at order locations and at the depots. |
continuous_travel_time_range | Travel time and waiting time from the completion of the previous order. Handling time is not taken into account. |
Start the break no earlier than in 2 hours and not later than after 3 hours of continuous travel. |
driving_time_range | Travel time from the start of the route. Waiting time and handling time are not taken into account. |
Start the break no earlier than 1 hour and no later than 3 hours from the start of the continuous travel. |
exact_time_range | Break start time. The break can't be repeated. The work start time, the presence and duration of other breaks don't matter. The break won't start if the route ends before the break start time. |
Start a break from 17:00 to 20:00. |
If there are multiple breaks, each range specifies the working range after the end of the previous break. For example, if the first break is 04:00–05:00
and the second break is 02:00–03:00
, the first break must start between 4 and 5 hours after work starts, and the second break must start between 2 and 3 hours after the end of the first break.
Break planning conditions
You can specify additional parameters: make a break mandatory or set the minimum working time for the break start.
Parameter | Value | Example |
---|---|---|
necessary_route_duration_s | The time from the start of the route after which a break must be made. Set in seconds. |
Be sure to start the break after 4 hours (14,400 seconds) have passed from the route start. |
route_duration_s | The parameter sets the minimum working time at which a break should be scheduled. If the total working time is less, a break isn't scheduled. Set in seconds. |
Start the break only if the route lasts at least 4 hours (14,400 seconds). |
Parameter | Value | Example |
---|---|---|
necessary_route_duration_s | The time from the start of the route after which a break must be made. Set in seconds. |
Be sure to start the break after 4 hours (14,400 seconds) have passed from the route start. |
route_duration_s | The parameter sets the minimum working time at which a break should be scheduled. If the total working time is less, a break isn't scheduled. Set in seconds. |
Start the break only if the route lasts at least 4 hours (14,400 seconds). |
Combining breaks conditions
Parameter | Value | Example |
---|---|---|
before_first_location | The possibility of combining a break with other breaks before the first order. The break can only be combined with the breaks whose types are specified in merge_with_types . |
The break will be combined with the last break before the first location where the break type is specified in |
after_last_location | The possibility of combining a break with other breaks after the last order. The break can only be combined with the breaks whose types are specified in merge_with_types . |
The break will be combined with the first break after the last location where the break type is specified in |
type | Break type. |
A “lunch” break. |
merge_with_types | The parameter sets which break types can be combined with the specified break. You can only use it in combination with after_last_location or before_first_location . |
You can combine this break with a lunch or a sleep break. |
Parameter | Value | Example |
---|---|---|
before_first_location | The possibility of combining a break with other breaks before the first order. The break can only be combined with the breaks whose types are specified in merge_with_types . |
The break will be combined with the last break before the first location where the break type is specified in |
after_last_location | The possibility of combining a break with other breaks after the last order. The break can only be combined with the breaks whose types are specified in merge_with_types . |
The break will be combined with the first break after the last location where the break type is specified in |
type | Break type. |
A “lunch” break. |
merge_with_types | The parameter sets which break types can be combined with the specified break. You can only use it in combination with after_last_location or before_first_location . |
You can combine this break with a lunch or a sleep break. |
Break place
Parameter | Value | Example |
---|---|---|
at_rest_place | An option to have some rest in a location with the rest_place type. If this option is enabled, either all breaks must be in such locations, or all breaks must be outside such locations. |
All breaks will take place in locations with the |
Parameter | Value | Example |
---|---|---|
at_rest_place | An option to have some rest in a location with the rest_place type. If this option is enabled, either all breaks must be in such locations, or all breaks must be outside such locations. |
All breaks will take place in locations with the |
For orders with the rest_place
type, you can specify compatibility with vehicles or orders of other types using geofences or the load_types parameter.
Break chains
The rest_schedule
can contain many independent breaks
break chains. Each chain can contain many breaks with special conditions. The start of a break in every chain depends only on the built route. It doesn't depend on breaks in other chains.
Example | Explanation | How to set |
---|---|---|
Chain 1: Rest for 15 minutes after every 3 hours of transit. Chain 2: Rest for 6 hours 8 hours after the shift started. | Breaks in chain 2 depend only on the shift start. They don't depend on the transit and rest schedule in chain 1. | |
Chain 1: Rest for 15 minutes after every 3 hours of transit. Chain 2: Rest for 6 hours after every 8 hours of transit. | The start of the break in chain 2 depends on the transit and rest schedule in chain 1. |
Example | Explanation | How to set |
---|---|---|
Chain 1: Rest for 15 minutes after every 3 hours of transit. Chain 2: Rest for 6 hours 8 hours after the shift started. | Breaks in chain 2 depend only on the shift start. They don't depend on the transit and rest schedule in chain 1. | |
Chain 1: Rest for 15 minutes after every 3 hours of transit. Chain 2: Rest for 6 hours after every 8 hours of transit. | The start of the break in chain 2 depends on the transit and rest schedule in chain 1. |
The order of chains doesn't matter, but you must specify breaks in one chain sequentially.
If the route is completed before the stop (for example, the route is completed in 3 hours, and the stop is scheduled after 4 hours), all the unmade stops are reset.
Example
The route is built with 30-minute rest breaks after 4–4.5 hours of work. 15 hours after the start of the route, a sleep break is planned. As a result, a sleep break is scheduled 1.5 hours after a rest break.
Penalties
In some cases, RouteQ can plan routes that violate the rest window. To apply penalties for such violations, use the fields penalty.late
and penalty.early
. If the penalty is higher than the savings resulting from the window violation, the route is planned without violations.
Parameter | Value | Example |
---|---|---|
penalty.early.fixed | Penalty for an early break start. |
Sets a penalty of 1000 for an early break. |
penalty.early.minute | Penalty for every minute of an early break. |
Sets a penalty of 17 for every minute of an early break. |
penalty.late.fixed | Penalty for a late break. |
Sets a penalty of 1000 for a late break. |
penalty.late.minute | Penalty for every minute of a late break. |
Sets a penalty of 17 for every minute of a late break. |
Parameter | Value | Example |
---|---|---|
penalty.early.fixed | Penalty for an early break start. |
Sets a penalty of 1000 for an early break. |
penalty.early.minute | Penalty for every minute of an early break. |
Sets a penalty of 17 for every minute of an early break. |
penalty.late.fixed | Penalty for a late break. |
Sets a penalty of 1000 for a late break. |
penalty.late.minute | Penalty for every minute of a late break. |
Sets a penalty of 17 for every minute of a late break. |
Repeat conditions
Parameter | Value | Example |
---|---|---|
repeatable | The parameter specifies that the break must be repeated. It can only be used for the last break in the chain. |
The break will be repeated before the shift end. |
Parameter | Value | Example |
---|---|---|
repeatable | The parameter specifies that the break must be repeated. It can only be used for the last break in the chain. |
The break will be repeated before the shift end. |
Example 1
We built a route with a lunch break after 4–5 hours of work in this example. As a result, the algorithm schedules a lunch stop for a courier.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
In this example, a route is built between Moscow and St. Petersburg with the first break after 4-4.5 hours, and then with breaks every 2 hours. The algorithm scheduled two breaks.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
For two couriers a break is set with the work_time_range_from_start
condition in 3–4 hours after the start of work, but only if the total duration route_duration_s
is at least 6 hours. The first courier finishes work in 5 hours, so they work without rest. The second courier works for more than 6 hours, so they get one break.
API request (JSON) ⋅ API response ⋅ View on map
Example 4
The courier delivers orders to a neighboring city and periodic breaks. Breaks are set every 60–80 minutes of the route (travel_time_range
) using the repeat condition repeatable
. As a result, the algorithm scheduled two breaks.
API request (JSON) ⋅ API response ⋅ View on map
Example 5
As in example 4, but the route lasts several days, and breaks are set for sleep every 12 hours:
The repeat condition
repeatable
is used.The minimum and maximum route duration before rest
travel_time_range
:"12:00–12:00"
.
API request (JSON) ⋅ API response ⋅ View on map
Example 6
10-minute breaks are set for every 55–60 minutes of continuous traveling continuous_travel_time_range
. As a result, a break is scheduled only between points where the travel time is more than 55 minutes.
API request (JSON) ⋅ API response ⋅ View on map
Example 7
For couriers, two breaks with the break start condition work_time_range_till_rest
are scheduled for 2–3 hours after the last break or start of work if this is the first break.
The first break is 20 minutes.
The second break is 30 minutes.
The first courier finishes work earlier and gets only the first break. The second courier works longer and gets both breaks.
Planned route
The user can specify which vehicle should deliver particular orders. This is useful:
For additional planning when you have pre-planned routes.
When the order requires a specific vehicle.
To specify pre-planned orders for the vehicle, use the vehicle.planned_route
option. This option has the following properties:
When planning, all orders that you specify in
vehicle.planned_route
can't be unallocated, even if strict restrictions are violated, such as vehicle capacity or time windows for whichhard_window = true
.By default, the order sequence set in
planned_route
isn't fixed. When re-planning, orders can be arranged in a new sequence.If you need to save the route that's specified in
planned_route
without saving changes (sequence changes and adding new orders), usevehicle.fixed_planned_route = true
.
For each order in planned_route
, be sure to specify the vehicle shift (even if the vehicle only has 1 shift).
If in planned_route
several shifts are specified, you can lock orders for shifts using the fix_planned_shifts
= true
option. By default, the value is false
.
If a courier arrives too early, delivery time of the order is determined by the vehicle.wait_if_early
parameter:
true
: The courier waits for the order time window to start (default value).false
: The courier handles the order as soon as they arrive.
If there is a hard time window for an order location.hard_window
= true
, the vehicle.wait_if_early
parameter value is true
.
In the planned_route
field, you can specify depots for reloading, which a courier needs to visit when traveling along the route.
Example 1
Both couriers had pre-planned orders in planned_route
. As a result, these orders were given to these two couriers.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
This example involves 1 vehicle that has orders linked to it via planned_route
. The total weight of the orders exceeds the vehicle capacity, but the route is still being planned (because orders specified in this option can't be unallocated). But the ask status is UNFEASIBLE
.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
Theoretically, 2 couriers could deliver all 20 orders without overload and without being late. But a fixed sequence is specified for courier 1 using the vehicle.fixed_planned_route = true
parameter, so they'll only deliver orders from this sequence. Courier 2 isn't limited by a strict plan, so they'll take as many orders as they can carry. Several orders will remain in the depot, despite the fact that courier 1 has the space and time.
API request (JSON) ⋅ API response ⋅ View on map
Example 4.1
2 couriers need to deliver 15 orders in 2 shifts. Using the planned_route
option, orders 1-8 are assigned to courier 1, and orders 9-15 to courier 2. At the same time, it's indicated that orders 1-4 and 9-12 must be delivered during the first shift, and orders 5-8 and 13-15 during the second shift. Since fix_planned_shifts
= false
and couriers manage to deliver all orders within one shift, the distribution of orders by shifts is not taken into account.
API request (JSON) ⋅ API response ⋅ View on map
Example 4.2
The conditions are the same as in example 4.1, but the option fix_planned_shifts
= true
. This means the shifts during which orders have to be delivered are taken into account.
The order is already in the vehicle
If the order is already in the vehicle, the courier can immediately start delivery. To run this scenario, specify the parameters in the planned_route
field:
Parameter | Description | Value |
---|---|---|
location.loaded_orders * | List of order id s with the delivery type, which are uploaded to locations. If the parameter isn't specified, you can pick up any orders at the location.You can bring any orders with the | id |
location.delivery_in_current_run * | All orders loaded at the locations must be serviced during the same run before the vehicle returns to the depot. | true / false |
planned_runs_first | The vehicle will visit all depots in Use if:
| true / false |
Parameter | Description | Value |
---|---|---|
location.loaded_orders * | List of order id s with the delivery type, which are uploaded to locations. If the parameter isn't specified, you can pick up any orders at the location.You can bring any orders with the | id |
location.delivery_in_current_run * | All orders loaded at the locations must be serviced during the same run before the vehicle returns to the depot. | true / false |
planned_runs_first | The vehicle will visit all depots in Use if:
| true / false |
* Specified for depots and orders of the garage
type.
Example
Several orders were loaded in the courier's vehicle last night. The courier doesn't have to pick them up at the depot. Therefore, the point of the garage
type is specified in the place where the courier will go.
The loaded_orders
parameter shows that orders 1 and 2 have been loaded. The courier can immediately deliver them to the destination.
The following parameters are also set in the conditions:
planned_runs_first = true
.delivery_in_current_run = true
for depot and garage.
The courier starts from the garage and immediately delivers orders 1 and 2. They then go to the depot to pick up orders 3 and 4, which they must deliver immediately after loading. After these two deliveries, the courier returns to the depot to pick up orders 5 and 6 and follows the route further.
Fixed part of the route
The visited_locations
feature is useful if:
The beginning of route must follow a particular path.
You need to change the start point when doing additional planning.
The route must be fixed for each courier individually.
To do this, specify the visited_locations
array in vehicles
and describe the points of the fixed route using the following parameters.
Parameter | Description |
---|---|
id * | Order ID from locations or depot ID from depots . Please note that the order and depot IDs must be different. |
shift_id | ID of the courier shift from vehicle.shifts . Determines the shift in which to serve this point. |
time | The time of departure from the point. If the first point of a fixed part of the route:
You can specify this parameter for several orders, so that the visit time is calculated according to the time specified in |
wait_if_early | The need to wait for the start of the time window in case of early arrival.
|
Parameter | Description |
---|---|
id * | Order ID from locations or depot ID from depots . Please note that the order and depot IDs must be different. |
shift_id | ID of the courier shift from vehicle.shifts . Determines the shift in which to serve this point. |
time | The time of departure from the point. If the first point of a fixed part of the route:
You can specify this parameter for several orders, so that the visit time is calculated according to the time specified in |
wait_if_early | The need to wait for the start of the time window in case of early arrival.
|
* Required parameter
Example 1
There are 5 orders in this example. The sequence of orders 1, 2, 3 is fixed in visited_locations
. Orders 4 and 5 can be delivered in any sequence.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
In visited_locations
, it's specified that the route must start with order 2 at 10:00.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
The order sequence 1, 2, 3 is set as in example 1. It's also specified that departure from order 1 must be at 08:20 and from order 3 at 11:00.
API request (JSON) ⋅ API response ⋅ View on map
Example 4
There are 8 orders in this example. The specified sequence is orders 1, 2, 3, then the depot, then order 4. The courier may deliver the remaining orders in any sequence.
Adjusting the vehicle's moving time
To calculate the speed of the vehicle when building a route, RouteQ uses Yandex Maps data about traffic and the speed specified in the request. Although the trucks usually move slower in traffic jams, some drivers drive more aggressively and arrive earlier than the calculated timeframes.
To compensate for such deviations, RouteQ has the travel_time_multiplier
option where you can specify a fractional value. If the value is 1
, the calculation is made for the vehicle with the expected average speed. At smaller values (for example, 0.8
), the calculation accounts for faster vehicles. At higher values (for example, 1.2
), the calculation accounts for slower vehicles.
The travel_time_multiplier
parameter only affects the vehicle speed. The handover time at the delivery point remains the same.
Example 1
In the example below, the routing request is sent without adjusting the transit time. As a result, the vehicle delivers the order in 4 hours and 20 minutes, with 3 hours and 40 minutes spent moving between the points.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The same as in example 1, but with the travel_time_multiplier
parameter set to 0.5
. In the resulting route, the courier delivers the order in 2 hours and 25 minutes, spending 1 hour and 45 minutes moving between the points. However, time spent on parking and handover remains unchanged.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
The same as in example 1, but with the travel_time_multiplier
parameter set to 2
. In the resulting route, the courier delivers the order in 7 hours and 58 minutes, spending 7 hours and 18 minutes moving between the points. Traveling the route takes more than twice as long as in example 1, because part of the route occurs at peak hours, and the vehicle can't drive at the maximum speed. Time spent on parking and handover remains unchanged.
Adjusting handling time
To the courier needs some time to hand over the order on arrival. This time includes parking, riding the elevator, handing over the delivery, and paperwork. RouteQ ensures that by using the order's service_duration
and shared_service_duration
fields. However, some couriers deliver goods faster than others. For example:
In the case of parallel planning for vehicles and couriers using public transport, couriers who travel by public transport don't have to spend time parking. As a result, they need lower handling time.
Some couriers are faster than others. Experienced couriers usually spend less time handing over orders.
To compensate for the difference in courier time, RouteQ has the service_duration_multiplier
and shared_service_duration_multiplier
options that affect the handling time for a specific courier. If the value is 1, the handling time is the same as in service_duration
or shared_service_duration
. If the value is less than 1, the handling time is lower. If the value is greater than 1, the handling time is higher.
The service_duration_multiplier
and shared_service_duration_multiplier
parameters only affect the handling time. The transit time between the points remains the same.
Example 1
In the example below, the routing request is sent without adjusting the handling time.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
In the example below, the same request is sent to RouteQ as in example 1, but with the service_duration_multiplier
parameter set to 0.5
. The calculated service order is half the time specified in example 1.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
In the example below, the same request is sent to RouteQ as in example 1, but with the service_duration_multiplier
parameter set to 2
. Handling time is twice as long as in example 1.
Prompt delivery
To build an optimal route, the algorithm minimizes the wait time between route points. But there are cases when it's useful to shift delivery to an earlier time. For example:
- You have to minimize the risk of late arrival.
- It's more comfortable for the courier to travel in the daytime.
To deliver goods as early as possible, use the penalty.arrival_after_start
penalty, which consists of two parameters:
average_h
: Sets the penalty amount for the average arrival time after the start of the time window. When using the option, we always recommend specifying this value.as_soon_as_possible
: Determines whether to start the route as early as possible. The parameter takes the valuetrue
orfalse
(by default). It is specified in addition toaverage_h
.
The algorithm can shift the start and arrival time of a vehicle only if the flexible start time is enabled for the depot.
If you don't use the penalty.arrival_after_start
penalty, the route will be built with the minimal wait time between points and the latest possible start time from the depot.
When using the penalty, the algorithm will build routes to start them earlier, provided it doesn't reduce quality.
If the route must start as early as possible (even if it causes additional waiting), specify penalty.arrival_after_start.as_soon_as_possible
= true
.
Example 1
The route includes 4 orders with different time windows. The earliest start of the time window for order 5 is 08:00. The courier starts from the depot at 11:02 and arrives at the first delivery point at 11:40. Order 5 is delivered at 12:59.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
The same data is used as in example 1, but the penalty is set for the average arrival time after the start of the time window using the penalty.arrival_after_start.average_h
parameter. The courier starts from the depot at 06:59, waits for 8 minutes, and then delivers the earliest order (order 5) at 08:00.
API request (JSON) ⋅ API response ⋅ View on map
Example 3
The same data is used as in example 2, but the penalty.arrival_after_start.as_soon_as_possible
= true
parameter is additionally set. The courier starts from the depot at 06:00, waits for 1 hour and 7 minutes, and delivers the earliest order (order 5) at 08:00.
Trailers
A trailer is a truck (tractor) with a trailer attached. You can place orders in the tractor and in the trailer, while one order can be loaded partially into the tractor and into the trailer.
To describe the trailer, use the trailer
object.
Field | Description |
---|---|
trailer.сapacity | The trailer carrying capacity is described by the fields:
It's added to the tractor capacity. |
trailer.capacity.custom | Amount of custom units a trailer can carry. Carrying capacity in custom units is set in "name": size format, where:
If the unit name is present in deliveries or other vehicles, but not in this one, the capacity is assumed to be unlimited. |
trailer.capacity.limits | The trailer loading limit is described by the fields:
|
trailer.capacity.volume | The trailer dimensions are described by the fields:
The values are expressed in meters. * Required parameter |
trailer.max_capacity_difference | The maximum difference in the load of a trailer and a tractor is described by the fields:
If one of the fields is omitted, there are no restrictions on it. There are physical restrictions on the difference in the load of a trailer and a tractor. If the tractor is empty, and the trailer is heavy, the vehicle becomes uncontrollable and the trailer can't go. |
trailer.max_capacity_difference.custom | The maximum permissible difference in the loaded number of custom units for a trailer and a tractor. The permissible difference in custom units is set in "name": size format where:
If the unit name is present in deliveries or other vehicles, but not in this one, there is no restriction. |
trailer.cost | The trailer cost is described by the fields:
It's added to the tractor cost if the trailer is used. |
trailer.decoupling_time_s | Time to decouple the trailer in seconds. Only for orders with the |
trailer.coupling_time_s | Time to couple the trailer in seconds. Only for orders with the |
trailer.rolling_cost | Penalty for each rolling* of cargoes from a trailer to a tractor. * Rolling means moving orders from a trailer to a tractor (to deliver them to non-accessible locations. See Using a trailer). |
trailer.rolling_time | The time to roll cargo from a trailer to a tractor is set in seconds. It can be described by the following fields:
If multiple time types are specified, use the one that spends the most time. If no type is specified, use only the fixed time.
|
Field | Description |
---|---|
trailer.сapacity | The trailer carrying capacity is described by the fields:
It's added to the tractor capacity. |
trailer.capacity.custom | Amount of custom units a trailer can carry. Carrying capacity in custom units is set in "name": size format, where:
If the unit name is present in deliveries or other vehicles, but not in this one, the capacity is assumed to be unlimited. |
trailer.capacity.limits | The trailer loading limit is described by the fields:
|
trailer.capacity.volume | The trailer dimensions are described by the fields:
The values are expressed in meters. * Required parameter |
trailer.max_capacity_difference | The maximum difference in the load of a trailer and a tractor is described by the fields:
If one of the fields is omitted, there are no restrictions on it. There are physical restrictions on the difference in the load of a trailer and a tractor. If the tractor is empty, and the trailer is heavy, the vehicle becomes uncontrollable and the trailer can't go. |
trailer.max_capacity_difference.custom | The maximum permissible difference in the loaded number of custom units for a trailer and a tractor. The permissible difference in custom units is set in "name": size format where:
If the unit name is present in deliveries or other vehicles, but not in this one, there is no restriction. |
trailer.cost | The trailer cost is described by the fields:
It's added to the tractor cost if the trailer is used. |
trailer.decoupling_time_s | Time to decouple the trailer in seconds. Only for orders with the |
trailer.coupling_time_s | Time to couple the trailer in seconds. Only for orders with the |
trailer.rolling_cost | Penalty for each rolling* of cargoes from a trailer to a tractor. * Rolling means moving orders from a trailer to a tractor (to deliver them to non-accessible locations. See Using a trailer). |
trailer.rolling_time | The time to roll cargo from a trailer to a tractor is set in seconds. It can be described by the following fields:
If multiple time types are specified, use the one that spends the most time. If no type is specified, use only the fixed time.
|
Sample trailer description in a request:
{ "trailer": { "capacity": { "weight_kg": 10000, "units": 200 }, "max_capacity_difference": { "units": 10, "weight_kg": 0 }, "cost": { "fixed": 1000, "km": 10 }, "decoupling_time_s": 300, "coupling_time_s": 300, "rolling_time": { "fixed_time_s": 3000 } } }
Copied to clipboard
For more information about using a tractor with a trailer, see Using a trailer.
Minimum order weight for a vehicle
To prevent a heavy truck from carrying a single small order across town, use the min_stop_weight
parameter. Using this parameter, you can specify the minimum total weight that a vehicle will deliver to a single location. This is relevant when planning freight transportation by vehicles of different capacity.
The restriction is soft: the algorithm may violate it. Penalties are set in the fields:
penalty.min_stop_weight.fixed
: A penalty for violating the minimum total weight for all orders in a single location (1000 by default).penalty.min_stop_weight.kg
: A penalty for each kilogram that the total order weight delivered to a single location (50 by default) is short.
For more information about using vehicles with different capacity, see Transport with different load capacities.
Example 1
Two vehicles with capacities of 1500 and 10,000 kg are delivering orders weighing 100, 500, 900, and 9000 kg. The large truck gets both light and heavy orders.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
For a vehicle with a capacity of 10,000 kg, the specified value of min_stop_weight
is 1000
. As a result, the larger vehicle only gets the order weighing 9000 kg.