Примеры настроек по бизнес-кейсам

Планирование загрузки собственных курьеров

В каких ситуациях использовать

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

  • чтобы были задействованы все курьеры;
  • чтобы все они работали примерно поровну.

Алгоритм в этом случае должен строить маршрут так, чтобы все ресурсы использовались равномерно. Цели минимизировать количество ресурсов нет.

Как реализовать сценарий

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

  1. Уменьшите стоимость за факт использования cost.fixed. Алгоритм стремится уменьшить общую стоимость решения (подробнее в разделе Что оптимизируется) и если cost.fixed будет указана, то он будет минимизировать в том числе количество курьеров. Поэтому для сценария, когда все курьеры должны быть задействованы, нужно эту стоимость ставить 0 или минимальной. Выбор значения зависит от вместимости транспорта:

    • Если используется транспорт одинаковой вместимости, то cost.fixed = 0.

    • Если используется транспорт разной вместимости, то cost.fixed должна быть минимальной, но пропорциональной вместимости (см. пример в разделе Вместимость автомобиля или курьера). В этом случае cost.fixed обязательно должна быть отличной от 0 — иначе возможны ситуации с несоответствием загрузки для разных транспортных средств (например, автомобиль вместимостью 0,8 т будет загружен на 700 кг, в то время как автомобиль вместимостью 1,5 тонны — на 100 кг).

  2. Иногда использования cost.fixed = 0 недостаточно. Тогда необходимо применить ограничение по минимальному количеству остановок minimal_stops (подробнее в разделе Ограничение количества остановок в смене). Нужно присвоить minimal_stops значение 1 и назначить большие штрафы penalty.stop_lack.fixed (за факт остановок меньше минимального количества) и penalty.stop_lack.per_stop (за каждую остановку меньше минимального количества).

  3. Для равномерного распределения заказов по автомобилям или курьерам нужно использовать настройки балансировки (подробнее в разделе Опция равномерной загрузки).

Внимание

Стоимость за факт использования имеет значение по умолчанию cost.fixed = 3000. Поэтому для указания нулевой стоимости необходимо явно ставить 0, а не оставлять пустое значение.

Пример 1

В этом примере рассматривается работа алгоритма без использования настроек для равномерной загрузки.

В задаче 28 заказов и 5 курьеров. В результате планирования используются только 4 курьера.

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

Пример 2

Решаем ту же задачу, что и в примере 1, но с использованием параметра cost.fixed = 0. Итог — все 5 курьеров работают.

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

Пример 3

В задаче 28 заказов и 10 курьеров. Используем minimal_stops = 1 и штрафы. Итог — алгоритм распределяет заказы по всем 10 курьерам.

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

Одновременное планирование курьеров на автомобиле и общественном транспорте

Как реализовать сценарий

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

  • Стоимость пробега курьеров на общественном транспорте

    Для курьеров на общественном транспорте пробег в сервисе считается только для той части маршрута, которую курьер пройдет пешком.

    Настройте стоимость за километр пробега cost.km для курьеров на общественном транспорте больше, чем для курьеров на автомобилях. Это необходимо, чтобы маршрут, в котором придется много ходить пешком (например, если точки находятся далеко от остановок общественного транспорта), стоил бы для алгоритма дороже маршрута, где точки доставки находятся рядом с остановками. Алгоритм будет стремиться уменьшить стоимость решения, а значит будет склонен строить маршруты с короткими пешеходными участками.

  • Разделение по заказам

    Курьеры на автомобилях должны выполнять более дальние заказы, а курьеры на общественном транспорте — заказы в центре города.

    Строго разделить заказы можно только с использованием тегов (подробнее в разделе Теги автомобиля), но косвенно достичь это можно через различную стоимость часа работы cost.hour (стоимость за километр пробега использовать не получится, так как пробег для курьеров на общественном транспорте считается только в пешеходной части). Значит, для курьеров на общественном транспорте стоимость cost.hour должна быть больше, чтобы алгоритм строил для них короткие маршруты.

Пример

В задаче 4 курьера: 2 курьера на общественном транспорте, 2 на автомобилях — и 40 заказов. Для курьеров на общественном транспорте cost.km = 30, cost.hour = 300. Для курьеров на автомобилях cost.km = 8, cost.hour = 100.

Итог — работают 3 курьера из 4, из них 2 на автомобилях и только 1 на общественном транспорте. Общее время движения для курьера на общественном транспорте 3 часа 12 минут. Для курьеров на автомобилях — 5 часов 53 минуты и 7 часов 5 минут.

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

Одновременное планирование заказов текущего и следующего дня

В каких ситуациях использовать

Иногда период отгрузки занимает более дня. Например, при следующих условиях:

  1. Планирование выполняется днем.
  2. Отгрузка выполняется вечером или ночью этого же дня и утром следующего.

Как реализовать сценарий

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

В интерфейсе дату планирования задайте при запуске задачи, а в запросе API — в поле options.date.

Важно корректно расставить сдвиг не только для окон заказов, но и для окон смен курьеров и окон склада. Пример заказа с вечерним окном 21:00–23:00:

  • утреннее окно для следующего дня задано как 1.07:00–1.09:00;

  • у машин, которые доставляют вечером и ночью, задана смена 20:00–1.04:00;

  • у машин, которые доставляют утром, задана смена 1.05:00–1.18:00;

  • для склада задано окно, которое будет охватывать весь период доставки, 20:00–1.20:00 (возврат машины на склад должен также попадать в окно работы склада).

