Информация о штрафах при маршрутизации
- Заказ
- Склад
- Транспортное средство
- Маршруты
- За неравномерность маршрутов относительно друг друга
- За неустойчивость маршрута к вероятному изменению временных окон заказов
- За недостаточную сгруппированность маршрутов
- За нарушение ограничений пешей части маршрутов
- За повторные посещения адресов мультизаказов
- За выполнение рейса с меньшей загрузкой раньше чем с большей
- За нереалистичное решение
- Опции
В системе существуют следующие виды штрафов. Для удобства ниже они сгруппированы по тематическим блокам.
Заказ
За недоставку заказа
Штраф начисляется, когда алгоритм по какой-то причине не может включить данный заказ ни в один из маршрутов. Значение суммируется по всем недоставленным заказам.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
За нарушение временного окна заказа
Штраф начисляется за каждую ситуацию, когда курьер прибывает на заказ раньше или позже границ временного окна (если определено, что такие ситуации допустимы, и, соответственно, location.hard_window
= false
).
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
При расчете могут быть указаны параметры locations.penalty.late
и locations.penalty.early
. В этом случае указанные в этих полях значения будут использоваться вместо значений в поле locations.penalty.out_of_time
. То есть:
-
При раннем прибытии (опоздании) и указанном поле
locations.penalty.early.fixed
(locations.penalty.late.fixed
), будет начислена указанная сумма. Если поле не указано, проверяется значение в полеlocations.penalty.out_of_time.fixed
и начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию. -
При раннем прибытии (опоздании) и указанном поле
locations.penalty.early.minute
(locations.penalty.late.minute
), за каждую минуту раннего прибытия будет начислена указанная сумма. Если поле не указано, проверяется значение в полеlocations.penalty.out_of_time.minute
и за каждую минуту опоздания начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию.
Штраф рассчитывается отдельно по количеству нарушений границ временного окна заказа и по длительности таких нарушений:
-
failed_time_window_locations_count_penalty
рассчитывается как сумма штрафов за факт нарушения по всем случаям нарушений. -
failed_time_window_locations_duration_penalty
рассчитывается как сумма штрафов за длительность нарушений по всем случаям нарушений.
За нарушение срока доставки на склад
Штраф начисляется за каждый случай нарушения срока доставки заказа на склад и за каждую минуту такого нарушения.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
locations.penalty.delivery_deadline.fixed
+ <длительность нарушения в минутах> * locations.penalty.delivery_deadline.minute
Пример
Курьер везет pickup-заказ на склад, locations.delivery_deadline
= 20:00
. Для штрафов используются значения по умолчанию penalty.delivery_deadline.fixed
= 1000, penalty.delivery_deadline.minute
= 17.
Курьер приезжает на склад в 20:20. Штраф будет рассчитан как 1000 + 20*17 = 1340
.
За вероятные опоздания
Штраф начисляется за каждый случай вероятного прибытия вне границ временного окна заказа, только если включена опция minimize_lateness_risk
= true
.
При расчете времени прибытия на заказ на основе статистики вычисляется не только математическое ожидание длительности прибытия, но и вероятное отклонение от него. Соответственно, когда полученное вероятное отклонение выходит за границу временного окна, то начисляется штраф (равный штрафу за фактическое прибытие вне границ временного окна, умноженному на вероятность возникновения такой ситуации).
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
<вероятность прибытия вне границ временного окна> * (locations.penalty.out_of_time.fixed
+ locations.penalty.early.fixed
+ locations.penalty.late.fixed
+ <математическое ожидание длительности прибытия вне границ временного окна в минутах> * locations.penalty.out_of_time.minute
+ <математическое ожидание длительности прибытия вне границ временного окна в минутах> * locations.penalty.early.minute
+ <математическое ожидание длительности прибытия вне границ временного окна в минутах> * locations.penalty.late.minute
)
Пример
Пусть задано временное окно заказа с 8:00 до 9:00, и курьер отравляется с предыдущей точки в 7:30. Математическое ожидание длительности его поездки составляет 81 минуту: условно, с вероятностью 0,4 он приедет за 75 минут, с вероятностью 0,4 — за 80 минут, с вероятностью 0,1 — за 90 минут и с вероятностью 0,1 — за 100 минут.
Тогда система спланирует прибытие курьера на заказ в 8:51. Вместе с тем, есть вероятность 0,1, что курьер опоздает на 10 минут (то есть приедет в 9:10, когда его поездка составит 100 минут). Соответственно, за это вероятное опоздание и будет начислен штраф при minimize_lateness_risk
= true
.
За нарушение ограничения времени пребывания заказа у курьера
Штраф начисляется за каждый случай нарушения мягкого ограничения времени пребывания заказа у курьера и за каждую минуту такого нарушения.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
Штраф рассчитывается следующим образом:
location.penalty.transit_time.fixed
+ <длительность нарушения в минутах> * location.penalty.transit_time.minute
Разделенные заказы
За нарушение ограничения времени прибытия частей заказа
Штраф начисляется за каждый случай нарушения интервала между прибытием разных частей заказа и за каждую минуту такого нарушения.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
Штраф рассчитывается следующим образом:
locations.penalty.time_between_visits.fixed
+ <длительность нарушения в минутах> * locations.penalty.time_between_visits.minute
За превышение максимальной доли разделенных заказов
Штраф применяется, если превышается максимальная доля заказов, которые могут быть разделены на несколько частей. См. раздел Деление заказов на части.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
За доставку небольших частей заказов раньше, чем больших
Штраф применяется, если меньшая часть заказа доставлена раньше, чем большая. Начисляется только если обе части заказа доставил один курьер. См. раздел Деление заказов на части.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
Рекомендуемый размер штрафа — тысячи или десятки тысяч.
Склад
За нарушение временного окна склада
Штраф начисляется за каждую ситуацию, когда курьер выезжает со склада раньше временного окна работы склада или возвращается на склад позже временного окна работы склада (если определено, что такие ситуации допустимы, и, соответственно, depot.hard_window
= false
).
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
При расчете могут быть указаны параметры depot.penalty.late
и depot.penalty.early
. В этом случае указанные в этих полях значения будут использоваться вместо значений в поле depot.penalty.out_of_time
. То есть:
-
При раннем прибытии (опоздании) и указанном поле
depot.penalty.early.fixed
(depot.penalty.late.fixed
), будет начислена указанная сумма. Если поле не указано, проверяется значение в полеdepot.penalty.out_of_time.fixed
и начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию. -
При раннем прибытии (опоздании) и указанном поле
depot.penalty.early.minute
(depot.penalty.late.minute
), за каждую минуту нарушения временного окна будет начислена указанная сумма. Если поле не указано, проверяется значение в полеdepot.penalty.out_of_time.minute
и за каждую минуту опоздания начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию.
Рассчитывается отдельно по количеству нарушений границ временного окна склада и по длительности таких нарушений:
-
failed_time_window_depot_count_penalty
рассчитывается как сумма штрафов за факт нарушения по всем случаям нарушений. -
failed_time_window_depot_duration_penalty
рассчитывается как сумма штрафов за длительность нарушений по всем случаям нарушений.
За нарушение параметров пропускной способности склада
Штраф начисляется за каждый случай нарушения пропускной способности склада:
-
При превышении скорости загрузки автомобилей на складе — если определен
locations.depot_duration_s
и фактические значения параметровdepot.throughput.kg_per_hour
,depot.throughput.units_per_hour
иdepot.penalty.throughput.vehicle
превысили заданные для склада. -
При превышении скорости подготовки заказов к погрузке — если определен
locations.depot_duration_s
и фактические значения параметровdepot.package_throughput.kg_per_hour
иdepot.package_throughput.units_per_hour
превысили заданные для склада.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
-
В случае нарушения пропускной способности склада по погрузке (
depot.penalty.throughput
):-
За факт такого нарушения (
fixed
). -
В зависимости от типа ограничения, заданного для склада,
- за каждый килограмм (
kg
), - за каждую грузовую единицу (
unit
), - за каждый автомобиль (
vehicle
), которые превысили заданное ограничение.
- за каждый килограмм (
-
-
В случае нарушения пропускной способности склада по подготовке к погрузке (
depot.penalty.package_throughput
).-
За факт такого нарушения (
fixed
). -
В зависимости от типа ограничения, заданного для склада,
- за каждый килограмм (
kg
), - за каждую грузовую единицу (
unit
), которые превысили заданное ограничение.
- за каждый килограмм (
-
Транспортное средство
За нарушение временного окна смены
Штраф начисляется за каждую ситуацию, когда курьер начинает работу раньше временного окна смены или заканчивает работу позже временного окна смены (если определено, что такие ситуации допустимы, и, соответственно, vehicles.shifts.hard_window
= false
).
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
При расчете могут быть указаны параметры vehicles.shifts.penalty.late
и vehicles.shifts.penalty.early
. В этом случае указанные в этих полях значения будут использоваться вместо значений в поле vehicles.shifts.penalty.out_of_time
. То есть:
-
При раннем (позднем) старте смены и указанном поле
vehicles.shifts.penalty.early.fixed
(depot.penalty.late.fixed
), будет начислена указанная сумма. Если поле не указано, проверяется значение в полеvehicles.shifts.penalty.out_of_time.fixed
и начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию. -
При раннем (позднем) старте смены и указанном поле
vehicles.shifts.penalty.early.minute
(vehicles.shifts.penalty.late.minute
), за каждую минуту раннего (позднего) старта смены будет начислена указанная сумма. Если поле не указано, проверяется значение в полеvehicles.shifts.penalty.out_of_time.minute
и за каждую минуту опоздания начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию.
Рассчитывается отдельно по количеству нарушений границ временного окна смены и по длительности таких нарушений:
-
failed_time_window_shifts_count_penalty
рассчитывается как сумма штрафов за факт нарушения по всем случаям нарушений. -
failed_time_window_shifts_duration_penalty
рассчитывается как сумма штрафов за длительность нарушений по всем случаям нарушений.
За нарушение максимальной продолжительности смены
Штраф начисляется за каждую ситуацию, когда длина смены курьера превышает значение, определенное для него в поле vehicles.shifts.max_duration_s
.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
При расчете можно указать параметр vehicles.shifts.penalty.late
. В этом случае указанное в этом поле значение будет использоваться вместо значения в поле vehicles.shifts.penalty.out_of_time
. То есть:
-
При слишком длинной смене и указанном поле
vehicles.shifts.penalty.late.fixed
, будет начислена указанная сумма. Если поле не указано, проверяется значение в полеvehicles.shifts.penalty.out_of_time.fixed
и начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию. -
При слишком длинной смене и указанном поле
vehicles.shifts.penalty.late.minute
, за каждую минуту раннего прибытия будет начислена указанная сумма. Если поле не указано, проверяется значение в полеvehicles.shifts.penalty.out_of_time.minute
и за каждую минуту опоздания начисляется указанное в нем значение. Если и это поле не указано, начисляется штраф по умолчанию.
Штраф рассчитывается отдельно по количеству и по длительности нарушений, при которых продолжительность смены превышена:
-
overtime_shifts_count_penalty
= сумма {vehicles.shifts.penalty.out_of_time.fixed
vehicles.shifts.penalty.late.fixed
} по всем случаям нарушений -
overtime_duration_penalty
= сумма {<длительность нарушения в минутах> *vehicles.shifts.penalty.out_of_time.minute
+vehicles.shifts.penalty.late.minute
} по всем случаям нарушений
За формирование маршрутов с количеством остановок меньше или больше заданного ограничения
Штраф начисляется за каждую ситуацию, когда количество остановок в итоговом маршруте меньше значения vehicles.shifts.minimal_stops
или больше значения vehicles.shifts.maximal_stops
, определенных в параметрах смены курьера.
Для minimal_stops
штраф начисляется за каждую ситуацию, когда количество остановок в итоговом маршруте меньше значения vehicles.shifts.minimal_stops
, определенного в параметрах смены курьера.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Для maximal_stops
штраф начисляется за каждую ситуацию, когда количество остановок в итоговом маршруте больше значения vehicles.shifts.maximal_stops
, определенного в параметрах смены курьера.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
Сумма {vehicles.shifts.penalty.stop_lack.fixed
} по всем нарушениям + Сумма {<количество остановок, недостающих до параметра minimal_stops
> * vehicles.shifts.penalty.stop_lack.per_stop
} по всем нарушениям + Сумма {<количество остановок свыше параметра maximal_stops
> * vehicles.shifts.penalty.stop_excess.per_stop
} по всем нарушениям.
За пропущенные перерывы
Штраф начисляется за каждую ситуацию, когда планируется маршрут с пропущенным запланированным перерывом, то есть с нарушением режима труда и отдыха.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
За нарушение продолжительности работы до перерыва
Штрафы начисляются за ранний или поздний перерыв и за каждую минуту такого нарушения.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
При расчете штрафов учитываются следующие параметры:
-
necessary_route_duration_s
-
work_time_range_from_start
-
continuous_travel_time_range
-
route_duration_s
Каждый из них отвечает за начало перерыва не раньше (или не позже) определенного периода с начала маршрута.
За нарушение максимального пробега за смену
Штраф начисляется за каждый случай нарушения максимального пробега машины за смену и за каждый километр сверх назначенного в поле vehicles.shifts.max_mileage_km
.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
vehicles.shifts.penalty.max_mileage.fixed
+ <количество километров сверх максимального пробега> * vehicles.shifts.penalty.max_mileage.km
Пример
Пусть задано vehicles.shifts.max_mileage_km
= 100. Для штрафов используются значения по умолчанию shifts.penalty.max_mileage.fixed
= 1000, shifts.penalty.max_mileage.km
= 100.
Запланированный для курьера маршрут получился 120 км. Штраф будет рассчитан как 1000 + 20*100 = 3000
.
Маршруты
За неравномерность маршрутов относительно друг друга
Штраф начисляется, если для определенных смен курьеров задано значение vehicles.shifts.balanced_group_id
.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается отдельно по каждой группе балансировки и затем суммируется в итоговой метрике. Отдельно для каждого транспортного средства вычисляется отклонение от среднего значения параметров в полях options.balanced_groups.penalty
, причем среднее значение берется по всем транспортным средствам, относящимся к конкретной группе балансировки. Далее суммарный штраф рассчитывается на основе суммы квадратов отклонений от среднего.
Значение опции balanced_groups.N.penalties.ignore_unused_vehicles
определяет, как рассчитывается среднее значение:
false
— значение по умолчанию. Среднее значение считается по всем автомобилям, которые указаны в задаче, даже если они не используются в решении. В этом случае алгоритм стремится распределить загрузку равномерно между всеми автомобилями, и поэтому в решении может быть задействовано больше автомобилей, чем необходимо;true
— среднее значение считается только по используемым автомобилям.
Пример
Пусть было задано 3 транспортных средства. Построилось 2 маршрута со следующими характеристиками:
-
количество остановок — 10 и 8.
-
продолжительность — 5 и 4 часа.
Тогда среднее количество остановок будет рассчитано как (10+8)/3 = 6, а средняя продолжительность маршрута — как (5+4)/3 = 3 часа.
За неустойчивость маршрута к вероятному изменению временных окон заказов
Штраф применяется при ненулевом значении options.proximity_factor
.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Порядок расчета следующий. Для каждого маршрута рассчитываются варианты движения при изменении последовательности точек и моделируется среднее значение продолжительности и километража маршрута. Таким образом имитируется ситуация, когда изменяется временное окно заказа. Смоделированное среднее значение для конкретного транспортного средства умножается сначала на стоимость за час или за км (vehicles.cost.hour
или vehicles.cost.km
соответственно), а затем — на коэффициент proximity_factor
.
За недостаточную сгруппированность маршрутов
Штраф применяется при ненулевом значении options.global_proximity_factor
.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Для каждого маршрута алгоритм рассчитывает среднюю дальность точек между собой и моделирует среднее значение продолжительности и километража маршрута. Смоделированное среднее значение для конкретного транспортного средства умножается на стоимость за час или за км (vehicles.cost.hour
или vehicles.cost.km
соответственно), а затем — на коэффициент global_proximity_factor
.
Если задан параметр vehicles.global_proximity_attraction_point
(см. раздел Кучность маршрута), то значение поля total_global_proximity_penalty
рассчитывается исходя из расстояния до «точки притяжения», а не до последней точки в маршруте, как при global_proximity_factor
.
За нарушение ограничений пешей части маршрутов
Штрафы начисляются за нарушение ограничений для пеших частей смешанных маршрутов, когда курьер выполняет часть маршрута на автомобиле, а заказы, расположенные недалеко друг от друга, разносит пешком.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
За повторные посещения адресов мультизаказов
Штраф применяется, если несколько заказов доставляются по одному адресу, но для этого задействовано более одного курьера (или потребовалось более одного посещения одного курьера). См. раздел Мультизаказы.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
Штраф рассчитывается:
- за каждый адрес мультизаказа, на который пришлось приехать повторно;
- за каждое повторное посещение адреса мультизаказа;
- за каждого курьера, который дополнительно посещает адрес мультизаказа.
За выполнение рейса с меньшей загрузкой раньше чем с большей
Штраф начисляется за каждый рейс с меньшей загрузкой, который был выполнен раньше чем рейс с большей загрузкой. Начисляется только если рейсы выполнил один курьер. См. раздел Штраф за недогруженные рейсы.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
Штраф рассчитывается следующим образом:
Для каждого рейса считается максимальная утилизация (число от 0 до 1) и максимальная утилизация последующих рейсов. Разница этих утилизаций умножается на размер штрафа.
Рекомендуемый размер штрафа — тысячи или десятки тысяч.
Пример
В маршруте 3 рейса. В первом рейсе курьер доставил 10 единиц груза, во втором — 15, в третьем — 20. Вместимость автомобиля — 25 единиц.
Максимальная утилизация достигается в третьем рейсе — 20 единиц. По первому и второму рейсам начислен штраф:
[(20-10)/25 + (20-15)/25] * options.penalty.empty_run_before_full.scaled
.
Если тот же курьер доставляет в первом рейсе 20 единиц груза, во втором — 10, в третьем — 15, будет начислен штраф только по второму рейсу:
[(15-10)/25] * options.penalty.empty_run_before_full.scaled
.
За нереалистичное решение
Штраф применяется достаточно редко и рассчитывается в следующих случаях:
-
При использовании опций
vehicles.visited_locations
иvehicles.planned_route
, когда в маршруте заданы заказы, которые по ограничениям невозможно выполнить в данном маршруте (при планировании без использованияvehicles.visited_locations
иvehicles.planned_route
эти заказы попали бы в нераспределенные). -
При нарушениях ограничений по
tag
,load_type
, нарушений по вместимости при ручных корректировках.
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается как сумма {locations.penalty.drop
} по заказам, которые включены в маршрут, но их невозможно выполнить по каким-то ограничениям.
Опции
За превышение пропускной способности точки
Штраф начисляется за каждый случай нарушения пропускной способности точки, если для нее задан один из параметров:
options.points_throughputs[].throughput.kg_per_hour
options.points_throughputs[].throughput.units_per_hour
options.points_throughputs[].throughput.vehicle_count
Поле в ответе API |
Поля запроса в API, которые влияют на расчет |
|
|
* У данного поля есть значение по умолчанию.
Штраф рассчитывается следующим образом:
Сумма {options.points_throughputs.penalty.throughput.fixed
+ options.points_throughputs.penalty.throughput.kg
* <количество килограмм сверх ограничения> + options.points_throughputs.penalty.throughput.unit
* <количество грузовых мест сверх ограничения> + options.points_throughputs.penalty.throughput.vehicle
* <количество автомобилей сверх ограничения>} по каждой точке, где имеются нарушения.