Cмены курьеров и маршруты

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

Смены работы автомобиля или курьера

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

hard_window = true

max_duration_s = 6 часов (меньше окна смены)

flexible_start_time = true

Начать работу строго в 9 часов, желательно завершить работу до 15 часов, при необходимости можно работать до 18 часов, строго не позже (это сочетание параметров аналогично условию time_window = 9:00 - 15:00, hard_time_window = 9:00 - 18:00, flexible_start_time = false)

hard_window = true

max_duration_s = 6 часов (меньше окна смены)

flexible_start_time = false

Выбрать интервал работы желательно не больше 6 часов желательно между 9 и 18 часами

hard_window = false

max_duration_s = 6 часов (меньше окна смены)

flexible_start_time = true

Начать работу строго в 9 часов, желательно завершить работу до 15 часов, при необходимости можно работать до 18 часов, желательно не позже (это сочетание параметров аналогично условию time_window = 9:00 - 15:00, max_duration_s = 9 часов)

hard_window = false

max_duration_s = 6 часов (меньше окна смены)

flexible_start_time = false

Начать работу можно позднее 9 часов, желательно закончить работу до 18 часов, желательно работать не более 10 часов

hard_window = false

max_duration_s = 10 часов (больше окна смены)

flexible_start_time = true

Начать работу строго в 9  часов, желательно завершить работу до 18 часов, но желательно не позже 19 часов (это сочетание параметров аналогично условию time_window = 9:00 - 19:00, max_duration_s = 9 часов)

hard_window = false

max_duration_s = 10 часов (больше окна смены)

flexible_start_time = false

Такое сочетание параметров не позволит запланировать решение

hard_window = true

max_duration_s = 10 часов (больше окна смены)

flexible_start_time = true или flexible_start_time = false

Примечание

Обратите внимание, что для определения нескольких смен необходимо несколько полей в 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Открыть на карте

Перерыв перед последним рейсом

Перерыв задается с помощью объекта vehicle.extra_wait_before_last_run_s. Особенности использования:

  • Перерыв назначается перед последним рейсом в смене.

  • Начало последнего рейса сдвигается на указанное время перерыва.

Параметр

Значение

Пример

extra_wait_before_last_run_s

Продолжительность перерыва в секундах.

"extra_wait_before_last_run_s": 2700

Время перерыва — 45 минут (2700 секунд).

Пример

Для курьера запланировано два рейса. Задан один часовой перерыв и перерыв на 45 минут между рейсами (extra_wait_before_last_run_s = 2700).

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

  • в первом рейсе — 60 минут;
  • перед началом второго рейса — 45 минут. В результате второй рейс начнется на 45 минут позже.

Пример 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Открыть на карте

Максимальное время ожидания

В многодневных маршрутах курьеры часто приезжают к заказам или начальным складам заранее. Например, курьер приезжает к точке в 9:00, хотя временное окно заказа — с 10:00. Если не учитывать ограничения на ожидание, могут возникнуть:

  • простои;
  • перерасход ресурсов;
  • неоптимальные маршруты.

Чтобы этого избежать, вы можете задать:

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

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

Используйте параметры в поле vehicle:

Параметр

Описание

max_wait_at_location_hour

Максимальное время ожидания перед началом временного окна заказа, в часах

max_wait_at_starting_depot_hour

Максимальное время ожидания перед началом временного окна начального склада, в часах

penalty.wait_at_location.fixed

Штраф за факт превышения времени ожидания у заказа

penalty.wait_at_location.per_hour

Штраф за час ожидания у заказа сверх разрешенного времени

penalty.wait_at_starting_depot.fixed

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

penalty.wait_at_starting_depot.per_hour

Штраф за час ожидания у начального склада сверх разрешенного времени

Примечание

  • Если max_wait_at_starting_depot_hour не задан, но задан max_wait_at_location_hour, то для начального склада используется значение max_wait_at_location_hour.
  • Если penalty.wait_at_starting_depot не задан, но задан penalty.wait_at_location, то на начальном складе применяется штраф penalty.wait_at_location.

Параметр penalty.wait_at_starting_depot помогает алгоритму выбрать наиболее оптимальный вариант:

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

Алгоритм сравнивает штрафы за ожидание и за нарушение окна и выбирает вариант с меньшей стоимостью.

Пример настройки через API

...
"vehicles": [
  ...
  {
    ...
    "id": 1,
    "max_wait_at_location_hour": 0.1666,
    "max_wait_at_starting_depot_hour": 0.1666,
    "penalty": {
      "wait_at_location": {
        "fixed": 10,
        "per_hour": 120
      },
      "wait_at_starting_depot": {
        "fixed": 10,
        "per_hour": 120
      }
      ...
    },
    ...
  },
  ...

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

penalty.wait_at_location = penalty.wait_at_starting_depot.fixed + (wait_duration_h - max_wait_at_location_hour) * per_hour)

Если ожидание меньше или равно разрешенному времени — штраф равен 0.

Аналогично рассчитывается штраф для penalty.wait_at_starting_depot.

Пример 1

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

Временное окно заказа — 10:00-17:00. В результате планирования курьер приезжает в 10:54 и ждет 1 час 6 минут до начала временного окна заказа. Это невыгодно, так как простой автомобиля значительно увеличивает стоимость маршрута.

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