Пример

В примере есть заказы, которые нужно доставить текущим вечером и в течение следующего дня. Один курьер работает в ночную смену, второй — в утреннюю и дневную. Окно работы склада задано с расчетом на весь период доставки. В результате заказы текущего дня доставляет первый курьер, следующего — второй.

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

Планирование заказов, которые можно перенести / Планирование части заказов

В каких ситуациях использовать

Используйте сценарий в ситуациях, когда по результатам планирования некоторые заказы могут попасть в нераспределенные, например:

  • Заказов изначально больше

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

  • Определен возможный период доставки

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

Как реализовать сценарий

Поменяйте у заказов штраф за недоставку в параметре penalty.drop. По умолчанию он равен 1 000 000. Такое большое значение используется, поскольку в обычной ситуации при планировании предполагается, что все заказы должны быть доставлены.

На что еще следует обратить внимание:

  • Задайте штраф penalty.drop с учетом количества заказов на одной точке.

    В структуре данных штраф penalty.drop задается на заказ (location), а не на точку. Если в одну точку будут несколько заказов, то штраф за недоставки заказов именно до этой точки будет в несколько раз выше, чем для остальных точек. Это может приводить к ситуации, когда точки с несколькими заказами будут обязательно включаться в маршруты, даже если будут неоптимальными по пробегу. Когда мультизаказов мало, эффект может быть незаметен, но если они встречаются часто, то проставляйте для мультизаказов penalty.drop как штраф для одной точки, разделенный на количество заказов в ней. Например, если penalty.drop для всех заказов равен 10 000, то penalty.drop для точки с четырьмя заказами проставьте 10 000 / 4 = 2500.

  • Разделите заказы по приоритетам.

    Если есть логика в том, какие заказы лучше доставить сегодня, а какие перенести, то реализуйте ее через разные значения штрафа penalty.drop для более приоритетных и менее приоритетных заказов. Более приоритетному заказу надо задать большее значение penalty.drop. Если сделать штраф penalty.drop одинаковым, то при прочих равных останутся недоставленными дальние заказы, которые находятся в стороне от остальных. Чтобы дальние заказы не попали в нераспределенные, используйте параметр max_drop_penalty_percentage (подробнее см. Допустимая доля нераспределенных заказов).

  • Настройте стоимость.

    Не используйте в этом сценарии значение penalty.drop по умолчанию, поскольку алгоритму при построении маршрутов очень важно соотношение стоимостей и штрафов. Например, если стоимость за км равна 10, за час равна 100, а penalty.drop = 1000, то заказ, до которого ехать 2 часа и 81 км окажется в нераспределенных. Это случится, поскольку стоимость его доставки 2 * 100 + 10 * 81 больше штрафа за нераспределенный заказ, который равен 1000.

Пример 1

Пример с небольшим значением penalty.drop у всех заказов. Часть заказов находится близко, часть — далеко. В результате дальние заказы оказываются нераспределенными.

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

Пример 2

Пример с заказами корпоративных клиентов, которые нельзя переносить, и заказами физических лиц, которые можно перенести на завтра.

У заказов корпоративных клиентов penalty.drop = 1 000 000, а у физических лиц penalty.drop небольшой. В результате алгоритм планирует все заказы корпоративных клиентов, даже если они находятся далеко, и часть заказов для физических лиц.

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

Пример 3

  1. В примере несколько заказов и один дальний мультизаказ. Для них указан одинаковый penalty.drop. В результате алгоритм спланирует дальний мультизаказ, несмотря на то, что на карте это будет выглядеть неоптимально.

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

  2. В примере несколько заказов и один дальний мультизаказ. Для них указан разный penalty.drop. В результате алгоритм спланирует ближние заказы и не распределит дальний мультизаказ.

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

Планирование с равномерным нарушением смены у водителей

В каких ситуациях использовать

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

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

Как реализовать сценарий

Чтобы нарушать смену водителей более равномерно, поменяйте значение по умолчанию у штрафов за нарушение временного окна смены (подробнее в разделе Смены работы автомобиля или курьера).

Поменяйте штрафы:

  1. Задайте значение shifts.penalty.out_of_time.fixed как небольшое или нулевое.
  2. Задайте значение shifts.penalty.out_of_time.minute значительно больше (можно исходить из стоимости за км), например в 3–10 раз больше стоимости за км.

Еще один способ реализовать равномерное нарушение смены у водителей — задать жесткое окно вокруг мягкого окна.

Пример 1

Пример, где несколько водителей и несколько десятков заказов. У водителей гибкая смена, и значения штрафов заданы по умолчанию, а у заказов указаны жесткие окна. Окно смены — с 10 до 17, окна заказов — с 10 до 21. Сервисное время заказов и их расположение такое, что нельзя выполнить их все без нарушения смен водителей. В результате получается, что у одного водителя смена сильно нарушена, а у остальных смена не нарушается.

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

Пример 2

Тот же пример, но с равномерным нарушением смены. Здесь выставлены значения штрафов за нарушение окна смены shifts.penalty.out_of_time.fixed = 0, shifts.penalty.out_of_time.minute = 800.

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

