Свойства заказов

Заказы в Яндекс Маршрутизации представляют собой точки, которые посещаются одним или более автомобилями в оптимальном порядке с соблюдением ограничений.

Для определения заказов используется поле запроса locations. Принцип «заказ = location» применим в большинстве ситуаций доставки со склада. Но в общем случае для сервиса планирования маршрутов location — это точка, в которой нужно выполнить определенное действие.

В locations будет больше точек, чем ваших заказов, если:

Идентификатор заказа

Обязательным атрибутом заказа является уникальный числовой или строковый идентификатор, который задается в поле 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 (стоимость заказа):

Стоимость заказа

shipment_size.custom.0.name

shipment_size.custom.0.size

price

100

Суммарная стоимость заказов

capacity.custom.0.name

capacity.custom.0.size

price

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. Возможные варианты перечислены ниже:

align/type

rigid

fixed_bottom

all_axes

Заказ может быть повернут на 900 по любой оси, но всегда ставится строго параллельно осям кузова.

Заказ может быть повернут на 900, но его дно** остается неизменным, то есть находится на дне кузова автомобиля.

height

Заказ может быть повернут как угодно, при условии, что одна любая сторона остается на дне кузова автомобиля, то есть высота* должна быть параллельна высоте грузового отсека.

Заказ может быть повернут как угодно, при условии, что его дно** остается неизменным, то есть находится на дне кузова автомобиля.

* Параметр 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». Для этого:

  1. Добавьте заказ с типом pickup и в поле location.delivery_to укажите идентификатор заказа типа delivery, куда нужно доставить заказ в контейнере.
  2. Добавьте заказ с типом return — адрес точки, куда нужно вернуть контейнер после доставки заказа.
  3. Для заказа с типом 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.

Например, один автомобиль перевозит стул, кресло и кровать с трех адресов на три другие адреса. Если загружать и выгружать мебель в таком же порядке, то для выгрузки стула потребуется сначала достать кровать, затем кресло и только в конце стул, а после этого загрузить обратно кресло и кровать, чтобы поехать на следующий адрес. Очевидно, дополнительные циклы загрузки и выгрузки потребуют дополнительное время и силы. Чтобы избежать лишних затрат, стоит заранее спланировать очередь загрузки и выгрузки:

  1. Загрузить кровать.
  2. Загрузить кресло.
  3. Загрузить стул.
  4. Выгрузить стул.
  5. Выгрузить кресло.
  6. Выгрузить кровать.

Такой порядок действий отражает принцип «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.

Привязка к складу не требуется в следующих случаях:

Какой именно склад выбран для получения или доставки груза, можно посмотреть в параметрах маршрута в ответе API:

  • Идентификаторы заказов, доставленных на склад, указаны в поле delivered_orders для этого склада.
  • Идентификаторы заказов, полученных на складе, указаны в поле picked_orders для этого склада.

Пример

Даны три склада, три заказа и три автомобиля. Каждый автомобиль стартует со своего склада. Привязка заказов к складам через location.depot_id:

  • Заказ 1 не привязан к складам. Его можно доставлять с любого склада.

  • Заказ 2 привязан к складам 1 и 2. Этот заказ можно доставить с одного из двух указанных складов.

  • Заказ 3 привязан к складу 3. Он находится на определенном складе.

В результате алгоритм рассчитал два маршрута:

  1. Один курьер обслуживает заказы 1 и 2 со склада 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Открыть на карте

Написать в службу поддержки