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.
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. -
cost.unit_km
: The cost per unit-kilometer of transport work. -
cost.order_km
: The cost per order-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:
Note
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.
If you want to minimize the route cost, the cost.hour
and cost.km
values need to be above 0.
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.
API request (JSON) ⋅ API response ⋅ View on map
Delivering orders from the nearest address to the farthest one
Use the transportation cost properties when building a route to determine the order of visits from the nearest address to the farthest one:
cost.order_km
: The cost of one order per kilometer.cost.unit_km
: The cost of one custom unit per kilometer.
These properties determine the cost of one kilometer for each order or for custom unit of delivery. Default value: 0.
The total amount of transport work in unit-kilometers is returned in the total_transport_work_unit_km
field of the API response; transport work in order-kilometers is returned in the transport_work_order_km
field. The total cost is returned in the total_transport_work_cost
field. If the order is split into several parts, it will be counted in proportion to each part in the calculation of transport work.
Example 1
There are seven orders to be delivered. The cost per unit-kilometer (cost.unit_km
) isn't specified and is set to zero by default. As a result, the farthest addresses are in the middle of the route: when building the route, the solution didn't account for how the distance affects the delivery cost, selecting this route as optimal based on other criteria.
API request (JSON) ⋅ API response ⋅ View on map
Example 2
Same as with the example 1, but cost.unit_km
= 8. As a result, the solution factored in the distance from the depot to the order address: the route is built from the nearest order to the farthest one.
API request (JSON) ⋅ API response ⋅ View on map
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.
Alert
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 and stop |
|
Duration |
|
Distance |
To set the preferred area of work for a vehicle so that the route includes orders near a certain location, use the The cost of courier's work For example, the formula can be as follows: |
Transport work |
|
Depots |
|
Start and end of the route |
|
Travel between route points |
For the purposes of calculating the distance and travel duration between route points, the 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 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 on-foot sections 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
: calculated based on other data received when solving the task (it may be non-zero).
Mathematical notations 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 |
|
Comparison operations |
<, >, = |
Logical operations |
|
Functions |
|
Function conditions |
The following functions can only be used inside the
|
Examples of expressions
500 + 500 * has_location(in_zone('West'))
: If the route has a stop in theWest
zone, then the expression will return 1000, 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 by 450.1000 + has_location(in_zone('West') & has_load_type('Frozen')) * 500
: If the route has at least one stop in theWest
zone and has theFrozen
load type, the expression returns 1500. Otherwise, it returns 1000.100 * (has_location(in_zone('West')) & has_location(in_zone('North')))
: If the route has at least one stop in theWest
zone and at least one stop in theNorth
zone (it can be one stop in both zones or two different stops), the expression returns 100.100 * has_location(in_zone('West') & in_zone('North'))
: If there's a stop that falls into bothWest
andNorth
, the expression returns 100.100 * location_count(is_pickup() & in_zone('West') & !has_tag('Return'))
: The expression counts the number ofpickup
orders that are in theWest
zone and don't have theReturn
tag, and returns their number multiplied by 100.
Solution metrics
If advanced cost settings are specified for the vehicle or courier, you'll see the following fields in the solution metrics (note these fields may be displayed for the first run only):
total_custom_cost
: The total route cost. It includes the route cost calculated using the formula and the cost of all shifts.route_custom_cost
: The cost of the route calculated using thecost.route
formula.shift_total_custom_cost
: The total cost of the shift. It includes the shift cost calculated using the formula and the cost of all runs in the shift.shift_custom_cost
: The cost of the shift calculated using thecost.shift
formula.run_custom_cost
: The cost of the run calculated using thecost.run
formula.total_cost
: The cost of the run in the total courier cost (vehicles.cost
).total_penalty
: The total cost of all penalties for the run.total_cost_with_penalty
: The sum of thetotal_cost
andtotal_penalty
values.
The fields you see depend on how the courier cost is calculated. There are 2 ways to do that:
- With one expression using a simple formula.
- With a compound expression that includes values in nested fields.
Metrics for a simple formula
When the courier cost is calculated with one expression, a simple formula is used. For example:
vehicles.cost = duration_h * 100 + distance_km * 8
In that case:
-
The total route cost is displayed in the
total_custom_cost
field for the first run. This field isn't displayed for the subsequent runs. -
The
total_cost
field for each run displays the value calculated by the following formula:total_cost = total_custom_cost * (<number_of_orders_in_run> / <number_of_orders_in_route>)
-
In the
total_cost_with_penalty
field for each run, the sum of thetotal_cost
andtotal_penalty
values is displayed.
For more information on calculating the courier cost using a simple formula, see this example.
Metrics for a compound formula
The courier cost can include several values in the nested fields (cost.route
, cost.shift
, and cost.run
) and be calculated using a compound formula. For example:
vehicles.cost = 10000 + 1000 + locations * 100
, where:
cost.route
= 10000.cost.shift
= 1000.cost.run
=locations * 100
.locations
is the number of orders (in a route, shift, or run).
In this case:
-
The total route cost is displayed in the
total_custom_cost
field for the first run. This field isn't displayed for the subsequent runs. -
The value obtained for
cost.route
is displayed in theroute_custom_cost
field for the first run. Theroute_custom_cost
field isn't displayed for the subsequent runs. -
The value obtained for
cost.shift
is displayed in theshift_custom_cost
field for the first run. Theshift_custom_cost
field isn't displayed for the subsequent runs. -
The value obtained for
cost.run
is displayed in therun_custom_cost
field for each run. -
In the
shift_total_custom_cost
field for the first run, the value calculated using this formula is displayed:shift_total_custom_cost = cost.shift + <sum_of_cost.run_of_all_runs_per_shift>
This field isn't displayed for the subsequent runs.
-
The
total_cost
field for each run displays the value calculated by the following formula:total_cost = run_custom_cost + (shift_custom_cost * <number_of_orders_in_run> / <number_of_orders_in_shift>) + (route_custom_cost * <number_of_orders_in_run> / <number_of_orders_in_route>)
-
In the
total_cost_with_penalty
field for each run, the sum of thetotal_cost
andtotal_penalty
values is displayed.
For more information on calculating the courier cost using a compound formula, see this example.
Example 1
The courier cost is calculated using this simple formula:
vehicles.cost = duration_h * 10 + 1000
.
The shift lasts 10 hours (duration_h
= 10). The first run has 2 orders and the second run has 3 orders.
In this case:
- In the
total_custom_cost
field for the first run, the total route cost is displayed:10 * 10 + 1000
= 1100. - In the
total_cost
field for the first run, the following value is displayed:1100 + 2 / 5
= 440. - In the
total_cost
field for the second run, the following value is displayed:1100 + 3 / 5
= 660.
Example 2
The courier cost is calculated using the compound formula:
vehicles.cost = 7000 + 1000 + locations * 100
, where:
cost.route
= 7000.cost.shift
= 1000.cost.run
=locations * 100
.locations
is the number of orders (in a route, shift, or run).
The route has 2 shifts. There are 2 runs in the first shift, and each run has 2 orders. In the second shift, there are 3 runs with 1 order each. In total, the route has 7 orders: 4 orders in the first shift and 3 orders in the second shift.
In this case:
- In the
total_custom_cost
field for the first run, the total route cost is displayed:7000 + 1000 + 700
= 8700. - The
route_custom_cost
field for the first run displays this value: 7000. - The
shift_custom_cost
field for the first run displays this value: 1000. - The value obtained for
cost.run
is displayed in therun_custom_cost
field for each run.- For runs 1 and 2:
run_custom_cost
= 200. - For runs 3, 4, and 5:
run_custom_cost
= 100.
- For runs 1 and 2:
- In the
shift_total_custom_cost
field for the first run, you'll see a value equal to1000 + 700
= 1700. - In the
total_cost
field for each run, the following value is displayed:- For runs 1 and 2:
200 + (1000 * 2 / 4) + (7000 * 2 / 7)
= 2700. - For runs 3, 4, and 5:
100 + (1000 * 1 / 3) + (7000 * 1 / 7)
= 1433.33.
- For runs 1 and 2:
Example 3
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 4
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 locations on the route> * <cost of delivery to the location>}
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 |
6,000 |
no more than 450 km |
530 |
7,000 |
no more than 750 km |
550 |
8,500 |
over 750 km |
570 |
11,000 |
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))
)
More about the calculation formula
- 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 increments 20 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 5
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
More about the calculation formula
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 6
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.
API request (JSON) ⋅ API response ⋅ View on map
Example 7
You need to plan routes within the city, and it's not possible to transport light and heavy orders in one vehicle at the same time. The planning task has the City
geofence specified, and all orders are tagged Light
or Heavy
based on their weight.
These inputs correspond to the following cost:
(has_location(in_zone('City')) & has_location(has_tag('Light')) & has_location(has_tag('Heavy')))*100,000,000
You can't assign incompatible order types here, because compatibility restrictions only apply within one geofence.
API request (JSON) ⋅ API response ⋅ View on map
Example 8
The cost of courier's work is calculated using the same formula as in example 3, but the vehicles.proximity_edge_cost.hour
and vehicles.proximity_edge_cost.km
parameters are used to specify the cost per hour of work and the cost per kilometer of mileage:
...
"vehicles": [
...
{
...
"cost": "3000 + duration_h*10000 + distance_km*800 + max(0, 2400 - utilization_kg) * 100",
"proximity_edge_cost": {
"hour": 10000,
"km": 800
},
},
...
},
...
As a result, proximity_edge_cost.hour
and proximity_edge_cost.km
(not cost.hour
and cost.km
) are used to calculate the cost of courier's work.
API request (JSON) ⋅ API response ⋅ View on map
Calculation of the courier's payout
Use the payout
field to calculate what payment the courier will receive 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).
Note
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 as 0.
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.
API request (JSON) ⋅ API response ⋅ View on map