После расчета видим отрисовку и расчет по каждой фуре моментально.
После расчета видим отрисовку и расчет по каждой фуре моментально.

Представьте логиста, у которого перед глазами 400 разных коробок и 8 машин. У него есть Excel, калькулятор и два часа времени. Я решил, что это несправедливо, и написал веб-сервис на Django, который делает это мгновенно. Внутри: 3D MaxRects, полная свобода вращения (6 осей) и учет суровой реальности — от очередности выгрузки до предельной нагрузки на нижние ряды.

От алгоритма к продукту: как родилась Packing Platform

История проекта началась с разработки высокоскоростных оптимизационных движков. Были достигнуты показатели в 0.4 сек для задачи коммивояжера на 10 000 точек и менее 1 сек для упаковки сложных топографических фигур (трилистники, спирали).

Первая реализация логистического упаковщика существовала в виде Telegram-бота. Логика была проста: на вход подавался JSON с габаритами груза и транспорта, на выходе — упакованный массив координат. Однако фидбек от профильных продакт-менеджеров показал, что для реального ритейла уровня «Пятерочки» или «Магнита» голого API в мессенджере недостаточно. Продукту требовались:

  1. Доступный веб-интерфейс с формами ручного ввода.

  2. Нативная поддержка Excel (основной рабочий инструмент логиста).

  3. Интерактивная 3D-визуализация, которую можно покрутить в браузере.

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

Так появился Skewer Scrapper («Шампур») Packing Platform — сервис, где математика адаптивного 3D-пакинга обернута в понятную бизнес-логику.

  • Стек: Python/Django, PostgreSQL (в Docker), фронтенд на Three.js.

  • Концепция: "Packing Platform" — это не просто калькулятор, это инструмент для реального склада. Поэтому приоритет: Скорость (0.19с) и LIFO, а не теоретическая 100% плотность «мертвого» груза.

Для тех, кто предпочитает один раз увидеть: вот 3-минутное демо работы интерфейса и визуализации на Three.js

https://youtu.be/JP80ESX0YiQ

Техническая начинка: 3D MaxRects и «укрощенная жадность»

В основе лежит модифицированный алгоритм 3D MaxRects. Вместо перебора координат, движок оперирует списком свободных объемов (параллелепипедов) внутри транспорта.

Ключевые параметры «физичности» расчета:

  • 6 проекций (Full Rotation): В отличие от простых упаковщиков, здесь поддерживается вращение по всем осям. Если длинномер (например, 2400 мм) не проходит по длине, система пробует поставить его вертикально или на ребро, если позволяют габариты кузова.

  • Support Area (90%): Геометрия ограничена физикой. Коробка не может висеть в воздухе — она должна опираться на нижний слой минимум на 90% своей площади. Это исключает «математические» решения, которые невозможно реализовать на складе.

  • Скорость: Благодаря векторизации, расчет флота из 8 машин (Еврофуры, контейнеры, малотоннажники) для 400+ SKU занимает 0.19 – 0.3 секунды. Для сравнения: популярные рыночные решения тратят на аналогичный объем в сотни раз больше времени, часто игнорируя при этом LIFO.

Архитектура и Deployment

Сервис развернут в Docker-контейнерах и работает на стеке Django + PostgreSQL.

Для обеспечения отказоустойчивости используется связка Nginx + Gunicorn (3 воркера). Такой подход гарантирует, что даже при интенсивном «простукивании» сервиса несколькими пользователями одновременно, система сохранит отклик. Проброс через Nginx по поддомену (HTTPS, порт 443) позволяет обходить ограничения корпоративных служб безопасности, которые часто блокируют нестандартные порты.

Интерфейс Packing Platform: от JSON к блочной верстке

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

Структура рабочего пространства:

  • Справа — Панель Флота: Здесь отображаются доступные транспортные единицы (от малотоннажников до 40-футовых контейнеров). Пользователь видит габариты, грузоподъемность и количество доступных машин.

  • Слева — Панель Груза: Список SKU, которые необходимо распределить. Для каждой позиции указаны размеры, вес, количество и специфические параметры (LIFO, StackLimit).

Гибкость ввода данных:

Сервис поддерживает два сценария работы, что критично для разных этапов планирования:

  1. Ручной ввод (Формы): Удобен для оперативной корректировки или добавления единичных коробок прямо «на ходу».

  2. Пакетная загрузка (Excel): Основной режим для больших партий. Система парсит стандартные логистические таблицы, проводя мгновенную валидацию данных.

Умные фильтры и чекбоксы (Параметры оптимизации):

В нижней части интерфейса расположены инструменты тонкой настройки алгоритма:

  • Крен (Tilt/Orientation): Галочка, разрешающая или запрещающая вращение груза по осям. Если груз хрупкий и его нельзя переворачивать, алгоритм жестко зафиксирует его положение.

  • Оптимизация флота: Переключатель логики выбора машин. При активации движок сначала старается максимально плотно заполнить самые крупные фуры (Еврофуры, контейнеры), минимизируя общее количество рейсов. Если галочка снята — расчет идет последовательно по списку доступного транспорта.

Визуализация и результат

После нажатия кнопки «Расчитать», за доли секунды (0.19–0.3с) система выдает готовый план. Благодаря Three.js, результат — это не просто сухая таблица координат, а полноценная 3D-сцена.

  • Цветовое кодирование: Каждому типу SKU присваивается свой цвет (#hex), что позволяет мгновенно оценить структуру загрузки в кузове.

  • Интерактивность: Диспетчер может вращать модель фуры, заглядывать внутрь слоев и проверять, как соблюдены правила LIFO и площадь опоры (Support Area).

Такой подход превращает «черный ящик» алгоритма в прозрачный процесс. Логист видит не просто «ок, упаковано», а реальную схему, которую можно отдать грузчикам в виде PDF-отчета или выгрузить обратно в Excel с точными координатами X, Y, Z для каждой единицы товара.

Авторизация без лишних сущностей: почему Django Auth?

Одним из осознанных решений при разработке Packing Platform стал отказ от открытой регистрации. Система ориентирована на b2b-сегмент и конкретных логистов, поэтому создание аккаунтов происходит централизованно.

Выбор Django в качестве бэкенда позволил не «изобретать велосипед» в вопросах безопасности:

Стандартная джанговская авторизация, в случае попытки "пробросиьт" данные анонимным пользователем
Стандартная джанговская авторизация, в случае попытки "пробросиьт" данные анонимным пользователем
  • Готовая система авторизации: Вместо написания кастомных модулей логина и сессий, были использованы проверенные механизмы Django Auth. Это позволило сфокусироваться на главном — алгоритме упаковки.

  • Изоляция данных: Несмотря на общую базу данных в Docker-контейнере, архитектура гарантирует полную изоляцию. У каждого авторизованного пользователя — свой уникальный флот и свой список грузов. Диспетчер «Магнита» никогда не увидит настройки флота диспетчера «Пятерочки».

  • История расчетов: Благодаря Django ORM, каждый пользователь имеет доступ к своей истории. Можно в любой момент открыть старый расчет, посмотреть JSON на входе или снова покрутить 3D-модель в Three.js.

Развертывание: Docker, Nginx и Gunicorn

Чтобы сервис был по-настоящему автономным и готовым к нагрузкам, вся инфраструктура упакована в Docker.

  1. Gunicorn + 3 воркера: Сервис запускается не через стандартный runserver, а через полноценный WSGI-сервер. Наличие трех параллельных воркеров гарантирует, что даже если один пользователь запустит объемный расчет, интерфейс для остальных останется отзывчивым.

  2. Nginx как Reverse Proxy: Все запросы проходят через Nginx. Это позволило реализовать работу через поддомен по HTTPS (порт 443). Для корпоративных служб безопасности это стандарт: никаких «странных» портов, только чистый зашифрованный трафик.

  3. Ресурсы: На сервере с 8 Гб оперативной памяти такая связка работает с огромным запасом. Среднее потребление памяти при расчете 400+ SKU ничтожно мало благодаря эффективности векторного движка на Python.

После добавления сервиса Packing Platform потребление памяти выросло, как видно на изображении 29%. Раньше при одиноком телеграм боте, было в районе 6.
После добавления сервиса Packing Platform потребление памяти выросло, как видно на изображении 29%. Раньше при одиноком телеграм боте, было в районе 6.

Что в итоге?

Проект прошел путь от абстрактной математики и Telegram-бота до полноценного веб-сервиса, который понимает специфику реальных фур.

  • Скорость: 0.19 – 0.3 сек.

  • Физика: LIFO, 90% площадь опоры, 6 осей вращения.

  • Надежность: 98% тестового покрытия и Production-ready стек.

Skewer Scrapper — это пример того, как «укрощенный» жадный алгоритм в правильной обертке может конкурировать с тяжеловесными рыночными решениями, выигрывая у них в скорости и удобстве для конечного пользователя.

Вместо послесловия: От критики к решению

В одной из своих прошлых статей я подробно разбирал архитектурные и логистические огрехи в структурах крупных ритейлеров (в частности, «Магнита»). Но критика без предложения решения — это путь в никуда.

Packing Platform (Skewer Scrapper) — это мой ответ на вопрос «как это может работать по-человечески».

Я открыт к диалогу с техническими командами и департаментами логистики крупных сетей («Магнит», «Пятерочка» и др.). Если ваша текущая TMS «думает» слишком долго или игнорирует LIFO, я готов к пилоту:

  1. Тест на ваших данных: Присылайте свои спецификации грузов и флота — прогоним их через движок и сравним плотность/скорость.

  2. Доработка под специфику: Если вам критически важен учет нагрузки по осям или специфические температурные режимы — я готов обсудить внедрение этих параметров в алгоритм.

  3. Прямой доступ: Напишите мне, и я выдам доступ к платформе, чтобы вы могли сами потестировать интерфейс и скорость на «боевых» задачах.

Связаться со мной:

LinkedIn: https://www.linkedin.com/in/мазо-андрей-09040139/

Telegram: @AndreyMazo

Telegram-бот: @routeload_bot — здесь можно запустить демо-расчет с рандомными параметрами или отправить сообщение через команду /feedback. Я просматриваю входящие раз в день.

Связь через фидбэк бота .
Связь через фидбэк бота @routeload_bot.