Пример 2

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

  • максимальное время ожидания перед началом временного окна заказа без штрафа — 10 минут (max_wait_at_location_hour = 0.1666);
  • штраф за факт превышения времени ожидания у заказа — 100 000 единиц (penalty.wait_at_location.fixed = 100 000).

В результате планирования курьер приезжает в 12:36 и не ждет начала временного окна заказа.

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

Пример 3

Курьер начинает маршрут в 8:00 с точки типа garage. Склад начинает работу в 9:00. Для склада задан штраф за ранний приезд — 1000 единиц (penalty.early = 1000).

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

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

Пример 4

Те же условия, что в примере 3, но для курьера заданы:

  • максимальное время ожидания перед началом временного окна начального склада — 10 минут (max_wait_at_starting_depot_hour = 0.1666);
  • штраф за факт превышения времени ожидания у начального склада — 2000 единиц (penalty.wait_at_starting_depot.fixed = 2000).

Алгоритм сравнивает два варианта:

  • приехать к начальному складу заранее и ждать;
  • приехать раньше и нарушить временное окно склада.

Поскольку штраф за нарушение окна склада меньше, алгоритм выбирает приезд в 8:26 — с нарушением временного окна склада, но без превышения времени ожидания.

Запрос 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Открыть на карте

Ограничения пробега и количества остановок в рейсе

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

Чтобы задать лимит по пробегу, на листе Vehicles в поле shifts.N.run_restrictions.max_mileage_km.value укажите максимальный пробег в километрах за рейс. При необходимости добавьте штрафы за превышение лимита в поля:

  • shifts.N.run_restrictions.max_mileage_km.penalty.fixed — штраф за факт превышения максимального пробега (по умолчанию 1 000);

  • shifts.N.run_restrictions.max_mileage_km.penalty.km — штраф за каждый километр превышения максимального пробега (по умолчанию 100).

Для ограничения количества остановок в рейсе на листе Vehicles укажите значения параметров:

  • shifts.N.run_restrictions.maximal_stops.value — максимальное количество остановок;

  • shifts.N.run_restrictions.minimal_stops.value — минимальное количество остановок.

За нарушение количества остановок предусмотрены штрафы. Если требуется, укажите их значения в полях:

  • shifts.N.run_restrictions.maximal_stops.penalty.fixed — штраф за факт нарушения максимального количества остановок (по умолчанию 1 000);

  • shifts.N.run_restrictions.maximal_stops.penalty.per_stop — штраф за каждую лишнюю остановку (по умолчанию 100);

  • shifts.N.run_restrictions.minimal_stops.penalty.fixed — штраф за факт нарушения минимального количества остановок (по умолчанию 1 000);

  • shifts.N.run_restrictions.minimal_stops.penalty.per_stop — штраф за каждую недостающую остановку (по умолчанию 100).

Пример 1

Курьер должен доставить 10 заказов. Ограничения по пробегу и количеству остановок в рейсе не заданы.

В результате все заказы доставляются одним рейсом.

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

Пример 2

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

  • shifts.0.run_restrictions.maximal_stops.value = 1
  • shifts.0.run_restrictions.maximal_stops.penalty.fixed = 1 000 000
  • shifts.0.run_restrictions.maximal_stops.penalty.per_stop = 1 000

Штрафы настолько велики, что нарушать ограничения по остановкам становится невыгодно. В результате курьер доставляет заказы двумя рейсами. Первым рейсом он отвозит заказ 8, вторым — все остальные заказы.

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

Пример 3

То же, что и в примере 2, но для рейсов первой смены убраны штрафы за нарушение максимального количества остановок shifts.0.run_restrictions.maximal_stops.penalty.fixed и shifts.0.run_restrictions.maximal_stops.penalty.per_stop. Для рейса задано ограничение shifts.0.run_restrictions.maximal_stops.value = 1.

Также в поле cost.run добавлена стоимость выполнения одного рейса, равная 3 000.

В результате все заказы доставляются одним рейсом. При заданных условиях нарушить ограничение и получить штраф оказалось выгоднее, чем разделить заказы на несколько рейсов. Размер штрафа при этом составит 1 100, где 1 000 — значение по умолчанию для shifts.0.run_restrictions.maximal_stops.penalty.fixed и 100 — для shifts.0.run_restrictions.maximal_stops.penalty.per_stop.

Пример 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.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 со значением false не повлияет на вручение заказа.

Если курьеру во время маршрута необходимо посетить склады для дозагрузки, укажите их в поле 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Открыть на карте

Фиксированная часть маршрута

Функциональность visited_locations пригодится, если:

  • начало маршрута должно проходить в строгом порядке.

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

Маршрут необходимо фиксировать для каждого курьера индивидуально.

Чтобы это сделать, укажите в vehicles массив visited_locations и опишите точки фиксированного маршрута с помощью следующих параметров.

Параметр

Описание

id*

Идентификатор заказа из locations или склада из depots. Обратите внимание, что идентификаторы заказов и складов не должны совпадать.

shift_id

Идентификатор смены курьера из vehicle.shifts. Определяет, в какой смене нужно обслужить эту точку.

time

Время отправления из точки. Если для первой точки фиксированной части маршрута:

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

Параметр можно указать на нескольких заказах — тогда время посещения рассчитается согласно указанному времени time.

wait_if_early

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

  • По умолчанию имеет значение true — то есть курьер будет ждать начала временного окна.
  • Если указано false, то курьер начнет обслуживание сразу после прибытия.

* Обязательный параметр

Пример 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Открыть на карте

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