Пример 3

Тот же пример, но теперь окна заказов с 10 до 17 и мягкие. Нарушение смены также стало равномерным, потому что для алгоритма теперь играет роль ограничение по окнам заказов: те водители, которые будут работать после 17, уже будут нарушать не только смену, но и окна заказов.

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

Пример 4

То же, что и в примере 1, но теперь кроме основного временного окна time_window у курьеров задано внешнее жесткое окно hard_time_window. Оно ограничивает допустимое время нарушения основного окна с 09:45 до 19:00. В результате все заказы будут выполнены в пределах установленных ограничений.

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

Транспорт с разной грузоподъемностью

Как реализовать сценарий

Большой грузовик с фурой в эксплуатации дороже, чем маленький курьерский автомобиль. Поэтому стоит указывать стоимость за факт использования (cost.fixed) в зависимости от грузоподъемности (weight_kg): чем больше тоннаж, тем выше стоимость. Обычно это линейная зависимость вида: cost.fixed = X + weight_kg * Y.

Стоимость за километр, за час, за тонно-километр (cost.km, cost.hour, cost.tonne_km) в большинстве случаев рекомендуется оставить одинаковой для машин с разным тоннажем.

Для расчета cost.fixed мы будем использовать значения коэффициентов X = 2000 и Y = 0,5. Для таких коэффициентов ответы будут следующими:

  • Что дешевле: отправить 2 машины с грузоподъемностью 1500 кг или 1 машину с 3000 кг?

    • 2 легкие машины: 2 × (2000 + 1500 × 0,5) = 5500.
    • 1 тяжелая: 2000 + 3000 × 0,5 = 3500.
    • 5500 > 3500, значит, отправить 1 тяжелую машину дешевле.
  • Что дешевле: отправить 4 машины с грузоподъемностью 3000 кг или 3 машины с 5000 кг?

    • 4 легкие машины: 4 × (2000 + 3000 × 0,5) = 14000.
    • 3 тяжелые машины: 3 × (2000 + 5000 × 0,5) = 13500.
    • 14000 > 13500, значит, отправить 3 тяжелые машины дешевле.

Внимание

В вашем случае коэффициенты могут отличаться.

В этом бизнес-кейсе часто бывает необходимо ограничивать минимальный вес заказов, доставляемых в одну точку, для крупнотоннажных машин. Также для таких машин можно ограничивать максимальное количество остановок на маршруте.

В некоторых ситуациях, чтобы управлять распределением заказов, используйте параметр weighted_drop_penalty — он устанавливает штрафы за невыполнение заказов пропорциональными весу/объему заказов. Подробнее см. Пропорциональный штраф за невыполнение заказа.

Пример 1

В планировании участвуют 3 автомобиля с грузоподъемностью 1,5 т, 3 т и 5 т. Стоимость за факт использования одинаковая. Все заказы могут выполнить по меньшей мере два курьера за одну смену. В результате загружаются самые грузоподъемные автомобили: 5 т и 3 т.

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

Пример 2

Тот же пример, но стоимость за факт использования рассчитываем по формуле. Получаем значения 2750, 3500, 4500. В результате алгоритм планирует наиболее выгодную комбинацию автомобилей: 5 т и 1,5 т.

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

Опытные курьеры и курьеры-новички

В каких ситуациях использовать

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

Как реализовать сценарий

Есть два способа реализации этого сценария:

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

Корректировка времени обслуживания учитывает время на парковку и время на передачу заказа.

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

Приоритетные курьеры

В каких ситуациях использовать

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

  1. Одних курьеров нужно загрузить максимально, а других — по остаточному принципу. Например, когда часть курьеров работает на постоянной основе, остальные — временные работники.
  2. Надо загрузить всех курьеров, но одним дать больше заказов, а других меньше. Например, в пиковые дни текущий штат не справляется и выходят дополнительные курьеры, но их нагрузку нужно минимизировать. Или в ситуациях, когда оплата труда у курьеров сдельная, то курьерам со стажем, которых важно сохранить в компании, нужно дать более нагруженные или более удобные маршруты.

Как реализовать сценарий

В первой ситуации стоит указать меньшее значение cost.fixed у более приоритетных курьеров — тогда при прочих равных они будут предпочтительнее (подробнее в разделе об одновременном использовании собственного и наемного транспорта).

Во второй ситуации используйте функциональность ограничения количества остановок в смене — приоритетным курьерам стоит указать большее значение maximal_stops.

Пример 1

40 заказов и 4 курьера, из которых 2 приоритетных и 2 дополнительных. Указаны разные cost.fixed: 2500 для приоритетных курьеров, 3500 для дополнительных. В результате все заказы делятся между приоритетными курьерами.

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

Пример 2

Данные, как в примере 1, но указано maximal_stops, равное 15 для приоритетных курьеров и 10 — для дополнительных. Также добавлены штрафы за лишние остановки, обязательные при использовании параметра maximal_stops. В результате приоритетные курьеры получают по 15 заказов, а один дополнительный курьер — 10 заказов.

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

Запрет приезда на точку раньше

Как реализовать сценарий

