5

Logistics_Analyzer расчет зон покрытия

Серия Разработка логистической программы

Мне показалось что в последнем посте Logistics_Analyzer "Что если?" и новые функции программы мною не до конца был раскрыт вообще весь смысл анализатора "Что если?", а так же данные были очень корявые и не точные. Сегодня я постараюсь объяснить более детально, наглядно и заодно расскажу о новой функции.

Для начала начнем с данных. Я переработал все данные, создал более грубую но работоспособную модель тестовых значений для программы. Ушел от глобализации на всей карте, в сторону "Меньше объектов, один город, при этом более верные данные".

Новая карта объектов:

Текущая заливка данных, один город и 34 объекта

Текущая заливка данных, один город и 34 объекта

Сама карта — та же самая, что и была ранее, просто вместо 118 объектов теперь их всего 34, и собраны в одном городе.

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

Зон доставок я сделал 5 вариантов, т. е. одинаковые зоны будут у 6 объектов, но это не критично, даже хорошо для проведения анализа.

Основной объект который будет разобран в сегодняшнем обзоре

Основной объект который будет разобран в сегодняшнем обзоре

Возьмем за пример объект с кодом ST_MSK_004 (магазин «Таганская»).

У него есть своя зона доставок, которая сложилась исторически.

Историческая зона доставок

Историческая зона доставок

Примерно так видит зону доставок логист

Примерно так видит зону доставок логист

Мемом выше можно понять, что зона не оптимизирована. Почему этот 004 магазин доставляет в зоны где тоже есть магазины? Загадка, а впрочем, и нет. Это же тест-данные. Я предположил, что, например, есть один объект, у которого каким-то странным образом падала основная часть доставок, и он отдавал сам курьерку. При этом магазин стал слишком мало приносить прибыли, и аренда взлетела, надо закрыть его.

Переработанное окно анализа "Что если"

Переработанное окно анализа "Что если"

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

Выбираем объект 004, ставим учитывать ABC-анализ и анализировать влияние на доставку клиентам и запускаем расчет.

Самое долгое - это влияние на зонирование

Самое долгое - это влияние на зонирование

Пока грузиться процесс, опишу что такое "Влияние на доставку".

У компании Х есть магазин, который они хотят закрыть, надо понять визуально, какое покрытие и кому отдать кусок от «пирога». Вот это как раз и делает программа. И в этом процессе закрылась основная проблема, с которой я долго боролся, на скрине выше, где показана зона, есть маленькие зеленые точки, это исторические данные, куда были произведены отправки. На их основе программа и строит полигональную сетку для визуализации. А как быть с пустыми местами? Вот она, основная проблема. Чуть позже вернемся к этому.

Как раз расчет завершен, предлагаю посмотреть труды.

Окно товарных запасов

Окно товарных запасов

Окно товарных запасов - визуально на табличном примере показываем фактический остаток товара в магазине

Ближайшие объекты

Ближайшие объекты

Ближайшие объекты - показывает то куда можно переместить товар, какое расстояние, емкость и доступность

План перераспределения

План перераспределения

План перераспределения — это уже предлагаемые распределения остатков с закрываемого объекта на ближайшие по следующей логике:

  1. Проверяем товарную матрицу

  2. Проводим АВС анализ (в будущем добавлю и XYZ)

  3. Проверяем вместимость нового объекта

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

Логи наверное скажут все за меня и гораздо больше)

Стоимость доставок

Стоимость доставок

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

Влияние на регион - ничего интересного там нету, кейс без особенностей, программа говорит что все отлично


И вот она, та самая "Вишенка" на торте - влияние на доставку

Рассмотрим два типа карт: общая информация и данные о влиянии на время.

Информация о влиянии на время, как считает программа:

  1. Смотрит 3 точки из текущей зоны доставки по закрываемому объекту:

    1. Самая дальняя точка по километражу

    2. Средняя точка

    3. Ближняя точка
      2. Считает время от объекта до каждой из этих точек и берет среднее арифметическое значение

      Кластеризует текущую зону на подзоны для новых объектов и делает аналогичное, как в пункте 1+2, добавляя среднее по всем объектам.

Визуализация перераспределения зон доставки

Визуализация перераспределения зон доставки

Нажимая на "Синюю" кнопку открывается окно в котором при нажатии на пуск - происходит визуализация перераспределения зоны с учетом объектов и введенных параметров (Учет объектов вне зоны км). Состоит данный процесс из 5ти этапов.

  1. Показываем закрываемый объект

2. Показываем все объекты которые находятся внутри текущей зоны и внешние согласно параметра.

3. Показываем фактическую зону доставок

4. Делим зоны на кластеры. И вот тут самое интересное.

Минимальное приближение

Минимальное приближение

