Привет, Хабр! Я Нина Горохова, руководитель гиперлокальной логистики в СДЭК.
Вместе с моим Java‑разработчиком Алексеем Паршиковым мы расскажем о том, как работали с метрикой своевременности на последней миле и научились успевать доставлять в часовой интервал.
Дисклеймер
Мы рассказываем о конкретном участке работ на «последней миле», когда ваша посылка уже в городе и курьер везет её к вам домой. Однако на общий срок доставки, особенно если посылка едет из другого города или страны, влияет множество факторов, которые мы не всегда можем контролировать (нелётная погода, изменение закона в конкретных странах на транзит груза в Россию и т. д.).
Сегодня мы поговорим только о последней миле, или о том, как помочь курьеру успеть привезти заказ в тот день и час, который выбрал получатель, когда посылка уже в городе получения.
Исходная точка
Внутригородская доставка осуществлялась в течение всего дня (с 9 до 21 часа). Курьеру выдавали сразу весь объём посылок для доставки в этот день, и когда он проезжал мимо нужного адреса (читай — когда курьеру удобно), он доставлял посылку.
Или не доставлял. В конце концов, если вы не можете ждать курьера весь день дома, то это уже «не его проблема: он один, а адресов много!» (нет, мы так не считаем, однако на практике сценарий повторялся постоянно, что естественно никому не нравилось, и нам тоже).
А ещё другая проблема: если курьеру уже с утра выдали груз, а ваша посылка прибыла на склад только в обед, то доставка переносилась на следующий день. Склады находятся за городом; можно, конечно, в середине дня возвращать курьеров за новой порцией посылок, но это приводит к удорожанию доставки.
Что нужно сделать
Доставлять в то время, которое удобно получателю. И чтобы можно было выбрать это время сразу в тот же день, когда посылку привезут (потому что обычно люди лучше знают свои планы «на сегодня», чем, например, на следующую неделю). Но чтобы и выбранное время можно было поменять. И чтобы привезли всё вовремя.
А еще важно, чтобы этот продукт был бесплатен и для получателей, и для отправителей. Ведь это не дополнительная услуга, а требование рынка — конкуренты уже научились доставлять посылки в заданные интервалы, и крупные клиенты все чаще задавали вопросы об этом.
Ресурсы
Маршрутизации, которая бы строила маршрут для курьера — нет (на тот момент). Увеличить штат курьеров — тоже нет. Ресурсов на разработку — почти нет. Нужно дешёвое и быстрое решение, но чтобы сработало и своевременность попадания даже в короткий интервал (например, часовой) была не ниже 92% (спойлер — у нас получилось).
Гиперлокальная логистика
В первую очередь мы стали решать проблему сокращения времени доставки на последней миле.
Как, не увеличивая штат курьеров и затраты на пробеги, сделать возможным возврат курьеров за посылками на склад? Разместить склады поближе!
У СДЭКа большая сеть ПВЗ во всех крупных городах. Мы организовали развоз посылок из складов до пунктов выдачи — по утрам, до начала рабочего дня курьеров. Вокруг ПВЗ определяли зону доставки — 2–3 км и привозили утром те посылки, которые нужно доставить в этой зоне. Грузы, что поступали на склад в обед, мы также развозили по ПВЗ с помощью газелей.
И теперь курьеры смогли возвращаться за посылками несколько раз в день и быть более гибкими при изменении интервалов доставки (об этом ниже).
Поначалу, конечно, дополнительное плечо логистики увеличивало срок доставки. Но через 1,5 месяца подкручивания всех процессов нам удалось вернуться к изначальным срокам и даже немного их улучшить.
Теперь настала очередь проработать задачу «как привезти посылку получателю в нужный ему час, не увеличив штат курьеров, и чтобы остальные доставки не страдали». Мы решили не придумывать здесь сложных ходов и в момент, когда посылка оказывалась у курьера, отправляли получателю SMS с ссылкой, перейдя по которой он мог выбрать время доставки.
Но встал вопрос: «А если все получатели выберут один и тот же интервал?» Например, 20 получателей захотели, чтобы посылку привезли с 13 до 14 часов, курьер ведь не разорвётся. Напомню, умной маршрутизации, которая сама бы строила маршрут курьеру, у нас на тот момент не было, проблему надо было решить быстро и дёшево.
Для начала нужно было определить почасовую загруженность курьера. Для этого взяли все недоставленные заказы курьера на момент расчёта. Для каждого задания определили величину интервала, в котором оно должно быть доставлено:
Если согласованного интервала доставки нет, то считаем, что это весь рабочий день курьера. Для примера возьмём с 9 часов до 21. И тогда интервал равен 12 часам.
Далее для каждого задания определяем удельную почасовую нагрузку и сохраняем её значение для каждого часа из интервала. Удельная нагрузка определяется по формуле:
И в конце суммируем эти удельные почасовые нагрузки в течение рабочего дня курьера для всех заданий. Значения округляем в большую сторону, потому что лучше доставить меньше посылок, чем нарушить данное обещание. Получившиеся числа можем сравнить с коэффициентом нагрузки. Если суммарная нагрузка на час больше или равна установленному коэффициенту, то считаем, что курьер в этот час загружен и доставить больше заказов не успеет.
Для клиента это выглядит примерно так:
Если нагрузка меньше, то час считается свободным и можно добавить ещё заказов.
Для примера рассмотрим курьера, у которого есть 10 недоставленных посылок. Три из них без установленного интервала доставки (весь день), 4 задания с интервалом 4 часа, 2 задания с интервалом 2 часа и одно задание с часовым интервалом. Коэффициент нагрузки, после которого час считается загруженным примем за 3.
Из таблицы видно, что у курьера три и больше заданий в 13 и 14 часов (интервалы с 13 до 14 и с 14 до 15 часов). Получается, что эти часы заняты, все остальные — свободны.
Таким образом, мы предлагаем получателю выбрать разные варианты интервалов, но уже перегруженные интервалы недоступны для выбора — мы стараемся выполнять свои обещания, поэтому даём выбрать заведомо возможные промежутки для доставки.
Чего-то не хватает
На бумаге всё выглядит здорово, а что на практике? А на практике сначала всё получилось вовсе не так радужно. Принятые нами коэффициенты в каких‑то районах города срабатывали отлично, но в большинстве — курьеры либо не успевали доставлять выданный объём вовремя, либо, наоборот, имели избыток свободного (между доставками) времени. В итоге своевременность попадания в интервалы упала до 68%. Кошмар.
Тогда мы не подумали об очевидном: город не является идеально равномерным полигоном, где формулы работают с одинаковой эффективностью на всех участках.
Пообщавшись с курьерами и бригадирами, а также посмотрев на статистику производительности курьеров в разных районах города, мы нашли неучтённый фактор.
Коэффициент плотности застройки
Есть центр, с его офисными зданиями, где по одному адресу может быть сразу много доставок — курьер зашёл внутрь и по этажам и офисам быстро вручил посылки получателям.
А есть окраины города с низкоэтажной застройкой, большими развязками, где нужно много времени, чтобы добраться до дома напротив.
Мы разделили город на три условных зоны: с высоким, средним и низким коэффициентом плотности. Например, для Москвы в районе с высоким коэффициентом плотности мы приняли количество доставок в час (которые курьер успеет доставить без опозданий) = 6. А в районах с низкой плотностью доставки курьер успеет доставить не более 3–4 посылок в час. Этот коэффициент мы и применили к формуле выше.
Что в итоге
В итоге этот коэффициент оказался тем самым недостающим звеном для эффективной работы формулы. Спустя неделю тестирования мы достигли показателя в 93% попаданий в интервалы доставки. В течение полугода работы по этой схеме значения колебались от 92 до 95% в среднем за месяц, даже с учётом повышения нагрузок в праздничные дни или роста заказов ввиду сезонности.
Сейчас начинаем выстраивать этот же процесс в Петербурге, опытным путем подбирая свои коэффициенты плотности застройки для разных районов города. И далее по плану: Новосибирск, Екатеринбург, Краснодар, Омск и Самара.
Главное, чему мы научились за время работы над проектом: эффективно — не обязательно сложно или дорого. Нужно только попробовать взглянуть на проблему с другого ракурса — и всё получится :)
А как вы действовали, когда нужно было решить что‑то быстро и с минимальными ресурсами?