В ситуациях, когда нельзя спланировать маршруты без плановых нарушений окон заказов, стоит использовать мягкие временные окна. При этом алгоритм может запланировать прибытие как раньше, так и позже временного окна. Чтобы разрешить опоздания, но запретить опережения, воспользуйтесь разными штрафами на заказах:

  • Используйте большие значения для штрафов, которые регулируют раннее прибытие — penalty.early.fixed и penalty.early.minute.

  • Укажите 0 для штрафа за факт опоздания — penalty.late.fixed.

  • Для штрафа за каждую минуту опоздания — penalty.late.minute — укажите значение, сопоставимое со стоимостью использования автомобиля за час или километр (например, если 1 км стоит 10, то рекомендуется значение штрафа в диапазоне 20-100).

Также можно задать жесткое окно вокруг мягкого с помощью параметра hard_time_window. Чтобы запретить опережения и разрешить опоздания, левая граница жесткого окна должна совпадать с мягким, а правая  — превышать мягкое.

Пример 1

Окна заказов мягкие и непродолжительные, штрафы за опережение и опоздание равные. Курьер не успевает везде вовремя.

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

Пример 2

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

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

Пример 3

То же, что и в примере 1, но заданы жесткие окна вокруг мягких окон у заказов. В результате среднее время ожидания увеличится, а время движения и время маршрута уменьшатся.

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

Собственный и наемный транспорт одновременно

В каких ситуациях использовать

Для ситуации с одновременным использованием собственного и наемного транспорта характерны следующие требования:

  1. Собственный транспорт использовать в приоритетном порядке и максимально эффективно, а наемный транспорт использовать минимально.
  2. Собственный транспорт должен возвращаться на склад, а наемный — не должен.

Как реализовать сценарий

Для приоритетного использования собственного транспорта воспользуйтесь рекомендациями из раздела Планирование загрузки собственных курьеров.

  • Для собственных машин стоит снизить стоимость за факт использования в cost.fixed (подробнее в разделе Транспорт с разной грузоподъемностью).

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

  • Если снижение cost.fixed не помогает, то необходимо применить ограничение по минимальному количеству остановок.

    Указать для собственных машин minimal_stops = 1 и большие штрафы за нарушение (penalty.stop_lack.fixed и penalty.stop_lack.per_stop).

  • Если свои машины должны вернуться на склад в конце смены, а наемные не должны, то рекомендуется снизить стоимость за час и/или за км для своих машин (cost.km и cost.hour). Значения этих параметров для своего транспорта должны составлять примерно 10-80% от значений для наемного транспорта.

Пример 1

3 заказа весом 1,5 т и 3 своих и наемных машины грузоподъемностью 1,5 т, 3 т и 5 т. Каждый заказ занимает одно место, и в каждой машине доступно одно место. Стоимость за факт использования ниже для своих машин и увеличивается с тоннажем. Стоимость за 1 км ниже для своих. В результате собственная машина грузоподъемностью 5 т останется в гараже, а наемный автомобиль грузоподъемностью 1,5 т выйдет на рейс, так как он обойдется дешевле.

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

Пример 2

Тот же пример, но добавлено условие minimal_stops = 1 для собственных машин и штрафы за нарушение минимального количества остановок. В результате все собственные машины выйдут на рейс и все наемные останутся в гараже.

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

Минимизация времени ожидания у курьеров

В каких ситуациях использовать

Когда в планировании находится много заказов с узкими временными окнами, в маршрутах могут появляться ожидания у курьера. Ожидание — ситуация, когда курьер приехал на точку раньше временного окна и вынужден ждать его начала.

  • В случае мягких временных окон (hard_window = false) при появлении ожиданий у алгоритма есть выбор, который будет зависеть от стоимости часа курьера (cost.hour) и штрафов за нарушение временного окна заказа:

    • Нарушить временное окно: начать обслуживание раньше начала временного окна.

    • Создать простой курьера: ждать начала временного окна.

  • В случае жестких временных окон (hard_window = true) выбора нет, курьер будет ждать начала окна.

Для примера рассмотрим ситуацию, когда курьер приехал на 10 минут раньше начала временного окна заказа. При этом известны такие характеристики:

  • стоимость часа работы cost.hour = 300;

  • фиксированный штраф за нарушение окна penalty.out_of_time.fixed (или penalty.early.fixed ) = 100;

  • штраф за минуту нарушения окна penalty.out_of_time.minute (или penalty.early.minute) = 20.

Алгоритм выберет ожидание, потому что стоимость дополнительного простоя курьера 300 * 10 / 60 = 50 меньше, чем стоимость нарушения временного окна на 10 минут 100 + 10*20 = 300.

Примечание

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

Как реализовать сценарий

Добиться снижения времени ожидания у курьеров можно двумя способами (отдельно или комбинируя между собой):

  • Повысить стоимость часа курьера.

  • Настроить гибкие временные окна и снизить штрафы за нарушение временного окна.

Обратите внимание, что многие характеристики маршрутов зависят друг от друга и улучшение одного показателя часто достигается за счет других. Взаимозависимыми характеристиками являются:

  • количество и общее время нарушений окон;

  • общее время ожидания;

  • общий пробег;

  • кучность маршрутов.

Пример 1

Много заказов с узкими временными окнами, стоимость работы часа курьера cost.hour = 100 . В итоге суммарное время ожидания — 4 часа 27 минут.

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

