Logistics_Analyzer расчет зон покрытия
Мне показалось что в последнем посте Logistics_Analyzer "Что если?" и новые функции программы мною не до конца был раскрыт вообще весь смысл анализатора "Что если?", а так же данные были очень корявые и не точные. Сегодня я постараюсь объяснить более детально, наглядно и заодно расскажу о новой функции.
Для начала начнем с данных. Я переработал все данные, создал более грубую но работоспособную модель тестовых значений для программы. Ушел от глобализации на всей карте, в сторону "Меньше объектов, один город, при этом более верные данные".
Новая карта объектов:
Сама карта — та же самая, что и была ранее, просто вместо 118 объектов теперь их всего 34, и собраны в одном городе.
Всем объектам была присвоена одинаковая товарная матрица и примерно одинаковые продажи, разница только в том, что один магазин, например, продавал «Сковороды» и у него этот сегмент А, другой продавал холодильники, которые так же попадают в А сегмент, но сковороды у него в С.
Зон доставок я сделал 5 вариантов, т. е. одинаковые зоны будут у 6 объектов, но это не критично, даже хорошо для проведения анализа.
Возьмем за пример объект с кодом ST_MSK_004 (магазин «Таганская»).
У него есть своя зона доставок, которая сложилась исторически.
Мемом выше можно понять, что зона не оптимизирована. Почему этот 004 магазин доставляет в зоны где тоже есть магазины? Загадка, а впрочем, и нет. Это же тест-данные. Я предположил, что, например, есть один объект, у которого каким-то странным образом падала основная часть доставок, и он отдавал сам курьерку. При этом магазин стал слишком мало приносить прибыли, и аренда взлетела, надо закрыть его.
Немного переработал интерфейс, дизайн, добавил новые функции и пока что заглушки для будущих умных расчетов.
Выбираем объект 004, ставим учитывать ABC-анализ и анализировать влияние на доставку клиентам и запускаем расчет.
Пока грузиться процесс, опишу что такое "Влияние на доставку".
У компании Х есть магазин, который они хотят закрыть, надо понять визуально, какое покрытие и кому отдать кусок от «пирога». Вот это как раз и делает программа. И в этом процессе закрылась основная проблема, с которой я долго боролся, на скрине выше, где показана зона, есть маленькие зеленые точки, это исторические данные, куда были произведены отправки. На их основе программа и строит полигональную сетку для визуализации. А как быть с пустыми местами? Вот она, основная проблема. Чуть позже вернемся к этому.
Как раз расчет завершен, предлагаю посмотреть труды.
Окно товарных запасов - визуально на табличном примере показываем фактический остаток товара в магазине
Ближайшие объекты - показывает то куда можно переместить товар, какое расстояние, емкость и доступность
План перераспределения — это уже предлагаемые распределения остатков с закрываемого объекта на ближайшие по следующей логике:
Проверяем товарную матрицу
Проводим АВС анализ (в будущем добавлю и XYZ)
Проверяем вместимость нового объекта
Если не подошло ни под одно действие, либо проверяем все найденные объекты в зоне, либо отправляем на склад, чуть-чуть логики с логов программы ниже:
Логи наверное скажут все за меня и гораздо больше)
Стоимость доставок - вообще должна считать по объему утилизации трака, сейчас как бы тоже (со скрипом) живой вариант, но есть уже накиданная логика, лежит под фичатоглом, надо проверять в будущем.
Влияние на регион - ничего интересного там нету, кейс без особенностей, программа говорит что все отлично
И вот она, та самая "Вишенка" на торте - влияние на доставку
Рассмотрим два типа карт: общая информация и данные о влиянии на время.
Информация о влиянии на время, как считает программа:
Смотрит 3 точки из текущей зоны доставки по закрываемому объекту:
Самая дальняя точка по километражу
Средняя точка
Ближняя точка
2. Считает время от объекта до каждой из этих точек и берет среднее арифметическое значениеКластеризует текущую зону на подзоны для новых объектов и делает аналогичное, как в пункте 1+2, добавляя среднее по всем объектам.
Нажимая на "Синюю" кнопку открывается окно в котором при нажатии на пуск - происходит визуализация перераспределения зоны с учетом объектов и введенных параметров (Учет объектов вне зоны км). Состоит данный процесс из 5ти этапов.
Показываем закрываемый объект
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%. То что "Ну очевидно можно сделать вот так" она делала "Тебе очевидно, а мне нет. Хочешь - делай сам".
Всем спасибо за прочтение. Пишите комментарии кто и что думает. Задавайте вопросы - отвечу)

























ИТ-проекты пикабушников
602 поста3.4K подписчик
Правила сообщества
0. Запрещены посты вне тематики сообщества
1. Уважайте труд людей, пишите только конструктивную критику,
2. Не выкладывайте информацию по своему проекту чаще 2ух раз в месяц