← Projects

Rutea Waste Collection Routes for Suba

Waste collection route planner for Suba, in Bogotá, on its real streets. My own routing solver in Java, measured against public instances, that follows the sanitation rules and replans when a truck breaks down.

Stack
Java 21 · Spring · PostGIS · React · MapLibre
Status
Completed
Year
2026
Code

Both degrees in one problem

I'm an environmental engineer, and waste collection is the problem from that field that looks most like an algorithm: which truck picks up which container and in what order, without going over its capacity or its shift. Rutea solves it for Suba, a district of Bogotá, on the real OpenStreetMap streets and with Colombia's sanitation rules written into the code.

My own solver, measured in public

The core is a capacitated vehicle routing (CVRP) solver in pure Java, with no optimization libraries: Clarke-Wright to start, local search and ALNS, with four searches in parallel. I measured it on the 43 CVRPLIB X instances from 101 to 301 nodes, the ones the literature uses, at 60 s per instance: it lands 0.18 % from the best known solution cold and 0.19 % warm. On the Suba plan, Timefold with its default configuration drives 35 % more km cold and 33 % more warm.

The real Suba

An OpenStreetMap reader of my own builds the directed graph of Suba and of the corridor to the Doña Juana landfill, 30 km away. With it, the 1,701 × 1,701 matrix comes out in 377 ms on 16 threads. 97.5 % of its cells are asymmetric: because of one-way streets, going from A to B doesn't cost the same as coming back.

The 1,612 containers are simulated from official figures, because there's no public inventory. Against a naive quadrant sweep, the plan drives 20.5 % fewer km and emits 20.5 % less CO₂. Chaining trips as well brings it to 25.3 % fewer km, and with 40-minute unloads 9 compactors cover the 17 trips.

The rules, in the code

Every rule cites its decree and article, and has a test that names it. The plan flags the 79 containers where compacting isn't allowed, within 50 m of a school or a health center (R07), and the stops between 21:00 and 06:00 that need noise measures (R02). Recyclables go in waste pickers' vehicles to a sorting station, as Decree 1381 of 2024 requires, and every UPZ, Bogotá's planning unit, has its published pass schedule (R04). Whatever I couldn't verify against the official text is flagged as pending, not stated as fact.

When something breaks

Above is a breakdown exactly as the API answered it. Rutea freezes what's already done and starts ALNS from the current plan. Over 500 random breakdowns, replanning takes 124.6 ms at P99, and the reserve truck arrives within 76 min in the worst case, well inside the 3 hours the rules allow (R05).

A road closure doesn't recompute the matrix: it repairs only the rows and columns whose paths went through that street. That takes 9.2 ms against 87.8 ms from scratch, with the same result in all 500 closures measured. The clock, positions and events travel over WebSocket and are stored in PostGIS.

What is still an assumption

Speeds per road type, diesel consumption and the 60 s stop per container are assumptions. The operator's real routes aren't public, so the sweep is a naive baseline, not today's operation. The whole thing runs with a single docker compose up.