Пример 2

Повысим стоимость часа курьера до 300. Время ожидания заметно уменьшилось и составило 1 час 2 минуты. При этом увеличился общий пробег.

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

Пример 3

Стоимость работы часа курьера вернем к базовому значению cost.hour = 100. Уменьшим штрафы за нарушение временного окна. Теперь location.penalty.early.fixed = 0 и location.penalty.late.fixed = 0, location.penalty.early.minute = 10 и location.penalty.late.minute = 10. В маршруте появилось 2 нарушения временных окон, но зато время ожидания курьеров — всего 8 минут.

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

Минимизация количества курьеров

В каких ситуациях использовать

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

Внимание

Для алгоритма важны соотношения используемых стоимостей и штрафов. Поэтому добиться уменьшения количества курьеров можно, если оставить cost.fixed неизменным, но снизить значения для всех остальных стоимостей и штрафов.

Как реализовать сценарий

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

  • времени работы (10 курьеров работали по 8 часов; чтобы оставить 9 — все должны работать 8,5).

  • нарушений окон заказов (10 курьеров смогут выполнить все заказы без опозданий; если оставить 9 — то для 10 клиентов придется опоздать на полчаса).

  • кучности маршрутов.

Настройки, использование которых может завысить количество курьеров в решении:

  • proximity_factor и global_proximity_factor, если слишком сильно поднимать их значения (больше 1).

  • balanced_groups, если слишком сильно поднять штрафы за балансировку. В этом случае алгоритм будет стремиться строить равномерные маршруты, даже если для этого придется использовать больше курьеров.

  • minimal_stops, если использовать ее без учета опции ignore_min_stops_for_unused.

Пример 1

В этом примере 150 заказов с временными окнами по 5 часов. Как настроены параметры:

  • Окон:

    • окна заказов мягкие (hard_window = false);

    • окна смены у курьеров мягкие (shifts.0.hard_window = false).

  • Штрафов:

    • штраф за факт нарушения окна отсутствует (locations.penalty.out_of_time.fixed = 0);

    • штраф за минуту нарушения штраф равен 30 (location.penalty.out_of_time.minute = 30);

    • штрафа за факт нарушения окна нет (vehicles.shifts.penalty.out_of_time.fixed = 0);

    • штраф за минуту нарушения равен 100 (vehicles.shifts.penalty.out_of_time.minute = 100).

  • Кучности:

    • Маршруты должны быть кучными, поэтому используем proximity_factor = 1.
  • Стоимости:

    • стоимость километра пробега cost.km = 16;

    • фиксированная стоимость использования автомобиля cost.fixed = 3000 (значение по умолчанию).

Алгоритм распределил заказы таким образом, что получилось 7 хорошо сгруппированных маршрутов. Нарушений временных окон нет.

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

Пример 2

То же, что и в примере 1, но другая стоимость использования автомобиля. Теперь cost.fixed = 5000.

В результате количество курьеров стало меньше: теперь их 6, но появилось 2 нарушения временных окон. Увеличились общий пробег и время движения.

Примечание

Подобное перераспределение заказов между меньшим количеством курьеров возможно, если не мешают другие ограничения:

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

Пример 3

То же, что и в примере 1, но еще сильнее поднимем фиксированную стоимость использования автомобиля. В этом примере cost.fixed = 30000.

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

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

Приоритетные заказы

Как реализовать сценарий

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

  1. Выполнить приоритетный заказ в заданное временное окно, без опозданий

    Установите у приоритетного заказа жесткое временное окно. Иногда нужно дополнительно применять параметры штраф за обслуживание вне временного окна и минимизация риска опозданий.

  2. Выполнить приоритетный заказ в любом случае, остальные заказы — по возможности

    Подробнее в разделе Планирование заказов, которые можно перенести / Планирование части заказов.

Кроме того, для заказов можно задать порядок выполнения в рамках определенного маршрута с помощью параметра sequence_order. Последовательность заказов устанавливается в сквозном порядке для всех рейсов автомобиля. В рамках всего планирования для разных маршрутов возможна ситуация, когда заказ с бо́льшим значением параметра sequence_order в одном маршруте будет доставлен раньше, чем заказ с меньшим значением параметра в другом маршруте. Заказы с одинаковым значением sequence_order выполняются в произвольной последовательности. Если порядок выполнения не указан, заказы могут размещаться в любом порядке и любом месте маршрута.

Пример 1

Маршрут строится для одного автомобиля, выполняющего 7 заказов. Окна заказов частично совпадают. У четырех заказов — повышенный приоритет, для них установлено жесткое временное окно. В результате планирования для заказов с жестким временным окном маршруты спланированы без нарушений, а у двух заказов с мягким окном есть опоздания.

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

Пример 2

Маршрут строится для двух автомобилей, которые должны выполнить 7 заказов. Среди них есть два заказа на раннее время в удаленные точки, для которых установлен порядок выполнения при помощи параметра sequence_order (заказы 1 и 4). Эти заказы нужно доставить в первую очередь, хотя по дороге можно выполнить попутные заказы для оптимизации маршрута.

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

Кучные маршруты

В каких ситуациях использовать