Среднее приближение

Среднее приближение

Как сказать программе: «Смотри, есть вот такая зона, в ней есть 10, 15 или 20 объектов, подели рисунок на пропорциональные части с учетом оптимальной логистики?» А ведь внутри родительского кластера есть пустые зоны, в которых исторически не было доставок, а мы все равно должны их учесть и распределить.

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

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

Мы находим в начале объекты и рядом с объектами начинаем раскидывать точки с определенной плотностью.

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

На примере одного из кластера. Есть магазин на Павелецкой, есть зона которая перейдет к нему.

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

Красным написано "Маг" т.е. "Магазин" что бы более наглядно было

Красным написано "Маг" т.е. "Магазин" что бы более наглядно было

Внешние магазины рядом с контуром

Внешние магазины рядом с контуром

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

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


На моменте первой визуализации я думал: «Это успех», и лучше уже ничего не добавлять. Но потом пришла мысль, маленькая мысль, которая не давала покоя: «А что, если кому-то этого мало, а если надо показать визуально маршруты, точки из расчета?». Имея готовый скрипт JS и логику, мне просто потребовалось скопировать, вставить и дополнить первоначальный код.

Процесс анимирования занимает гораздо больше времени. Программе надо отправить API запрос, получить ответ, так для каждого объекта по 3 раза.

2025-12-15 16:08:02,800 - INFO - STDOUT - 🌍 Построение маршрута через OSRM (карта: yandex)

2025-12-15 16:08:02,800 - INFO - STDOUT - 🌐 OSRM API: попытка 1/2

2025-12-15 16:08:02,801 - DEBUG - urllib3.connectionpool - Starting new HTTP connection (1): 127.0.0.1:53913

2025-12-15 16:08:03,674 - DEBUG - urllib3.connectionpool - http://127.0.0.1:53913 "GET http://router.project-osrm.org/route/v1/driving/37.6215,55.7... HTTP/1.1" 200 682

2025-12-15 16:08:03,675 - INFO - STDOUT - ✅ Маршрут через OSRM: 0.9 км, 2 мин

2025-12-15 16:08:03,675 - INFO - STDOUT - ✅ Зона 21 добавлена: 1 маршрутов, 10 точек полигона

2025-12-15 16:08:03,675 - INFO - STDOUT - 🔍 Обработка зоны 22: facility=True, polygon=9, points=0

2025-12-15 16:08:03,675 - INFO - STDOUT - ⚠️ Зона 22: нет точек доставки, добавляем без маршрутов

2025-12-15 16:08:03,675 - INFO - STDOUT - ✅ Зона 22 добавлена: 0 маршрутов, 9 точек полигона

2025-12-15 16:08:03,675 - INFO - STDOUT - 🔍 Обработка зоны 23: facility=True, polygon=13, points=0

2025-12-15 16:08:03,675 - INFO - STDOUT - ⚠️ Зона 23: нет точек доставки, добавляем без маршрутов

2025-12-15 16:08:03,675 - INFO - STDOUT - ✅ Зона 23 добавлена: 0 маршрутов, 13 точек полигона

2025-12-15 16:08:03,675 - INFO - STDOUT - 🔍 Обработка зоны 24: facility=True, polygon=10, points=5

Лог работы построения маршрута.

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

Итог:

Мы получаем кластер с тремя ключевыми точками и путями до них, включая полное описание маршрутов.

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


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

На мой взгляд, это успех. Конечно, есть некоторые недочеты, но они едва заметны и будут быстро исправлены. Логика работы выстроена, отчет динамичен. Теперь остается только проверить все на практике и собрать для него ОС от пользователей.

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


В интерфейсе произошли некоторые изменения. Например, я перешел от скучной бежевой темы к более темным цветам. Часть стилей выделил в QSS и настроил их подключение в Main_window. Меню дашбордов стало напоминать Power BI с Excel, и были внесены другие мелкие правки.

Работаю над проектом по вечерам, уделяя этому 2-3 часа. Основные алгоритмы визуализации были написаны давно, но я долго не мог понять, в чем проблема. То данные распределялись неверно, то пробелы не учитывались. В начале реализации функции был у меня дата-файл, где зоны были более реалистичными, чем сейчас. При перераспределении их покрытие составляло всего 30%. То что "Ну очевидно можно сделать вот так" она делала "Тебе очевидно, а мне нет. Хочешь - делай сам".


Всем спасибо за прочтение. Пишите комментарии кто и что думает. Задавайте вопросы - отвечу)

Правила сообщества

0. Запрещены посты вне тематики сообщества

1. Уважайте труд людей, пишите только конструктивную критику,

2. Не выкладывайте информацию по своему проекту чаще 2ух раз в месяц

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества