Справжньою проблемою була не логістика. Нею був процес ухвалення рішень.

Кожен ранок починався однаково.

Сотні нових заявок надходили в GLPI. Багато з них вимагали фізичного виїзду — забрати обладнання, доставити заміну пристроїв, відвезти документи або виконати обслуговування на місці.

У середньому компанія отримувала по 250–350 заявок щодня.

Звісно, не кожна заявка вимагала виїзду, але логістичних тікетів вистачало, щоб повністю зайняти диспетчера на 2–3 години щоранку.

Його робота здавалася простою лише на перший погляд:

  • переглянути вхідні заявки;
  • визначити локації;
  • дізнатися про доступність водіїв;
  • оцінити навантаження;
  • призначити тікети.

Насправді це була безперервна задача оптимізації, яку доводилося вирішувати вручну.

Зі зростанням обсягу заявок процес ставав усе складнішим.

Іноді водії обслуговували клієнтів на одній вулиці, тоді як інший район міста залишався без уваги аж до другої половини дня.

Деякі маршрути були невиправдано довгими.

Частина запитів чекала просто тому, що ніхто не міг одночасно оцінити сотні локацій.

І річ не в тому, що диспетчер ухвалював погані рішення.

Просто людина фізично не здатна швидко прорахувати сотні точок у голові з урахуванням десятків умов. Для цього потрібні алгоритми.

Купівля іншої логістичної платформи не була виходом

Багато компаній вирішили б це впровадженням спеціалізованого софту для логістики.

Я обрав інший підхід.

У компанії вже була система, яка містила все необхідне для планування:

  • адреси клієнтів;
  • пріоритети заявок;
  • заплановані дати;
  • сервісну інформацію;
  • призначені відділи.

Це була GLPI.

Замість того, щоб міняти звичний процес, я розширив його.

Результатом став кастомний плагін, який перетворює вхідні заявки на задачу оптимізації та автоматично призначає водіїв.

Архітектура системи

Сам процес логіки роботи виглядає максимально просто:

Заявки GLPI
    │
    ▼
Вилучення логістичних запитів
    │
    ▼
Нормалізація адрес та геокодування
    │
    ▼
Двигун оптимізації маршрутів (OR-Tools)
    │
    ▼
Призначення водіїв
    │
    ▼
Оновлені завдання в GLPI

Жодного окремого логістичного порталу.

Жодного дублювання баз даних.

Диспетчер просто натискає одну кнопку.

Локаційні дані — це складніше, ніж здається

Адреси, введені людьми, рідко бувають ідеальними.

Різняться скорочення, трапляються описки, бракує номерів будинків чи формати запису не збігаються.

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

Щоб зробити це надійним і водночас знизити витрати на API, я впровадив гібридний підхід до геокодування.

Система спочатку перевіряє локальний кеш SQLite. Якщо адреса вже оброблялася раніше, координати повертаються миттєво.

В іншому випадку:

  • Google Geocoding API використовується як основний провайдер;
  • Photon (OpenStreetMap) слугує автоматичним фолбеком;
  • лімітер частоти запитів захищає публічні сервіси від надмірного навантаження.

Після кількох місяців роботи на продакшені більшість запитів тепер розв'язується безпосередньо з кешу, що зменшує як час виконання, так і витрати на API.

Результати розрахунку оптимізації маршрутів

Результати розрахунку та візуалізація оптимальних маршрутів для водіїв у Києві

Оптимізація маршрутів замість їх вгадування

Коли кожна точка має координати, проблема стає суто математичною.

Google OR-Tools моделює її як задачу маршрутизації транспорту (VRP). Проте мета полягає не просто в пошуку найкоротшого шляху — реальна логістика сповнена жорстких обмежень.

Оптимізатор повинен враховувати:

  • Робочий час водіїв: наприклад, суворе планування змін із 9:30 до 17:30.
  • Обідня перерва водія: обов'язкове вікно відпочинку, яке алгоритм автоматично вбудовує в оптимальний момент маршруту.
  • Депо компанії: усі поїздки плануються як циклічні — початок і завершення маршруту відбуваються в єдиній точці (депо).
  • Часові вікна та пріоритети: урахування критичності (ургентності) заявок та бажаного часу візиту для клієнта.
  • Час на візит: фіксований час перебування водія на точці залежно від типу завдання.

Час у дорозі розраховується за допомогою власного інстансу OpenRouteService (ORS) на базі даних OpenStreetMap. Це дозволяє приймати рішення на основі реальної дорожньої мережі, а не відстаней по прямій.

Однією з найкорисніших функцій OR-Tools є Disjunctions & Penalties (диз'юнкції та штрафи).

У реальному житті бувають дні, коли наявні водії фізично не в змозі виконати кожен запит.

Замість того, щоб генерувати нездійсненний графік або видавати помилку, оптимізатор автоматично відкладає найменш важливі завдання (із нарахуванням штрафних балів у моделі), водночас створюючи валідний план для всіх інших.

Для глобальної оптимізації та уникнення локальних мінімумів застосовується метаевристика Tabu Search (пошук із заборонами) разом зі стратегією першого рішення PARALLEL_CHEAPEST_INSERTION.

Окрім цього, математична модель підтримує легке масштабування: за умови мінімальних доопрацювань алгоритм дозволяє враховувати місткість та вантажопідйомність автомобілів (Capacity Constraints) для доставки габаритних вантажів.

З кількох годин до двох хвилин

Після завершення оптимізації водії призначаються автоматично всередині GLPI. Диспетчер перевіряє готовий результат замість того, щоб збирати його вручну.

Після більш ніж шести місяців роботи на продакшені покращення стали значними:

Параметр До автоматизації Після автоматизації
Щоденне планування 2–3 години ~2 хвилини
Призначення заявок Вручну Автоматично
Пропущені запити Періодично (людський фактор) Повністю виключено
Якість маршрутів На основі суб'єктивного досвіду Алгоритмічно оптимізовано
Витрати пального Вищі (через перетини та пробіг) Знижені
Стабільність планування Залежала від диспетчера Стабільна та передбачувана

Логістична команда тепер витрачає свій час на вирішення нестандартних ситуацій замість рутинного планування.

Найважливіший урок

Цей проект ніколи не був про Google OR-Tools. Він не був про OpenStreetMap. І точно не про написання чергового плагіна для GLPI.

Справжня цінність полягала у виявленні повторюваного бізнес-рішення та перенесенні його в код. Щоранку одна людина вручну вирішувала ту саму задачу оптимізації. Алгоритм просто став краще виконувати цю роботу.

Автоматизація є найбільш цінною тоді, коли вона усуває повторювані рішення, а не повторювані кліки.

Корисні посилання

  • Вступ до Google OR-Tools — офіційна документація Google щодо інструментів оптимізації та вирішення задач VRP.