Требование к формированию кучных маршрутов обычно обусловлено следующим:

  • Большая вероятность переноса времени получения заказа у клиента.
  • Большая погрешность при определении планового сервисного времени.
  • Удобство работы для курьеров в знакомых районах и при доставке постоянным клиентам.

Как реализовать сценарий

Вариант 1

Используйте опции:

  • proximity_factor — для получения маршрутов, более устойчивых к переносам временных окон.

  • global_proximity_factor — для получения более географически локализованных маршрутов.

  • use_in_proximity — для исключения некоторых заказов и складов при построении кучных маршрутов.

В некоторых случаях можно отдельно повысить стоимость за километр cost.km.

Для отдельных курьеров можно планировать маршруты, географически сгруппированные вокруг «точки притяжения» (см. раздел Кучность маршрута).

Вариант 2

Используйте формулу для расчета стоимости vehicles.cost с параметрами max_edge_duration_h и max_edge_distance_m. Эти параметры позволяют задать четкие ограничения по близости соседних последовательных точек на маршруте.

Параметры proximity_factor и global_proximity_factor влияют на среднюю длину отдельных отрезков между заказами, а параметры max_edge_distance_m и max_edge_duration_h ограничивают максимальную длину или максимальное время прохождения каждого из последовательных отрезков между заказами.

Пример 1

Параметр cost.km = 8 (значение по умолчанию), а значения proximity_factor и global_proximity_factor нулевые.

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

Пример 2

То же, что и в примере 1, но повысили значения proximity_factor и global_proximity_factor до 0,5. Маршруты стали более сгруппированы, расстояние между всеми точками уменьшилось.

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

Пример 3

То же, что и в примере 1, но значение proximity_factor = 0.5, а global_proximity_factor = 0. Маршруты менее сгруппированы территориально, но расстояние между соседними последовательными точками уменьшилось.

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

Пример 4

То же, что и в примере 1, но используются расширенные настройки стоимости для рейса vehicles.cost.run:

  • 3000 за выезд на маршрут;
  • 8 за каждый километр пути;
  • 1000 штраф, если максимальная длина отрезков между заказами max_edge_distance_m больше 3 км.

Формула расчета:

vehicles.cost.run = 3000 + distance_km * 8 + (max_edge_distance_m > 3000) * 1000

В результате планирования расстояние между соседними последовательными точками на маршруте уменьшилось.

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

Снижение количества опозданий

Как реализовать сценарий

Если используются мягкие временные окна, то алгоритм может спланировать маршрут с нарушениями этих окон. Снижение количества нарушений окон достигается за счет изменений группы штрафов penalty.out_of_time или отдельно групп штрафов penalty.late и penalty.early (также см. сценарий Запрет приезда на точку раньше — в ряде случаев необходимо выставлять эти штрафы различными).

Рекомендованный сценарий изменения настроек:

  • Штраф за факт нарушения — поставить 0 или небольшое значение.

  • Штраф за минуту нарушения — поставить значение больше дефолтного. Чем больше значение — тем меньше будет возникать нарушений окон.

Еще один вариант снижения количества нарушений окон — задать жесткое окно вокруг мягкого с помощью параметра hard_time_window.

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

Пример 1

11 курьеров обслуживают 149 заказов, окна доставки — мягкие. Штрафы выставлены по умолчанию: 1000 за факт нарушения окна и 17 за каждую минуту. Получилось 6 опозданий, суммарно более чем на 5 часов. Есть 4 больших опоздания, длительность каждого — более часа.

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

Пример 2

То же, что и в примере 1, но теперь нет штрафа за факт нарушения окна, а штраф за каждую минуту увеличен до 100. В результате стало больше нарушений окон (19 опозданий), но общее время нарушений сократилось до 2 часов. В этом примере удалось избавиться от долгих опозданий — теперь большинство опозданий меньше 10 минут.

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

Пример 3

То же, что и в примере 1, но теперь у заказов задано жесткое окно вокруг мягкого — hard_time_window. Левая граница жесткого окна совпадает с мягким окном, а правая увеличена на 1 час относительно мягкого. В результате среднее время опоздания и ожидания сократилось, а пробег увеличился.

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

Планирование маршрутов по зонам

В каких ситуациях использовать

При планировании может потребоваться распределять маршруты так, чтобы конкретные автомобили или курьеры работали только на определенных территориях, либо чтобы определенные территории не пересекались между собой в одном маршруте. Для этого используются геозоны.

Преимущества использования геозон:

  • разметить геозоны проще, так как для этого используется визуализация на карте;
  • геозоны могут пересекаться.

При этом следует учитывать, что геозоны — это жесткое ограничение, которое алгоритм не может нарушить.

Рекомендуем:

  1. Не применять слишком мелкое дробление на зоны. На практике лучше всего работают укрупненные зоны, в которые могут ездить сразу несколько курьеров. Так алгоритм сможет сглаживать возможные неравномерности по заказам в тот или иной день. Вместе с зонами можно использовать функциональность Кучные маршруты.
  2. Не оставлять между зонами области доставки, в которые теоретически может попасть заказ.

Помимо жестких ограничений по геозонам для раcпределения заказов можно использовать:

Внимание

Если вы используете несовместимость заказов, совместимость заказов и автомобилей или опциональные теги, то выполните первоначальную разметку соответствия заказа определенной зоне вне сервиса. При использовании зарезервированных тегов это делать необязательно.

