Od praktyk do solvera CVRP — i firmy pochłoniętej wdrażaniem ERPa

Przez piętnaście lat trzymałem się jednego pytania: jak rozesłać pojazdy tak, żeby koszt był najniższy, a ładowność nie pękła. Zaczęło się na praktykach. Skończyło — na razie — na algorytmie, który działał, i na firmie, która nie miała już na niego miejsca, bo wdrażała duży system zarządczy.

Łukasz Biedak · LuBi-Software ~7 min czytania
CVRP praca inżynierska VRPFinal ERP
Centrum operacji systemu planowania tras: pojazdy w ruchu, zlecenia na dziś, aktywne trasy VRP i alerty
Panel, do którego ten wątek zmierzał: flota, zlecenia, trasy, alerty.

1. Praktyki: dowieźć, nie zaprezentować

Na studiach chciałem się wykazać. Nie „zrobić praktyki”, tylko zostawić po sobie coś, z czego ktoś na hali albo w magazynie realnie skorzysta. Trafiłem do dużej sieci handlowej. Nazwy nie podaję — nie o brand tu chodzi.

Z bliska widać było to, czego nie ma w ćwiczeniach z grafów: popyt, który skacze z dnia na dzień, samochody, które nie są nieskończone, okna czasowe sklepów i dyspozytora, który dogaduje trasy szybciej, niż ktokolwiek zdąży otworzyć „oficjalny” system.

Nie wyniosłem stamtąd certyfikatu. Wyniosłem pytanie, które nie chciało zejść z głowy: kto jedzie gdzie, z czym i w jakiej kolejności, żeby flota jeździła oszczędzając kilometry i czas pracy kierowców.

2. Praca inżynierska: problem wielu komiwojażerów

W grudniu 2011 na Politechnice Gdańskiej złożyłem projekt inżynierski Problem wielu komiwojażerów. Matematyka, informatyka, transport — jedno zadanie. Jeden komiwojażer to TSP. Kilku, z magazynem i ładownością, to już mTSP i VRP: nie jedna pętla, tylko paczka rozłącznych cykli, które razem pokrywają wszystkie punkty.

Kod do pracy napisałem w Matlabie i utajniłem. We wstępie jest zdanie, którego nie żałuję: nie uważałem algorytmu za przełom, ale miałem go stosować w przedsięwzięciu komercyjnym, na innej platformie.

Wyniki tłumaczyły, dlaczego Matlab nie mógł zostać tą platformą. Dla losowych instancji, na dwurdzeniowym pecie z 2011:

0,86 s średnio dla 10 miast
23 s średnio dla 11 miast
587 s średnio dla 12 miast — prawie 10 minut

Dwanaście punktów odbioru. Nie Polska. Nie sieć hurtowni. Dwanaście kropek na kwadracie 20×20 i interpreter, który dusi się na inkrementacjach. W pracy jest też druga połowa prawdy: VRP jest „podwójnie trudny” — najpierw trzeba mieć dobre cykle, potem złożyć z nich pokrycie zbioru. Dwa problemy NP-zupełne w jednym dniu dyspozytora.

Strona tytułowa: Problem wielu komiwojażerów, Łukasz Biedak, Politechnika Gdańska, 2011

Praca inżynierska (PDF)

Łukasz Biedak, Problem wielu komiwojażerów, Politechnika Gdańska, Wydział Fizyki Technicznej i Matematyki Stosowanej, 6 grudnia 2011. 25 stron.

3. VRPFinal: solver, który wreszcie był wystarczająco szybki

Obietnica ze wstępu pracy wymagała C++, nie Matlaba. Tak powstało repozytorium VRPFinal: rdzeń solvera, potem warstwy HTTP, na końcu panel dla dyspozytora.

Szkielet algorytmu został z pracy: wygeneruj cykle spełniające kryteria (ładowność, liczba węzłów, dystans), potem połącz je w pokrycie. Zmieniło się wszystko dookoła. Bitmaski zamiast naiwnych permutacji, 32-bitowe indeksy, kiedy cykli robi się więcej niż 65 tysięcy, tryb mikroserwisu, testy wydajności aż do okolic 30 węzłów klientów. Matlab na dwunastu miastach potrzebował dziesięciu minut. Solver z VRPFinal dla 100 miast wracał, zanim dyspozytor wypił kawę.

Potem doszedł front. React, mapa sieci, lista zleceń, parametry: maksymalna ładowność, maksymalny dystans, ile węzłów na trasę, które magazyny są dziś aktywne. Warstwa UI rozmawia z serwisami solvera (Go / C++). Na stronie firmowej ten system wisi jako case CVRP / mTSP.

Panel dyspozytora: parametry optymalizacji VRP i lista aktywnych magazynów
To, co z pracy inżynierskiej zostało w produkcie: kryteria na cykl i decyzja, które punkty odbioru w ogóle biorą udział w optymalizacji danego dnia.
Mapa sieci dystrybucji: magazyny i punkty dostaw w Polsce
Pełna sieć punktów odbioru w Polsce
Schemat architektury VRPFinal: frontend, backend Spring, scheduler i solver C++
Jedno z wcieleń VRPFinal: UI, backend, kolejka, solver C++. Później dochodziły Go i nowszy panel — ten sam węzeł.

4. Firma pochłonięta ERPem

Był moment, w którym algorytm przestał być ćwiczeniem. Firma miała realną flotę, realne magazyny i realny ból dyspozytora. Solver był gotów wejść w ten obieg: zlecenia, trasy i proponowanie rozwiązań dokładnie przeliczonych.

Nie wszedł. Nie dlatego, że wyniki były złe, ani dlatego, że „nie da się zintegrować”. Dlatego, że organizacja była w środku wdrażania dużego ERPa.

Duży system zarządczy zjada kalendarz, budżet i uwagę. Przez miesiące (czasem lata) wszystko, co nie jest „wdrożeniem”, spada na boczny tor: za wcześnie, za wąsko, „zrobimy po go-live”. Specjalistyczny optimizer tras nie konkuruje wtedy z inną aplikacją. Konkuruje z programem sterującym całą firmą, który ma stać się źródłem prawdy dla księgowości, magazynu, zakupów i raportów dla zarządu. W takim klimacie nawet działający kod wygląda jak dodatkową rzecz do utrzymania.

Algorytm, który liczy się w sekundach, przegrywa z projektem, który liczy się w kwartałach — jeśli ten drugi zajął już wszystkie ręce. Wydajność solvera nie ratuje braku slotu w organizacji.

5. Co z tego zostaje

Z praktyk została postawa: dowieźć, nie zaprezentować. Z pracy inżynierskiej — formalny kształt pytania i PDF, który można wreszcie otworzyć. Z VRPFinal — solver, którego nie wstyd podpiąć pod panel dyspozytora. Z tamtej firmy — lekcja, że oprócz dobrego produktu potrzeba też skali i umiejętności sprzedaży.

W LuBi-Software budujemy wąskie narzędzia pod procesy, którymi ludzie naprawdę pracują — obok dużego systemu, nie zamiast niego. Jeśli u Was trasy, zlecenia albo rotacje wciąż żyją w arkuszu „do czasu, aż ERP to ogarnie”, warto zrobić research co proponuje rynek. Większość matematycznych problemów da się teraz szybko rozwiązać.

Masz proces, którego ERP nie zdąży zgarnąć?

Trasy, dobór, kolejka, panel dla ludzi z hali — to da się zbudować obok systemu ewidencji, bez czekania na go-live wielkiego projektu.

[email protected] · +48 601 949 602