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

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

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

При построении маршрутов может возникнуть необходимость реализовать разные сценарии:

  • Доставить несколько заказов одним курьером:

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

  • Перевезти пассажиров:

    • забрать одного пассажира из одной точки и доставить в другую;
    • забрать нескольких пассажиров из одной точки и доставить в несколько других точек;
    • забрать нескольких пассажиров из нескольких точек и доставить в одну точку.

В Маршрутизации есть возможность группировать такие заказы. Параметры группировки задаются на листе 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 или способ передвижения курьера.

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