Как реализовать сценарий

Геозоны можно использовать и при планировании через интерфейс Маршрутизации, и при работе через API, подробнее см. в разделе Геозоны.

Зоны, в которые курьер или автомобиль может доставлять заказы, задаются параметром vehicles.allowed_zones. Зоны, запрещенные для данного автомобиля или курьера, задаются параметром vehicle.forbidden_zones.

Пример 1

Санкт-Петербург разделен на 7 геозон. Для каждого автомобиля задана зона доставки в поле allowed_zones. Принадлежность заказов к геозонам определяется автоматически по координатам. В результате каждый курьер обслуживает заказы только в одной зоне и не заезжает в соседние.

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

Пример 2

В примере описаны 2 курьера: штатный и наемный, заданы 2 геозоны: «север» и «юг». Штатный курьер должен выполнять заказы только в северной части Подмосковья.

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

Примечание

Чтобы воспроизвести описанные в Excel примеры, добавьте используемые геозоны в справочник геозон.

Пример 3

Санкт-Петербург разделен на 7 зон, каждой зоне соответствует 1 тип (load_type). Для каждого заказа указан 1 тип и расписана несовместимость типов друг с другом. В результате каждый курьер обслуживает заказы только в одной зоне и не заезжает в соседние.

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

Пример 4

Заказы за пределами МКАД помечены тегом «Пригород». Такой же тег указан в свойствах наемного курьера. В результате собственный (штатный) курьер будет выполнять заказы только внутри МКАД.

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

Пример 5

В задаче планирования 30 заказов, расположенных в разных зонах Москвы: внутри ТТК, между ТТК и МКАД, вне МКАД. Для их выполнения выделено три автомобиля:

  1. Автомобиль может обслужить заказы внутри ТТК и внутри МКАД, vehicle.tags = inside_ttk, inside_mkad.
  2. Может обслужить заказы только от ТТК до МКАД, vehicle.tags = inside_mkad.
  3. Может работать только за МКАД, без тегов.

В результате планирования:

  • Курьер с доступом внутрь ТТК развозит 15 заказов внутри ТТК и между МКАД и ТТК.

  • Курьер с тегом inside_mkad развозит 10 заказов между МКАД и ТТК.

  • Курьер без тегов развозит 5 заказов за МКАД.

Теги на заказах алгоритм автоматически распределил так — 16 заказов с inside_mkad и 9 с inside_ttk.

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

Приоритетные районы для курьеров

Как реализовать сценарий

Для настройки приоритетных районов для курьеров рекомендуем использовать опциональные теги или геозоны.

Планирование заказов на несколько дней

В каких ситуациях использовать

В некоторых задачах планирование выходит за рамки одного дня. Например, когда заказ ожидают в любой из ближайших дней, но в строго определенное время.

Как реализовать сценарий

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

  • Для заказов: укажите несколько окон, по 1 окну на каждый день доставки, например 08:00 – 16:00 и 1.08:00 – 1.16:00 соответственно. Подробнее см. в разделе Относительный формат временных окон.

  • Для курьеров: аналогично укажите несколько смен, например 07:00 – 18:00 для первого дня, 1.07:00 – 1.18:00 для второго дня и т. д.

  • Для склада: укажите одно большое окно, которое будет охватывать весь период доставки, например 08:00 – 2.22:00.

Пример

В ближайшие три дня с 08:00 до 16:00 нужно доставить много заказов. Для этого указано по три временных окна для каждого заказа, три смены для курьеров (по одной на каждый день) и общее время работы склада с первого по третий день.

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

Многодневные маршруты

Как реализовать сценарий

Для планирования многодневного маршрута нужно указать:

Пример

В задаче планирования 8 заказов, которые нужно доставить за 3 дня. Для этого указано по три временных окна для каждого заказа, три смены для курьеров и общее время работы склада с первого по третий день. Задан шаблон перерывов на отдых. После смены один из двух курьеров возвращается на склад.

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

Транспортное средство с несколькими отсеками

Внимание

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

Также предполагается, что отсеки заданы изначально (не поддерживается сценарий с динамическим перемещением перегородки, чтобы менять размер отсеков).

В каких ситуациях использовать

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

Как реализовать сценарий

Описать такое транспортное средство в задаче планирования можно через:

Обе опции необходимо применять одновременно.

Пример

В планировании использован автомобиль с кузовом, разделенным на 2 отсека:

  • холодный отсек для продуктов, требующих низкой температуры;

  • стандартный отсек для продуктов, не требующих особых условий перевозки.

Для каждого отсека с помощью парных параметров задана вместимость:

Параметры

Что задают

capacity.custom.0.name capacity.custom.0.size

Вместимость по весу для холодного отсека, кг

capacity.custom.1.name capacity.custom.1.size

Вместимость по объему для холодного отсека, м3

capacity.custom.2.name capacity.custom.2.size

Вместимость по весу для стандартного отсека, кг

capacity.custom.3.name capacity.custom.3.size

Вместимость по объему для стандартного отсека, м3

Заказ № 1 должен размещаться только в холодном отсеке, заказ № 2 — только в стандартном, а заказ № 3 надо разделить на две части по разным отсекам. Заказы описаны при помощи пользовательских параметров вместимости:

Параметры

