Группировка заказов и мультизаказы
Чтобы сократить время на выполнение маршрута, некоторые заказы могут объединяться. Объединение может быть задано вручную, с помощью группировки заказов. Если заказы расположены по одному адресу (например, торговый центр или многоквартирный дом), то они могут автоматически объединяться в один мультизаказ. Если на маршруте есть несколько близко расположенных заказов, вы можете настроить требования к их посещению одним курьером или в одном маршруте.
Группировка заказов
При построении маршрутов может возникнуть необходимость реализовать разные сценарии:
-
Доставить несколько заказов одним курьером:
Например, для компании важно, чтобы все заказы были выполнены на одном автомобиле. Или в случае, когда курьеру нужно отвезти заказ на точку, получить там документы о доставке и привезти их в офис.
-
Перевезти пассажиров:
- забрать одного пассажира из одной точки и доставить в другую;
- забрать нескольких пассажиров из одной точки и доставить в несколько других точек;
- забрать нескольких пассажиров из нескольких точек и доставить в одну точку.
В Маршрутизации есть возможность группировать такие заказы. Параметры группировки задаются на листе Location_groups (options.location_groups
в API).
Для каждой группы можно указать название в поле title
. Это не влияет на маршрутизацию, но позволяет присваивать группам удобные для работы имена. Заказы добавляются в группу по их идентификаторам — location_ids
. Порядок заказов в группе может быть строго фиксированным или произвольным.
На листе Location_groups поле ordered
может принимать следующие значения:
true
— при планировании алгоритм выстроит заказы в порядке, определенном вlocation_ids
;false
или без значения — порядок заказов соблюдаться не будет. По умолчанию значениеordered
не задано.
Также для групп заказов можно указать следующие свойства:
solid
— значениеtrue
указывает, что группа неразрывная: заказы в ней должны выполняться без других заказов между ними. Порядок заказов в группе не фиксируется. Это часто используется, например, для грузового такси, которое должно доставить груз из одной точки в другую, и до выгрузки новый заказ в машину добавить нельзя. Значение по умолчанию —false
.dependent
— значениеtrue
определяет, что группа неделимая: все ее заказы должны быть или выполнены, или, если невозможно доставить хотя бы один, сброшены в нераспределенные вместе. Значение по умолчанию —false
.
Пример 1
В этом примере два автомобиля развозят заказы по 8 адресам. Поскольку заказы не объединяются в группы, Маршрутизация строит оптимальный маршрут.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2
То же, что и в примере 1, но заказы 7 и 8 объединены в одну группу. Маршрутизация распределяет эти заказы в один автомобиль. Полученный маршрут менее оптимальный по метрикам, но соответствует требованиям по доставке.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
8 заказов разбиты на 3 группы, каждая из которых включает заказы одного клиента. Группы определены как неразрывные: на листе Location_groups указано значение solid
= true
. В построенном маршруте заказы разных клиентов не были перемешаны друг с другом: сначала выполняются заказы клиента 1, затем клиента 2 и в конце — клиента 3.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 4
8 заказов разбиты на 2 группы. На листе Location_groups указано значение dependent
= true
. Это значит, что если хоть один заказ группы невозможно выполнить, то сбрасывается вся группа целиком.
Суммарный вес заказов первой группы составляет 250 кг, второй — 450 кг. Из-за ограниченной грузоподъемности (600 кг) курьер не сможет развезти две неделимые группы заказов за один рейс, поэтому алгоритм сбрасывает одну из групп.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 5
8 заказов объединены в 1 группу. На листе Location_groups указаны значения для полей:
location_ids
— указан обратный порядок доставки (от последнего заказа к первому);ordered
=false
.
В результате при планировании заказы распределяются произвольным образом. Порядок location_ids
не соблюдается.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 6
Те же условия, что и в примере 5, но на листе Location_groups в поле ordered
указано значение true
.
В результате при планировании заказы распределяются в строго заданном порядке location_ids
от последнего к первому.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Мультизаказы
Заказы, расположенные по одному адресу, могут автоматически объединяться в один мультизаказ. При объединении учитываются территориальная близость заказов, а также возможность доставки в одно время и одним автомобилем или курьером с учетом тегов, вместимости и приоритета выполнения.
Чтобы гарантировать объединение заказов, расположенных по одному адресу, в один мультизаказ (с учетом остальных ограничений), установите опцию merge_multiorders
= true
. В этом случае заказы могут объединяться в один мультизаказ, даже если между ними есть ожидание (опция wait_in_multiorders
по умолчанию равна true
).
Чтобы мультизаказ был неделимым, установите опцию options.force_merge_multiorders
= true
. В этом случае все заказы по одному адресу будут доставлены одним автомобилем, если это невозможно — весь мультизаказ попадет в нераспределенные. Значение по умолчанию — false
.
По умолчанию заказы, которые доставляются по одному адресу для разных клиентов (с разными client_id
), считаются как одна остановка. Чтобы считать их отдельными остановками, установите опцию options.merge_multiorders_of_different_clients
= false
. Количество остановок может использоваться при расчете стоимости маршрута. Опция не влияет на расчет сервисного времени — для расчета времени вручения документов или паркинга location.shared_service_duration_s
берется самое большое время среди всех заказов в мультизаказе.
Близость заказов определяется опцией multiorder_radius_m
(по умолчанию 1 м). Значение не следует устанавливать слишком большим, чтобы в мультизаказ не попадали заказы, расположенные в соседних зданиях — в таких случаях для планирования лучше использовать сценарий Доставка с парковкой автомобиля перед пешей частью маршрута.
По умолчанию время на паркинг или вручение документов shared_service_duration_s
учитывается один раз на весь мультизаказ. Но если между заказами есть ожидание (т.е. заказы имеют разные временные окна, и курьер завершает обслуживание одного заказа раньше, чем может начать обслуживать следующий), сервисное время shared_service_duration_s
можно учитывать отдельно для каждого заказа. Для этого отключите опцию ожидания options.wait_in_multiorders
= false
. Чтобы учитывать время shared_service_duration_s
отдельно для конкретного заказа, установите для него location.can_be_merged
= false
. Подробнее об учете времени на заказ можно прочитать в разделе Сервисное время при доставке заказов.
При планировании алгоритм будет стремиться сократить повторные посещения адресов мультизаказов. В ответе API доступны метрики:
multiorders_extra_points
— количество адресов мультизаказов, куда курьеры приезжали больше одного раза .multiorders_extra_visits
— количество повторных приездов на адреса мультизаказов.multiorders_extra_vehicles
— количество курьеров, которые дополнительно посещали адреса мультизаказов.
За повторные посещения можно назначать соответствующие штрафы:
options.penalty.multiorders.per_extra_point
— за каждый адрес мультизаказа, на который пришлось приезжать повторно.options.penalty.multiorders.per_extra_visit
— за каждый повторный приезд на адрес мультизаказа.options.penalty.multiorders.per_extra_vehicle
— за каждого курьера, который дополнительно посещает адрес мультизаказа.
Пример 1
Автомобиль развозит три заказа. Заказы 1 и 2 доставляются по одному адресу и объединяются в мультизаказ.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.1
Автомобиль развозит три заказа. Заказы 1 и 2 доставляются по одному адресу и объединены в один мультизаказ. По умолчанию wait_in_multiorders
= true
, и сервисное время учитывается один раз. Из-за разницы временных окон между этими заказами есть ожидание, поэтому визуально заказы 1 и 2 не объединены в один мультизаказ, но в ответе API у заказа 2 параметр multi_order
= true
.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 2.2
Доставляются те же заказы, что и в примере 2.1, но опция wait_in_multiorders
= false
. Заказы 1 и 2 не объединились в один мультизаказ (у заказа 2 multi_order
= false
), и сервисное время учитывается отдельно для каждого заказа.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Пример 3
Заказы 1, 2 и 3 нужно доставить по одному и тому же адресу. Заказ 4 нужно доставить по другому адресу. Каждый заказ весит 500 кг. Вместимость автомобиля всего 1200 кг, поэтому автомобиль делает два рейса — сначала доставляет заказы 1 и 2, а затем заказы 3 и 4.
Алгоритм объединил заказы 1 и 2 в мультизаказ, несмотря на то, что merge_multiorders
= false
(по умолчанию). Так как на этот адрес пришлось приехать повторно для доставки заказа 3, начислены штрафы: 10 единиц за наличие адреса мультизаказа, на который пришлось приехать повторно, и 1000 единиц за повторный приезд на адрес мультизаказа.
Пример Excel ⋅ Запрос API (JSON) ⋅ Ответ API ⋅ Открыть на карте
Близкие заказы
Если вы хотите ограничить количество курьеров или маршрутов, которые ведут к близко расположенным заказам, объедините такие заказы в группы. Для этого на листе Options задайте следующие параметры:
close_location_groups_radius_m
— предел расстояния, при котором заказы считаются близкими, в метрах. По умолчанию 0;penalty.close_location_groups.per_extra_point
— штраф за каждую точку, в которую курьер приезжает больше одного одного раза;penalty.close_location_groups.per_extra_vehicle
— штраф за каждого дополнительного курьера, который приезжает в группу близко расположенных заказов;penalty.close_location_groups.per_extra_visit
— штраф за каждый дополнительное посещение группы близко расположенных заказов.
Если задан параметр close_location_groups_radius_m
> 0, мы рекомендуем использовать группировку близко расположенных заказов только на этапе дооптимизации последовательности. Для этого установите опции options.post_optimization
= true
и options.close_locations_during_post_optimization_only
= true
(по умолчанию false
).
Чтобы установить ограничения на посещение близко расположенных заказов для курьера, на листе Vehicles задайте следующие параметры:
close_locations.routing_mode
— способ передвижения для определения близости заказов, одинаковый для всех заказов в решении;close_locations.search_radius_m
— расстояние между двумя заказами при выбранном способе передвижения, которые считаются близкими и на которые распространяются ограничения;close_locations.soft_search_radius_m
— если значение этого параметра превышает значение соответствующегоclose_locations.search_radius_m
, то на заказы на расстоянии отsearch_radius_m
доsoft_search_radius_m
также будет накладываться штраф, но его размер линейно уменьшается в зависимости от расстояния. Например, на расстоянии (search_radius_m
+soft_search_radius_m
) / 2 будет действовать штраф с весом 0,5;close_locations.duration_till_service_s.value
иclose_locations.duration_till_service_s.penalty
— максимально допустимое время (в секундах) между обслуживанием двух близких заказов и штраф за нарушение ограничения;close_locations.distance_till_service_m.value
иclose_locations.distance_till_service_m.penalty
— максимально допустимое пройденное расстояние (в метрах) между обслуживанием двух близких заказов и штраф за нарушение ограничения.
Пример использования настроек близких заказов
{
...
"vehicles": [{
...
"close_locations": [
{
"routing_mode": "driving",
"search_radius_m": 400,
"soft_search_radius_m": 500,
"distance_till_service_m": {
"penalty": 0.02,
"value": 1500
}
},
{
"routing_mode": "driving",
"search_radius_m": 100,
"soft_search_radius_m": 160,
"duration_till_service_s": {
"penalty": 0.02,
"value": 1500
}
}
],
...
},
...
],
...
}
Внимание
Если на листе Vehicle для курьера не определен параметр walking_courier
, способ передвижения close_locations.routing_mode
указать нельзя — по умолчанию используется способ передвижения курьера. Если параметр walking_courier
определен, в качестве значения close_locations.routing_mode
можно указать walking
или способ передвижения курьера.