Свойства транспортных средств
- Идентификатор автомобиля или курьера
- Вместимость автомобиля или курьера
- Характеристики транспортного средства
- Сервисное время погрузки на складе
- Старт автомобиля не со склада
- Старт с одного из нескольких складов
- Дозагрузка на промежуточном складе
- Возврат на склад в конце маршрута или рейса
- Начало или окончание маршрута как можно ближе к складу
- Смены работы автомобиля или курьера
- Несколько рейсов курьера в день
- Ограничение количества остановок в смене
- Максимальная продолжительность смены
- Максимальный пробег за смену
- Кучность маршрута
- Стоимость автомобиля или курьера
- Расширенные настройки стоимости
- Расчет выплаты курьеру
- Теги автомобиля
- Несовместимость заказов в автомобиле
- Геозоны
- Способ передвижения
- Режим работы курьера
- Запланированный маршрут
- Фиксированная часть маршрута
- Корректировка времени движения автомобиля
- Корректировка времени обслуживания
- Доставка как можно раньше
- Сцепки
- Минимальный вес заказа для автомобиля
Доставка заказов в Яндекс Маршрутизации может выполняться как обычными автомобилями, так и курьерами, передвигающимися пешком или на общественном транспорте. Автомобиль и курьер имеют общий набор свойств.
Для определения автомобиля или курьера используется поле запроса vehicles
.
Идентификатор автомобиля или курьера
Обязательным атрибутом автомобиля или курьера является уникальный числовой или строковый идентификатор, который задается в поле id
. Идентификатор должен быть уникальным в пределах одного запроса к сервису. При экспорте в Мониторинг этот идентификатор будет использоваться как логин курьера.
Дополнительно вы можете указать числовой или строковый идентификатор автомобиля или курьера из вашей учетной системы в поле ref
, а также номер мобильного телефона курьера в поле phone
для связи с ним из Мониторинга.
Вместимость автомобиля или курьера
Маршрутизация поддерживает определение вместимости автомобиля для определения максимального веса или количества груза, которое автомобиль/курьер может перевезти за один маршрут.
Чтобы определить вместимость автомобиля или курьера, используйте поле capacity
(достаточно указать один из вариантов):
-
capacity.units
— количество мест (паллет, коробок, кег). -
capacity.weight_kg
— вес в килограммах или объемный вес. -
capacity.volume
— объем, который измеряется в кубометрах и задается как произведение измерений:-
capacity.volume.width_m
— ширина в метрах. -
capacity.volume.depth_m
— глубина в метрах. -
capacity.volume.height_m
— высота в метрах.
Если измерения неизвестны, используйте
capacity.volume_cbm
. -
-
capacity.volume_cbm
— объем, заданный в кубометрах.
Если у автомобиля заданы и метрические размеры, и объем, то capacity.volume
определяет габариты, а capacity.volume_cbm
— вместимость.
Более подробно с определением веса вы можете ознакомиться в главе Вес и объем.
Примечание
Обратите внимание, если вес заказов задан в килограммах или как объемный вес, вместимость автомобиля должна быть задана в таких же единицах. Аналогично, если вес заказов задан в виде количества мест, определение вместимости автомобиля должно содержать максимальное количество мест в каждом автомобиле.
Дополнительно, возможно определение максимальной загрузки автомобиля в процентах от заданной грузоподъемности. Для этого используется поле запроса limits
:
-
limits.volume_perc
— процентное значение от заданного вcapacity.volume.width_m
*capacity.volume.depth_m
*capacity.volume.height_m
. -
limits.weight_perc
— процентное значение от заданного вcapacity.weight_kg
. -
limits.unit_perc
— процентное значение от заданного вcapacity.units
.
Чтобы указать возможность перегруза относительно заданного значения, укажите значение больше 100. Чтобы оставить запас грузоподъемности, например под возможные неточности в оценке габаритов заказа, укажите значение меньше 100. Например, значение 110 позволяет 10% перегруза, а значение 90 — максимальную загрузку в 90% от указанной грузоподъемности.
Вместимость автомобиля (с учетом limits
) — жесткое ограничение, которое не будет нарушено. При этом при расчете загруженности автомобиля учитываются заказы на прием и доставку. Подробнее в разделе Прием и доставка.
Примечание
Через вместимость автомобиля можно косвенно управлять количеством заказов, которые должны в него попасть. Например, если указать объем каждого заказа в 1 юнит (независимо от реальных размеров заказа), а вместимость автомобиля – 10 юнитов, то при планировании в каждый автомобиль попадет не более 10 заказов.
Пример
Дано два автомобиля грузоподъемностью 1,5 тонны (Автомобиль 1) и 3 тонны (Автомобиль 2), а также три заказа для доставки весом 1 тонна, 1,2 тонны и 1,4 тонны.
При оптимизации маршрутов, заказ весом 1,2 тонны будет размещен в Автомобиль 1, и два заказа весом 1 и 1,4 тонны в Автомобиль 2.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пользовательские единицы вместимости
Пользовательская единица ограничивает вместимость автомобиля по пользовательской единице измерения, указанной для заказов.
Можно задать несколько пользовательских единиц вместимости автомобиля, каждая из них должна иметь свой порядковый номер N
(нумерация начинается с 0). Каждая единица описывается двумя параметрами:
-
capacity.custom.N.name
— имя пользовательской единицы; -
capacity.custom.N.size
— вместимость автомобиля по пользовательской единице.
По умолчанию вместимость по параметру capacity.custom.N.size
не ограничена.
Внимание
Название пользовательской единицы вместимости автомобиля должно совпадать с указанным для заказа.
Если пользовательские единицы измерения вместимости указаны для заказов или явно заданы у одних автомобилей, но не заданы у других, то для автомобилей, где они не заданы, вместимость по пользовательским единицам измерения считается неограниченной.
Пример заполнения листов файла Excel для пользовательского параметра price
(стоимость заказа):
Стоимость заказа
|
|
|
100 |
Суммарная стоимость заказов
|
|
|
1000 |
Пример 1.1
4 автомобиля выполняют 16 заказов. Для автомобилей указаны вес, объем и грузоподъемность (количество грузовых мест). С помощью пользовательских единиц для заказов указана стоимость location.shipment_size.custom.0
, а для автомобилей — ограничение по суммарной стоимости перевозимых заказов vehicle.capacity.custom.0
.
Есть 2 автомобиля, которые везут по 1 заказу, хотя утилизация по весу, объему и количеству мест у них небольшая – это обусловлено тем, что стоимость этих заказов находится близко к установленному для автомобиля ограничению.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 1.2
То же, что в примере 1.1, но дополнительно указано максимальное количество заказов, которое может перевезти автомобиль. Ограничение задано с помощью параметров location.shipment_size.custom.1
и vehicle.capacity.custom.1
. Каждый автомобиль теперь может везти не более 5 заказов.
Количество заказов в трех автомобилях изменилось. Теперь 1 заказ везет только 1 автомобиль, в который нельзя больше добавить заказы из-за ограничения по суммарной стоимости. По остальным достигнута максимальная утилизация по суммарной стоимости в каждом автомобиле, но удалось выдержать ограничение по количеству заказов.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Два автомобиля выполняют 20 заказов. Заказы имеют разную длину, эта характеристика описывается двумя пользовательскими единицами:
- единица
Length5
(location.shipment_size.custom.0
) равна 1 для заказов длиной 5 метров (это заказы с 10 по 15) и 0 для остальных заказов; - единица
Length6
(location.shipment_size.custom.1
) равна 1 для заказов длиной 6 метров (это заказы с 16 по 20) и 0 для остальных заказов. Заказы с 1 по 9 имеют длину менее 5 метров, для них обе пользовательские единицыLength5
иLength6
равны 0.
Автомобили имеют одинаковую грузоподъемность, но разную длину кузова:
- у Vehicle6 длина кузова 6 метров, он может перевозить любые заказы. Для него
vehicle.capacity.custom.0
иvehicle.capacity.custom.1
равны 10 (с учетом веса заказов и грузоподъемности автомобиля); - у Vehicle5 длина кузова 5 метров, он не может перевозить заказы длиной 6 метров. Для него
vehicle.capacity.custom.0
= 10, аvehicle.capacity.custom.1
= 0.
В спланированном решении автомобиль Vehicle5 перевозит заказы длиной 5 метров и менее 5 метров, а Vehicle6 — заказы длиной 6 метров, 5 метров и менее 5 метров.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Характеристики транспортного средства
Характеристики транспортного средства можно задать в поле vehicle.specs
. В нем могут быть указаны следующие параметры:
-
width
— ширина транспортного средства в метрах; -
height
— высота транспортного средства в метрах; -
length
— длина транспортного средства в метрах; -
max_weight
— максимальный вес транспортного средства в тоннах; -
max_weight_kg
— максимальный вес транспортного средства в килограммах (округляется до тонн в большую сторону при решении задачи планирования).
Примечание
Если в задаче планирования одновременно заданы параметры vehicle.specs.max_weight
и vehicle.specs.max_weight_kg
, то в решении будет использован vehicle.specs.max_weight
.
Для всех перечисленных характеристик минимальное значение равно 0.
Внимание
Эти параметры можно указывать только для грузовых автомобилей (routing_mode
= truck
).
Для расчета вместимости грузового автомобиля используются 24 класса, см. спецификацию. Алгоритм учитывает габариты и грузоподъемность каждого автомобиля и подбирает по спецификации ближайший класс, у которого все характеристики равны или превышают характеристики автомобиля. Если хотя бы одна из характеристик автомобиля превышает максимально определенные значения, ему присваивается класс truck_N24
. В решении могут использоваться не более 5 классов. Если при планировании их больше, то меньшие классы равномерно убираются из решения, а автомобили получают ближайший больший класс из оставшихся.
Посмотреть, какие классы использовались в решении, можно в массиве matrix_statistics
ответа API.
Спецификация классов
Класс |
Высота ТС, м |
Ширина ТС, м |
Длина ТС, м |
Максимальный вес ТС, т |
|
0 |
0 |
0 |
0 |
|
1.5 |
0 |
0 |
0 |
|
2 |
0 |
0 |
0 |
|
2 |
2 |
3.2 |
3.5 |
|
2.2 |
2.1 |
4 |
0 |
|
2.2 |
2.1 |
4 |
3.5 |
|
2.4 |
2.6 |
4 |
5 |
|
2.4 |
2.6 |
8 |
8 |
|
2.5 |
0 |
0 |
0 |
|
2.5 |
2.2 |
6.5 |
3.5 |
|
2.7 |
2.6 |
8 |
10 |
|
3 |
2.6 |
8 |
10 |
|
3 |
2.6 |
8 |
14.5 |
|
3.2 |
2.6 |
9 |
12 |
|
3.5 |
2.6 |
10 |
22 |
|
3.9 |
2.6 |
10 |
18 |
|
3.9 |
2.6 |
10 |
20 |
|
3.9 |
2.6 |
10 |
22 |
|
3.9 |
2.6 |
10 |
25 |
|
3.9 |
2.6 |
10 |
30 |
|
3.9 |
2.6 |
20 |
40 |
|
4 |
2.6 |
10 |
30 |
|
4 |
2.6 |
20 |
35 |
|
4 |
2.6 |
20 |
40 |
Учет характеристик транспортных средств включается опцией options.enable_vehicle_classes
. По умолчанию enable_vehicle_classes
= true
— в этом случае алгоритм классифицирует транспортные средства на основе их характеристик. Учет характеристик можно отключить, установив enable_vehicle_classes
= false
.
Пример 1.1
Два автомобиля, грузовик и легковой автомобиль, развозят 10 заказов. 2 адреса расположены рядом с Черкизовской переправой, у которой ограничение по высоте для проезжающего транспорта — 2,5 метра. Самый короткий путь между этими адресами проходит через нее.
Алгоритм построит 2 маршрута, так как грузовик слишком высокий для переправы. Заказы, расположенные рядом с ней, повезет легковой автомобиль без ограничивающих характеристик. Поскольку у грузовика задана высота specs.height
= 3, согласно спецификации ему присвоен класс truck_N13
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 1.2
В планировании участвуют те же заказы и автомобили, что в примере 1.1, но характеристики грузовика vehicle.specs
не заданы, поэтому класс грузовику не присвоен.
Алгоритм не находит ограничений на проезд и планирует путь грузовика через переправу.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.1
Курьер должен развезти 2 заказа, которые находятся за МКАДом. Точки заказов диаметрально противоположны. У автомобиля не указан максимальный вес specs.max_weight
, поэтому алгоритм без ограничений рассчитывает движение по МКАД. Из-за отсутствия характеристик vehicle.specs
класс грузовику не присвоен.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.2
То же, что и в примере 2.1, но в этот раз у автомобиля указан specs.max_weight
= 12. Согласно спецификации, грузовику присвоен класс truck_N12
. Алгоритм спланировал пробег в 3,5 раза больше, потому что автомобиль не может двигаться по МКАД.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.3
То же, что и в примере 2.2, но вместо max_weight
использован параметр max_weight_kg
, и значение указано в кг. Грузовику присвоен тот же класс truck_N12
. Алгоритм также спланировал маршрут в объезд, потому что автомобиль не может двигаться по МКАД.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Сервисное время погрузки на складе
Время загрузки или разгрузки на складе может зависеть как от заказов, так и от свойств автомобиля (например, габариты или оборудование).
Чтобы указать количество дополнительного времени, необходимого для загрузки на складе, используйте параметр vehicle.depot_extra_service_duration_s
. Время указывается в секундах.
Примечание
Время, которое назначается в параметре vehicle.depot_extra_service_duration_s
, суммируется с временем обслуживания склада.
Пример
2 автомобиля с одинаковой грузоподъемностью выполняют доставку 13 крупногабаритных заказов. Сервисное время на складе depot.service_duration_s
составляет 5 минут (300 секунд). Для погрузки заказов в автомобиль на складе задано дополнительное время vehicle.depot_extra_service_duration_s
— 30 минут (1800 секунд). В результате планирования каждый автомобиль проведет на складе 35 минут перед началом движения по маршруту.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Старт автомобиля не со склада
По умолчанию автомобили и курьеры стартуют со склада, но иногда нужно начинать маршрут из другой точки (например, из дома или с места парковки). Как правило, эта задача подходит для планирования маршрутов торговых представителей, сервисных инженеров и прочих специалистов, которые не развозят товары, а оказывают услуги.
Это требование можно реализовать с помощью свойства vehicle.start_at
. В этом случае курьер или автомобиль начнет маршрут из указанной точки с типом garage
, а не со склада.
Посещение склада перед началом рабочего дня
При начале рабочего дня не со склада курьерам может понадобиться посетить склад, чтобы получить там заказы. Для этого используйте свойство vehicle.visit_depot_at_start
. Если указано true
, то перед началом выполнения заказов курьер или автомобиль обязаны посетить склад (это поведение по умолчанию). В противном случае они могут сразу начать выполнять заказы. Подробнее см. в разделе Старт или окончание маршрута в произвольной точке.
Если курьеры стартуют из точки типа garage
, но часть заказов нужно забрать на складе, включите опцию Может посещать склад в начале маршрута (can_visit_depot_at_start
в API, по умолчанию false
). Опция работает только для тех курьеров, у кого указан параметр visit_depot_at_start
= false
. У заказов, которые нужно забрать на складе, укажите один из следующих параметров:
— depot_id
, чтобы привязать заказ к складу;
— depot_ready_time
— время готовности заказа на складе;
— depot_expiring_time
— крайнее время получения заказа на складе.
Также можно неявно разрешить заезд на склад в начале маршрута при выключенной опции can_visit_depot_at_start
, если явно указать склад в planned_route
, зафиксированной части маршрута или при допланировании.
Пример 1
Доставку выполняют три автомобиля. Первый начинает доставку со склада. Второй начинает и заканчивает маршрут без посещения склада. При этом точка старта для курьера — заказ 6, который имеет тип garage
. Третий начинает маршрут не со склада, а с заказа 4 (тип garage
), но обязан посетить склад до начала выполнения заказов.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Доставку выполняют три автомобиля. Первый начинает доставку со склада. Второй и третий начинают и заканчивают маршрут без посещения склада. Заказы 1 и 7 имеют тип pickup
, и алгоритм выбирает их первыми точками маршрутов.
В результате запланированы три отдельных маршрута из-за наличия приоритетов у заказов.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Доставку выполняют два автомобиля (visit_depot_at_start
= false
и can_visit_depot_at_start
= true
). Первый стартует с точки типа garage
и в начале пути заезжает на склад за заказом 1. Маршрут второго не предполагает заезд на склад, он сразу едет на доставку.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Старт с одного из нескольких складов
Курьер может стартовать с одного из нескольких складов. Эти склады нужно перечислить в поле depot_id
(склады, которые может посещать курьер) или starting_depot_id
(склады, с которых курьер может начинать маршрут). Эти списки могут пересекаться. Если складов несколько, алгоритм выберет оптимальный склад для старта. Если поля depot_id
и starting_depot_id
для курьера не заполнены, то он стартует с первого склада из списка depots
.
Внимание
В полях vehicle.depot_id
и vehicle.starting_depot_id
нельзя одновременно указывать и обычные склады, и кросс-доки. В одном маршруте курьер может посещать или только обычные склады, или только кросс-доки.
Если использовать функциональность доставки с одного из нескольких складов, курьер сможет забирать заказы с любого из складов, которые он может посещать.
Дополнительно для курьера можно задать параметры allow_different_depots_in_route
и max_middle_depots
. Подробнее см. в разделе Выбор оптимального склада для старта.
Дозагрузка на промежуточном складе
Чтобы у курьера была возможность посещать во время движения по маршруту дополнительные склады для дозагрузки заказов, установите параметр allow_different_depots_in_route
= true
. Склады для дозагрузки необходимо указать в поле depot_id
(склады, которые может посещать курьер) или middle_depot_id
(склады для дозагрузки). Списки складов могут пересекаться. Если заказы есть на нескольких складах, то алгоритм выберет оптимальный склад для дополнительной загрузки.
Внимание
В полях vehicle.depot_id
и vehicle.middle_depot_id
нельзя одновременно указывать и обычные склады, и кросс-доки. В одном маршруте курьер может посещать или только обычные склады, или только кросс-доки.
Если курьер может заезжать на промежуточные склады для дозагрузки только в начале маршрута (до посещения первого заказа), установите параметр depots_only_at_run_beginning
= true
(по умолчанию false
).
Дополнительно для курьера можно задать параметр max_middle_depots
. Подробнее см. в разделе Заезд на дополнительный склад.
Возврат на склад в конце маршрута или рейса
По умолчанию курьер завершает маршрут на складе, с которого стартовал. Чтобы разрешить курьеру посещать несколько складов на маршруте, устанавливают параметр allow_different_depots_in_route
= true
. В этом случае курьер может завершать маршрут на складе, отличном от начального.
Склады, где курьер может завершить маршрут, указывают в поле depot_id
(склады, которые может посещать курьер) или ending_depot_id
(склады, где курьер может завершать маршрут). Эти списки могут пересекаться. Если складов несколько, алгоритм выберет оптимальный склад для возврата.
Внимание
В полях vehicle.depot_id
и vehicle.ending_depot_id
нельзя одновременно указывать и обычные склады, и кросс-доки. В одном маршруте курьер может посещать или только обычные склады, или только кросс-доки.
Чтобы курьер завершал маршрут на том же складе, откуда выехал, используйте параметр finish_route_in_starting_depot
= true
(по умолчанию false
). Если при этом курьер начинает маршрут не со склада (visit_depot_at_start
= false
), он должен будет вернуться на тот склад, откуда выехал на второй рейс маршрута.
Чтобы курьер завершал каждый рейс на том же складе, откуда этот рейс был начат, используйте параметр finish_run_in_starting_depot
= true
(по умолчанию false
). Чтобы курьер между рейсами мог переехать с одного склада на другой, задайте параметр can_change_depot_between_runs
= true
, см. Старт нового рейса с другого склада.
Примечание
Параметры finish_route_in_starting_depot
= true
и finish_run_in_starting_depot
= true
имеют смысл, только если allow_different_depots_in_route
= true
.
Если курьер не должен возвращаться на склад после выполнения всех заказов, используйте опцию return_to_depot
= false
.
Пример 1.1
Два курьера должны доставить два заказа: один заказ delivery
нужно забрать со Склада 1, второй заказ pickup
нужно доставить на Склад 2. Оба курьера могут сделать только по 1 рейсу, выехать с любого склада и завершить маршрут на любом складе. Обоим курьерам разрешено посещать разные склады в одном рейсе, но заезжать на промежуточные склады курьеры не могут.
В решении используется только один курьер: он выезжает со Склада 1, забрав заказ delivery
, доставляет его, забирает заказ pickup
и доставляет его на Склад 2, где и завершает маршрут.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 1.2
То же, что в примере 1.1, но курьеры должны завершить маршрут на том же складе, откуда выехали (finish_route_in_starting_depot
= true
).
В решении используются оба курьера. Курьер 1 выезжает со Склада 1, забрав заказ delivery
, доставляет его и возвращается на Склад 1. Второй курьер выезжает со Склада 2, забирает заказ pickup
и возвращается с ним на Склад 2.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Возврат на произвольную точку в конце маршрута
Если в вашем сценарии работы необходимо учитывать удаленность последнего заказа от места парковки курьера или, например, домашнего адреса, вы можете это учесть следующим образом:
-
Создайте точку с типом
garage
(полеlocation.type
). Эта точка будет использоваться только для окончания маршрутов. -
Для курьера, которому необходимо вернуться в конце работы «домой» или «на парковку», укажите идентификатор этой точки в поле
vehicle.finish_at
.
При решении задачи все автомобили или курьеры, у которых указано свойство finish_at
, вернутся на указанную точку. Если включена опция возврата на склад (vehicle.return_to_depot
= true
), то в маршруте сначала будет посещен склад, а затем проложен путь до места парковки.
Пример
В примере ниже используется два автомобиля с разной грузоподъемностью и четыре заказа с различным весом. Оба автомобиля участвуют в доставке из-за весовых ограничений. Автомобиль 2 не должен возвращаться на склад после доставки последнего заказа.
Примечание
Обратите внимание, что в ответе Маршрутизации автомобиль 2 завершает маршрут на последнем заказе.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Начало или окончание маршрута как можно ближе к складу
Для курьера можно запланировать маршрут так, чтобы он начинал или заканчивал движение на заказе, который находится ближе всего к складу, или наоборот, дальше всего от склада. Например, можно начинать маршрут с наиболее близких к складу заказов, если с утра могут появиться дополнительные заказы, за которыми нужно вернуться на склад. Также иногда удобно начинать маршрут с самого дальнего заказа, чтобы к вечеру оказаться недалеко от склада.
Если вы не применяете расширенные настройки стоимости, используйте следующие параметры:
-
first_edges_penalty_factor
— штраф за расстояние от склада до первого заказа, по умолчанию 0. Если значение больше 0, алгоритм минимизирует это расстояние, а если меньше 0 — максимально увеличивает. -
last_edges_penalty_factor
— штраф за расстояние от склада до последнего заказа, по умолчанию 0. Если значение больше 0, алгоритм минимизирует это расстояние, а если меньше 0 — максимально увеличивает.
Штрафы рассчитываются по аналогии с длительностью и длиной отрезков на маршруте, см. группу Движение между точками на маршруте в разделе Расширенные настройки стоимости.
При больших значениях штрафов маршруты могут получиться неоптимальными по пробегу. При маленьких значениях штрафов требование по выбору первого или последнего заказа на маршруте может нарушаться, если это значительно экономит пробег.
Если вы применяете расширенные настройки стоимости, используйте ключевые слова из группы Движение от склада или к складу.
Пример
В примере ниже 1 курьер и 10 заказов. Заданы 2 штрафа: first_edges_penalty_factor
= 2 и last_edges_penalty_factor
= -2. В результате планирования маршрут начинается с самого близкого к складу заказа и заканчивается самым дальним.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Смены работы автомобиля или курьера
Для автомобиля можно определить одну или несколько смен работы. Для определения смен используется поле vehicle.shifts
.
Смена представляет собой диапазон времени, в который разрешена работа автомобиля. Время смены включает в себя время нахождения на складе при загрузке, а также время в движении, сервисное время на заказах и время разгрузки на складе (если автомобиль возвращается на склад).
Для использования одной или более смен в Excel необходимо определить следующие поля:
-
shifts.0.time_window
— мягкое временное окно, соответствующее времени работы автомобиля. -
shifts.0.hard_window
— флаг жесткого временного окна. Если окно жесткое, алгоритм не может выйти за рамки заданного интервала. -
shifts.0.service_duration_s
— время между сменами (в секундах). Например, время на замену водителя, обмен документами и т.д.
Также можно ограничить максимальную продолжительность смены (shifts.N.max_duration_s
и shifts.N.hard_max_duration_s)
.
В случае определения мягкого временного окна можно дополнительно задать штрафы:
-
за нарушение временного окна:
shifts.0.penalty.out_of_time.fixed
— штраф за факт нарушения временного окна смены.shifts.0.penalty.out_of_time.minute
— штраф за минуту нарушения временного окна смены.
-
за ранний выезд:
shifts.0.penalty.early.fixed
— штраф за факт начала работы раньше временного окна смены.shifts.0.penalty.early.minute
— штраф за минуту начала работы раньше временного окна смены.
-
за опоздание:
shifts.0.penalty.late.fixed
— штраф за факт завершения работы позже временного окна смены.shifts.0.penalty.late.minute
— штраф за минуту завершения работы позже временного окна смены.
Чтобы ограничить допустимые нарушения временного окна смены, можно задать жесткое окно вокруг мягкого.
Начало, окончание и продолжительность смены
Пусть задано временное окно смены time_window
с 9:00 до 18:00. Используются признак жесткости временного окна hard_window
, максимальная продолжительность смены max_duration_s
и признак гибкого времени старта со склада depot.flexible_start_time
.
Как нужно запланировать работу курьера |
Параметры |
Выбрать интервал работы желательно не больше 6 часов строго между 9 и 18 часами |
|
Начать работу строго в 9 часов, желательно завершить работу до 15 часов, при необходимости можно работать до 18 часов, строго не позже (это сочетание параметров аналогично условию |
|
Выбрать интервал работы желательно не больше 6 часов желательно между 9 и 18 часами |
|
Начать работу строго в 9 часов, желательно завершить работу до 15 часов, при необходимости можно работать до 18 часов, желательно не позже (это сочетание параметров аналогично условию |
|
Начать работу можно позднее 9 часов, желательно закончить работу до 18 часов, желательно работать не более 10 часов |
|
Начать работу строго в 9 часов, желательно завершить работу до 18 часов, но желательно не позже 19 часов (это сочетание параметров аналогично условию |
|
Такое сочетание параметров не позволит запланировать решение |
|
Примечание
Обратите внимание, что для определения нескольких смен необходимо несколько полей в Excel с увеличивающимся числовым индексом.
Например shifts.0.time_window
относится к первой смене, а shifts.1.time_window
— ко второй смене.
Пример
В запросе к Маршрутизации задан 1 автомобиль с 3 сменами (утренняя, дневная, вечерняя), а также 3 заказа, из которых 1 имеет время доставки утром, и 2 вечером.
Примечание
Обратите внимание, что в ответе Маршрутизации будут использованы только утренняя и вечерняя смена, так как на дневную смену нет ни одного заказа на доставку.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Несколько рейсов курьера в день
По умолчанию курьер начинает и завершает маршрут на складе, то есть выполняет ровно один маршрут в течение рабочего дня (смены).
Если курьер может возвращаться на склад в любое время рабочей смены для дозагрузки дополнительных заказов, количество рейсов можно ограничить с помощью одного из параметров:
-
vehicle.shifts.N.max_runs
— максимальное количество рейсов для данной смены. По умолчанию равно 1. -
vehicle.max_runs
— максимальное количество рейсов для всех смен курьера в сумме (например, курьер может выполнить все рейсы в одну смену). Количество рейсов курьера может быть меньше, чем количество смен. По умолчанию равно 1. -
если ни один из параметров не задан, курьер может делать столько рейсов, сколько у него смен — в каждой смене по одному рейсу.
Примечание
В задаче планирования можно использовать либо vehicle.max_runs
, либо vehicle.shifts.N.max_runs
, но не оба параметра одновременно.
Для курьера должна быть задана хотя бы одна смена.
Пример
В примере ниже используется один автомобиль с ограниченной вместимостью в 2 тонны и три заказа с весом в 0,8 тонн. Автомобилю разрешено два рейса, то есть автомобиль может вернуться на склад после выполнения двух заказов для загрузки и доставки еще одного заказа.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Ограничение количества остановок в смене
При планировании маршрута можно указать минимальное и максимальное количество остановок в маршруте. Это может быть полезно, например, чтобы ограничить максимальную нагрузку на курьера в день или, наоборот, обязательно вывести курьера на маршрут с каким-то количеством остановок.
В Маршрутизации для этого используются параметры смены minimal_stops
и maximal_stops
. Для каждого курьера можно задать свое количество остановок.
Ограничение не является строгим и может быть нарушено. При нарушении ограничения по минимальному количеству остановок начисляется штраф, указанный в полях смены penalty.stop_lack.fixed
(за факт остановок меньше минимального количества) и penalty.stop_lack.per_stop
(за каждую остановку меньше минимального количества).
Соответственно, при нарушении ограничения по максимальному количеству остановок начисляются штрафы, указанные в полях смены в полях смены penalty.stop_excess.fixed
(за факт остановок больше максимального количества) и penalty.stop_excess.per_stop
(за каждую остановку больше максимального количества).
Примечание
Как правило, использование ограничений на количество остановок приводит к ухудшению метрик решения, поскольку решение смещается в сторону выполнения ограничений в ущерб оптимальности маршрута.
Уникальные остановки
При использовании параметра minimal_stops
заказы с совпадающими координатами считаются различными остановками, если в маршруте они расположены не подряд. Поэтому чтобы выполнить условие minimal_stops
, алгоритм может спланировать маршрут так, что курьеру придется несколько раз приезжать на один и тот же адрес.
Чтобы избежать повторных приездов, вместо minimal_stops
используйте параметр minimal_unique_stops
и штрафы penalty.unique_stop_lack.fixed
и penalty.unique_stop_lack.per_stop
.
Параметр minimal_unique_stops
учитывает только заказы с уникальными координатами, поэтому курьеру не будут запланированы повторные приезды. Однако заказы по одному и тому же адресу могут быть распределены на разных курьеров, поскольку в этом случае они считаются разными остановками, и алгоритм может использовать это для выполнения ограничения minimal_unique_stops
.
Ограничение minimal_unique_stops
имеет смысл использовать, если в маршруте много мультизаказов.
Остановки у неиспользуемых курьеров
По умолчанию ограничения количества минимальных остановок minimal_stops
и minimal_unique_stops
работают для всех заданных курьеров. Если курьеров задано больше чем необходимо, и значение штрафов penalty.stop_lack
или penalty.unique_stop_lack
слишком высокое, это может приводить к неоптимальному результату планирования.
Использовать ограничение минимального количества остановок в смене и в то же время построить эффективный маршрут позволяет опция ignore_min_stops_for_unused
, см. раздел Учет минимального количества остановок только для используемых ТС.
Пример 1
В примере маршрут строится для 3 курьеров, выполняющих доставку по 15 точкам. Поскольку на маршруте не указано никаких ограничений, маршрут строится обычным образом.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В примере указаны те же условия, что и в примере 1, но указано ограничение на 4 минимальных остановки для каждого курьера. В результате маршруты изменились так, чтобы каждый курьер посетил хотя бы 4 точки доставки.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
В примере указаны те же условия, что и в примере 1, но указано ограничение на 5 максимальных остановок для каждого курьера. В результате заказы распределены равномерно между всеми курьерами, даже несмотря на то, что несколько заказов расположены рядом и могли бы быть выполнены одним курьером.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Максимальная продолжительность смены
Иногда возникает необходимость продлить период работы курьера. При этом нужно ограничить максимальную продолжительность смены и установить период, в который желательно попасть. Например, есть определенное окно, в которое курьеры выполняют доставки, длиной в 14 часов (с 8 до 22 часов), но продолжительность смены каждого курьера не должна превышать 10 часов (max_duration_s
), а продолжительность рабочего времени в смене — 8 часов (max_working_duration_s
).
Маршрутизация позволяет планировать смены с жесткими временными окнами и желательной продолжительностью. При этом продолжительность смены курьера не влияет на время начала работы, а только на то время, которое он потратит на выполнение заказов.
Максимальная продолжительность смены может быть задана как мягкое ограничение shifts.N.max_duration_s
, которое можно нарушить и получить штраф, и как жесткое ограничение shifts.N.hard_max_duration_s
, которое нарушить нельзя:
-
При планировании с мягким ограничением нагрузка, не укладывающаяся в желательную смену одного курьера, распределяется на других или на того же курьера, но со штрафами за превышение длины смены. Все заказы, которые невозможно выполнить за время
max_duration_s
, добавляются в маршрут со штрафом за опозданиеshift.penalty.late
, если это значение указано, или за нарушение окнаshift.penalty.out_of_time
в противном случае. Итоговая сумма штрафа для маршрута за нарушение максимальной продолжительности смены указывается в ответе API в полеovertime_penalty
. Если расчетная стоимость заказа с учетом штрафов выше, чем стоимость выполнения заказа другим курьером, заказ передается другому курьеру. -
При планировании с жестким ограничением смена курьера ни при каких условиях не превышает значение, заданное в
hard_max_duration_s
.
Максимальная продолжительность рабочего времени в смене также может быть задана как мягкое shifts.N.max_working_duration_s
и жесткое shifts.N.hard_max_working_duration_s
ограничения.
-
Если нарушается мягкое ограничение, лишняя нагрузка распределится на других курьеров или на того же курьера, но со штрафами. Заказы, которые не будут выполнены за рабочее время в смене
max_working_duration_s
, добавятся в маршрут со штрафомworking_overtime
:-
shifts.N.penalty.working_overtime.fixed
— штраф за факт превышения максимальной продолжительности рабочего времени в смене; -
shifts.N.penalty.working_overtime.minute
— штраф за минуту такого превышения.
Если значение этого штрафа не указано, к заказам применится штраф за нарушение окна
shift.penalty.out_of_time
. Итоговая сумма штрафа отразится в ответе API в полеworking_overtime_penalty
. Заказ будет передан другому курьеру, если расчетная стоимость заказа с учетом штрафов превысит стоимость выполнения заказа другим курьером. -
-
При планировании с жестким ограничением максимальная продолжительность рабочего времени в смене ни при каких условиях не превышает значение, заданное в
hard_max_working_duration_s
.
Если для max_duration_s
и max_working_duration_s
заданы оба ограничения (мягкое и жесткое), то жесткое должно быть не меньше мягкого. По умолчанию max_duration_s
и max_working_duration_s
составляют 2 суток, hard_max_duration_s
и hard_max_working_duration_s
— 30 суток.
Пример 1
Пусть окно смены shifts.N.time_window
— с 8 до 23. По умолчанию маршруты будут построены с использованием минимального количества курьеров.
Если указать max_duration_s
= 14400, то нагрузка будет распределена между курьерами так, чтобы каждый из них работал примерно 4 часа (длина смены задается в секундах). При этом некоторые курьеры все еще могут работать больше 4 часов, потому что выгоднее оплатить лишнее время работы, чем доставить заказ другим курьером.
В результате планирования заказы распределены между тремя курьерами. Длина смены одного из курьеров превысила 4 часа, сумма штрафа за нарушение указана в ответе API в поле overtime_penalty
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но вместо мягких ограничений максимальной продолжительности смены заданы жесткие: hard_max_duration_s
= 14400. При планировании для каждого курьера выдержана смена, не превышающая 4 часов. В результате количество курьеров увеличилось до 4.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Три курьера развозят 26 заказов. Окно смены shifts.N.time_window
— с 8 до 23. Установлены штрафы за факт (shifts.N.penalty.working_overtime.fixed
) и минуту (shifts.N.penalty.working_overtime.minute
) превышения максимальной продолжительности рабочего времени в смене.
Если указать shifts.0.max_working_duration_s
= 14400, то каждый из курьеров будет работать примерно 4 часа. Ограничение мягкое, поэтому смена одного из курьеров превышает это время.
В результате планирования все заказы распределены между курьерами, а общая сумма штрафа за нарушение указана в ответе API в поле working_overtime_penalty
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
То же, что в примере 3, но задано жесткое ограничение максимальной продолжительности рабочего времени в смене shifts.N.hard_max_working_duration_s
= 14400.
В результате планирования все курьеры задействованы и работают не дольше 4 часов, но один из заказов при этом остался нераспределенным.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Максимальный пробег за смену
В некоторых случаях пробег машины нужно ограничить. Например:
-
В планировании участвуют наемные машины, и тариф за их использование подразумевает лимит по пробегу.
-
На дальние точки должны ехать определенные машины. Тогда прочим машинам можно ограничить пробег.
Параметр shifts.max_mileage_km
определяет максимальный пробег машины за смену. Учитывается весь пробег, включая:
-
движение от склада или точки старта до первой точки из списка заказов;
-
возврат на склад или точку завершения маршрута от последней точки из списка заказов.
Ограничение мягкое: алгоритм может его нарушить. Штрафы задаются в полях:
-
shifts.penalty.max_mileage.fixed
— штраф за факт превышения максимального пробега (по умолчанию 1000); -
shifts.penalty.max_mileage.km
— штраф за каждый километр превышения максимального пробега (по умолчанию 100).
Если для вас важен максимальный пробег за рейс, а машина может выполнить несколько рейсов за смену, нужно сделать несколько одинаковых смен (см. Пример 2).
Если курьер передвигается общественным транспортом, в пробеге возвращается только пешая часть маршрута.
Пример 1
Ограничение пробега каждого курьера — 50 км. За нарушение задан большой штраф. В результате плановый пробег на любом маршруте не превышает 50 км.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Есть один курьер, и каждый его рейс должен быть ограничен 50 км. Для этого у курьера задано несколько смен с одинаковыми временными окнами и ограничениями по пробегу. В результате сформировано 3 рейса, каждый протяженностью менее 50 км.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Кучность маршрута
Если для автомобиля нужно задать желаемый район работы — так, чтобы в маршрут включались заказы, расположенные недалеко от определенной точки, — используйте параметр global_proximity_attraction_point
. В значении параметра укажите id
точки с типом garage
. Эта точка используется как «точка притяжения» — алгоритм стремится уменьшить сумму расстояний от заказов в маршруте до этой точки.
На кучность построения маршрутов вокруг «точки притяжения» влияет опция options.global_proximity_factor
— чем больше ее значение, тем маршруты кучнее. Подробнее об опции см. в разделе Кучные маршруты.
Максимальное расстояние от точек маршрута до «точки притяжения» хранится в параметре max_distance_to_attraction_point_m
, который может использоваться для расчета стоимости маршрута. Итоговая сумма расстояний от всех заказов до «точки притяжения» в маршруте влияет на размер штрафа за недостаточную сгруппированность маршрутов.
Другие способы сгруппировать заказы географически
- С помощью опции
global_proximity_factor
можно построить кучные маршруты без указания «точки притяжения». Опция работает только для автомобилей, у которых не задан параметрglobal_proximity_attraction_point
. - С помощью геозон для автомобилей можно задать ограничения по зонам доставки. Ограничение по геозонам нельзя нарушить, по сравнению с ним настройки кучности маршрутов являются более гибким инструментом.
Пример 1
Три автомобиля должны доставить 15 заказов. Маршрут рассчитывается исходя из веса заказов и грузоподъемности автомобилей. Иных ограничений на маршруте не задано.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но для каждого курьера задана «точка притяжения», обозначающая желаемый район работы. В результате маршруты стали более кучными. Максимальное расстояние от заказа до «точки притяжения» в маршруте составило 20 663 м.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
То же, что и в примере 2, но для одного из курьеров изменена «точка притяжения». В результате за счет перегруппировки заказов расположение маршрутов на карте поменялось. Максимальное расстояние от заказа до «точки притяжения» увеличилось и составило 28 528 м.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Стоимость автомобиля или курьера
Для каждого автомобиля в запросе к Маршрутизации можно задать различные компоненты стоимости использования. Для определения стоимости автомобиля или курьера используется опциональное поле запроса vehicle.cost
.
Маршрутизация позволяет определить следующие основные компоненты стоимости:
-
cost.fixed
— фиксированная стоимость использования автомобиля. -
cost.hour
— стоимость за час работы. -
cost.km
— стоимость за километр пробега. -
cost.location
— стоимость посещения одного заказа. -
cost.run
— стоимость выполнения одного рейса. -
cost.tonne_km
— стоимость за тонно-километр транспортной работы.
В данном случае используется стоимость, по которой алгоритм выбирает оптимальный вариант маршрутизации. Это не тариф, который начисляется в реальности за использование автомобиля, а скорее настройки алгоритма.
Cтоимость автомобиля или курьера также можно задать в виде арифметического выражения. Подробнее см. в разделе Расширенные настройки стоимости.
Значения стоимости
Обратите внимание, что некоторые компоненты стоимости транспортного средства уже заданы по умолчанию:
-
cost.fixed
= 3000 -
cost.hour
= 100 -
cost.km
= 8
Они применяются в случаях:
-
если вы используете Excel и оставляете эти поля пустыми;
-
если вы обращаетесь по API и не заполняете поле запроса
vehicle.cost
.
Часто значения по умолчанию необходимо корректировать. Например, в следующих бизнес-кейсах:
Примечание
Всегда заполняйте cost.hour
и cost.km
значениями, отличными от 0 — иначе маршруты будут получаться хаотичными. Это происходит потому, что алгоритм оптимизирует итоговую стоимость, а если стоимость пробега или времени для него равна 0, то маршрут с любым пробегом будет стоить одинаково.
Если вы хотите минимизировать стоимость маршрута, значения cost.hour
и cost.km
должны быть больше 0.
Стоимость тонно-километра транспортной работы
Тяжело нагруженные машины расходуют больше топлива и быстрее изнашиваются. Поэтому для перевозки тяжелых грузов требуется строить маршруты так, чтобы расстояние, которое ТС проходит с большой загрузкой, было минимальным.
В Маршрутизации для этого используется свойство cost.tonne_km
. Оно определяет стоимость одного километра пути для каждой тонны груза в машине. Значение по умолчанию — 0.
Суммарный объем транспортной работы в тонно-километрах возвращается в поле total_transport_work_tonne_km
ответа API, а ее суммарная стоимость — в поле total_transport_work_cost
.
Пример 1
Нужно доставить 3 груза весом 100, 200 и 2000 кг. Стоимость одного тонно-километра cost.tonne_km
задана равной нулю. В результате самый тяжелый заказ доставлен последним: загрузка ТС не учитывалась при построении маршрута, а по другим критериям такой вариант оказался оптимальным.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Исходные данные те же, но cost.tonne_km
= 8. В итоге решение оптимизировано с учетом загрузки: самый тяжелый заказ выгружен первым.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Расширенные настройки стоимости
Стоимость автомобиля или курьера можно задать в виде арифметического выражения. При планировании вы можете рассчитать стоимость одним выражением в поле vehicles.cost
или использовать несколько выражений во вложенных полях:
cost.route
— для маршрута;cost.shift
— для смены;cost.run
— для рейса.
Внимание
Если в поле vehicle.cost
заданы формулы, то алгоритм рассчитывает стоимость автомобиля или курьера только по этим формулам. При этом стандартные компоненты стоимости участвуют в расчете, только если указаны в формулах в явном виде.
В выражении можно использовать ключевые слова и математические обозначения, которые приведены в таблицах ниже. Проверить правильность выражения можно с помощью HTTP-запроса.
Ключевые слова для параметров маршрута
Группа |
Ключевое слово и пояснение |
Рейсы |
|
Смены |
|
Заказы и остановки |
|
Длительность |
|
Расстояние |
Если для автомобиля нужно задать желаемый район работы — так, чтобы в маршрут включались заказы, расположенные недалеко от определенной точки, — используйте параметр |
Транспортная работа |
|
Склады |
|
Начало и окончание движения |
|
Движение между точками на маршруте |
При вычислении расстояния и времени движения между точками на маршруте заказами считаются типы Параметры используются для реализации тех же сценариев, что и штрафы за начало или окончание маршрута как можно ближе к складу. |
Движение с заказами и без заказов |
|
Вместимость |
|
Прицеп |
|
Пешеходные маршруты |
|
Метрики маршрута рассчитываются по следующим формулам:
- общая длительность маршрута
transit_duration_h
=walking_transit_duration_h
+driving_transit_duration_h
; - общая длина маршрута
distance_km
=walking_distance_km
+driving_distance_km
.
На вычисление переменных, которые используются в маршрутах с пешеходными частями, влияет способ передвижения:
walking
— весь маршрут обслуживается пешком, расстояниеdriving_distance_km
и длительностьdriving_transit_duration_h
равны 0;transit
:driving_distance_km
= 0 — считается, что все заказы курьер посетил пешком (для подсчета расстояния, пройденного на общественном транспорте, недостаточно данных);driving_transit_duration_h
вычисляется на основании других данных, полученных при решении задачи (может быть ненулевым).
Математические обозначения и функции
Математические обозначения |
Пояснение |
Числа |
Целые (положительные, отрицательные), рациональные. Для десятичных дробей в качестве разделителя используйте точку. |
Арифметические действия |
+, -, *, / |
Скобки |
(…) |
Математические функции |
|
Логические функции |
|
Операции сравнения |
<, >, = |
Логические операции |
|
Функции |
|
Условия функций |
Следующие функции можно использовать только внутри условий функций
|
Примеры выражений
500 + 500 * has_location(in_zone('West'))
— если в маршруте есть остановка в зонеWest
, то вернется 1000, иначе 500.450 * location_count(in_zone('West') | in_zone('North'))
— выражение посчитает количество остановок, которые попадают хотя бы в одну из двух зон (West
,North
) и вернет их количество, умноженное на 450.1000 + has_location(in_zone('West') & has_load_type('Заморозка')) * 500
— если в маршруте есть хотя бы одна остановка, которая одновременно находится в зонеWest
и имеет тип загрузкиЗаморозка
, то выражение вернет 1500, иначе 1000.100 * (has_location(in_zone('West')) & has_location(in_zone('North')))
— если есть хотя бы одна остановка в зонеWest
и хотя бы одна остановка в зонеNorth
(может быть одна остановка в обеих зонах или две разных), то вернется 100.100 * has_location(in_zone('West') & in_zone('North'))
— если есть остановка, которая одновременно попадает в обе зоныWest
иNorth
, то выражение вернет 100.100 * location_count(is_pickup() & in_zone('West') & !has_tag('Возврат'))
— выражение посчитает количество заказов с типомpickup
, которые находятся в зонеWest
и при этом не имеют тегаВозврат
, и вернет их количество, умноженное на 100.
Метрики решения
Если для автомобиля или курьера заданы расширенные настройки стоимости, в метриках решения вы увидите следующие поля:
run_custom_cost
— стоимость рейса по формуле дляcost.run
.shift_custom_cost
— стоимость смены по формуле дляcost.shift
. Выводится только в первом рейсе смены.shift_total_custom_cost
— общая стоимость смены. Включает в себя стоимость смены, рассчитанную по формуле, и стоимость всех входящих в смену рейсов. Выводится только в первом рейсе смены.route_custom_cost
— стоимость маршрута по формуле дляcost.route
. Выводится только в первом рейсе маршрута.total_custom_cost
— полная стоимость маршрута, включая стоимость маршрута, рассчитанную по формуле, и стоимость всех смен. Выводится только в первом рейсе маршрута, в остальных рейсах выводится 0.
Пример 1
В задаче используется следующая схема тарификации:
-
Базовая стоимость одного мультизаказа — 170 единиц.
-
Стоимость мультизаказа повышается на 20 единиц каждые 100 километров.
-
За смену курьер получает не менее 4000 единиц, даже если по заказам столько не набирается.
Такому тарифу соответствует следующая стоимость: 100 * duration_h + 8 * distance_km + max(4000, (170 + 20 * Floor(distance_km / 100)) * unique_stops)
.
В результате стоимость использования каждого автомобиля получается не менее 4000
. Стоимость сверх оплаты смены (или выполненных заказов) формируется исходя из общего времени и длины маршрута.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Нужно спланировать маршрут при условии, что стоимость зависит от пробега и определяется по формуле:
<стоимость автомобиля> = максимум {<минимальная стоимость маршрута>, <количество точек на маршруте> * <стоимость доставки на точку>}
Минимальная стоимость маршрута и стоимость доставки на точку указаны в таблице:
Пробег |
Стоимость одного мультизаказа (руб.) |
Минимальная стоимость маршрута (руб.) |
не более 150 км |
510 |
6 000 |
не более 450 км |
530 |
7 000 |
не более 750 км |
550 |
8 500 |
свыше 750 км |
570 |
11 000 |
Тогда при планировании стоимость автомобиля рассчитывается по формуле:
max(6000 + (distance_km > 150)*1000 + (distance_km > 450)*1500 + (distance_km > 750)*2500
, stops
*(510 + min(60, Ceil(max(0, distance_km - 150)/300)*20))
)
Подробнее о формуле расчета
- минимальная стоимость маршрута:
6000 + (distance_km > 150)*1000 + (distance_km > 450)*1500 + (distance_km > 750)*2500
; - количество точек на маршруте — определяется с помощью параметра
stops
; - стоимость доставки на точку — определяется следующим образом. Минимальная стоимость мультизаказа —
510
, максимально возможная прибавка к ней —570 - 510 = 60
. Важно, что стоимость мультизаказов увеличивается равномерно с шагом 20 на каждые 300 км пробега — это можно представить с помощью формулыCeil(max(0, distance_km - 150)/300)*20
. Тогда стоимость доставки на точку с учетом данных из таблицы равна510 + min(60, Ceil(max(0, distance_km - 150)/300)*20))
.
В итоге у машины 1 длина маршрута больше 150 км, количество остановок — 18 (есть 1 мультизаказ). Итоговая стоимость — 9540. У машины 2 длина маршрута не более 150 км, количество остановок — 21 (есть 1 мультизаказ). Итоговая стоимость — 10710.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Нужно спланировать маршрут так, чтобы минимизировать недозагрузку автомобиля. Для этого в формуле можно задать дополнительную стоимость автомобиля при условии его загрузки менее определенного предела. Например, при планировании автомобилей грузоподъемностью 3000 кг необходимо загружать их не менее чем на 80%. При этом предполагаем, что остальная стоимость (за час, за км, за факт использования) будет по умолчанию. Тогда стоимость автомобиля рассчитывается по формуле:
3000 + duration_h*100 + distance_km*8 + max(0, 2400 - utilization_kg) * 100
Подробнее о формуле расчета
3000, 100, 8 в первых трех слагаемых — значения по умолчанию стоимости за факт использования, за час и за километр соответственно. В формуле добавляется стоимость 100 единиц за каждый недогруженный килограмм от 2400: <номинальная грузоподъемность> * <минимальный порог утилизации> = 3000 * 80% = 2400.
В итоге алгоритм будет стремиться нагрузить все машины не менее чем на 80% (если это возможно).
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
Нужно спланировать маршрут при условии, что некоторые торговые сети начинают работу раньше. В задаче используется следующая схема тарификации:
-
Базовая cтоимость маршрута формируется исходя из затраченного времени и пройденного расстояния.
-
Желательно начинать маршруты пораньше, чтобы избежать утренних пробок. Для этого в формулу расчета стоимости добавляется штраф за выезд позднее 8 часов утра.
Такому тарифу соответствует следующая стоимость:
100 * duration_h + 8 * distance_km + 50 * (start_route_time_s > 28800)
В результате планирования все автомобили приезжают на склад до 8 утра.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 5
Нужно спланировать маршруты при условии, что в пределах города в одном автомобиле нельзя перевозить легкие и тяжелые заказы одновременно. В задаче планирования задана геозона City
и всем заказам присвоены теги Light
или Heavy
в зависимости от веса заказа.
Таким условиям соответствует следующая стоимость:
(has_location(in_zone('City')) & has_location(has_tag('Light')) & has_location(has_tag('Heavy')))*100000000
Использовать несовместимые типы заказов в этом случае не получится, так как ограничение на совместимость действует только в пределах одной геозоны.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Расчет выплаты курьеру
Чтобы рассчитать, какую оплату получит курьер за выполнение маршрута, используйте поле payout
. При планировании вы можете рассчитать выплаты одним выражением в поле vehicle.payout
или использовать несколько выражений во вложенных полях:
payout.route
—для маршрута;payout.shift
— для смены;payout.run
— для рейса.
В выражениях можно использовать те же ключевые слова и математические обозначения, что и для расчета стоимости маршрута для компании (поле vehicle.cost
).
Примечание
Поле vehicle.payout
не влияет на оптимизацию маршрута, оно рассчитывается уже после того, как задача планирования решена.
Если для курьера задано поле vehicle.payout
, в метриках решения вы увидите следующие поля:
run_payout
— выплата за рейс по формуле дляpayout.run
.shift_payout
— выплата за смену по формуле дляpayout.shift
. Выводится только в первом рейсе смены.shift_total_payout
— общая выплата за смену. Включает в себя выплату за смену, рассчитанную по формуле, и выплату за все входящие в смену рейсы. Выводится только в первом рейсе смены.route_payout
— выплата за маршрут по формуле дляpayout.route
. Выводится только в первом рейсе маршрута.total_payout
— полная выплата за маршрут, включая выплату за маршрут, рассчитанную по формуле, и выплату за все смены. Выводится только в первом рейсе маршрута, в остальных рейсах выводится 0.
Если хотя бы для одного курьера задано поле payout
, в результатах планирования также присутствует метрика total_payout
— общий объем выплат курьерам.
Расчет выплат курьерам Посмотреть видео |
Пример 1
Два курьера развозят 40 заказов, каждый курьер делает по 2 рейса. Стоимость курьеров для компании задается выражением в поле cost
. Для курьера 1 рассчитывается сумма выплаты за выполненный маршрут с помощью выражения в поле payout
— эта сумма отображается в метриках первого рейса и составляет 5000 единиц. Для курьера 2 сумма выплаты не рассчитывается, поэтому общая сумма выплат total_payout
также составляет 5000 единиц.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Два курьера развозят 40 заказов. Для курьера 1 задан расчет выплат: за факт выхода на смену курьер получает 3000 единиц, за каждый километр пути — 10 единиц, за каждый доставленный заказ — 50 единиц. Если за смену он доставит больше 10 заказов, ему начисляется бонус в 500 единиц. Для курьера 2 сумма выплаты не рассчитывается.
В результате планирования курьер 1 делает 2 рейса и доставляет 20 заказов. За каждый рейс ему начисляется run_payout
— 1232 и 1053 единиц, за смену shift_total_payout
— 2785 единиц (с учетом бонуса shift_payout
в 500 единиц) и за маршрут route_payout
— 3000 единиц. Всего курьеру начислено total_payout
5785 единиц.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Нужно спланировать маршрут при условии, что выплата курьеру зависит от зоны, в которой находится заказ. Для заказов используется следующая схема тарификации:
- Стоимость доставки внутри МКАД — 150 единиц.
- Стоимость доставки за пределами МКАД — 250 единиц.
Выплата курьеру определяется как суммарная стоимость доставки всех заказов в маршруте:
<выплата курьеру> = 150 * <количество заказов внутри МКАД> + 250 * <количество заказов за пределами МКАД>
При планировании используются публичные геозоны public_inside_ttk
(зона внутри ТТК) и public_inside_mkad
(зона от ТТК до МКАД). Тогда выплата рассчитывается по формуле:
150 * order_count(in_zone('public_inside_ttk') | in_zone('public_inside_mkad')) + 250 * order_count(!in_zone('public_inside_ttk') & !in_zone('public_inside_mkad'))
Для 7 заказов внутри МКАД и 3 заказов за пределами МКАД выплата составляет 1050 + 750 = 1800
единиц.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Теги автомобиля
При определении автомобиля или курьера в запросе к Маршрутизации можно назначить ему правила совместимости (или теги) с заказами.
Правила совместимости могут потребоваться при наличии у автомобиля специального оборудования, которое необходимо для выполнения того или иного заказа — например, изотермического фургона для перевозки продуктов питания.
Правила совместимости автомобилей и заказов (теги автомобиля) задаются в следующих полях:
-
Поле
vehicle.tags
— свойства автомобиля, которые частично могут совпадать со свойствами, требуемыми заказом. -
Поле
vehicle.excluded_tags
— свойства автомобиля, которые не должны совпадать со свойствами, требуемыми заказом.
Для определения тегов заказов используется поле запроса location.required_tags
.
Внимание
Теги заказов определяют требуемые заказом характеристики автомобиля, а теги автомобилей определяют фактические правила совместимости того или иного автомобиля с различными заказами.
Определение тегов автомобиля возможно как в виде строк, так и в виде регулярных выражений. В строках теги могут перечисляться через запятую. В этом случае автомобиль сможет доставить заказ, если хотя бы один из перечисленных тегов автомобиля совпадает с тегом заказа или если у заказа нет тегов. Регулярные выражения — это способ описать более сложную логику и правила совместимости между автомобилями и заказами.
В Яндекс Маршрутизации используется синтаксис регулярных выражений POSIX Extended. Для тестирования регулярных выражений можно воспользоваться сервисом Regex101.
Рассмотрим, как можно применять теги на реальных примерах.
Пример 1
Рассмотрим сценарий, в котором транспортная компания доставляет продукты питания и напитки мелким оптом. Некоторые из продуктов питания необходимо доставлять строго в изотермических грузовиках. При этом все напитки и часть товаров из группы продуктов питания могут быть доставлены без холодильников. В дополнение часть клиентов может принять груз, только если автомобили оборудованы гидробортом.
Для определения таких ограничений заказов укажем в поле location.required_tags
следующие теги:
-
TAIL_LIFT
— для заказов, которые могут быть разгружены, только если автомобиль оборудован гидробортом. -
ISOTHERMAL_TRUCK
— для заказов, содержащих товары, которые требуют перевозки с соблюдением температуры. -
NORMAL_TRUCK
— для заказов, не имеющих товаров со специальными условиями перевозки.
Для определения возможностей автомобилей используем следующие теги в поле vehicle.tags
:
-
TAIL_LIFT
— для автомобилей, оснащенных гидробортом. -
ISOTHERMAL_TRUCK
— для автомобилей, оснащенных изотермическим фургоном. -
NORMAL_TRUCK
— для обычных автомобилей без изотермического фургона.
Примечание
Автомобиль при этом может иметь как один, так и несколько тегов, или не иметь их вообще, в зависимости от его реальной конфигурации. Это же правило касается и тегов заказов.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Рассмотрим сценарий, в котором в некоторых заказах есть ограничение по высоте кузова для автомобиля из-за разной высоты зон разгрузки.
Например, есть заказы, у которых ограничение по высоте кузова составляет 2 метра, 2,3 метра и 2,5 метра. В таком случае у них должны быть соответствующие теги: Max_200
, Max_230
, Max_250
.
На машинах теги необходимо проставлять более сложным образом, поскольку машина высотой до 2 метров может доставить любые заказы, а машина высотой 2,8 метра – далеко не все заказы. То есть если использовать только tags
, то при высоте машины:
-
до 2 метров — в поле
vehicle.tags
будут все значенияMax_200
,Max_230
,Max_250
; -
от 2 до 2,3 метра — в поле
vehicle.tags
будут значенияMax_230
,Max_250
; -
от 2,3 до 2,5 — в поле
vehicle.tags
будет значениеMax_250
; -
более 2,5 метров — поле
vehicle.tags
будет пустым.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Рассмотрим сценарий, в котором в некоторых заказах есть ограничение по заезду автомобилей определенной грузоподъемности (при этом действует условие ИЛИ, когда подходит любая из соответствующих машин).
Например, есть машины с разной грузоподъемностью: 1, 3, 9 и 15 тонн. Зафиксируем эти характеристики с помощью тегов vehicle.tags
. Поскольку при описании заказов эти теги придется комбинировать, зададим их с помощью регулярных выражений: .*1TON.*
, .*3TON.*
, .*9TON.*
и .*15TON.*
(.*
— означает «любая подстрока»).
Для некоторых заказов ограничение по грузоподъемности автомобиля составляет от 1 до 15 тонн, от 3 до 9 тонн и от 1 до 3 тонн. Это ограничение задается для заказа строкой с регулярным выражением, которое включает теги всех подходящих машин. То есть в поле location.required_tags
будут следующие регулярные выражения при требуемой грузоподъемности:
- от 1 до 15 тонн —
##1TON##3TON##9TON##15TON##
; - от 3 до 9 тонн —
##3TON##9TON##
; - от 1 до 3 тонн —
##1TON##3TON##
.
Примечание
В примере 2 теги заказа задаются простым перечислением, так как у автомобиля должны быть все перечисленные теги (условие И). В примере 3 необходимо, чтобы у автомобиля был хотя бы один из тегов заказа (условие ИЛИ), это можно реализовать с помощью регулярных выражений или через создание отдельных тегов для каждого возможного сочетания из условий ИЛИ.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Опциональные теги
Иногда при планировании нужно учитывать, какие автомобили желательно использовать (или не использовать) для определенных заказов. Например, доставку VIP-заказов лучше поручать специально обученным курьерам.
Для таких необязательных требований предназначены опциональные теги, которые перечисляются в поле location.optional_tags
. Допускается нарушение заданных предпочтений, если их нельзя удовлетворить (например, из-за ограничений по весу или времени доставки). Этим опциональные теги отличаются от требуемых характеристик ТС.
Примечание
Если автомобили желательно (но не обязательно) использовать на определенной территории, задайте для них опциональные геозоны.
Приоритет предпочтений регулируется с помощью веса тега location.optional_tags.value
. Его значение может быть как положительным, так и отрицательным. При планировании опциональный тег сравнивается с тегами машины, на которой выполняется заказ. Если тег из location.optional_tags
совпал с тегом ТС в списке:
-
vehicle.tags
, тоvalue
вычитается из стоимости маршрута; -
vehicle.excluded_tags
, тоvalue
прибавляется к стоимости маршрута.
Значение, которое опциональные теги добавляют к стоимости маршрута, возвращается в поле result.routes.metrics.total_optional_tags_cost
(может быть отрицательным).
Пример
Нужно доставить 10 заказов, некоторым из них заданы следующие опциональные теги:
vip
— 6 заказов, вес тега на разных точках варьируется от 100 до 350;morning
— 3 заказа, вес тега на всех точках одинаковый, 500.
У одного из автомобилей теги vip
и morning
определены в поле vehicle.excluded_tags
. Таким образом указано, что этому курьеру лучше не поручать заказы с тегом vip
, а также заказы с тегом morning
из-за позднего времени начала маршрута.
В итоге требования в большинстве случаев нарушены не были: пять из шести vip-заказов доставляет курьер без ограничения по тегу vip
, по тегу morning
нарушений нет.
Но один vip-заказ был запланирован на автомобиль с тегом vip
в excluded_tags
— из-за ограничения по вместимости. В поле total_optional_tags_cost
этого маршрута возвращается значение 100: использование «нежелательного» автомобиля увеличило стоимость на 100 единиц. Предпочтение было нарушено для заказа c наименьшим весом location.optional_tags.value
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Зарезервированные теги
Внимание
С 1 ноября 2024 года использование зарезервированных тегов при планировании не будет поддерживаться. Вместо них можно использовать публичные геозоны.
Для проезда по Москве грузовикам нужны специальные пропуска:
-
для проезда внутрь МКАД;
-
для проезда внутрь ТТК.
Эту особенность необходимо учитывать при составлении задачи планирования, чтобы грузовики без пропусков не получали маршруты в зоны, куда им нельзя проехать.
-
Для определения разрешений используйте теги автомобиля:
-
vehicle.tags
=inside_mkad
— для отметки грузовика с пропуском внутрь МКАД, но без въезда в ТТК; -
vehicle.tags
=inside_ttk, inside_mkad
— для отметки грузовика с пропуском внутрь МКАД и внутрь ТТК; -
vehicle.tags
=inside_ttk
— для отметки грузовика, который будет брать заказы только внутри ТТК.
-
-
Алгоритм при загрузке присвоит теги заказам:
-
location.required_tags
=inside_ttk
— точкам внутри TTK; -
location.required_tags
=inside_mkad
— точкам между МКАД и ТТК.
-
Если вы проставите теги заказам самостоятельно, то алгоритм:
-
не будет их корректировать;
-
не присвоит использованный вами тег другим заказам, даже если они ему соответствуют.
Примечание
Алгоритм не присвоит заказам теги, которых нет ни у одного автомобиля.
Например, для автомобиля указан тег vehicle.tags
= inside_ttk
. Тогда тег inside_mkad
для заказов не будет добавлен, даже если точка доставки заказа находится между МКАД и ТТК.
Примеры бизнес-кейсов см. в разделе Планирование маршрутов по зонам.
Несовместимость заказов в автомобиле
Заказы могут иметь несовместимые типы, они задаются с помощью параметров:
-
options.incompatible_load_types
— задает несовместимость заказов для всех автомобилей одинаково. Подробнее см. в разделе Несовместимость заказов. -
vehicle.incompatible_load_types
— задает несовместимость заказов для конкретного автомобиля, то есть позволяет учесть особенности автомобиля. -
vehicle.onboard_incompatible_load_types
— при значенииfalse
(по умолчанию) несовместимость заказов действует в течение всего рейса; при значенииtrue
— только пока заказы находятся в автомобиле.
Примечание
Параметр vehicle.incompatible_load_types
имеет более высокий приоритет и для данного автомобиля полностью переопределяет параметры options.incompatible_load_types
.
Например, для перевозки молока и мороженого требуются разные температурные режимы. Если у автомобиля один отсек, он будет перевозить либо молоко, либо мороженое. Если же у автомобиля два отсека с разными температурными режимами, он может перевозить молоко и мороженое одновременно, в разных отсеках. В этом случае достаточно указать несовместимость заказов vehicle.incompatible_load_types
для автомобилей с одним отсеком. Для автомобилей с двумя отсеками этот параметр не нужен, и для заказов в целом несовместимые типы options.incompatible_load_types
также указывать не нужно.
Если несовместимость заказов вызвана не характеристиками автомобиля, а иными причинами, используйте параметр vehicle.onboard_incompatible_load_types
= true
. Например, если нельзя одновременно перевозить заказы конкурентов, тогда курьер будет забирать и развозить заказы каждой фирмы по отдельности без заезда на склад. Это позволит уменьшить пробег и время маршрута.
Пример 1
Доставка состоит из 4 адресов со следующими типами заказов:
-
заказ 1 (
id
= 1) —flowers
; -
заказ 2 (
id
= 2) —flowers
; -
заказ 3 (
id
= 3) —flowers
,sweets
; -
заказ 4 (
id
= 4) —flowers
,ice-cream
.
При этом flowers
и sweets
несовместимы для доставки в одном автомобиле. Дополнительно, в автомобиле 2 запрещается одновременная доставка flowers
и ice-cream
, но разрешена доставка flowers
и sweets
. Тогда решение будет содержать доставку заказов 2 и 4 в первом автомобиле и заказов 1 и 3 во втором автомобиле.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.1
Нужно забрать и доставить 3 заказа разных компаний. Заказы 1 и 2, 2 и 3 нельзя доставлять вместе, так как они принадлежат компаниям-конкурентам.
В результате планирования курьер забирает и развозит заказы 1 и 3, затем возвращается на склад, чтобы в новом рейсе загрузить и доставить заказ 2.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.2
То же, что и в примере 2.1, но vehicle.onboard_incompatible_load_types
= true
.
В результате планирования курьер забирает и доставляет заказ 2, а затем без заезда на склад забирает и развозит заказы 1 и 3. Пробег и время маршрута уменьшились.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Геозоны
Для автомобилей могут быть заданы ограничения по зонам доставки. Зоны, в которые транспортное средство может доставлять заказы, задаются на листе Vehicles в поле Разрешенные геозоны (vehicles.allowed_zones
в API):
-
автомобиль может выполнять заказы в любой зоне, указанной в этом поле;
-
если зоны доступности не заданы, то курьер может выполнять заказы без ограничений;
-
заказ не может быть выполнен, если для всех курьеров указаны зоны доступности, а точка заказа не попадает ни в одну из них.
Зоны, запрещенные для доставки, задаются в поле Запрещенные геозоны (vehicle.forbidden_zones
в API). Курьер не может доставлять заказы ни в одну из зон, указанных в этом поле.
Примечание
Если заказ расположен в области пересечения разрешенной и запрещенной зон, то он не может быть доставлен — значения в поле Запрещенные геозоны (forbidden_zones
) имеют более высокий приоритет, чем в поле Разрешенные геозоны (allowed_zones
).
Если зоны запрещены для посещения всем курьерам, используйте глобальную опцию options.avoid_zones
. В зонах из vehicle.forbidden_zones
курьер не может выполнять заказы, но может проезжать через них. В зоны из options.avoid_zones
курьеры не могут даже заезжать. Подробнее см. Исключенные зоны.
Для проезда по Москве грузовикам нужны специальные пропуска:
-
для проезда внутрь МКАД;
-
для проезда внутрь ТТК.
Эту особенность необходимо учитывать при составлении задачи планирования, чтобы грузовики без пропусков не получали маршруты в зоны, куда им нельзя проехать.
Чтобы задать ограничение по доставке, используйте следующие публичные геозоны:
public_inside_ttk
— территория внутри ТТК;public_inside_mkad
— территория от МКАД до ТТК (не включает территорию внутри ТТК);
Укажите идентификатор публичной геозоны как значение поля Разрешенные геозоны или Запрещенные геозоны.
При распределении заказов учитывается несовместимость геозон — как заданная глобальной опцией, так и определенная для отдельных курьеров. Также при планировании можно отменить все ограничения, связанные с геозонами.
Пример
В примере 4 заказа и 2 автомобиля, в интерфейсе заданы 4 геозоны. Принадлежность заказов к геозонам определяется автоматически по координатам:
-
Заказ 1 — одновременно в зонах
zone1
иzone2
; -
Заказ 2 — в зоне
zone1
; -
Заказ 3 — одновременно в зонах
zone2
иzone3
; -
Заказ 4 — в зоне
zone4
.
Определена доступность геозон для автомобилей:
Логин курьера |
Разрешенные геозоны ( |
Запрещенные геозоны ( |
Автомобиль 1 |
|
|
Автомобиль 2 |
Зоны не определены |
|
В итоге Автомобиль 1 развозит Заказы 1 и 2, Автомобиль 2 — Заказ 4. А Заказ 3 остался нераспределенным, потому что его адрес находится в зонах, запрещенных для обоих автомобилей.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Опциональные геозоны
Для распределения заказов между автомобилями можно использовать опциональные геозоны, за посещение которых начисляется бонус или штраф. Для каждого автомобиля можно назначить одну или несколько таких геозон.
Опциональные геозоны — это нежесткое ограничение. С их помощью можно задать предпочтительные для посещения зоны (приоритетные и неприоритетные).
Опциональные геозоны задаются с помощью массива vehicle.optional_zones
:
optional_zones.N.zone
— название геозоны;optional_zones.N.value
— если значение параметра больше 0, то автомобиль получает бонус за посещение указанной геозоны (значение этого параметра вычитается из стоимости маршрута), а если меньше 0 — штраф (значение прибавляется к стоимости маршрута).
Приоритет геозон Посмотреть видео |
Пример 1
Нужно доставить 10 заказов двумя автомобилями. Для одного автомобиля задана опциональная геозона South
, а для другого North
. За посещение этих геозон назначен бонус 1000 единиц. В результате один автомобиль развозит заказы на юге, а второй — на севере. Заказ 5 стал исключением — он относится к зоне South
, но был доставлен автомобилем Courier north.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
4 курьера должны доставить 27 заказов. Для курьеров город поделен на 4 опциональных геозоны: Northwest
, Northeast
, Southwest
и Southeast
. Для каждого курьера задана одна приоритетная зона, за посещение которой он получает бонус, две неприоритетных зоны и зона, за посещение которой будет начислен штраф. В результате планирования курьеры доставляют заказы в своих приоритетных зонах. Исключениями стали заказы 18, 20 и 23 из-за ограничения по вместимости автомобилей.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Несовместимые геозоны
Чтобы в один рейс курьера не попадали заказы, которые относятся к разным зонам доставки, можно определить несовместимость геозон.
Список таких зон можно задать не только для всего решения, но и для конкретного курьера — параметром vehicles.incompatible_zones
. Несовместимые зоны, определенные для курьера, имеют приоритет над зонами, определенными глобально. Чтобы на курьера не распространялось глобальное ограничение options.incompatible_zones
, задайте для него в поле vehicles.incompatible_zones
пустой список.
Внимание
При планировании через Excel, чтобы на курьера не распространялось глобальное ограничение несовместимости геозон, проставьте для него в ячейках incompatible_zones.N
пробел (соответствует пустому списку).
Пример
Каждый из трех курьеров должен доставить по 4 заказа в разные районы города: северо-западный, юго-западный, северо-восточный и юго-восточный. Эти районы заданы при планировании геозонами: Northwest
, Southwest
, Northeast
, Southeast
.
Глобально определена несовместимость геозон: южные зоны (Southwest
и Southeast
) несовместимы с северными (Northwest
и Northeast
). Для двух курьеров также задан параметр vehicles.incompatible_zones
: у первого курьера он содержит пустой список, а для второго определено, что западные зоны (Northwest
и Southwest
) несовместимы с восточными (Northeast
и Southeast
).
В результате планирования:
- на первого курьера
Courier 1
глобальное ограничение несовместимости не распространяется и у него в один рейс попадают все 4 заказа из разных районов; - для второго курьера
Courier 2
работают ограничения по несовместимости зон, заданные для него в параметреvehicles.incompatible_zones
: в один рейс попадают заказы в восточные зоны, а в другой — в западные; - на третьего курьера
Courier 3
действуют глобальные ограничения: по разным рейсам разнесены заказы в южные зоны и в северные.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Способ передвижения
При построении маршрутов по умолчанию предполагается, что курьер использует для доставки легковой автомобиль (грузоподъемность меньше 2,5 тонн). Доставку грузов пешком, на грузовом автомобиле или с помощью общественного транспорта можно отразить с помощью параметра vehicle.routing_mode
. Если все курьеры выполняют доставку одним способом, можно использовать опцию маршрутизации options.routing_mode
.
Примечание
Параметр vehicle.routing_mode
имеет более высокий приоритет, чем options.routing_mode
.
Возможные значения:
-
driving
— способ по умолчанию, маршрутизация для автомобилей с грузоподъемностью меньше 2,5 тонн; -
truck
— маршрутизация для грузовых автомобилей, по умолчанию — с грузоподъемностью от 2,5 тонн. Дополнительные параметры можно указать в характеристиках транспортного средства. При планировании с использованием этого способа передвижения учитываются дорожные знаки, ограничивающие движение грузовых автомобилей, в том числе грузовой каркас для Москвы; -
walking
— маршрут с пешеходным профилем. В маршруте используются только те дороги, по которым может ходить пешеход; -
transit
— маршрут с использованием общественного транспорта и перемещением пешком от остановки до точки доставки. Реальное расписание общественного транспорта при этом не учитывается, но считается, что:-
добраться таким способом возможно;
-
курьер приходит на остановку и сразу садится в транспорт.
-
Для курьеров, которые передвигаются на велосипедах или самокатах, указывайте способ передвижения пешком routing_mode
= walking
и используйте коэффициент корректировки скорости travel_time_multiplier
. Для каждого курьера стоит вывести индивидуальный коэффициент корректировки. Например, с помощью отчета План-факт можно сравнить фактическое время в пути для курьера на велосипеде или самокате с плановым временем в пути, рассчитанным для передвижения пешком.
Пример 1
В примере ниже используется способ передвижения transit
для всех курьеров. В результате курьеры выполняют доставку на общественном транспорте и заказы распределены оптимально для них.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Примечание
В построенных маршрутах пробег указан только для расстояний, которые курьер ходит пешком. Расстояния, покрытые в общественном транспорте, учитываются для оптимизации, но не указываются в метриках.
Пример 2
В примере ниже используется способ передвижения transit
для одного курьера, и driving
для другого курьера. Заказы распределены между курьерами так, чтобы автомобиль выполнял доставку в точки, более удаленные от остановок общественного транспорта или друг от друга.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Режим работы курьера
По умолчанию сервис планирует маршрут только с остановками, которые необходимы для доставки грузов. Однако часто курьеры не работают без остановок: им нужно делать перерыв на обед, и это надо учитывать при построении маршрутов. Также на дальних рейсах есть требование соблюдать режим труда и отдыха, когда водитель обязан останавливаться после определенного времени движения.
Чтобы управлять режимом работы курьеров, используйте объект vechicle.rest_schedule.breaks
. Вы можете описать простые или сложные схемы перерывов на отдых, техническое обслуживание и другие действия.
Пресеты перерывов
Вы можете задать режим работы курьера с помощью параметра vehicles.rest_schedule_preset
, который содержит готовый набор настроек:
-
не позже чем через 4,5 часа работы курьера будет установлен 45-минутный перерыв;
-
на длительность смены без учета перерывов будут наложены ограничения:
-
мягкое — 9 часов;
-
жесткое — 10 часов.
-
Возможные значения параметра rest_schedule_preset
:
-
public_transport
— перерыв можно разбить на несколько частей продолжительностью не меньше 10 минут; -
private_transport
— перерыв можно разбить на две части: 15 и 30 минут; -
multiday_private_transport
— режимprivate_transport
для многодневных маршрутов. Дополнительно к обычным перерывам добавляются:- ежедневный перерыв — последние 11 часов каждого буднего дня;
- еженедельный перерыв — последние 45 часов каждой недели.
Перерыв в маршруте будет разбиваться на части при выполнении следующих условий:
-
если между заказами нет интервала, в который можно полностью поместить перерыв;
-
между заказами есть ожидания, куда могут поместиться перерывы.
Также вы можете запретить разбивать перерывы на части. Для этого используйте опцию can_split_preset_work_breaks
= false
(по умолчанию can_split_preset_work_breaks
= true
).
Пример 1
Для курьера назначен режим работы rest_schedule_preset
= private_transport
. В него входит один перерыв, который можно разбить на две части. Между заказами есть интервал, в который полностью помещается перерыв. В результате запланирован один перерыв продолжительностью 45 минут.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Для курьера назначен режим работы rest_schedule_preset
= public_transport
. В него входит один перерыв, который можно разбить на несколько частей. Между заказами нет интервала, куда можно полностью поместить перерыв. Также есть ожидание, в которое может поместиться часть перерыва. В результате запланировано 2 перерыва: 32 и 12 минут.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Для курьера назначен режим работы rest_schedule_preset
= public_transport
. У курьера 14 заказов. На длительность смены наложено жесткое ограничение: 10 часов. В результате один заказ остался невыполненным, так как для его доставки курьеру пришлось бы работать больше 10 часов.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
Для курьера назначен режим работы rest_schedule_preset
= multiday_private_transport
. Нужно доставить один дальний заказ. В результате курьер доставляет заказ на второй день. Он начинает движение в 8:00 и в пути делает три перерыва:
- 45 минут через 1ч 15 мин движения;
- 11 часов в конце рабочего дня, до 8:00 следующего дня;
- 45 минут через 4ч 30 мин движения.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Шаблоны расписаний
Вы можете описать перерывы отдельно для каждого курьера или создать шаблоны для нескольких курьеров. В том числе, можно совмещать индивидуальные расписания и шаблонные.
Чтобы создать шаблон, добавьте в options
параметр template_rest_schedules
и укажите в нем массив расписаний: [{"id": string, "breaks": [...]}]
.
Чтобы использовать шаблон, добавьте в vehicles
параметр rest_schedule_id
и укажите в нем id
шаблона расписания из options
.
Продолжительность перерыва
Продолжительность перерыва устанавливается параметром rest_duration_s
, обязательным для каждого перерыва.
Параметр |
Значение |
Пример |
|
Продолжительность перерыва в секундах. |
Перерыв должен длиться 10 минут (600 секунд). |
Условия начала перерыва
Начало перерыва обозначается диапазоном времени (от и до). Условия можно задать несколькими способами, которые рассмотрены подробнее в таблице ниже.
Параметр |
Значение |
Пример |
|
Время работы от начала маршрута. Включает в себя: время движения, ожидания и сервисное время на заказах и складах. Наличие и продолжительность других перерывов не имеют значения. |
Начать перерыв не раньше, чем через 1 час, и не позже, чем через 3 часа после начала маршрута. |
|
Время работы от последнего перерыва (или от начала маршрута, если это первый перерыв). Включает в себя: время движения, ожидания и сервисное время на заказах и складах. |
Начать перерыв не раньше, чем через 2 часа, и не позже, чем через 4 часа после начала смены (включая приезд на склад, сервисное время, периоды движения и ожидания). |
|
Время движения и ожидания от начала маршрута. Сервисное время при этом не учитывается. |
Начать перерыв не раньше, чем через 1 час, и не позже, чем через 3 часа после начала маршрута с учетом периодов движения и ожидания, но без учета сервисного времени на заказах и складах. |
|
Время движения и ожидания от момента завершения предыдущего заказа. Сервисное время при этом не учитывается. |
Начать перерыв не раньше, чем через 2 часа, и не позже, чем через 3 часа непрерывного движения. |
|
Время движения от начала маршрута. Время ожидания и сервисное время не учитывается. |
Начать перерыв не раньше, чем через 1 час, и не позже, чем через 3 часа от начала движения. |
|
Время начала перерыва. Перерыв не может быть повторяющимся. Время начала работы, наличие и продолжительность других перерывов не имеют значения. Перерыв не начнется, если маршрут закончится раньше времени начала перерыва. |
Начать перерыв в диапазоне с 17:00 до 20:00. |
Если перерывов несколько, в каждом указывается диапазон времени работы после завершения предыдущего перерыва. Например, если в первом перерыве задано 04:00–05:00
, а во втором — 02:00–03:00
, то первый перерыв должен начаться между 4 и 5 часами после начала работы, а второй — между 2 и 3 часами работы после завершения первого перерыва.
Условия планирования перерыва
Вы можете указать дополнительные параметры: сделать перерыв обязательным или задать минимальное время работы для начала перерыва.
Параметр |
Значение |
Пример |
|
Время с начала маршрута, после которого перерыв обязателен. Задается в секундах. |
Обязательно начать перерыв, когда с начала маршрута пройдет 4 часа (14400 секунд). |
|
Параметр устанавливает минимальное время работы, при котором перерыв должен быть запланирован. Если общее время работы меньше, то перерыв не будет запланирован. Задается в секундах. |
Начать перерыв, только если маршрут длится как минимум 4 часа (14400 секунд). |
Условия объединения перерывов
Параметр |
Значение |
Пример |
|
Возможность объединения перерыва с другими перерывами до первого заказа. Перерыв можно объединять только с теми перерывами, типы которых указаны в |
Перерыв будет объединен с последним перерывом перед первой локацией, где тип перерыва указан в |
|
Возможность объединения перерыва с другими перерывами после последнего заказа. Перерыв можно объединять только с теми перерывами, типы которых указаны в |
Перерыв будет объединен с первым перерывом после последней локации, где тип перерыва указан в |
|
Тип перерыва. |
Тип этого перерыва — «обед». |
|
Параметр устанавливает, с какими типами перерывов можно объединить указанный перерыв. Его можно использовать только в сочетании с |
Этот перерыв можно объединить с перерывом на обед или сон. |
Разделяемые перерывы
При необходимости вы можете разделить перерыв на несколько частей. Например, если между заказами перерыв целиком не помещается. Для этого в расписании у перерыва breaks
укажите параметр can_be_split
= true
.
Вы можете указать дополнительные параметры для разделяемого перерыва:
Параметр |
Значение |
Пример |
|
Параметр определяет, сколько у перерыва будет частей. По умолчанию это 2 части. |
Перерыв можно разбить на 5 частей. |
|
Минимальное время, на которое можно разбить часть перерыва. Задается в секундах. По умолчанию это 10 минут. |
Часть перерыва можно разбить минимум на 20 минут (1200 секунд). |
|
Параметр устанавливает минимальное время для первой части перерыва. Задается в секундах. По умолчанию это 1/3 от общей длительности перерыва. |
Первая часть перерыва должна длиться не меньше 30 минут. (1800 секунд). |
|
Минимальное время для последней части перерыва. Задается в секундах. По умолчанию это 2/3 от общей длительности перерыва. |
Последняя часть перерыва должна длиться не меньше 40 минут (2400 секунд). |
Пример
Для курьера предусмотрен 1 перерыв продолжительностью 2 часа "rest_duration_s": 7200
. Для первых трех заказов установлены узкие временные окна, поэтому время ожидания перед заказами можно заполнить перерывами. Так как между заказами перерыв целиком не помещается, он разбивается на 3 части.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Перерывы во время обслуживания заказов
Параметр |
Значение |
Пример |
|
Параметр перерыва. Определяет, может ли этот перерыв пересекаться с сервисным временем заказа или склада. По умолчанию |
|
|
Параметр заказа или склада. Определяет, может ли перерыв пересекаться с сервисным временем этого заказа или склада. По умолчанию |
|
По умолчанию перерывы могут пересекаться с сервисным временем заказа или склада. В маршруте такие перерывы указываются перед заказом или складом. Время начала arrival_time_s
и окончания departure_time_s
перерыва совпадают с arrival_time_s
и departure_time_s
заказа или склада. Внутри этого общего интервала длительность сервисного времени определяется параметром service_duration_s
. В ответе для такого заказа или склада добавляется поле is_after_service_work_break
= true
, означающее, что обслуживание начинается после перерыва.
При can_rest_during_service
= true
перерыв может быть спланирован как первая точка в смене. Для обычных перерывов, не пересекающихся с сервисным временем, такое невозможно.
Чтобы запретить пересечение перерыва с сервисным временем, нужно для заказа или склада указать can_have_rest_during_service
= false
, а для перерыва — can_rest_during_service
= false
.
Пример 1
Перерыв длительностью 50 минут должен быть запланирован через 1,5 часа после начала маршрута. В маршруте 2 заказа, у которых время обслуживания 1 час и параметр can_have_rest_during_service
= true
. В результате перерыв пересекается со временем обслуживания первого заказа, на который курьер приезжает через 1 час 8 минут после начала маршрута и уезжает через 2 часа 20 минут.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что в примере 1, но у заказов параметр can_have_rest_during_service
= false
. В результате перерыв запланирован в точке первого заказа, но перед обслуживанием заказа, раньше времени — всего через 1 час 9 минут после начала маршрута.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Место перерыва
Параметр |
Значение |
Пример |
|
Возможность отдохнуть в точке с типом |
Все перерывы будут проходить точках с типом |
Курьер не может посещать места для перерывов, которые находятся в запрещенных для него геозонах.
Вы можете задавать требования к заезду в место перерыва с типом rest_place
с помощью параметра incompatible_load_types
, см. Несовместимость заказов. Например, курьер перевозит заказ с типом load_type
= ice-cream
, а у точки rest_place
указан тип load_type
= no-refrigerator
. Чтобы курьер не мог заехать в такое место для перерыва, на листе Incompatible_load_types укажите, что тип ice-cream
несовместим с no-refrigerator
.
Цепочки перерывов
Расписание rest_schedule
может содержать множество независимых цепочек перерывов breaks
. Каждая цепочка может содержать множество перерывов с особенными условиями. Наступление перерыва в каждой цепочке зависит только от построенного маршрута и не зависит от перерывов в других цепочках.
Пример |
Пояснение |
Возможность задать |
1 цепочка: отдыхать 15 минут через каждые 3 часа движения. 2 цепочка: отдыхать 6 часов через 8 часов после начала смены. |
Перерывы в цепочке 2 зависят только от начала смены и не зависят от расписания движения и отдыха в цепочке 1. |
|
1 цепочка: отдыхать 15 минут через каждые 3 часа движения. 2 цепочка: отдыхать 6 часов через каждые 8 часов движения. |
Начало перерыва в цепочке 2 зависит от расписания движения и отдыха в цепочке 1. |
|
Порядок цепочек не имеет значения, но перерывы в одной цепочке необходимо указывать последовательно.
Если маршрут заканчивается до наступления остановки (например, маршрут выполнен за 3 часа, а остановка запланирована через 4), то все невыполненные остановки сбрасываются.
Пример
Маршрут построен с получасовыми перерывами на отдых через 4–4,5 часа работы, а через 15 часов после начала маршрута запланирован перерыв на сон. В результате алгоритм запланировал перерыв на сон через 1,5 часа после перерыва на отдых.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Штрафы
В некоторых случаях сервис может планировать маршруты с нарушением окна отдыха. Чтобы начислять штрафы за эти нарушения, используйте поля penalty.late
и penalty.early
. Если штраф выше, чем полученная от нарушения окна экономия, то маршрут будет запланирован без нарушений.
Параметр |
Значение |
Пример |
|
Штраф за факт раннего начала перерыва. |
Устанавливает штраф 1000 за факт раннего перерыва. |
|
Штраф за каждую минуту раннего перерыва. |
Устанавливает штраф 17 за каждую минуту раннего перерыва. |
|
Штраф за факт позднего перерыва. |
Устанавливает штраф 1000 за факт позднего перерыва. |
|
Штраф за каждую минуту позднего перерыва. |
Устанавливает штраф 17 за каждую минуту позднего перерыва. |
Условия повтора
Параметр |
Значение |
Пример |
|
Параметр указывает, что перерыв нужно повторять. Можно использовать только для последнего в цепочке перерыва. |
Перерыв будет повторяться до конца смены. |
Пример 1
В этом примере построен маршрут с перерывом на обед через 4–5 часов работы. В результате алгоритм планирует остановку на обед для выполняющего доставку курьера.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В этом примере построен маршрут между Москвой и Санкт-Петербургом с первым перерывом через 4–4,5 часа, и затем с перерывами каждые 2 часа. Алгоритм выделил два перерыва.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Для двух курьеров задан перерыв с условием work_time_range_from_start
через 3-4 часа после начала работы, но только если общая продолжительность route_duration_s
минимум 6 часов. Первый курьер заканчивает работу за 5 часов, поэтому работает без отдыха. Второй курьер работает более 6 часов, поэтому получает один перерыв.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
Курьер везет заказы в соседний город и нуждается в периодическом отдыхе. С помощью условия повтора repeatable
заданы перерывы через каждые 60-80 минут маршрута (travel_time_range
). В результате алгоритм запланировал два перерыва.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 5
Как в примере 4, но маршрут длится несколько дней, и перерывы задаются на сон каждые 12 часов:
-
используется условие повтора
repeatable
; -
минимальная и максимальная продолжительность маршрута до отдыха
travel_time_range
:"12:00-12:00"
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 6
Задаются перерывы длительностью 10 минут на каждые 55-60 минут непрерывного движения continuous_travel_time_range
. В результате запланирован перерыв на единственном интервале между точками, где время движения более 55 минут.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 7
Для курьеров запланировано два перерыва с условием начала перерыва work_time_range_till_rest
через 2-3 часа от последнего перерыва или от начала работы, если это первый перерыв.
-
первый перерыв — 20 минут.
-
второй перерыв — 30 минут.
Первый курьер заканчивает работу раньше и получает только первый перерыв. Второй курьер работает дольше и получает оба перерыва.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 8
Для двух курьеров запланировано 19 заказов. Первый курьер должен отдыхать каждые 2-3 часа работы, второй — каждые 3-4 часа. Для них указано общее место для отдыха — точка с типом rest_place
.
Первый курьер выезжает на маршрут в 7:00 и в 9:48 приезжает на место отдыха, отдыхает 30 минут и продолжает маршрут. Второй курьер выезжает на маршрут в 8:00 и успевает развезти все свои заказы до 12 часов, без перерыва на отдых.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Запланированный маршрут
Пользователь может указать, какой курьер должен выполнить конкретные заказы. Это пригодится:
-
при допланировании — когда есть заранее запланированные маршруты;
-
когда заказ связан с определенным курьером.
Для указания ранее спланированных заказов для данного курьера используется опция vehicle.planned_route
. Опция обладает следующими свойствами:
-
Все заказы, указанные в
vehicle.planned_route
, при планировании не могут стать нераспределенными, даже если будут нарушены жесткие ограничения — вместимость автомобиля или временные окна, у которыхhard_window
=true
. -
Последовательность заказов, определенная в
planned_route
, по умолчанию не фиксируется. При повторном планировании заказы могут перестроиться в новой последовательности. -
Если необходимо сохранить указанный в
planned_route
маршрут без изменений (без изменения последовательности и без добавления новых заказов), то используйтеvehicle.fixed_planned_route
=true
.
Для каждого заказа, определенного planned_route
, обязательно указывать принадлежность к смене автомобиля (даже если у автомобиля 1 смена).
Если в planned_route
задано несколько смен, то зафиксировать заказы за сменами можно при помощи опции fix_planned_shifts
= true
. По умолчанию опция принимает значение false
.
Если курьер приехал на заказ слишком рано, время вручения заказа определяется параметром vehicle.wait_if_early
:
true
— курьер ждет начала временного окна заказа (значение по умолчанию);false
— курьер обслуживает заказ сразу после прибытия.
Внимание
Если для заказа указано жесткое временное окно location.hard_window
= true
, параметр vehicle.wait_if_early
должен принимать значение true
.
Если курьеру во время маршрута необходимо посетить склады для дозагрузки, укажите их в поле middle_depot_id
. Они могут совпадать со складами, которые курьер посещает в начале или конце маршрута.
Если в planned_route
курьер должен посетить склады для дозагрузки, укажите для них опцию is_middle_depot
= true
(по умолчанию false
). Если указать опцию is_middle_depot
= true
для всех складов, то алгоритм спланирует начальные и конечные склады в соответствии с настройками курьера, см. разделы Старт с одного из нескольких складов и Возврат на склад в конце маршрута или рейса.
Пример 1
У каждого из двух курьеров в planned_route
были определены заказы, в итоге они так и попали на каждого из курьеров.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В данном примере участвует 1 машина, на которую привязаны заказы через planned_route
. Суммарный вес заказов превышает вместимость машины, но такой маршрут все равно планируется (поскольку заказы, определенные в этой опции, не могут попасть в нераспределенные), при этом статус задачи будет UNFEASIBLE
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Теоретически 2 курьера могли бы доставить все 20 заказов без перегруза и опозданий. Но для курьера 1 при помощи параметра vehicle.fixed_planned_route
= true
указана фиксированная последовательность заказов, поэтому он доставит только заказы из этой последовательности. Курьер 2 не ограничен жестким планом, поэтому возьмет столько заказов, сколько сможет увезти. И несколько заказов останется на складе, несмотря на свободные места и время у курьера 1.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4.1
2 курьерам за 2 смены необходимо доставить 15 заказов. При помощи опции planned_route
заказы 1-8 зафиксированы за курьером 1, а заказы 9-15 за курьером 2. При этом указано, что заказы 1-4 и 9-12 необходимо доставить в первую смену, а заказы 5-8 и 13-15 во вторую смену. Так как fix_planned_shifts
= false
и курьеры успевают доставить все заказы в одну смену, то распределение заказов по сменам не учитывается.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4.2
То же, что и в примере 4.1, но опция fix_planned_shifts
= true
. Поэтому при доставке заказов учитывается, в какую смену их необходимо доставить.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Загруженные заказы
Если заказ уже находится в автомобиле, курьер может сразу ехать на доставку. Для выполнения такого сценария укажите параметры в поле planned_route
:
Параметр |
Описание |
Значение |
|
Список |
|
|
Все загруженные в автомобиль заказы должны быть обслужены в этом же рейсе прежде, чем автомобиль заедет на склад. |
|
|
Автомобиль заедет на все склады в Используйте, если:
|
|
* Указывается для складов и заказов типа garage
.
Пример
Несколько заказов загружено в автомобиль курьера с вечера, за ними не нужно заезжать на склад. Поэтому в месте, откуда будет выезжать курьер, указана точка типа garage
.
Параметр loaded_orders
показывает, что загружены заказы 1 и 2 . Курьер может сразу отвезти их в место назначения.
В условиях также заданы параметры:
-
planned_runs_first
=true
; -
delivery_in_current_run
=true
для склада и гаража.
Курьер стартует из гаража и сразу доставляет заказы 1 и 2. Затем он отправляется на склад, где забирает заказы № 3 и № 4, которые должен доставить сразу после загрузки. После этих двух доставок курьер возвращается на склад за заказами 5 и 6 и следует по маршруту дальше.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Фиксированная часть маршрута
Функциональность visited_locations
пригодится, если:
-
начало маршрута должно проходить в строгом порядке.
-
нужно изменить точку старта при допланировании.
Маршрут необходимо фиксировать для каждого курьера индивидуально.
Чтобы это сделать, укажите в vehicles
массив visited_locations
и опишите точки фиксированного маршрута с помощью следующих параметров.
Параметр |
Описание |
|
Идентификатор заказа из |
|
Идентификатор смены курьера из |
|
Время отправления из точки. Если для первой точки фиксированной части маршрута:
Параметр можно указать на нескольких заказах — тогда время посещения рассчитается согласно указанному времени |
|
Необходимость ждать начала временного окна в случае раннего приезда.
|
* Обязательный параметр
Пример 1
В примере 5 заказов. Последовательность заказов 1, 2, 3 зафиксирована в visited_locations
. Заказы 4 и 5 могут быть выполнены в любом порядке.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
С помощью visited_locations
указано начать маршрут с заказа 2 в 10:00.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Последовательность заказов 1, 2, 3 задана, как в примере 1. Дополнительно указано отправление с заказа 1 в 08:20 и с заказа 3 — в 11:00.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
В примере 8 заказов. Указана последовательность: заказы 1, 2, 3, затем склад, затем заказ 4. Оставшиеся заказы курьер выполняет в любом порядке.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Корректировка времени движения автомобиля
Для расчета скорости автомобиля при построении маршрута используются данные Яндекс Карт о пробках и указанная в запросе скорость. Однако часто получается так, что грузовики движутся по пробками медленнее, а некоторые водители водят более агрессивно и приезжают раньше расчетных значений.
Чтобы компенсировать такие отклонения, в Маршрутизации есть опция travel_time_multiplier
, в которой можно указать дробное значение. При значении 1 расчет будет произведен для автомобиля с ожидаемой средней скоростью. При меньших значениях (например, 0,8), расчет будет для более быстрых автомобилей, при больших (например, 1,2) — для более медленных.
Примечание
Параметр travel_time_multiplier
влияет только на скорость движения автомобиля. Время обслуживания на точке доставки остается прежним.
Пример 1
В примере ниже запрос на маршрутизацию отправлен без корректировки времени движения. В результате автомобиль выполняет доставку за 4 часа 20 минут, из которых 3 часа 40 минут уходит на перемещение между точками.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но добавлен параметр travel_time_multiplier
, равный 0,5. В построенном маршруте курьер выполняет доставку за 2 часа 25 минут, из которых 1 час 45 минут уходит на перемещение между точками. При этом время, затраченное на парковку и передачу товара, не изменяется.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
То же, что и в примере 1, но добавлен параметр travel_time_multiplier
, равный 2. В построенном маршруте курьер выполняет доставку за 7 часов 58 минут, из которых 7 часов 18 минут уходит на перемещение между точками. На перемещение уходит примерно в 2 раза больше времени, чем в маршруте примера 1, потому что часть построенного маршрута выпадает на час пик, и автомобиль не может использовать максимальную скорость. Время, затраченное на парковку и передачу товара, не изменяется.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Корректировка времени обслуживания
Курьеру при доставке заказа нужно потратить время, чтобы его передать. В это время включается парковка, подъем на лифте, передача доставки и оформление бумаг. В Маршрутизации это обеспечивается полями service_duration
и shared_service_duration
у заказов. Однако некоторые курьеры передают товар быстрее, чем другие. Например:
-
При одновременном планировании для автомобилей и курьеров на общественном транспорте курьеры, которые передвигаются общественным транспортом, не тратят время на парковку. В результате им нужно меньше времени на обслуживание.
-
У курьеров может быть разный уровень квалификации. Опытные курьеры обычно тратят меньше времени на передачу заказа.
Чтобы компенсировать разницу между временем работы курьеров, в Маршрутизации есть опции service_duration_multiplier
и shared_service_duration_multiplier
, влияющие на длину обслуживания конкретным курьером. При значении 1 время обсуживания будет совпадать с указанным в поле service_duration
или shared_service_duration
, при значениях меньше 1 время обслуживания будет меньше, а при значениях больше 1 — больше.
Примечание
Параметры service_duration_multiplier
и shared_service_duration_multiplier
влияют только на время обслуживания. Время перемещения между точками остается прежним.
Пример 1
В примере ниже запрос на маршрутизацию отправлен без корректировки времени обслуживания.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
В примере ниже на маршрутизацию отправлен тот же запрос, что и в примере 1, но со значением параметра service_duration_multiplier
в 0,5. Обслуживание заказов в расчете занимает вполовину меньше времени по сравнению с примером 1.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
В примере ниже на маршрутизацию отправлен тот же запрос, что и в примере 1, но со значением параметра service_duration_multiplier
в 2. Обслуживание занимает вдвое больше времени по сравнению с примером 1.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Доставка как можно раньше
Для построения оптимального маршрута алгоритм минимизирует ожидание между точками маршрута. Но бывают случаи, когда полезно сдвигать доставку на более раннее время. Например:
- нужно минимизировать риск опоздания;
- курьеру комфортнее ехать в светлое время суток.
Чтобы заказы были доставлены как можно раньше, используйте penalty.arrival_after_start
, который состоит из двух параметров:
average_h
— задает размер штрафа за среднее время приезда после начала временного окна. При использовании опции рекомендуется всегда указывать это значение.as_soon_as_possible
— определяет, нужно ли начинать маршрут максимально рано. Параметр принимает значениеtrue
илиfalse
(по умолчанию). Указывается в дополнение кaverage_h
.
Примечание
Алгоритм может сдвигать время старта и приезда автомобиля, только если для склада включено гибкое время старта.
Если не использовать штраф penalty.arrival_after_start
, то маршрут будет строиться с минимальным ожиданием между точками и максимально поздним временем старта со склада.
При использовании штрафа алгоритм будет строить маршруты так, чтобы начинать их раньше, если это не ухудшает качество.
Если маршрут следует начать максимально рано (даже если из-за этого появится дополнительное ожидание), укажите penalty.arrival_after_start.as_soon_as_possible
= true
.
Пример 1
Маршрут состоит из 4 заказов, которые имеют разные временные окна. Самое раннее начало временного окна у заказа 5 — в 08:00. Курьер стартует со склада в 11:02 и прибывает на первый заказ в 11:40. Заказ 5 доставляется в 12:59.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Используются те же данные, что и в примере 1, но назначен штраф за среднее время приезда после начала временного окна при помощи параметра penalty.arrival_after_start.average_h
. При этом курьер стартует со склада в 06:59, ждет 8 минут и доставляет самый ранний заказ (заказ 5) в 08:00.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Используются те же данные, что и в примере 2, но дополнительно задан параметр penalty.arrival_after_start.as_soon_as_possible
= true
. При этом курьер стартует со склада в 06:00, ждет 1 час 7 минут и доставляет самый ранний заказ (заказ 5) в 08:00.
Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Сцепки
Сцепка — это грузовик с прицепом. Заказы можно размещать в грузовике и в прицепе, при этом один заказ может быть загружен частично в грузовик, частично в прицеп.
Для описания прицепа используйте объект trailer
.
Поле |
Описание |
|
Вместимость прицепа, описывается полями:
Добавляется к вместимости грузовика. |
|
Количество пользовательских единиц измерения, которое можно перевозить в прицепе. Вместимости в пользовательских единицах задаются в формате
Если название единицы присутствует в отправлениях или других автомобилях, но не в этом, то вместимость полагается неограниченной. |
|
Предел загрузки прицепа, описывается полями:
|
|
Метрические размеры прицепа, описываются полями:
Значения выражаются в метрах. * — Обязательный параметр |
|
Объем прицепа в кубометрах. Если у прицепа заданы и метрические размеры, и объем, то |
|
Максимальная разница в загрузке прицепа и грузовика описывается полями:
Если какое-то из полей пропущено, значит, по нему нет ограничений. На разницу в загрузке прицепа и грузовика есть физические ограничения. Если грузовик пустой, а прицеп тяжелый, то автомобиль становится неуправляемым, сцепка не сможет ехать. |
|
Максимально допустимая разница в загруженном количестве пользовательских единиц измерения у прицепа и грузовика. Допустимая разница в пользовательских единицах задается в формате
Если название единицы присутствует в отправлениях или других автомобилях, но не в этом, то ограничения нет. |
|
Стоимость прицепа, описывается полями:
Добавляется к стоимости грузовика, если прицеп будет использован. |
|
Время отсоединения прицепа в секундах. Только для заказов с типом |
|
Время присоединения прицепа в секундах. Только для заказов с типом |
|
Штраф за каждую перекатку* грузов из прицепа в грузовик. * Перекатка — перемещение заказов из прицепа в грузовик (чтобы доставить их в неподъездные локации (см. раздел Использование прицепа)). |
|
Время перекатки груза из прицепа в грузовик, задается в секундах. Может быть описано полями:
Если указано несколько типов времени, используется тот, который затрачивает больше всего времени. Если ни один тип не указан, используется только фиксированное время. Ко времени перекатки добавляется |
Пример описания прицепа в запросе:
{
"trailer": {
"capacity": {
"weight_kg": 10000,
"units": 200
},
"max_capacity_difference": {
"units": 10,
"weight_kg": 0
},
"cost": {
"fixed": 1000,
"km": 10
},
"decoupling_time_s": 300,
"coupling_time_s": 300,
"rolling_time": {
"fixed_time_s": 3000
}
}
}
Подробнее об использовании грузовика с прицепом см. в разделе Использование прицепа.
Минимальный вес заказа для автомобиля
Чтобы тяжелый грузовик не вез один легкий заказ в другой конец города, используйте параметр min_stop_weight
. С помощью этого параметра вы можете указать минимальный суммарный вес, который автомобиль будет доставлять в одну точку. Актуально при планировании грузовых перевозок разнотоннажным транспортом.
Ограничение мягкое — алгоритм может его нарушить. Штрафы задаются в полях:
-
penalty.min_stop_weight.fixed
— штраф за факт нарушения минимального суммарного веса всех заказов в одной точке (по умолчанию 1000); -
penalty.min_stop_weight.kg
— штраф за каждый недостающий килограмм в суммарном весе заказов, доставляемых в одну точку (по умолчанию 50).
Подробнее об использовании разнотоннажного транспорта см. в разделе Транспорт с разной грузоподъемностью.
Пример 1
Два автомобиля с грузоподъемностью 1500 и 10000 кг развозят заказы весом 100, 500, 900 и 9000 кг. Большому автомобилю достаются и легкие, и тяжелые заказы.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
Для автомобиля с грузоподъемностью 10000 кг указан параметр min_stop_weight
со значением 1000. В результате большому автомобилю достается только заказ с весом 9000 кг.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Значение по умолчанию.