Что задают

shipment_size.custom.0.name shipment_size.custom.0.size

Вес груза для холодного отсека, кг

shipment_size.custom.1.name shipment_size.custom.1.size

Объем груза для холодного отсека, м3

shipment_size.custom.2.name shipment_size.custom.2.size

Вес груза для стандартного отсека, кг

shipment_size.custom.3.name shipment_size.custom.3.size

Объем груза для стандартного отсека, м3

В решении все заказы распределились по нужным отсекам, полностью загрузив их.

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

Настройка времени выезда со склада

В каких ситуациях использовать

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

Как реализовать сценарий

Если параметр depot.flexible_start_time (гибкое время старта) принимает значение false, то время выезда определяется графиком работы и количеством смен курьера. Например, склад работает с 7 до 22 часов, а курьер с 8 до 20 часов. Время загрузки на складе — 30 минут. Тогда курьер выедет со склада в 8:30. Это самое позднее возможное начало окна (из окон склада и смены) с учетом времени загрузки на складе. Если у курьера 2 смены: с 8 до 20 часов и с 10 до 22 часов, тогда курьер выедет со склада либо в 8:30, либо в 10:30. В данном случае время выезда будет выбрано алгоритмом из двух возможных вариантов с учетом времени загрузки на складе.

На время выезда со склада влияют следующие настройки:

При определении времени выезда со склада суммируется все сервисное время, которое задано для склада, заказов и курьера.

Если depot.flexible_start_time=false и задано время готовности заказа на складе, то на время выезда дополнительно влияет опция options.load_when_ready (погрузка по мере готовности).

Если depot.flexible_start_time=true, то время выезда определяет алгоритм. При этом окно загрузки задает границы, когда может происходить отгрузка со склада. Нужно учитывать, что на время выезда влияют внешние факторы (такие как пробки на дорогах), географическое расположение и временные окна заказов, а также настройки планирования:

Если нужно сдвинуть время выезда со склада к началу временного окна, используйте функциональность Доставка как можно раньше.

Схема

Пример 1

Два курьера доставляют 30 заказов. Время работы склада и курьеров с 8 до 20. Все заказы необходимо доставить с 11 до 19. Курьеры приезжают на склад к 8 и загружают заказы. Время погрузки заказов складывается из сервисного времени на складе depot.service_duration_s, времени на погрузку каждого заказа location.depot_duration_s и времени погрузки заказов в автомобиль vehicle.depot_extra_service_duration_s. Так как параметр flexible_start_time=false, у каждого курьера возникает дополнительное ожидание.

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

Пример 2

То же, что и в примере 1, но параметр flexible_start_time=true. Время выезда рассчитывает алгоритм и подбирает его так, чтобы исключить лишнее ожидание. Дополнительно заданы параметры:

  • penalize_late_service=true — штраф за обслуживание вне временного окна;

  • minimize_lateness_risk=true — учет вероятности опоздания;

  • penalty.arrival_after_start:

    • average_h = 2000 — штраф за приезд после начала временного окна;
    • as_soon_as_possible = true — возможность начинать маршрут как можно раньше.

Время старта теперь стало позже, и в маршрутах нет длительных ожиданий.

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

Тарификация по зонам

В каких ситуациях использовать

Сценарий используется, если стоимость доставки заказа рассчитывается в зависимости от геозоны.

Как реализовать сценарий

Задайте стоимость автомобиля или курьера через формулу расчета с использованием расширенных настроек стоимости. Для определения геозоны заказа используйте функцию in_zone.

В данном сценарии есть ряд ограничений:

  • опция ignore_zones должна быть выключена;
  • публичные геозоны могут использоваться только при планировании через API;
  • геозоны для курьеров необходимо указывать не только в формуле расчета, но и в одном или нескольких параметрах: allowed_zones, forbidden_zones или incompatible_zones.

Пример

В примере 4 курьера должны развезти 18 заказов, у 4 заказов указан опциональный тег vip. Зона доставки разделена на 4 геозоны: North-West, South-West, North-East и South-East.

Используется следующая схема тарификации:

  • Базовая стоимость маршрута: 5 единиц за 1 километр.

  • Стоимость доставки по зонам (независимо от количества заказов):

    • South-West: 150 единиц;
    • North-West: 100 единиц;
    • South-East: 100 единиц;
    • North-East: 50 единиц.
  • Заказы с опциональным тегом vip оплачиваются дополнительно: 70 единиц к базовой стоимости.

Такому тарифу соответствует следующая формула:

5 * distance_km + 150 * has_location(is_delivery() & in_zone('South-West')) +
100 * has_location(is_delivery() & in_zone('South-East') | in_zone('North-West')) +
50 * has_location(is_delivery() & in_zone('North-East')) + 70 * order_count(has_tag('vip'))

В результате планирования получаем оптимизированный маршрут, в котором каждый курьер посещает только одну зону. Стоимость маршрута составит:

  • для курьера 1: 5*49,506 + 100 + 70*1 = 417,53 единиц;
  • для курьера 2: 5*39,03 + 50 + 70*1 = 315,15 единиц;
  • для курьера 3: 5*39,405 + 150 = 347,025 единиц;
  • для курьера 4: 5*34,047 + 100 + 70*2 = 410,235 единиц.

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

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