---
metadata:
  - name: generator
    content: Diplodoc Platform v5.19.6
alternate:
  - https://docs.routeq.com/doc/en/vrp/properties-of-vehicles-cost.md
  - https://docs.routeq.com/doc/tr/vrp/properties-of-vehicles-cost.md
title: RouteQ — vehicle properties — cost
---
> **Documentation Index:** Fetch the complete configuration index at https://docs.routeq.com/doc/en/llms.txt


# 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 {#cost}

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](#work-cost-optimization).

- `cost.unit_km`: The cost per [unit-kilometer of transport work](#work-cost-optimization).

- `cost.order_km`: The cost per [order-kilometer of transport work](#work-cost-optimization).

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](#custom-route-cost).


### Cost values  {#cost-value}

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:

- [Planning the load of your own couriers](https://docs.routeq.com/doc/en/vrp/examples-of-settings.md#own-couriers)

- [Transport with different load capacities](https://docs.routeq.com/doc/en/vrp/examples-of-settings.md#different-load-capacities)

- [Using your own and hired transport at the same time](https://docs.routeq.com/doc/en/vrp/examples-of-settings.md#own-and-hired-transport)

{% note info %}

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.

{% endnote %}

### Optimization of transportation costs {#work-cost-optimization}

Since transporting heavy cargo accelerates fuel consumption and vehicle wear, routes should be optimized to ensure the courier travels the shortest possible distance when under heavy load. 

To optimize the cost of transportation, open the **Vehicles** sheet and specify the following properties under **Cost of using a vehicle**:

- `cost.tonne_km`: The cost of one kilometer of travel for each ton of cargo in the vehicle.

- `cost.order_km`: The cost of one kilometer of travel for one order.

- `cost.unit_km`: The cost of one custom unit per kilometer.

The default value of all costs is 0.

The total cost of transportation is returned in the `total_transport_work_cost` field of the API response. 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**

You need to deliver 3 orders weighing 100, 200, and 2000 kg. The cost per ton-kilometer `cost.tonne_km` is zero. As a result, the heaviest order is delivered last: the route was built without factoring in vehicle load, and the resulting solution was optimal based on other criteria.

[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/9397b517-c419ae88-eb0b6516-38749812) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/9397b517-c419ae88-eb0b6516-38749812) ⋅ [View on map](https://yandex.com/courier/mvrp-map#9397b517-c419ae88-eb0b6516-38749812)

**Example 2**

Same example, but `cost.tonne_km` = 8. The resulting solution is optimized, taking the load into account: the heaviest order is unloaded first.

[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/a4c19c92-86de54ce-ad980bc4-f9974621) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/a4c19c92-86de54ce-ad980bc4-f9974621) ⋅ [View on map](https://yandex.com/courier/mvrp-map#a4c19c92-86de54ce-ad980bc4-f9974621)

**Example 3**

You need to complete 7 orders. The cost per unit-kilometer (`cost.unit_km`) isn't specified and is set to zero by default. As a result, the cost of delivery wasn't taken into account during planning, and this route was considered optimal based on other criteria.

[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/4cbce435-85e7157d-461a5d83-393b05d8) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/4cbce435-85e7157d-461a5d83-393b05d8) ⋅ [View on map](https://yandex.com/courier/mvrp-map#4cbce435-85e7157d-461a5d83-393b05d8)

**Example 4**

Same example, but `cost.unit_km` = 8. As a result, the solution is optimized and prioritizes orders located close to each other, decreasing the distance that the vehicle travels with a heavy load.

[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/64080945-92657383-c9576385-e3e5825c) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/64080945-92657383-c9576385-e3e5825c) ⋅ [View on map](https://yandex.com/courier/mvrp-map#64080945-92657383-c9576385-e3e5825c)

## Advanced cost settings {#custom-route-cost}

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.


{% note 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](#cost) are included in the calculation only if they are explicitly specified in the formulas.

{% endnote %}


Expressions support keywords and mathematical notations given in the tables below. To check the expression, use an [HTTP request](https://yandex.ru/routing/doc/en/vrp/redoc/index.html#operation/validateVehicleCostExpression).

**Keywords for route parameters**

#|
||**Group** | **Keyword and explanation**||
||Runs |
- `run_index_in_route`: The run number in the route, starting with 1. Only for runs.
- `run_count_in_route`: The number of runs in the route. Only for routes.
- `run_index_in_shift`: The run number in the shift, starting with 1. Only for runs.
- `run_count_in_shift`: The number of runs in the shift. Only for runs or shifts.
- `runs`: The number of runs. If the variable is used for a run, then its value is 1. For a shift, it's `runs` = `run_count_in_shift`, and for the entire route, `runs` = `run_count_in_route`.||
||Shifts |
- `shift_index_in_route`: The shift number in the route, starting with 1. Empty shifts are skipped and not counted.
- `shift_count_in_route`: The number of used (non-empty) shifts in the route.||
||Orders and stop |
- `locations`: The number of orders.
- `stops`: The number of stops, including all [types of orders](https://docs.routeq.com/doc/en/vrp/properties-of-orders.md#order-type) and visits to [cross-docking depots](https://docs.routeq.com/doc/en/vrp/properties-of-depot.md#depot-types) (adjacent points with the same coordinates are considered one stop).
- `unique_stops`: The number of stops with unique coordinates.
- `total_custom_value`: The sum of the `custom_value` field values ([additional order parameter](https://docs.routeq.com/doc/en/vrp/properties-of-orders.md#custom-value)) for all orders in a route.
- `max_custom_value`: The maximum value of the `custom_value` field for all orders in a route.
- `min_custom_value`: The minimum value of the `custom_value` field for all orders in a route.||
||Duration |
- `duration_h`: The total duration of routes, in hours.
- `transit_duration_h`: The duration of traveling.
- `service_duration_h`: The duration of handling orders.
- `wait_duration_h`: The waiting duration.
- `rest_duration_h`: The rest duration.||
||Distance |
- `distance_km`: The total length of routes, in km.
- `max_distance_from_depot_m`: The distance from the depot to the farthest location in the route.
- `max_distance_to_garage_m`: The maximum distance to a garage at the end of the route.
- `max_distance_to_attraction_point_m`: The maximum distance from the route locations to the hotspot specified in `global_proximity_attraction_point`. If the option isn't set, `max_distance_to_attraction_point_m` = 0.

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.<br><br>

The cost of courier's work `vehicles.cost` is made up of multiple components, including the cost per hour of work and the cost per kilometer of mileage. If the total cost of work is calculated using an arithmetic expression, you can use the `vehicles.proximity_edge_cost` option with the `km` and `hour` parameters. In this case, `proximity_edge_cost.km` and `proximity_edge_cost.hour` will be taken into account when calculating `vehicles.cost`. 

For example, the formula can be as follows: `vehicle.cost = 1000 + duration_h*10000 + distance_km*800 + …`. Then `proximity_edge_cost` should be set to the values equal to the factors at `duration_h` and `distance_km`: `hour` = 10000 and `km` = 800. For more information about using `proximity_edge_cost`, see the [example](#example-proximity-edge-cost).

||
||Transport work |
- `transport_work_tonne_km`: The transport work, in ton-kilometers.
- `transport_work_unit_km`: The transport work, in unit-kilometers.
- `transport_work_order_km`: The transport work, in order-kilometers.
||
||Depots |
- `middle_depots`: The number of intermediate depots on the route.||
||Start and end of the route |
- `start_route_time_s`: The start time of the route in seconds from the beginning of the day.
- `finish_route_time_s`: The end time of the route in seconds from the beginning of the day.||
||Travel between route points  |
- `first_edges_distance_km`: The length of the way from a depot or garage (`garage`-type point) to the first order of the run, in km.
- `first_edges_duration_h`: The duration of the way from a depot or garage to the first order of the run, in hours.
- `max_first_edges_distance_km`: The maximum length of the way from a depot or garage to the first order for all the runs of the route, in km.
- `max_first_edges_duration_h`: The maximum duration of the way from a depot or garage to the first order for all the runs of the route, in hours.
- `last_edges_distance_km`: The length of the way from the last order of the run to a depot or garage, in km.
- `last_edges_duration_h`: The duration of the way from the last order of the run to a depot or garage, in hours.
- `max_last_edges_distance_km`: The maximum length of the way from the last order to a depot or garage for all the runs of the route, in km.
- `max_last_edges_duration_h`: The maximum duration of the way from the last order to a depot or garage for all the runs of the route, in hours.
- `max_edge_distance_m`: The maximum distance between orders for all routes, in meters.
- `max_edge_duration_h`: The maximum duration of travel between orders for all routes, in hours.

For the purposes of calculating the distance and travel duration between route points, the `delivery`, `pickup`, and `drop_off` types are considered orders. Cross-docking depots are treated as regular depots. Parking spots (type: `parking`), anchor locations for trailers (`anchor`), and rest locations (`rest_place`) are ignored. For example, if route building results in an "order — parking spot — order" sequence, then the distance and travel duration are calculated directly between the two orders.

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](#edges).
||
||Travel with and without orders |
- `empty_distance_km`: The distance traveled without orders (empty runs), in km.
- `non_empty_distance_km`: The distance traveled with at least one order, in km.||
||Capacity |
- `utilization_cbm`: The maximum load capacity of the vehicle.
- `utilization_units`: The maximum order load capacity of the vehicle.
- `utilization_kg`: The maximum load weight of the vehicle.
- `min_free_units`: The minimum free space in the vehicle.
- `min_free_weight_kg`: The minimum free weight in the vehicle.
- `min_free_volume_cbm`: The minimum free volume in the vehicle.
- `total_weight_kg`: The total weight of transported cargo.
- `total_units`: The total amount of transported cargo.
- `total_volume_cbm`: The total volume of transported cargo.||
||Trailer |
- `trailer_used`: If a trailer is used on the route, `trailer_used` = 1. If it isn't used, `trailer_used` = 0.
- `trailer_duration_h`: The total duration of trailer use, in hours.
- `trailer_distance_km`: The distance traveled with the trailer, in km.||
||Walking routes |
- `walking_transit_duration_h`: The time spent walking.
- `driving_transit_duration_h`: The time spent driving.
- `walking_distance_km`: The distance the courier walked.
- `driving_distance_km`: The distance the courier drove.||
|#

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](https://docs.routeq.com/doc/en/vrp/routing-mode.md):

- `walking`: The entire route is traveled on foot, and the distance `driving_distance_km` and duration `driving_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 |
- `max()/min()`: With an arbitrary number of operands.
- `Round()`: Rounding to an integer.
- `Ceil()`: Rounding to a larger integer.
- `Floor()`: Rounding to a smaller integer.
- `Abs()`: Calculating the absolute value (modulus) of a number.
- `RoundTo()/CeilTo()/FloorTo()`: Rounding fractions to the digit that a user sets, for example, `(RoundTo(x, 100) == 100*Round(x/100))`.||
||Logical functions | `bool()`: Converts any nonzero real number to `1.0`, and zero number to `0.0`.||
||Comparison operations | <, >, = ||
||Logical operations |
- &: Logical AND.
- \|: Logical OR.
- ! : Logical negation.||
||Functions |
- `has_location(<condition>)`: Checks whether there's a stop in the route (run, shift) that matches the criteria.
- `has_order(<condition>)`: Checks whether there's an order (`pickup` or `delivery`) in the route (run, shift) that matches the criteria.
- `order_count(<condition>)`: Returns the number of orders (`pickup` or `delivery`) in the route (run, shift) that match the criteria.
- `stop_count(<condition>)`: Returns the number of stops (`pickup`, `delivery`, or `dropoff`) in the route (run, shift) that match the criteria. In a multi-order, all orders will be counted as one stop.
- `location_count(<condition>)`: Returns the number of stops of any type in the route (run, shift) that match the criteria. In a multi-order, each order will be counted as a separate stop.||
||Function conditions | The following functions can only be used inside the `has_location`, `has_order`, `order_count`, `stop_count`, and `location_count` function conditions:

- `in_zone(<zone name>)`: Checks if the stop is in the specified zone.
- `has_load_type(<load type name>)`: Checks if the order has the specified load type.
- `has_required_tag(<tag name>)`: Checks if the order has the specified required tag.
- `has_optional_tag(<tag name>)`: Checks if the order has the specified optional tag.
- `has_tag(<tag name>)`: Checks if the order has the specified tag (required or optional).
- `is_order()`: Checks if the stop is an order (`pickup` or `delivery`).
- `is_pickup()`: Checks if the stop is a `pickup` order.
- `is_delivery()`: Checks if the stop is a `delivery` order.||
|#

{% cut "Examples of expressions" %}

- `500 + 500 * has_location(in_zone('West'))`: If the route has a stop in the `West` 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 the `West` zone and has the `Frozen` 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 the `West` zone and at least one stop in the `North` 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 both `West` and `North`, the expression returns 100.
- `100 * location_count(is_pickup() & in_zone('West') & !has_tag('Return'))`: The expression counts the number of `pickup` orders that are in the `West` zone and don't have the `Return` tag, and returns their number multiplied by 100.

{% endcut %}

### Solution metrics {#custom-route-cost-metric}

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`: 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 the `cost.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 the `cost.shift` formula.
* `run_custom_cost`: The cost of the run calculated using the `cost.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 the `total_cost` and `total_penalty` values.

The fields you see depend on how the courier cost [is calculated](#custom-route-cost). There are 2 ways to do that:
* [With one expression](#custom-route-cost-metric-simple) using a simple formula.
* [With a compound expression](#custom-route-cost-metric-composite) that includes values in nested fields.

#### Metrics for a simple formula {#custom-route-cost-metric-simple}

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 the `total_cost` and `total_penalty` values is displayed.

For more information on calculating the courier cost using a simple formula, see [this example](#metrics-example-simple).

#### Metrics for a compound formula {#custom-route-cost-metric-composite}
       
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 the `route_custom_cost` field for the first run. The `route_custom_cost` field isn't displayed for the subsequent runs.
* The value obtained for `cost.shift` is displayed in the `shift_custom_cost` field for the first run. The `shift_custom_cost` field isn't displayed for the subsequent runs.
* The value obtained for `cost.run` is displayed in the `run_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 the `total_cost` and `total_penalty` values is displayed.

For more information on calculating the courier cost using a compound formula, see [this example](#metrics-example-composite).

**Example 1** {#metrics-example-simple}

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** {#metrics-example-composite}

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 the `run_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.
* In the `shift_total_custom_cost` field for the first run, the following value is shown: `1000 + 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.  

**Example 3**

The task uses the following pricing plan:

- The basic cost of one [multi-order](https://docs.routeq.com/doc/en/vrp/properties-of-orders.md#multi-orders) 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)](https://courier.yandex.ru/vrs/api/v1/log/request/ff1e1f6-6036d56b-b95a291a-7d9e4661) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/ff1e1f6-6036d56b-b95a291a-7d9e4661) ⋅ [View on map](https://yandex.com/courier/mvrp-map#b1537922-44e0fbcc-b82a1bee-28fd4c80)

**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))`)

{% cut "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 is `570 - 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 formula `Ceil(max(0, distance_km - 150)/300)*20`. Then the cost of delivery to the point, based on the data from the table, is equal to `510 + min(60, Ceil(max(0, distance_km - 150)/300)*20))`.

{% endcut %}

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)](https://courier.yandex.ru/vrs/api/v1/log/request/48924182-ec2944d-99909975-58a70bf8) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/48924182-ec2944d-99909975-58a70bf8) ⋅ [View on map](https://yandex.com/courier/mvrp-map#48924182-ec2944d-99909975-58a70bf8)

**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`

{% cut "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: <rated load capacity> * <minimum utilization threshold> = 3000 * 80% = 2400.

{% endcut %}

As a result, the algorithm will aim to load all vehicles by at least 80% (if possible).

[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/ebcfec83-e32bd98d-1284b873-aa773c10) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/ebcfec83-e32bd98d-1284b873-aa773c10) ⋅ [View on map](https://yandex.com/courier/mvrp-map#ebcfec83-e32bd98d-1284b873-aa773c10)

**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)](https://courier.yandex.ru/vrs/api/v1/log/request/3df139b9-6144ed47-4835df37-57d32dc7) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/3df139b9-6144ed47-4835df37-57d32dc7) ⋅ [View on map](https://yandex.com/courier/mvrp-map#3df139b9-6144ed47-4835df37-57d32dc7)

**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](#incompatible-load-types) here, because compatibility restrictions only apply within one geofence.


[API request (JSON)](https://courier.yandex.ru/vrs/api/v1/log/request/1916d976-7ec0744b-8aa0a012-5864559e) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/1916d976-7ec0744b-8aa0a012-5864559e) ⋅ [View on map](https://yandex.com/courier/mvrp-map#1916d976-7ec0744b-8aa0a012-5864559e)

**Example 8** {#example-proximity-edge-cost}

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:

```json
...
"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)](https://courier.yandex.ru/vrs/api/v1/log/request/91a5d1bb-7a55d16-951bc41d-de18446f) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/91a5d1bb-7a55d16-951bc41d-de18446f) ⋅ [View on map](https://yandex.com/courier/mvrp-map#91a5d1bb-7a55d16-951bc41d-de18446f)

## Calculation of the courier's payout {#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](https://docs.routeq.com/doc/en/vrp/properties-of-vehicles-cost.md#custom-route-cost) (the `vehicle.cost` field).


{% note info %}

The `vehicle.payout` field doesn't affect the route optimization, it's calculated after the planning task has been solved.

{% endnote %}


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 the `payout.run` formula.
- `shift_payout`: Payout for the shift calculated using the `payout.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 the `payout.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)](https://courier.yandex.ru/vrs/api/v1/log/request/64ee56f6-7d21664c-ff0649da-2a25636f) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/64ee56f6-7d21664c-ff0649da-2a25636f) ⋅ [View on map](https://yandex.com/courier/mvrp-map#64ee56f6-7d21664c-ff0649da-2a25636f)

**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)](https://courier.yandex.ru/vrs/api/v1/log/request/c94dcde6-16e7d7d7-654dc177-318a3c5b) ⋅ [API response](https://courier.yandex.ru/vrs/api/v1/result/c94dcde6-16e7d7d7-654dc177-318a3c5b) ⋅ [View on map](https://yandex.com/courier/mvrp-map#c94dcde6-16e7d7d7-654dc177-318a3c5b)


{% include [warehouse-feedback](_includes/feedback-81845556eeea.md) %}
