Группировка заказов и мультизаказы

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

Группировка заказов

При построении маршрутов часто возникает необходимость доставить несколько заказов одним курьером. Например, если для компании важно, чтобы все заказы были выполнены на одном автомобиле, или при осуществлении цепочек доставки, когда курьеру нужно отвезти заказ на точку, получить там документы о доставке и привезти их в офис.

В Маршрутизации есть возможность группировать заказы с помощью опции location_groups. Заказы добавляются в группу по их идентификаторам. Порядок заказов, определенный в группе, неважен — при планировании алгоритм может выстроить их в любом порядке.

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

Свойства групп для настройки планирования:

  • options.location_groups.solid — значение true указывает, что группа неразрывная: заказы в ней должны выполняться без других заказов между ними. Порядок заказов в группе не фиксируется. Это часто используется, например, для грузового такси, которое должно доставить груз из одной точки в другую, и до выгрузки новый заказ в машину добавить нельзя. Значение по умолчанию — false.

  • options.location_groups.dependent — значение true определяет, что группа неделимая: все ее заказы должны быть или выполнены, или (если невозможно доставить хотя бы один) сброшены в нераспределенные вместе. Значение по умолчанию — false.

Пример 1

В этом примере два автомобиля развозят заказы по 8 точкам. Поскольку опция location_groups не используется, Маршрутизация строит оптимальный маршрут.

Пример ExcelЗапрос API (JSON)Ответ APIОткрыть на карте

Пример 2

В этом примере используются те же вводные данные, что и в примере 1, но заказы 7 и 8 объединены в одну группу. Маршрутизация распределяет эти заказы в один автомобиль. Полученный маршрут менее оптимальный по метрикам, но соответствует требованиям по доставке.

Пример ExcelЗапрос API (JSON)Ответ APIОткрыть на карте

Пример 3

8 заказов разбиты на 3 группы, каждая из которых включает заказы одного клиента. Группы определены как неразрывные: свойство options.location_groups.solid установлено в true. В построенном маршруте точки разных клиентов не были перемешаны друг с другом: сначала выполняются заказы клиента 1, затем клиента 2 и в конце — клиента 3.

Пример ExcelЗапрос API (JSON)Ответ APIОткрыть на карте

Пример 4

8 заказов разбиты на 2 группы. Значение options.location_groups.dependent = true. Это значит, что если хоть один заказ группы невозможно выполнить, то сбрасывается вся группа целиком.

Суммарный вес заказов первой группы составляет 250 кг, второй — 450 кг. Из-за ограниченной грузоподъемности (600 кг) курьер не сможет развезти две неделимые группы заказов за один рейс, поэтому алгоритм сбрасывает одну из групп.

Пример 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 или способ передвижения курьера.

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