Свойства заказов
- Идентификатор заказа
- Координаты заказа
- Тип заказа
- Вес заказа
- Габариты заказа
- Временное окно заказа
- Штрафы за нарушение временных окон заказов
- Сервисное время при доставке заказов
- Сервисное время на загрузку или выгрузку заказа на складе
- Время готовности заказа на складе
- Крайнее время получения заказа на складе
- Прием и доставка
- Возврат контейнера
- Очередность приема и доставки
- Доставка в одну из возможных точек
- Получение груза в одной из возможных точек
- Привязка заказа к складу
- Доставка pickup-заказа на склад
- Время доставки заказа на склад
- Ограничение времени пребывания заказа в автомобиле
- Загрузка и выгрузка в гараже
- Мультизаказы
- Деление заказов на части
- Штрафы за невыполнение заказа
- Совместимость заказа и автомобилей
- Несовместимость заказов
- Включение и выключение опций кучности
- Порядок выполнения заказов
- Дополнительные параметры заказа для оптимизации маршрута
Заказы в Яндекс Маршрутизации представляют собой точки, которые посещаются одним или более автомобилями в оптимальном порядке с соблюдением ограничений.
Для определения заказов используется поле запроса locations
. Принцип «заказ = location
» применим в большинстве ситуаций доставки со склада. Но в общем случае для сервиса планирования маршрутов location
— это точка, в которой нужно выполнить определенное действие.
В locations
будет больше точек, чем ваших заказов, если:
-
используется pickup & delivery (delivery_to_any);
-
задаются старт не со склада или завершение не на складе (тогда в
locations
добавляются точки старта или окончания); -
ваш заказ по смыслу не равен заказу в Маршрутизации, т. е. ваш заказ разделяется или объединяется при загрузке в сервис планирования. Например:
-
заказ слишком большой (превышает вместимость любой из машин);
-
заказ содержит несовместимые товарные номенклатуры;
-
заказ представляет собой доставку/cбор в нескольких точках.
-
Идентификатор заказа
Обязательным атрибутом заказа является уникальный числовой или строковый идентификатор, который задается в поле id
. Идентификатор должен быть уникальным в пределах одного запроса. Если результаты планирования будут экспортироваться в Мониторинг, идентификатор заказа должен быть уникальным в рамках вашей компании.
Если поле id
не заполнено, то при загрузке данных из Excel и отправке задачи на маршрутизацию оно заполняется как 1, 2, 3… Если id
заполнено для заказа, то рекомендуется также указать id
для склада (или не указывать в id
заказов — 0, поскольку это значение зарезервировано для склада).
В дополнение к номеру заказа вы можете указать другие атрибуты заказов из вашей учетной системы:
-
ref
— дополнительный номер заказа. В некоторых случаях поля используются следующим образом:id
заполняют внутренним идентификатором из учетной системы (уникальным для всего листа),ref
— номером документа (возможно не уникальным), к которому привыкли пользователи; -
title
— название получателя; -
address
— адрес заказа. Отобразится в интерфейсе планирования, если поле заполнено. Обязательно для заполнения, если координаты заказа не указаны; -
description
— описание точки доставки или ее адрес. Имеет более высокий приоритет, чемaddress
, поэтому, если оба поля заполнены, в интерфейсе отобразится информация изdescription
; -
comments
— комментарий к заказу. Информация из этого поля выгружается в соответствующие поля карточки заказа в Мониторинг и в приложение Яндекс Курьер. Кроме текстового описания в комментарии можно передать ссылку, и курьер сможет открыть ее из приложения.Например, для заказа указан комментарий: «Ознакомьтесь с правилами парковки на территории бизнес-центра: https://krasnaya-roza.com». Курьер увидит его в разделе Комментарий логиста.
Также в комментарий к заказу можно добавить мобильный телефон клиента в формате:
<a href="tel:+79123456789">Позвонить</a>
. Чтобы указать добавочный номер, используйте разделители,
,;
,*
или#
:<a href="tel:+79123456789,12">Позвонить</a>
. В приложении появится кнопка Позвонить, и курьер сможет связаться с клиентом.Комментарий логиста в курьерском приложении
Внимание
Поля ref
, title
, description
и comments
являются информационными и не используются при оптимизации маршрутов.
В комментарии к заказу comments
рекомендуем указывать номера телефонов с +7 или 8, так как на номера, которые начинаются на 7, курьер не сможет позвонить из приложения.
Координаты заказа
Точку доставки заказа можно указать в системе WGS84. Координаты должны соответствовать точке парковки или остановки для вручения заказа. Если местоположение заказа в вашей системе задается адресом, необходимо произвести геокодирование (преобразование адреса в свободной форме в географические координаты).
Для определения координат заказа используются поля point.lat
и point.lon
. Важно убедиться, что координаты не перепутаны местами и нет координат, которые по значениям сильно отличаются от остальных (как правило это признак ошибочного геокодирования — при маршрутизации такой адрес может оказаться очень далеко от остальных и такой заказ не попадет ни в один из маршрутов).
Для определения координат заказа используется поле location.point
.
Корректность координат имеет очень большое значение для получения хороших результатов маршрутизации. Геокодер может неточно распознавать адреса, которые введены с ошибками или содержат информацию, не относящуюся к адресу. Поэтому стоит уделить внимание тому, как в вашей системе появляются и хранятся адреса:
-
Если клиенты указывают адреса в форме на сайте, желательно подключить проверку ввода адресов (например, проверку Яндекса).
-
Если адреса вводят сотрудники компании, рекомендуется упорядочить процесс ввода. Часто адрес набирают сплошной строкой, в том же поле сохраняют комментарий и информацию по окну доставки. Как минимум нужно отделить адрес от прочих данных, чтобы при геокодировании возникало меньше ошибок и проблем с распознаванием.
Внимание
Координаты 0,0
не будут обработаны корректно и приведут к ошибке при запросе Маршрутизации.
Тип заказа
Тип заказа указывается в поле type
. Возможные значения:
-
delivery
— точка доставки (значение по умолчанию). -
pickup
— точка получения груза. Только для таких точек доступны поля (одно из двух):-
delivery_to — уникальная точка с типом
delivery
; -
delivery_to_any — не уникальная точка с типом
drop_off
.
-
-
drop_off
— точка выгрузки в сценарии delivery_to_any. -
return
— точка, в которую нужно вернуть контейнер после доставки заказа. -
garage
— точка старта не со склада или завершения не на складе. -
anchor
— точка, в которой можно оставить прицеп надолго и сделать перекатку. -
parking
— точка, в которой можно оставить прицеп только на время разгрузки одного заказа. -
rest_place
— точка, в которую можно заехать на отдых во время перерыва (см. раздел Место перерыва). -
courier
— текущее местоположение курьера, используется только при допланировании (см. раздел Периодическое допланирование).
Вес заказа
Для каждого заказа к доставке может быть определен его вес. Определение веса не является обязательным, но рекомендуется во избежание перегрузки автомобилей.
Для определения веса заказа используется поле shipment_size
(достаточно указать один из атрибутов):
-
shipment_size.weight_kg
— вес в килограммах или объемный вес. -
shipment_size.volume_cbm
— объем заказа в кубометрах. Если полеvolume_cbm
не определено, тогда объем заказа вычисляется как произведение габаритов заказа:-
shipment_size.volume.width_m
— ширина заказа в метрах; -
shipment_size.volume.depth_m
— длина заказа в метрах; -
shipment_size.volume.height_m
— высота заказа в метрах.
-
-
shipment_size.units
— количество мест (паллет, коробок, кег).
Более подробно с определением веса вы можете ознакомиться в разделе Вес и объем.
При указании веса заказов необходимо указать грузоподъемность у автомобилей.
В запросе желательно задавать вес и объем заказа брутто, особенно если информация о весе тары может оказать существенно влияние на результаты маршрутизации. Если на этапе планирования информация по весу брутто в явном виде неизвестна, рекомендуется ее вычислять исходя из специфики перевозимых грузов. Например, если средний вес паллеты с грузом 800 кг, вес самой паллеты 20 кг, в заказе указан вес нетто 500 кг, и на момент планирования неизвестно, как груз будет скомплектован на складе, то вес в заказе при передаче в маршрутизацию можно указать так: 500 кг + 20 кг * (500/800)
= 512,5 кг
, количество грузовых единиц — как отношение ожидаемого веса брутто к среднему весу паллеты: 512,5/800
, то есть как 0,64
паллеты. Данный вариант является только одним из возможных подходов к такому приблизительному расчету.
Если заказ состоит из нескольких разных товаров, у каждого из которых свои габариты, нужно указывать итоговые характеристики по заказу: общий вес, общий объем, общее количество единиц. В габаритах заказа можно передать максимальные габариты (если это важно для планирования).
Подробнее
Например, пусть один заказ состоит из трех разных товаров, у каждого из которых свои габариты и вес:
№ товара |
Количество единиц |
Габариты, м |
Вес каждой единицы, кг |
1 |
50 |
0,1x0,1x0,1 |
2 |
2 |
10 |
0,2x0,2x0,2 |
3 |
3 |
1 |
1x0,5x0,1 |
50 |
Итоговые характеристики по заказу:
- общий вес —
50 * 2 + 10 * 3 + 50 = 180
; - общий объем —
50 * (0,1 * 0,1 * 0,1) + 10 * (0,2 * 0,2 * 0,2) + 1 * (1 * 0,5 * 0,1) = 0,18
; - количество единиц —
50+10+1 = 61
; - габариты заказа —
max(0,1; 0,2; 1) * max(0,1; 0,2; 0,5) * max(0,1; 0,2; 0,1) = 1 * 0,5 * 0,2
.
Внимание
Если вес, объем или количество юнитов в заказе будет превышать максимальную вместимость транспортного средства, то данный заказ при планировании попадет в нераспределенные — в Маршрутизации заказ считается неделимой единицей (за исключением случаев, когда деление заказов настроено отдельно, подробнее см. в разделе Деление заказов на части). При наличии больших заказов в учетной системе необходимо разделить их на несколько заказов на этапе выгрузки в Маршрутизацию.
Пример
Курьер на автомобиле с вместимостью грузового отсека 10 кубометров (capacity.volume.width_m
= 2, capacity.volume.depth_m
= 2,5 и capacity.volume.height_m
= 2) доставляет два заказа. Для первого заказа определен объем shipment_size.volume_cbm
= 5. Для второго заказа объем не определен, поэтому он вычисляется из габаритов shipment_size.volume.width_m
= 2, shipment_size.volume.depth_m
= 2 и shipment_size.volume.height_m
= 1. Оба заказа помещаются в автомобиль.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пользовательские единицы измерения
Помимо заданных единиц веса, объема (вычисляемого через габариты) и количества мест, в Маршрутизации есть возможность указать пользовательские единицы измерения на заказе и ограничить вместимость по данным единицам измерения в транспортном средстве.
Такая потребность может возникнуть, если в дополнение к используемым измерениям (вес, объем, количество мест) необходимо:
-
задать стоимость заказа и ограничить суммарную стоимость перевозимых курьером заказов, чтобы каждый курьер перевозил товаров на сумму не более N денежных единиц;
-
ограничить количество заказов, которые перевозит каждый курьер. В таком случае можно указать для каждого заказа пользовательскую единицу измерения = 1 и, соответственно, на каждом транспортном средстве задать ограничение по этому количеству заказов;
-
реализовать любую другую логику, связанную с ограничением количества определенных заказов на курьере. Например, если есть VIP-клиенты, к которым категорически нельзя опаздывать — можно установить правило, что на каждом курьере будет не более 2-х VIP-заказов, чтобы снизить риск невыполнения этих заказов из-за каких-то форс-мажоров.
Пользовательская единица измерения задается двумя параметрами:
-
shipment_size.custom.<порядковый номер>.name
— имя пользовательской единицы измерения; -
shipment_size.custom.<порядковый номер>.size
— размер заказа по пользовательской единице измерения.
По умолчанию shipment_size.custom.<порядковый номер>.size
= 0.
Можно задавать несколько пользовательских единиц измерения и присваивать им любое название.
Внимание
Название пользовательской единицы измерения на транспортом средстве должно совпадать с указанным для заказа.
Пример заполнения листов файла Excel для пользовательского параметра price
(стоимость заказа):
Стоимость заказа
|
|
|
100 |
Суммарная стоимость заказов
|
|
|
1000 |
Пример 1
В примере указаны вес, объем и количество грузовых единиц. Также задана стоимость заказа и ограничение на машине по суммарной стоимости перевозимых заказов с помощью параметров location.shipment_size.custom.0
и vehicle.capacity.custom.0
соответственно.
Видно, что есть 2 машины, которые везут по 1 заказу, хотя утилизация по весу, объему и количеству мест у них небольшая — это обусловлено тем, что стоимость этих заказов находится близко к установленному на машине ограничению.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но дополнительно указано максимальное количество заказов, которое может перевезти курьер. Ограничение описывается с помощью параметров location.shipment_size.custom.1
и vehicle.capacity.custom.1
. Каждый автомобиль теперь может везти не более 5 заказов.
Видно, что количество заказов в трех автомобилях изменилось. Теперь 1 заказ везет только 1 автомобиль, в который нельзя больше добавить заказы из-за ограничения по суммарной стоимости. По остальным достигнута максимальная утилизация по суммарной стоимости в каждом автомобиле, но удалось выдержать ограничение по количеству заказов.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Габариты заказа
При формировании заказа может быть необходимо учитывать не только его вес и объем, но и габариты. Например, в автомобиль с грузовым отсеком 1х1х1 метр нельзя поместить коробку размером 2х0,5х0,5 метра, даже несмотря на то, что по объему она должна помещаться.
Если заказ состоит из нескольких разных товаров, у каждого из которых свои габариты, нужно указывать итоговые характеристики по заказу: общий вес, общий объем, общее количество единиц. В габаритах заказа можно передать максимальные габариты (если это важно для планирования).
Подробнее
Например, пусть один заказ состоит из трех разных товаров, у каждого из которых свои габариты и вес:
№ товара |
Количество единиц |
Габариты, м |
Вес каждой единицы, кг |
1 |
50 |
0,1x0,1x0,1 |
2 |
2 |
10 |
0,2x0,2x0,2 |
3 |
3 |
1 |
1x0,5x0,1 |
50 |
Итоговые характеристики по заказу:
- общий вес —
50 * 2 + 10 * 3 + 50 = 180
; - общий объем —
50*(0,1*0,1*0,1) + 10*(0,2*0,2*0,2) + 1*(1*0,5*0,1) = 0,18
; - количество единиц —
50+10+1 = 61
; - габариты заказа —
max(0,1; 0,2; 1)*max(0,1; 0,2; 0,5)*max(0,1; 0,2; 0,1) = 1*0,5*0,2
.
В Маршрутизации можно использовать параметр location.shipment_size.volume.type
, чтобы задать тип перевозимого груза. Возможные значения:
-
bulk
— сыпучий. При формировании заказа его габариты не учитываются. Используется по умолчанию. -
rigid
— жесткий. При формировании заказа учитываются габариты, но груз может быть повернут произвольно (т. е. любая его сторона может находиться на дне кузова автомобиля). -
fixed_bottom
— жесткий с фиксированным дном. При формировании заказа груз нельзя переворачивать (фиксированное измерение —height
), но можно вращать (определенная сторона груза должна располагаться на дне кузова автомобиля).
Внимание
Проверка габаритов заказа выполняется для каждого заказа индивидуально. Несколько заказов, которые помещаются по объему, но не по габаритам, могут быть назначены в один автомобиль. Например, 2 заказа с пропорциями 0,6х0,6х0,6 могут быть помещены в кузов объемом 1х1х1.
Пример 1
Автомобиль с размером грузового отсека 1х1х1 метр доставляет заказ с размерами 2х0,5х0,5 метра. Поскольку по умолчанию габариты не учитываются, он помещается в автомобиль.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но заказ считается жестким и не помещается в автомобиль. В результате он не доставлен.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Ориентация заказа в автомобиле
Для определения ориентации заказов с типом rigid
или fixed_bottom
относительно оси автомобиля используется поле location.shipment_size.volume.align
.
По умолчанию значение align
= all_axes
, заказы должны размещаться строго параллельно оси автомобиля. Но иногда груз удобнее разместить в автомобиле под углом. Для поддержки такого сценария используется значение align
= height
.
Ориентация заказа зависит от сочетания значений type
и align
. Возможные варианты перечислены ниже:
|
|
|
|
Заказ может быть повернут на 900 по любой оси, но всегда ставится строго параллельно осям кузова. |
Заказ может быть повернут на 900, но его дно** остается неизменным, то есть находится на дне кузова автомобиля. |
|
Заказ может быть повернут как угодно, при условии, что одна любая сторона остается на дне кузова автомобиля, то есть высота* должна быть параллельна высоте грузового отсека. |
Заказ может быть повернут как угодно, при условии, что его дно** остается неизменным, то есть находится на дне кузова автомобиля. |
* Параметр shipment_size.volume.height_m
— высота заказа в метрах.
** Cторона, определенная как ширина х глубина, выраженные в параметрах:
-
shipment_size.volume.width_m
— ширина заказа в метрах; -
shipment_size.volume.depth_m
— длина заказа в метрах.
Пример 1
В задаче планирования заказ с габаритами 0,4х3,2х1 м и автомобиль с грузовым отсеком 2х3х1,5 м. Указано location.shipment_size.volume.type
= fixed_bottom
— заказ нельзя переворачивать. Ориентация location.shipment_size.volume.align
не указана, груз должен размещаться параллельно оси автомобиля.
В результате заказ не помещается в автомобиль, потому что длина заказа больше длины кузова.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но location.shipment_size.volume.align
= height
, груз можно поворачивать под любым углом.
В результате решения алгоритма груз размещается в кузове по диагонали, заказ будет доставлен.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Временное окно заказа
У всех заказов должно быть указано временное окно — интервал времени, когда автомобиль или курьер должен прибыть на адрес заказа.
Для определения временного окна используется поле time_window
.
Временное окно определяется в одном из следующих форматов:
-
07:00:00 – 23:00:00
— временное окно начинается в 7 утра и заканчивается в 23 вечера текущего дня; -
2019-10-10T07:00:00+03:00/2019-10-10T23:00:00+03:00
— временное окно на конкретную дату и часовой пояс (читается как YYYY-MM-DDThh:mm:ss±hh:mm).
В зависимости от типа временного окна, курьер приедет на заказ строго в заданный интервал (жесткое окно), или может нарушать окно с дополнительным штрафом (мягкое окно). Подробнее функциональность описана в разделе Жесткие и мягкие окна.
Для управления жесткими временными окнами используется поле hard_window
:
-
true
— временное окно будет жестким. -
false
— временное окно будет мягким.
В случае определения мягкого временного окна можно дополнительно задать штрафы за его нарушение. Подробнее функциональность описана в разделе Штрафы за нарушение временного окна склада.
Чтобы ограничить допустимые нарушения основного окна, можно задать жесткое окно вокруг мягкого.
При доставке к определенному времени не рекомендуется указывать окно с одинаковыми верхними и нижними временными границами, особенно если временное окно жесткое.
Например, если у заказа доставка строго к 9:00, то алгоритм обработает значение 9:00:00 – 9:00:00
без ошибок, но на практике водитель будет приезжать на такой заказ заранее. Поэтому рекомендуется указывать временное окно в более реалистичном диапазоне, например, 8:30:00 – 9:00:00
. Чем более узкие временные окна будут у заказов, тем (при прочих равных) больше потребуется машин, чтобы выполнить эти заказы в заявленные временные окна. Поэтому временное окно должно как можно более правдиво отражать реальную возможность приезда в заданную точку.
Внимание
Сервисное время не учитывается при определении факта попадания во временное окно. Например, если задано окно 10:00 – 16:00
и сервисное время составляет 30 минут, прибытие на заказ в 15:59 будет считаться своевременным.
Штрафы за нарушение временных окон заказов
Данный штраф добавляется к общей стоимости маршрута, если заказ удается запланировать к доставке, но доставка происходит раньше или позже указанного временного окна.
Примечание
Такое поведение возможно только в случае определения мягкого временного окна. Если нарушается жесткое окно, то заказ автоматически помечается как недоставленный и исключается из всех маршрутов.
Штраф за несвоевременную доставку позволяет повысить вероятность, что наиболее важные заказы будут доставлены без опозданий в ущерб менее важным.
Для управления своевременностью доставки заказов в Маршрутизации могут использоваться следующие объекты:
-
location.penalty.early
— устанавливает штраф за доставку раньше временного окна; -
location.penalty.late
— устанавливает штраф за доставку позже временного окна; -
location.penalty.out_of_time
— устанавливает единые штрафы за доставку как раньше, так и позже временного окна.
Если location.penalty.early
и location.penalty.late
не заданы, то используются значения из location.penalty.out_of_time
(то есть early
и late
работают как переопределение out_of_time
).
Каждый объект состоит из двух полей:
-
fixed
— фиксированный штраф за факт несвоевременной доставки; -
minute
— штраф за каждую минуту несвоевременной доставки.
Если в location.penalty.early
или location.penalty.late
задано только одно значение (fixed
или minute
), то второе берется из location.penalty.out_of_time
. Например, может быть задано только location.penalty.late.fixed
. Тогда при опоздании на заказ в качестве штрафа за каждую минуту будет использоваться location.penalty.out_of_time.minute
.
Примечание
Вышеперечисленные поля имеют значения по умолчанию, которые рекомендуется использовать в качестве стартовых значений при определении пользовательских приоритетов доставки заказов. При сомнениях свяжитесь с аналитиками Яндекс Маршрутизации для определения корректных коэффициентов.
Пример
Пример ниже содержит запрос с разными штрафами за раннюю и позднюю доставку заказов. Обратите внимание, что для всех заказов location.hard_window
= false
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Несколько временных окон в заказе
При необходимости в Маршрутизации можно указать несколько временных окон. Это используется в следующих ситуациях:
-
при доставке есть перерыв в работе точки доставки (например, доставить нужно с 9 до 12 либо с 15 до 18);
-
в многодневном маршруте нужно доставить в указанное время (например, с 9 до 18), но в один из дней доставки.
В поле time_windows
указывается массив элементов time_window
. Заказ будет выполнен в одно из возможных окон, и в поле used_time_window
ответа API будет содержаться информация об использованном временном окне.
Для каждого временного окна можно задать внешнее жесткое окно hard_time_window
.
Внимание
Окна time_window
не должны пересекаться между собой. Например, недопустимо одновременно указывать окна с 9:00 до 12:00 и с 11:00 до 14:00.
Пример 1
Нужно доставить два заказа с двумя временными окнами time_windows.0.time_window
= 9:00 – 12:00
и time_windows.1.time_window
= 15:00 – 18:00
(формат описания для Excel). Заказы доставлены в первое временное окно.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
За два дня нужно доставить 20 заказов в период с 8 до 15 часов. Окна заказов записаны в относительном формате: для первых суток — 08:00:00 – 15:00:00
, для вторых — 1.08:00:00 – 1.15:00:00
. Обратите внимание, что в этом случае временное окно склада тоже записывается в относительном формате и включает обе нужные даты. Cмены работы автомобиля нужно указать для каждого из дней.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Сервисное время при доставке заказов
При планировании маршрутов необходимо указать сервисное время (время обслуживания) для каждого заказа.
Доступны следующие параметры (задаются в секундах):
-
service_duration_s
— время на вручение заказа получателю. -
shared_service_duration_s
— время на обмен документами или парковку.
Если несколько заказов доставляются по одному адресу, они могут быть объединены в мультизаказ. Тогда сервисное время для них рассчитывается как Сумма{service_duration_s
} + Максимум{shared_service_duration_s
} по всем заказам в мультизаказе. Чтобы исключить заказ из мультизаказа и учитывать его сервисное время shared_service_duration_s
отдельно, установите location.can_be_merged
= false
. Подробнее см. в разделе Мультизаказы.
Для некоторых сценариев при расчете сервисного времени учитываются дополнительные параметры. Они описаны в разделе Возможные логистические сценарии (например, время на перегрузку заказов при кросс-докинге). Дополнительно при расчете сервисного времени обслуживания для автомобиля может быть задана корректировка сервисного времени.
По умолчанию сервисное время не включено во временное окно заказа. Возможна ситуация, когда курьер приезжает на точку в 17:59, хотя окно заказа до 18:00. Чтобы избежать возникновения таких ситуаций, используйте опцию options.penalize_late_service. Опция определяет, начисляется ли штраф за опоздание до момента начала обслуживания (false
, значение по умолчанию) или до момента окончания обслуживания (true
). То есть при значении true
алгоритм будет стремиться завершить время обслуживания в границах временного окна.
В исходных данных указывайте реалистичное сервисное время. Если заложить слишком много времени на обслуживание, то алгоритм запланирует больше курьеров, чем требуется на самом деле. Если заложить слишком мало времени, то решение получится слишком оптимистичным, и при доставке заказов возникнут опоздания.
Внимание
При большом количестве заказов даже небольшая разница во времени на 1 заказ может привести в итоге к разнице в количестве курьеров. Например, на 200 заказах разница в сервисном времени в 2 минуты — это практически полный день работы курьера: 200 * 2 мин = 400 мин = почти 7 ч.
Важно использовать в расчете именно усредненное время. Например, в 9 из 10 случаев курьер тратит на точке 10 минут, а в одном случае — 30 минут. Тогда усредненное сервисное время: (9 * 10 мин + 1 * 30 мин) / 10 = 12 мин.
Для подбора значения сервисного времени обслуживания:
-
Вычислите величину:
<Средняя длительность смены> − <Среднее фактическое количество точек за смену> * <Усредненное сервисное время>
В результате должно остаться какое-то разумное время, чтобы курьер мог передвигаться между точками.
-
Создайте справочник различных значений времени сервисного обслуживания, если сервисное время зависит от адресов доставки. Например, если необходимо разное время на прием заказа в магазинах одной торговой сети. Справочник создается вне сервиса Маршрутизации.
-
Реализуйте формулу расчета сервисного времени, если объемно-весовые характеристики заказов сильно изменяются. Например, 1 минута на каждые 100 кг, но не менее 5 минут. Значения должны быть указаны явно, поэтому формулу необходимо реализовать вне сервиса Маршрутизации.
Чтобы проверить значение сервисного времени, совершите реальный проезд по маршрутам и используйте отчет о качестве работы курьера в Мониторинге.
Пример
В примере определено сервисное время для каждого заказа.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Сервисное время на загрузку или выгрузку заказа на складе
В дополнение к общему сервисному времени на складе в Маршрутизации можно указать время загрузки отдельного заказа в автомобиль или выгрузки pickup-заказа на складе. Для определения времени на загрузку или выгрузку заказа используется поле запроса location.depot_duration_s
.
Если для склада задано общее сервисное время, оно будет прибавлено к общему времени загрузки заказов в каждый автомобиль. Дополнительная информация доступна в разделе Сервисное время на складе.
При использовании кросс-докинга учитывается время перегрузки заказов location.crossdock_service_duration_s
. Примеры планирования рассмотрены в разделе Кросс-докинг.
Пример
Сервисное время на складе для каждого из трех заказов составляет 5 минут, а общее сервисное время на складе — 10 минут. Итого машина проведет на загрузке 25 минут.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Время готовности заказа на складе
По умолчанию при планировании доставки заказов со склада предполагается, что они доступны к отгрузке. Но это не всегда так (например, если заказы готовятся в течение дня). В таких случаях нужно учитывать время готовности заказа. Нередко курьеры совершают несколько рейсов со склада, забирая заказы по мере их доступности (для этой схемы нужно задавать возможность выполнения курьером нескольких рейсов).
Время готовности заказа определяется на листе Orders в поле depot_ready_time
. Его можно использовать только для заказов с типом delivery
без связанных pickup
заказов (т. е. только для доставок со склада). Параметр depot_ready_time
задает жесткое ограничение — если оно нарушается, заказ попадает в нераспределенные. Чтобы задать мягкое ограничение, используйте параметр soft_depot_ready_time
(поддерживается только в API). При нарушении мягкого ограничения начисляются штрафы:
penalty.depot_ready_time.fixed
— за факт нарушения времени готовности заказа;penalty.depot_ready_time.minute
— за каждую минуту нарушения времени готовности заказа.
Дата и время в depot_ready_time
и soft_depot_ready_time
задаются в таком же формате, как и при определении временных окон.
Примеры значений:
-
10:15
-
2020-09-06T13:15:00+03:00
(6 сентября 2020 года в 13:15 по часовому поясу GMT+3) -
2020-09-06T10:15:00Z
(6 сентября 2020 года в 10:15 по UTC)
Если при планировании маршрутов значение depot_ready_time
задано в прошлом (например, когда заказ готов к отгрузке накануне вечером), то значение depot_ready_time
в ответе API будет отрицательным.
Пример расчетов отрицательного depot_ready_time
Маршруты планируются на 19 марта. Для одного из заказов задан depot_ready_time
= 2024-03-18T20:15:00+03:00
. Тогда в ответе API для этого заказа depot_ready_time
= -03:45.
Если курьер должен начинать загрузку по мере готовности заказов, то нужно использовать опцию Погрузка по мере готовности.
Пример 1
В примере выполняется доставка 10 заказов, для каждого из которых указано время готовности (9:00, 10:00, 12:00 или 14:00). В результате рейсы в маршруте курьера построены с учетом depot_ready_time
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что в примере 1, но у заказов заданы меньшие временные окна. Для каждого заказа указано мягкое ограничение soft_depot_ready_time
= 9:00, 10:00, 12:00, 14:00 или 15:00 и установлен штраф за каждую минуту нарушения penalty.depot_ready_time.minute
= 10.
В результате планирования алгоритм нарушает время готовности заказа 10, чтобы он был доставлен вовремя.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Крайнее время получения заказа на складе
Как правило, заказы можно забирать со склада в любое время в рамках временных окон склада. Но если нужно забрать заказ не позднее определенного времени, на листе Orders укажите параметр depot_expiring_time
. Параметр depot_expiring_time
задает жесткое ограничение — если оно нарушается, заказ попадает в нераспределенные. Чтобы задать мягкое ограничение, используйте параметр soft_depot_expiring_time
(поддерживается только в API). При определении мягкого ограничения используются штрафы:
penalty.depot_expiring_time.fixed
— за факт нарушения крайнего времени получения заказа;penalty.depot_expiring_time.minute
— за каждую минуту нарушения крайнего времени получения заказа.
Дата и время в depot_expiring_time
и soft_depot_expiring_time
задаются в таком же формате, как и при определении временных окон.
Примеры значений:
-
10:15
-
2020-09-06T13:15:00+03:00
(6 сентября 2020 года в 13:15 по часовому поясу GMT+3) -
2020-09-06T10:15:00Z
(6 сентября 2020 года в 10:15 по UTC)
После того, как заказ забрали для погрузки, может потребоваться время на его загрузку в автомобиль — depot_duration_s
. Также прибавляется общее сервисное время на складе depot.load_service_duration_s
.
Пример 1
В примере выполняется доставка 4 заказов. Заказы 1 и 2 — хрупкие, поэтому их нужно упаковать особым образом. Перед погрузкой упаковку проверяет работник, смена которого заканчивается в 13:00. Заказы 3 и 4 готовы к отгрузке только в 14:00. В результате рейсы в маршруте курьера построены с учетом depot_expiring_time
и depot_ready_time
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Нужно развезти 10 быстро портящихся заказов. Для каждого заказа указано мягкое ограничение для крайнего времени получения со склада: 8:30, 9:00, 9:30 и 10:00. Курьер начинает работу в 9:00, поэтому не может забрать заказ вовремя. За нарушение ограничения начислен штраф.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Прием и доставка
В общем случае заказы загружаются в автомобиль на складе и доставляются по адресам получателей.
В случае, если по адресу клиента необходимо осуществить прием заказа и его дальнейшую доставку на другой адрес (pickup & delivery), необходимо определить тип заказа.
Для определения типа заказа используется поле location.type
со значениями:
-
pickup
— прием заказа по адресу. -
delivery
— доставка заказа по адресу (по умолчанию).
Заказы с типом pickup
могут доставляться:
-
по указанному адресу — в поле
location.delivery_to
нужно указать идентификатор заказа с типомdelivery
; -
по одному из указанных адресов — в поле
location.delivery_to_any
нужно перечислить идентификаторы заказов с типомdrop_off
, см. Доставка в одну из возможных точек; -
на один из указанных складов — идентификаторы складов нужно перечислить в поле
location.depot_id
, см. Привязка заказа к складу. Заказ будет доставлен в текущем маршруте; -
на любой склад — в этом случае поле
location.depot_id
должно быть пустым. Заказ будет доставлен на склад в текущем маршруте, если выполняется хотя бы одно из условий:- включен признак
location.pickup_must_reach_depot
=true
, см. Доставка pickup-заказа на склад; - задан крайний срок доставки
location.delivery_deadline
, см. Время доставки заказа на склад; - курьер с pickup-заказом в конце маршрута обязательно возвращается на склад (
vehicle.return_to_depot
=true
). Если ни одно из перечисленных условий не выполняется, pickup-заказ останется у курьера и будет доставлен на склад в следующем маршруте.
- включен признак
Если доставка возможна в одну из нескольких точек, узнать, куда именно отвезен заказ, можно из ответа API — для заказа drop_off
или склада идентификаторы доставленных заказов перечисляются в поле delivered_orders
.
Пример
Первый курьер должен вернуться в конце смены на склад, для него значение vehicle.return_to_depot
= true
. Этот курьер забирает все заказы pickup. Второй курьер, у которого vehicle.return_to_depot
= false
, работает с удаленными заказами и завершает смену в удобной точке.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Внимание
Если заказы типа pickup
должны всегда возвращаться на склад и в планировании используются машины, у которых vehicle.return_to_depot
= false
и vehicle.return_to_depot
= true
, то нужно явно заполнить поле location.delivery_to
. Иначе заказ может остаться в машине курьера.
Чтобы учесть очередность приема и доставки, следует использовать параметр location.in_lifo_order.
Также Маршрутизация поддерживает смешанные прием и доставку, когда в запросе присутствуют как обычные заказы на доставку, так и прием/доставка.
Между сбором и доставкой заказа по другому адресу допустимы другие заказы, если у автомобиля достаточная грузоподъемность и такой маршрут окажется более выгодным.
Если необходимо доставить заказ сразу после сбора — воспользуйтесь группировкой заказов с опцией options.location_groups.solid
= true
.
Обратите внимание, что при наличии нескольких заказов на прием груза (pickup
) по одному адресу — в редких случаях прием может быть выполнен более чем одним автомобилем или курьером. Такое разделение может быть оправдано с точки зрения уменьшения общей стоимости доставки.
Возврат контейнера
Если в одной точке нужно забрать pickup-заказ в контейнере, доставить его по адресу, а затем вернуть контейнер в начальную или другую точку, можно использовать схему «pickup-delivery-return». Для этого:
- Добавьте заказ с типом
pickup
и в полеlocation.delivery_to
укажите идентификатор заказа типаdelivery
, куда нужно доставить заказ в контейнере. - Добавьте заказ с типом
return
— адрес точки, куда нужно вернуть контейнер после доставки заказа. - Для заказа с типом
delivery
в полеlocation.return_to
укажите идентификатор заказа с типомreturn
— в эту точку будет возвращен контейнер.
Пример
Маршрут курьера состоит из 7 заказов. Заказ 1 типа pickup
упакован в контейнер. В результате планирования курьер доставляет заказ 1 в точку 3, а затем возвращает контейнер в начальную точку. На доставку других заказов это не влияет.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Очередность приема и доставки
Параметр location.in_lifo_order
помогает создавать маршруты с учетом очередности приема и доставки заказов. Аббревиатура «lifo» происходит от английского «last in, first out», что означает «последним пришел, первым ушел». Параметр можно использовать для пар заказов pickup/delivery, когда важна последовательность загрузки и выгрузки. По умолчанию location.in_lifo_order
= false
.
Например, один автомобиль перевозит стул, кресло и кровать с трех адресов на три другие адреса. Если загружать и выгружать мебель в таком же порядке, то для выгрузки стула потребуется сначала достать кровать, затем кресло и только в конце стул, а после этого загрузить обратно кресло и кровать, чтобы поехать на следующий адрес. Очевидно, дополнительные циклы загрузки и выгрузки потребуют дополнительное время и силы. Чтобы избежать лишних затрат, стоит заранее спланировать очередь загрузки и выгрузки:
- Загрузить кровать.
- Загрузить кресло.
- Загрузить стул.
- Выгрузить стул.
- Выгрузить кресло.
- Выгрузить кровать.
Такой порядок действий отражает принцип «last in, first out». Чтобы соблюсти его, необходимо указать location.in_lifo_order
= true
для всех заказов, где важна очередность приема и доставки.
Внимание
В парах заказов pickup
/delivery
значение поля location.in_lifo_order
должно быть одинаковым.
Пример 1
В этом примере 6 точек доставки. Нужно перевезти заказ из точки 1 в точку 4, из 2 в 5, из 3 в 6. Очередность не принципиальна, поэтому маршрут соединяет точки последовательно: 1 → 2 → 3 → 4 → 5 → 6.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но для всех точек указано location.in_lifo_order
= true
, поэтому маршрут соединяет точки по принципу «lifo»: 1 → 2 → 3 → 6 → 5 → 4.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Доставка в одну из возможных точек
Иногда необходимо доставить заказ по любому из нескольких адресов. Например, когда заказ нужно отвезти в произвольный терминал сторонней логистической компании и включить в маршрут более предпочтительный адрес доставки.
В этой ситуации используется тип заказа pickup
, его особенности см. в разделе Прием и доставка. В поле delivery_to_any
через запятую перечисляются идентификаторы заказов с типом drop_off
или складов, на которые можно отвезти груз. Вес и объем для drop_off
-заказов можно не задавать. Узнать, куда именно доставлен заказ, можно из ответа API — для заказа drop_off
или склада идентификаторы доставленных заказов перечисляются в поле delivered_orders
.
Примечание
Значение delivery_to_any
указывается только для pickup-заказов.
Задать идентификаторы складов в поле delivery_to_any
можно только при планировании через API.
Для drop_off
-заказов на листе Orders можно обозначить:
-
Сервисное время (
depot_duration_s
).Если для
pickup
-заказа нужно указать специфичное время отгрузки вdrop_off
, укажите его в полеdepot_duration_s
. В результате оптимизации маршрута несколько заказов типаpickup
могут быть доставлены в одинdrop_off
. -
Жесткие ограничения вместимости (
pickup_capacity
).Вместимость может быть ограничена по следующим параметрам:
- вес (
pickup_capacity.weight_kg
); - количество занимаемых мест (
pickup_capacity.units
); - габариты (
pickup_capacity.volume
).
- вес (
Штраф за нарушение ограничений фиксируется в метрике total_pickup_capacity_penalty
ответа API.
Если значения ограничений должны быть в пользовательских единицах измерения, задайте параметры:
pickup_capacity.custom.<порядковый-номер>.name
— имя пользовательской единицы измерения;pickup_capacity.custom.<порядковый-номер>.size
— размерdrop-off
-заказа по пользовательской единице измерения. По умолчанию —0
.
При необходимости укажите несколько пользовательских единиц измерения и присвойте им любые названия.
Пример 1
В примере ниже 2 pickup-заказа и 2 drop_off-заказа. Для каждого pickup
в поле delivery_to_any
перечислены оба drop_off-заказа.
Обратите внимание, что сервисное время drop_off-заказов составляет 3 минуты. При этом на одном из pickup-заказов значение depot_duration_s
равно 30 минут. Итоговое время выгрузки в drop_off
составляет 33 минуты.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В примере ниже 3 pickup-заказа, 1 заказ drop_off
и 2 склада. Заказы pickup_1 и pickup_2 можно отвезти на любой склад, а pickup_3 — только в drop_off
. В результате планирования курьер отвозит заказ pickup_3 в drop_off
, а заказы pickup_1 и pickup_2 на склад Depot 1.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
3 заказа типа pickup
расположены по одному адресу. Курьер может отвезти каждый из них в одну из двух drop_off
-точек.
Габариты первого заказа превышают габариты, заданные для всех drop_off
. При планировании заказ 1 остается нераспределенным.
Заказы 2 и 3 могут быть доставлены в каждую из drop_off
-точек по-отдельности, но в совокупности превышают допустимые для drop_off
габариты. При планировании они распределяются по разным drop_off
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Получение груза в одной из возможных точек
Иногда груз для доставки можно забрать из любой точки на выбор. Например, если товар, который нужно отвезти на другую точку, есть на нескольких складах. В этом случае для заказа delivery
используется свойство pickup_from_any
.
С заказом delivery
, в котором параметр pickup_from_any
установлен в значение true
, обязательно должно быть связано несколько pickup-заказов. Связь задается в pickup-заказе в поле delivery_to
. При планировании маршрута может быть выбран любой из этих pickup-заказов, остальные игнорируются. Выбор pickup-заказа осуществляется исходя из оптимизации стоимости маршрута.
Обратите внимание, что у всех pickup
и у связанного delivery
вес должен быть одинаковым.
По умолчанию параметр pickup_from_any
равен false
.
Пример
В примере определены 2 заказа delivery
, у которых pickup_from_any
равен true
. С каждым из этих заказов связано по 2 заказа pickup
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Привязка заказа к складу
Используйте привязку заказа к складу, если:
- заказ типа
delivery
доступен только на определенных складах; - заказ типа
pickup
нужно привезти на один из определенных складов.
Для этого в поле depot_id
укажите через запятую один или несколько id
складов, на которых доступен заказ. Если заказ доступен на любом складе, оставьте значение пустым. Аналогично для заказов типа pickup
.
Привязка к складу не требуется в следующих случаях:
-
получение груза в одной из возможных точек (
pickup_from_any
); -
выполнение сценария «Прием и доставка» (
pickup & delivery
).
Какой именно склад выбран для получения или доставки груза, можно посмотреть в параметрах маршрута в ответе API:
- Идентификаторы заказов, доставленных на склад, указаны в поле
delivered_orders
для этого склада. - Идентификаторы заказов, полученных на складе, указаны в поле
picked_orders
для этого склада.
Пример
Даны три склада, три заказа и три автомобиля. Каждый автомобиль стартует со своего склада. Привязка заказов к складам через location.depot_id
:
-
Заказ 1 не привязан к складам. Его можно доставлять с любого склада.
-
Заказ 2 привязан к складам 1 и 2. Этот заказ можно доставить с одного из двух указанных складов.
-
Заказ 3 привязан к складу 3. Он находится на определенном складе.
В результате алгоритм рассчитал два маршрута:
- Один курьер обслуживает заказы 1 и 2 со склада 2.
- Другой курьер обслуживает заказ 3 со склада 3.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Доставка pickup-заказа на склад
Если pickup-заказ нужно привезти на склад, он может быть доставлен как в текущем маршруте (если курьер возвращается на склад в конце рабочего дня), так и в начале следующего маршрута (когда курьер утром стартует со склада). Подробнее см. сценарий Сбор грузов на склад.
Если заказ должен быть доставлен на склад в текущем маршруте, установите для него поле pickup_must_reach_depot
= true
(по умолчанию оно равно false
).
Для поля pickup_must_reach_depot
есть следующие ограничения:
- значение
pickup_must_reach_depot
=true
можно указывать только для pickup-заказов; - значение
pickup_must_reach_depot
=false
допустимо, только если не задано полеdepot_id
, то есть если заказ можно доставить на любой склад.
Если в поле depot_id
указаны один или несколько складов, то pickup-заказ будет доставлен на один из этих складов в текущем маршруте, независимо от значения pickup_must_reach_depot
.
Если в задаче есть pickup-заказы, которые нужно доставить на склад (location.pickup_must_reach_depot
= true
), но нет курьеров, которые посещают склады (т.е. либо стартуют со склада, либо возвращаются на склад в конце маршрута, либо заезжают на склад в середине маршрута), то такая задача планирования не может быть решена и выдаст ошибку.
Пример 1
Курьер развозит 15 заказов, в том числе 3 pickup-заказа, которые должны быть доставлены на склад. Курьер начинает маршрут на складе, но в конце дня не должен возвращаться на склад (return_to_depot
= false
). Поэтому он забирает pickup-заказы и оставляет их у себя, на склад эти заказы будут доставлены только следующим утром.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что в примере 1, но для pickup-заказов установлен признак pickup_must_reach_depot
= true
. Поэтому в конце маршрута курьер привозит эти заказы на склад.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Время доставки заказа на склад
В некоторых случаях pickup-заказы нужно собрать на складе к определенному времени. Например, это актуально для курьерских и логистических компаний, когда этот заказ нужно отправить дальше на другом транспорте (например, отвезти в аэропорт или отправить автомобилем в другой город) — то есть для обеспечения определенных общих сроков доставки может быть необходимо собрать все заказы до определенного времени, иначе их придется отправить уже на следующий день.
Чтобы определить время доставки pickup-заказа на склад, используйте параметр delivery_deadline
. Параметр устанавливает мягкие ограничения, то есть за его нарушение начисляется штраф penalty.delivery_deadline.fixed
или penalty.delivery_deadline.minute
. Параметр меняет поведение только для заказов с типом pickup
. Работа с такими заказами описана в разделе Прием и доставка.
Внимание
По умолчанию курьер выполняет только один рейс в день, и возврат на склад для доставки товара заканчивает рейс. Чтобы один курьер мог возвращаться на склад и продолжать доставку, укажите параметр max_runs
со значением больше 1. Подробнее про настройку количества рейсов написано в разделе Несколько рейсов автомобиля в день.
Пример
В примере ниже один курьер выполняет доставку всех заказов и возвращается на склад в середине дня, чтобы вернуть заказ до указанного delivery_deadline
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Ограничение времени пребывания заказа в автомобиле
При планировании маршрутов может возникать необходимость ограничить время пребывания заказа в автомобиле (например, при доставке замороженных продуктов или медицинских анализов). Для этого используется объект location.transit_time
, который состоит из двух полей:
limit_s
— мягкое ограничение в секундах;hard_limit_s
— жесткое ограничение в секундах.
Для заказа можно устанавливать одно из ограничений на время пребывания в автомобиле или оба одновременно.
Если задано мягкое ограничение limit_s
, то для него должен быть указан хотя бы один из следующих штрафов:
location.penalty.transit_time.fixed
— фиксированный штраф за факт превышения времени нахождения заказа в автомобиле;location.penalty.transit_time.minute
— штраф за каждую минуту превышения установленного ограничения.
Значения по умолчанию для штрафов не заданы.
Если задано жесткое ограничение hard_limit_s
, то заказ будет исключен из всех маршрутов при выполнении одного из следующих условий:
- заказ невозможно доставить без нарушения;
- доставка заказа дороже, чем штраф за его невыполнение.
Ограничение поддерживается для следующих сценариев:
- Доставка с одного склада
- Сбор грузов на склад
- Получение груза в одной из возможных точек
- Доставка в одну из возможных точек
Примечание
Ограничение нельзя использовать в сценариях с якорными точками и кросс-докингом.
Пример
В примере определены 8 заказов, для которых заданы значения transit_time.limit_s
= 3600 и transit_time.hard_limit_s
= 5600. В результате планирования у 2 заказов нарушено мягкое ограничение времени пребывания заказа в автомобиле. Еще 1 заказ невозможно доставить без нарушения жесткого ограничения, поэтому он попадает в список нераспределенных.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Загрузка и выгрузка в гараже
Курьеру можно разрешить загружать и выгружать заказы в гараже, не заезжая на склад. Для этого используйте параметр garage_loading_mode
. Возможные значения:
-
default
— значение по умолчанию. Заказ нельзя загружать или выгружать в гараже, если для него задано хотя бы одно из ограничений:для заказов с типом
delivery
:-
время готовности заказа
depot_ready_time
; -
крайнее время получения заказа на складе
depot_expiring_time
; -
склад, с которого нужно забрать заказ,
depot_id
.
для заказов с типом
pickup
:-
время доставки заказа на склад
delivery_deadline
; -
склад, на который нужно доставить заказ,
depot_id
; -
заказ должен быть доставлен на склад в текущем маршруте
pickup_must_reach_depot
=true
.
-
-
allowed
— заказ можно загружать и выгружать в гараже. Время готовности заказа на складеdepot_ready_time
, крайнее время получения заказа на складеdepot_expiring_time
и время доставки pickup-заказа на складdelivery_deadline
будут рассчитываться также, как для склада. -
forbidden
— заказ нельзя загружать и выгружать в гараже.
Пример 1
Доставку выполняет один курьер, который стартует из точки с типом garage
. Курьеру не обязательно заезжать на склад перед началом маршрута (can_visit_depot_at_start
= true
, visit_depot_at_start
= false
). Для заказа 1 указано время готовности depot_ready_time
= 9:10
, но этот заказ можно загружать в гараже (garage_loading_mode
= allowed
). Для остальных заказов ограничения не заданы. Поэтому курьер доставляет заказы, не заезжая на склад.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что в примере 1, но загрузка заказа 1 в гараже запрещена (garage_loading_mode
= forbidden
). Поэтому курьер в начале маршрута заезжает за заказом на склад.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Мультизаказы
При планировании маршрутов могут возникать случаи, когда несколько заказов должны быть доставлены по одному адресу, например, в один многоквартирный дом или бизнес-центр. Такие заказы могут автоматически объединяться в один или несколько мультизаказов.
Близость объединяемых заказов определяется параметром options.multiorder_radius_m
(по умолчанию 1 м), подробнее см. раздел Мультизаказы. При формировании мультизаказов учитываются не только координаты, но и временные окна заказов и связи между заказами — пары pickup&delivery и объединение в группы.
Объединение заказов в мультизаказы выполняется только в тех случаях, когда это улучшает метрики решения, а также если при этом не нарушаются другие ограничения — вместимость автомобиля или курьера, совместимость заказов по тегам. Можно запретить объединять заказ с другими, указав для него location.can_be_merged
= false
(по умолчанию этот параметр равен true
).
Примечание
Если вы хотите, чтобы все заказы, расположенные по одному адресу, были гарантированно объединены в один мультизаказ — воспользуйтесь опциями options.merge_multiorders
= true
и options.force_merge_multiorders
= true
. Однако в отдельных случаях это требование может ухудшить результаты планирования. Мы рекомендуем использовать эти опцию только если заказы, доставляемые по одному адресу, существенно меньше вместимости автомобиля и вы уверены, что они могут быть доставлены одним автомобилем (с учетом прочих ограничений).
По умолчанию при объединении заказов время на вручение документов или парковку учитывается один раз для группы заказов, если они обслуживаются как мультизаказ.
Если в одном мультизаказе у клиента несколько заказов, время на обслуживание клиента может быть общим.
Для определения сервисного времени для мультизаказа используются следующие параметры:
-
location.shared_service_duration_s
— время на вручение документов или паркинг. Для расчета берется максимальное значение среди всех заказов, объединенных в мультизаказ. -
location.service_duration_s
— время на вручение заказа. -
location.client_service_duration_s
— время на обслуживание одного клиента в мультизаказе. Для расчета берется максимальное значение этого параметра среди заказов одного клиента. Для идентификации клиента используется параметрlocation.client_id
. Алгоритм объединяет заказы с одинаковым идентификаторомclient_id
в один мультизаказ, если это не ухудшает решение (например, объединение двух заказов с разными временными окнами и одинаковым идентификаторомclient_id
может ухудшить решение).
Для обычных заказов, которые находятся по разным адресам, сервисное время на парковкуlocation.shared_service_duration_s
и время на обслуживание клиента location.client_service_duration_s
считаются для каждого заказа отдельно.
Для мультизаказов сервисное время на парковку location.shared_service_duration_s
учитывается только один раз. Время на обслуживание клиента location.client_service_duration_s
для заказов с одинаковым client_id
рассчитывается как максимальное значение среди заказов в мультизаказе, а для заказов с разным client_id
— суммируется.
Для заказов с can_be_merged
= false
время на вручение документов или парковку shared_service_duration_s
учитывается отдельно. Если вы хотите учитывать это время отдельно для каждого заказа в мультизаказе, отключите опцию ожидания options.wait_in_multiorders
= false
. Подробнее — в разделе Опции маршрутизации.
Пример 1
В примере определены 3 заказа с одинаковыми временными окнами и различным временем вручения. Опция объединения мультизаказов активирована.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В примере определены 4 заказа, которые объединяются в один мультизаказ. Заказы 1 и 3 относятся к первому клиенту, а заказы 2 и 4 — ко второму. Время обработки мультизаказа (параметр total_service_duration_s
в ответе API) складывается из следующих значений:
shared_service_duration_s
— 100 секунд, общее время для всех заказов.service_duration_s
— 600 секунд, время на вручение каждого заказа.client_service_duration_s
для первого клиента — 300 секунд (максимальное значение для заказов 1 и 3).client_service_duration_s
для второго клиента — 400 секунд (максимальное значение для заказов 2 и 4).
В результате время обработки мультизаказа составляет 100 + 4*600 + 300 + 400 = 3200
секунд.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
То же что в примере 2, но для заказа 1 установлено can_be_merged
= false
. Тогда для заказа 1 сервисное время составляет 100 + 600 + 100 = 800
секунд, а для мультизаказа, объединяющего 2, 3 и 4 заказы, сервисное время составляет 100 + 3*600 + 300 + 400 = 2600
секунд. Общее сервисное время total_service_duration_s
— 3400 секунд.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Деление заказов на части
При планировании маршрутов могут возникать случаи, когда заказ нужно разделить на несколько частей и развезти эти части разными автомобилями. Это могут быть сыпучие грузы или грузы в паллетах.
Чтобы разделить заказ на части, в объекте locations
укажите следующие параметры:
-
can_be_split
— заказ может быть разделен на части (только для заказов типаdelivery
иpickup
). По умолчаниюfalse
. -
max_split_parts
— максимальное число частей, на которые можно разделить заказ. По умолчанию 10. -
quant
— минимальный размер отделенной части, который задается форматами:"quant": 0.25
— соответствует доле заказа. В этом примере минимальная часть соответствует четверти заказа."quant": {"weight_kg": 2.5}
— задает размер минимальной части вweight_kg
,units
илиvolume_cbm
. В этом примере минимальная часть равна 2,5 кг.
Если при делении заказа на части возникает остаток, он может быть меньше чем quant
.
Чтобы от заказа отделялась часть, которая занимает весь автомобиль в текущем рейсе, используйте параметр locations.split_parts_must_fill_whole_vehicle
= true
(по умолчанию false
). В этом случае также может возникать остаток.
В одном рейсе можно перевезти несколько остатков от разных заказов.
Примечание
Если split_parts_must_fill_whole_vehicle
= true
, минимальный размер отделяемой части quant
указывать нельзя.
При работе с полученным решением или на карте вы можете проверить, какие заказы были разделены: у разделенных заказов в поле Номер заказа указан номер части заказа. В метрике split_orders_percentage
вы увидите долю разделенных заказов.
Внимание
Для решений с разделенными заказами не работают ручные корректировки в Рабочем месте логиста.
Пример 1
Нужно развезти 6 заказов по 1000 кг на 4 автомобилях вместимостью 1500 кг. Заказы можно делить пополам и доставлять частями, но не больше 50% от общего числа заказов. За нарушение ограничения начисляется фиксированный штраф. В результате планирования 2 заказа разделены пополам и доставлены на разных автомобилях. Штраф max_split_orders_percentage_penalty
= 0.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Нужно доставить 1 заказ объемом 50 кубометров со склада на строительную площадку. Доступны 3 автомобиля вместимостью 5, 7,5 и 10 кубометров, поэтому заказ будет доставлен по частям. Минимальный размер каждой части — 5 кубометров. Каждый автомобиль может сделать 3 рейса. В результате планирования заказ будет разделен на 7 частей.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Нужно доставить заказ из 20 паллет со склада в магазин. Доступен 1 автомобиль вместимостью 19 паллет, который может сделать только один рейс. В результате планирования доставлена часть заказа из 19 паллет, и 1 паллета осталась нераспределенной.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
Нужно доставить 2 заказа массой 1500 кг и 2200 кг на автомобиле грузоподъемностью 1000 кг. Параметр split_parts_must_fill_whole_vehicle
= true
, поэтому заказы будут разделены на части по 1000 кг с остатком. В результате планирования остатки от заказов будут доставлены в одном рейсе.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Время между прибытием частей заказа
Вы можете ограничить время между прибытием разных частей заказа. Для этого в параметре locations.max_time_between_visits_s
укажите максимально разрешенное время в секундах. Этот параметр устанавливает мягкое ограничение, за нарушение которого начисляются штрафы:
locations.penalty.time_between_visits.fixed
— фиксированный штраф за факт превышения установленного ограничения;locations.penalty.time_between_visits.minute
— штраф за каждую минуту превышения установленного ограничения.
Максимальная доля разделенных заказов
Чтобы ограничить максимальную долю заказов, которые могут быть разделены, используйте параметр options.max_split_orders_percentage
. Он устанавливает мягкое ограничение, за нарушение которого начисляются штрафы:
options.penalty.split_orders_percentage.fixed
— фиксированный штраф за факт превышения установленного ограничения;options.penalty.split_orders_percentage.per_percent
— штраф за каждый процент превышения установленного ограничения.
Доставка крупных частей заказа как можно раньше
Если важно, чтобы более крупные части заказа доставлялись как можно раньше, используйте штраф options.penalty.small_order_part_before_big.scaled
. Он начисляется за каждую пару частей заказа, которые были доставлены одним курьером, но меньшая часть раньше чем большая. Значение, указанное в параметре, умножается на разницу долей этих частей относительно всего заказа.
Например, заказ разбит на три части: 15 + 15 + 10 = 40 долей. Все три части заказа доставлены одним курьером. Часть из 10 долей доставлена раньше, чем обе части по 15 долей. В результате будет начислен штраф:
(options.penalty.small_order_part_before_big.scaled
* (15 - 10) / 40) * 2
Пример 1
Курьер доставляет два заказа по 40 юнитов каждый. Заказы можно разделить не более чем на три части, минимальный размер части заказа — 15 юнитов. Курьер может доставить не более 35 юнитов в одном рейсе.
Курьер отвозит:
- в первом рейсе — 25 юнитов из заказа 1 и 10 юнитов из заказа 2;
- во втором рейсе — 30 юнитов из заказа 2;
- в третьем рейсе — 15 юнитов из заказа 1.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что в примере 1, но задан штраф options.penalty.small_order_part_before_big.scaled
= 10 000. Курьер доставляет сначала более крупные части заказов:
- в первом рейсе — 30 юнитов из заказа 2;
- во втором рейсе — 25 юнитов из заказа 1 и 10 юнитов из заказа 2;
- в третьем рейсе — 15 юнитов из заказа 1.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Штраф за недоставку части заказа
При делении заказа на части одна или несколько частей могут оказаться нераспределенными. Чтобы штраф за недоставку penalty.drop
рассчитывался исходя из размера недоставленной части заказа, можно указать постоянную и переменную части штрафа: penalty.drop.fixed
и penalty.drop.scaled
.
Штраф вычисляется по формуле: penalty.drop.fixed + order_ratio * penalty.drop.scaled
, где order_ratio
— это часть (доля) заказа, которая не была доставлена.
Можно указать только постоянную или только переменную часть штрафа.
Пример
Нужно доставить заказ весом 2000 кг. Заказ можно делить на части по 250 кг. Доступен 1 автомобиль вместимостью 1500 кг, который может выполнить только 1 рейс. Штраф за недоставку части заказа складывается из фиксированной части в 1 000 000 единиц и переменной части в 200 000 единиц.
В результате планирования часть заказа, равная 500 кг (1/4 заказа), не была доставлена. Штраф составил 1 000 000 + (200 000 * 0,25) = 1 050 000 единиц.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Сервисное время при делении заказа на части
Сервисное время для разделяемого заказа можно задавать одним из способов:
- как фиксированное время для каждой части заказа независимо от ее размера;
- в зависимости от размера (доли) доставленной части заказа. В этом случае параметры
service_duration_s
,shared_service_duration_s
,client_service_duration_s
,depot_duration_s
иcrossdock_service_duration_s
задаются в виде структур с полямиfixed
иscaled
.
Примечание
Параметр parking_service_duration_s
не может задаваться в виде структуры с полями fixed
и scaled
и всегда задается как фиксированное число.
Параметры расчета сервисного времени разделяемого на части заказа можно объединить в структуру service_durations
с элементами:
location
— соответствует параметруservice_duration_s
;stop
— соответствует параметруshared_service_duration_s
;client
— соответствует параметруclient_service_duration_s
;depot
— соответствует параметруdepot_duration_s
;crossdock
— соответствует параметруcrossdock_service_duration_s
;parking
— соответствует параметруparking_service_duration_s
.
Каждый из этих элементов, кроме parking
, можно задавать либо числом, либо структурой с полями fixed
и scaled
— в этом случае соответствующее время обслуживания вычисляется по формуле: fixed + order_ratio * scaled
, где order_ratio
— это доставленная часть (доля) заказа.
Примечание
При использовании структуры service_durations
для заказа нельзя отдельно указывать соответствующие параметры service_duration_s
, shared_service_duration_s
, client_service_duration_s
, depot_duration_s
, crossdock_service_duration_s
и parking_service_duration_s
.
В ответе API содержимое структуры service_durations
остается без изменений: те поля, которые задавались в виде фиксированной и переменной части, выводятся как структуры, а те, которые задавались как число, выводятся как число.
Если сервисные времена заданы без структуры service_durations
, то параметры crossdock_service_duration_s
и depot_duration_s
в ответе API остаются такими же, какими были в запросе. Остальные параметры выводятся в виде числа, соответствующего реальному времени обслуживания для данного заказа в полученном решении. При этом на окончательное значение могут влиять и другие параметры, например, объединение в мультизаказ или множитель service_duration_multiplier
.
Пример 1
Автомобиль вместимостью 600 кг доставляет заказ весом 2100 кг. Заказ можно делить на части весом не менее 300 кг. В результате автомобиль делает 4 рейса: три рейса с грузом 600 кг (2/7 заказа) и один рейс с грузом 300 кг (1/7 заказа).
Для заказа задано:
- время обслуживания на заказ
service_duration_s
, состоящее из фиксированной части 600 сек и переменной 70 сек (по 10 сек на каждые 300 кг); - время загрузки на складе
depot_duration_s
, также состоящее из фиксированной части 300 сек и переменной 140 сек (по 20 сек на каждые 300 кг).
Общее время обслуживания составляет (600 + 20 + 300 + 40) * 3 + (600 + 10 + 300 + 20) = 3810 сек.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же что в примере 1, но сервисное время задано в виде структуры service_durations
.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Штрафы за невыполнение заказа
Для каждого заказа в запросе к Маршрутизации можно определить штраф за невыполнение заказа. При недостатке автомобилей или курьеров отдельные заказы могут быть исключены из всех маршрутов.
Например, если выполнение заказа, находящегося на большом расстоянии от остальных, приведет к опозданию на остальные заказы в несколько часов, такой заказ может быть исключен из маршрутов как невыполненный.
Примечание
В ответе Маршрутизации невыполненные заказы будут помещены в отдельное поле dropped_locations
.
Данный штраф добавляется к общей стоимости маршрута, если заказ не удается запланировать ни на один из заданных автомобилей.
Существует множество причин почему заказ не удалось включить в один из маршрутов, например:
-
вес заказа превышает грузоподъемность любого из заданных автомобилей;
-
суммарный вес заказов превышает общую грузоподъемность автомобилей, так что заказы нельзя развезти даже с учетом дополнительных рейсов. Поэтому в любом случае остаются нераспределенные заказы;
-
данный заказ несовместим ни с одним из заданных автомобилей, или грузоподъемность совместимых с определенным набором заказов автомобилей слишком мала, чтобы вместить их все;
-
невозможно доставить заказ в заявленное жесткое временное окно;
-
невозможно развезти заказы с учетом жесткого ограничения на смены водителей;
-
задано жесткое узкое окно склада и параметры возврата на склад у автомобилей — в результате система планирует возврат на склад, при этом не успевая развезти заказы
-
неверные координаты заказа, из-за которых он оказывается в географическом удалении от остальных заказов, и система не находит возможности выполнить этот заказ;
-
планирование сложной задачи в режиме low.
В общем случае, если у одного заказа задан штраф в 50 единиц, а у другого в 5 единиц, заказ со штрафом в 50 единиц будет считаться более важным и с более высокой вероятностью попадет в спланированные маршруты.
Для определения штрафа за недоставку заказа в Маршрутизации используется поле location.penalty.drop
.
Примечание
Обратите внимание на размерность значения по умолчанию для данного поля (по умолчанию 1000000). Изменение данного поля требуется только для сценариев, в которых ожидается, что должны возникать нераспределенные заказы. Для управления приоритетами рекомендуется использовать значение аналогичного или более высокого порядка и не использовать значение, равное 0.
В случае сомнения свяжитесь с аналитиками Яндекс Маршрутизации для определения корректных коэффициентов.
Совместимость заказа и автомобилей
При определении заказа в запросе к Маршрутизации возможно назначить список требований к автомобилю, который должен выполнить данный заказ.
Для определения тегов заказа (требуемых характеристик автомобилей) используется поле location.required_tags
.
Заказ считается совместимым с автомобилем, если выполняется любое из правил совместимости автомобиля и заказа. Правила совместимости задаются при определении автомобилей.
Подробнее о правилах совместимости смотрите в разделе Теги автомобиля.
Если для заказа существуют необязательные, но желательные требования к автомобилю или курьеру (например, рекомендуемый уровень квалификации курьера, предпочтение получателя, чтобы доставку осуществлял определенный курьер и т.п.), то они указываются в поле location.optional_tags
. Подробнее см. в разделе Опциональные теги.
Пример
В примере 4 заказа требуют перевозки с соблюдением температурного режима — в location.required_tags
значится тег Холодильник
. Причем два из них требуют автомобиль с гидробортом — у них в поле location.required_tags
указано два тега: Холодильник
, Гидроборт
. Эти заказы совмещаются с автомобилем 1, укоторого в поле vehicle.tags
указаны подходящие значения: Холодильник
, Гидроборт
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Несовместимость заказов
Если вам необходимо перевозить типы заказов, которые не могут находиться в машине одновременно, Маршрутизация позволяет определить один или более несовместимых типов. В Маршрутизации нет предопределенных типов заказов.
В качестве несовместимых типов могут использоваться:
-
Несовместимые грузы, которые по объективным причинам не могут перевозиться в одной машине в рамках одного рейса.
-
Несовместимость различных грузополучателей между собой. Например: разделение товаров конкурентов по разным машинам, разделение по определенным типам клиентов.
Для определения типа заказа используется поле location.load_types
. При необходимости вы можете указать более одного типа для каждого заказа. Для определения несовместимых заказов используется поле options.incompatible_load_types
, которое в Excel задается на листе Incompatible_order_types. В этом поле вы можете указать список несовместимых типов — при планировании заказы разделяются по разным автомобилям, если в них есть по крайней мере один несовместимый тип.
Чтобы задать несовместимость заказов для отдельного автомобиля, используйте параметр vehicle.incompatible_load_types
, который позволит учесть особенности автомобиля.
Примечание
Несовместимость заказов является жестким ограничением, то есть она не может быть нарушена при автоматической маршрутизации. Например, если в одну точку заданы несколько заказов и при этом они являются несовместимыми — алгоритм спланирует их в разные машины. Использование типов несовместимости заказов может привести к получению неоптимальных маршрутов. Поэтому стоит вводить только действительно значимые ограничения, которые и на практике являются обязательными правилами.
Несовместимость заказов с учетом геозон
Иногда курьеру в одном маршруте нужно доставить заказы:
- несовместимые по типам;
- относящиеся к разным геозонам с ограничениями.
Чтобы соблюсти условия перевозки, предусмотрено разделение маршрута на рейсы. Часть заказов при этом может остаться нераспределенной.
Если нужно, чтобы заказ был распределен и доставлен без учета несовместимости геозон, на листе Orders в поле ignore_zones_compatibility
укажите для него значение true
(по умолчанию ignore_zones_compatibility
= false
). В этом случае курьер сможет выполнить доставку, игнорируя ограничения, заданные в полях:
incompatible_zones
на листах Vehicles и Options;allowed_zones
иforbidden_zones
на листе Vehicles;optional_zones.N.zone
иoptional_zones.N.value
на листе Vehicles.
Параметр ignore_zones_compatibility
используется для заказов и точек, в которых можно выгрузить товар (drop_off
), а также оставить прицеп надолго и сделать перекатку (anchor
). Подробнее о типах заказов см. в разделе Тип заказа.
Пример 1
При перевозке бытовой химии, продуктов питания и цветов одним парком автомобилей в поле location.load_types
необходимо указать типы груза chemicals
, food
, flowers
для соответствующих заказов.
Чтобы товары бытовой химии никогда не оказались в одной машине с продуктами питания или цветами, но при этом цветы и продукты питания можно было перевозить вместе, задайте следующие правила несовместимости:
type |
incompatible_load_types |
chemicals |
food, flowers |
В примере мы задали 3 заказа и каждому их них присвоили один из этих 3 типов. Алгоритм в итоге спланировал 2 маршрута.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В примере указаны 4 заказа, задана несовместимость по грузам и дополнительно указана несовместимость по географическим зонам.
В итоге все заказы несовместимы между собой и алгоритм планирует 4 маршрута несмотря на то, что 2 заказа отправляются в одну точку.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Курьер за 2 рейса должен выполнить 15 заказов разных типов. Типы заказов указаны на листе Orders в поле type
. В заказах 3 и 5 должны перевозиться продукты питания (load_types
= food
), а в заказах 13 и 15 — корм для животных (load_types
= pets
). На листе Incompatible_order_types указано, что эти типы грузов несовместимы. Они не могут перевозиться вместе.
Для курьера заданы ограничения на посещение геозон. На листе Vehicles в поле forbidden_zones
указана запрещенная к посещению зона Lefortovo
. В поле incompatible_zones.0
указана зона Khovrino-park
, а в поле incompatible_zones.1
— зона Vorontsov-park
. Это несовместимые зоны. Курьер не сможет посетить их в одном рейсе.
Для всего решения на листе Options в полях incompatible_zones.0
и incompatible_zones.1
также указаны зоны Khovrino-park
и Vorontsov-park
.
В результате маршрут спланирован следующим образом:
- курьер не посещает запрещенную зону
Lefortovo
; - заказы 3 и 5 распределены в первый рейс, а заказы 13 и 15 — во второй;
- заказы 13 и 15 в зоне
Khovrino-park
и заказ 14 в зонеVorontsov-park
распределены в разные рейсы; - заказы 1 и 7 остаются нераспределенными.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
Те же условия, что в примере 3, но для заказов 1 и 7 на листе Orders в поле ignore_zones_compatibility
указано значение true
.
В результате для всех заказов, кроме 1 и 7, соблюдаются ограничения по посещению геозон из примера 3. Заказы 1 и 7 распределены в первый рейс. Они будут доставлены, несмотря на ограничения по геозонам.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Включение и выключение опций кучности
Опция location.use_in_proximity
точечно отключает options.proximity_factor и options.global_proximity_factor, которые отвечают за кучность маршрутов.
По умолчанию location.use_in_proximity
= true
, то есть опции кучности действуют на все заказы. Подробнее см. в разделе Кучные маршруты.
Порядок выполнения заказов
Если одни заказы в маршруте нужно выполнить раньше, чем другие, вы можете задать порядок выполнения с помощью параметра sequence_order
. Например, если для заказа 1 задано значение sequence_order
= 1, а для заказа 2 – sequence_order
= 2, то заказ 1 должен быть выполнен раньше заказа 2.
Внимание
Порядок устанавливается в рамках одного маршрута в сквозном порядке для всех рейсов автомобиля. Но для всего планирования возможна ситуация, при которой заказ с бо́льшим значением параметра sequence_order
в одном маршруте будет доставлен раньше, чем заказ с меньшим значением параметра в другом маршруте.
Примеры, для которых важен порядок выполнения заказов:
-
Сначала нужно забрать документы, потом подписать их на другой точке, затем вернуть обратно.
-
Автомобиль не оборудован холодильником, поэтому в первую очередь нужно доставить продукты с особым температурным режимом.
-
Прежде всего нужно выполнить заказы в дальних точках или заказы VIP-клиентов, после них — остальные.
Значением параметра sequence_order
может быть целое неотрицательное число.
Заказы выполняются в порядке неубывания sequence_order
. Соответственно, в каждом следующем рейсе значение sequence_order
должно быть не меньше, чем в предыдущем. Заказы с одинаковым значением порядка выполняются в произвольной последовательности. Заказы, для которых не задано значение sequence_order
, могут размещаться в любом порядке и любом месте маршрута.
Пример
В примере 3 заказа: заказ 1 с sequence_order
= 1, заказ 2 с sequence_order
= 2 и заказ 3 без указания порядка. Это значит, что в рамках маршрута сначала должен быть выполнен заказ 1, затем – заказ 2. Заказ 3 может быть выполнен в любой момент. В результате планирвоания возможны варианты последовательностей заказов:
-
Заказ 1 → Заказ 2 → Заказ 3
-
Заказ 1 → Заказ 3 → Заказ 2
-
Заказ 3 → Заказ 1 → Заказ 2
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Порядок выполнения в запланированных маршрутах
Если последовательность заказов в запланированном маршруте не соответствует порядку выполнения, заданному с помощью sequence_order
, то заказы будут упорядочены по sequence_order
.
Исключение: если параметр vehicles.fixed_planned_route
равен true
и запланированный маршрут не требуется оптимизировать. В этом случае, если решение нарушает порядок, задаваемый параметром sequence_order
, оно будет считаться невыполнимым (UNFEASIBLE
).
Пример
В примере 4 заказа и 1 курьер. В vehicles.planned_route
заказы записаны в прямом порядке: 1 → 2 → 3 → 4. В sequence_order
заказы записаны в обратном порядке: 4 → 3 → 2 → 1. Здесь запланированный маршрут не зафиксирован, vehicles.fixed_planned_route
= false
.
В результате заказы упорядочены в соответствии со значениями sequence_order
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Порядок выполнения в фиксированных маршрутах
Если фиксированная часть маршрута нарушает порядок, заданный с помощью sequence_order
, то решение будет считаться невыполнимым (UNFEASIBLE
). В противном случае заказы, которые нужно выполнить после фиксированной части маршрута, должны иметь значение sequence_order
не меньше, чем максимальное значение sequence_order
среди заказов в фиксированном маршруте.
Пример
В примере 4 заказа и 1 курьер. В vehicles.visited_locations
перечислены заказы: 2, 4, 3. Для заказов 2 и 4 параметр sequence_order
= 1, для заказов 1 и 3 – sequence_order
= 2. В результате сначала выполняются заказы из фиксированной части маршрута: 2 → 4 → 3 → 1.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Порядок выполнения в мультизаказах
Опция options.merge_multiorders
объединяет заказы, расположенные по одному адресу, в мультизаказ, только если для таких заказов задан одинаковый порядок выполнения sequence_order
. Отсутствие sequence_order
при этом считается отдельным значением. Если у нескольких заказов, расположенных по одному адресу, будет указано разное значение порядка выполнения, то эти заказы необязательно будут объединены в мультизаказ (но могут быть объединены, если такое решение будет более оптимальным и возможным с учетом заданных ограничений).
Примеры
В примерах 2 курьера с вместимостью по 8 заказов. Включена опция объединения в мультизаказы. Всего 12 заказов:
-
Первая группа — 4 заказа с одинаковыми значениями
sequence_order
и адресами. -
Вторая группа — 4 заказа с одинаковыми адресами, но 2 заказа с одинаковыми значениями
sequence_order
и 2 — без этих значений. -
Третья группа — 4 заказа с разными значениями
sequence_order
, среди которых только 2 с одинаковыми адресами.
Пример 1
В третьей группе одинаковые адреса у заказов 3-А и 3-Г. В результате объединены только заказы в первой и второй группах.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В третьей группе одинаковые адреса у заказов 3-А и 3-Б. В результате заказы 3-А и 3-Б тоже объединены в один мультизаказ.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Дополнительные параметры заказа для оптимизации маршрута
Иногда для оптимизации маршрута нужно учитывать какой-то специфический параметр заказа. Например, заработок курьера за выполнение конкретного заказа или ценность заказа с точки зрения бизнес-процессов. Для учета таких параметров в задачах используется дополнительное числовое поле custom_value
.
Значения custom_value
суммируются и записываются в переменную, доступную по ключевому слову total_custom_value
при использовании расширенных настроек стоимости.
Пример
В курьерской службе доставки еды курьеры получают оплату только за доставку заказа клиенту, а посещения ресторана, чтобы забрать заказы, не оплачиваются. Компании выгодно, чтобы за смену курьер доставил не менее 12 заказов.
Чтобы реализовать такой сценарий, заказам с типом delivery
назначается одинаковая ценность custom_value
= 1, а для заказов с типом pickup
значение этого поля равно 0. Стоимость использования автомобиля задается формулой: 1000 + 100 * duration_h + 100 * max(0, 12 – total_custom_value)
. Тогда если курьер доставит меньше 12 заказов, это увеличит стоимость автомобиля на 100 единиц за каждый недоставленный заказ. Для компании высокая стоимость будет означать неоптимальное использование автомобиля.
В примере курьер 1 доставляет только 4 заказа за 1,74 часа, поэтому стоимость решения для его маршрута total_custom_cost
составляет 1000 + 174 + 800 = 1974
единицы. Курьер 2 доставляет 12 заказов за 4,16 часа, и стоимость решения для его маршрута составляет 1000 + 416 = 1416
единиц.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте