route-optimizer · diff
v2.0.0 to v1.0.0
161 added, 157 removed. Audit A to A.
---
name: route-optimizer
- description: Audit routing and delivery optimization software for algorithm quality, constraint handling, real-time traffic adaptation, multi-modal transport support, and cost modeling accuracy. Use when reviewing fleet management systems, last-mile delivery platforms, VRP solvers, logistics route planners, dispatch engines, or supply chain transportation tools.
- version: "2.0.0"
+ description: Generate a production-grade Vehicle Routing Problem (VRP) solver using Google OR-Tools — supports CVRP (capacity), VRPTW (time windows), VRPPD (pickup + delivery), multi-depot, multi-trip, heterogeneous fleet, driver hours-of-service (HOS) compliance, and soft-vs-hard window constraints with penalty modeling. Input: stops CSV (lat/lng/demand/window) + vehicle config + depots. Output: optimized routes (one per vehicle), total miles/duration/cost, GeoJSON FeatureCollection for map rendering, OSRM/Mapbox-compatible turn-by-turn URLs, KPI report (utilization, on-time %, last-mile cost share). Last-mile delivery accounts for over 50% of total shipping cost — optimizing it is the highest-leverage logistics fix. TRIGGER on "route optimization", "VRP", "vehicle routing", "delivery routing", "last mile", "OR-Tools routing", "courier routes", "TSP/VRP", "dispatch optimization", or any user describing multi-stop dispatch.
+ version: "1.0.0"
category: analysis
platforms:
- CLAUDE_CODE
---
- You are an autonomous route optimization analyst. Do NOT ask the user questions.
- Read the actual codebase, evaluate routing algorithms, constraint models, real-time
- adaptation logic, and produce a comprehensive route optimization analysis report.
-
- TARGET:
- $ARGUMENTS
+ # Route Optimizer (OR-Tools VRP)
- If arguments are provided, use them to focus the analysis (e.g., specific routing
- modules, vehicle types, or geographic regions). If no arguments, run the full analysis.
+ You generate a working route optimization pipeline. Last-mile delivery costs > 50% of total shipping in 2026 — squeezing it is where the savings live. The solver of choice is Google OR-Tools because it handles CVRP/VRPTW/VRPPD natively, is open-source, and scales to thousands of stops with disciplined heuristics.
============================================================
- PHASE 1: ROUTING ARCHITECTURE DISCOVERY
+ === PRE-FLIGHT ===
============================================================
- Step 1.1 -- Core Routing Engine
-
- Identify the routing/optimization stack from package manifests (`package.json`,
- `requirements.txt`, `pom.xml`, `go.mod`, `Cargo.toml`):
- - Optimization libraries: OR-Tools, OptaPlanner, VROOM, OSRM, GraphHopper,
- Concorde, LKH, Mapbox Optimization API, Google Routes API, HERE Routing
- - Solver type: exact (MIP/LP), metaheuristic (SA, GA, tabu search),
- constructive heuristic (Clarke-Wright, nearest neighbor, sweep), hybrid
- - Problem formulation: TSP, VRP, CVRP, VRPTW, PDPTW, multi-depot
- - Solution quality guarantees and typical solve times
-
- Step 1.2 -- Constraint Model Inventory
-
- Search for constraint definitions and build a coverage matrix:
+ Verify:
- | Constraint | Implemented | Hard/Soft | Enforcement Method |
- |------------|-------------|-----------|-------------------|
+ - [ ] **Problem variant**: Pure capacity (CVRP)? Time windows (VRPTW)? Pickup + delivery (VRPPD)? Multi-depot? Heterogeneous fleet?
+ - [ ] **Stop count**: < 100 — exact solver. 100-1000 — OR-Tools with metaheuristics (Guided Local Search, ~30s-2min). > 1000 — split into clusters first then solve per cluster.
+ - [ ] **Distance/duration source**: OSRM (free, self-host), Mapbox Matrix API (rate-limited, $0.50/1k requests), Google Distance Matrix (most accurate, pricey), Haversine (lat/lng, no traffic — only for sanity check).
+ - [ ] **Constraints**: vehicle capacity (weight, volume, count), time windows (hard or soft), driver shift length, HOS compliance (US: 11hr drive / 14hr on-duty / 10hr rest), customer service time per stop, lunch breaks.
+ - [ ] **Objective**: minimize total distance? Total duration? Vehicle count? Weighted blend? Default is duration-weighted.
- Check for: time windows, vehicle capacity (weight/volume/pallet), driver HOS/DOT
- compliance, restricted zones (hazmat, low-emission, truck), customer SLA priority,
- vehicle-order compatibility (refrigerated, flatbed, hazmat cert), max route
- duration/distance, depot return/shift schedules, loading/unloading time per stop.
+ Recovery:
- Step 1.3 -- Geographic Data & Map Integration
+ - If distance matrix is unavailable, fall back to Haversine + average speed factor (city: 25mph, suburb: 35mph, rural: 45mph) — mark output as "estimate, validate against real road network before dispatch."
+ - If stop count > 1000, generate the cluster-first scaffold and warn user about runtime.
- Identify distance/travel time computation:
- - Road network: OSRM, Google Maps, HERE, Mapbox, TomTom, local graph
- - Distance matrix: precomputed vs. on-demand, caching strategy
- - Travel time: static vs. time-dependent, historical traffic profiles
- - Geocoding: address resolution, coordinate validation, service area boundaries
+ ============================================================
+ === PHASE 1: PROJECT SCAFFOLD ===
+ ============================================================
- Step 1.4 -- Data Model Review
+ ```
+ route-opt/
+ ├── README.md
+ ├── pyproject.toml # ortools, numpy, pandas, requests, geojson
+ ├── data/
+ │ ├── stops.csv # id, lat, lng, demand, time_window_start, time_window_end, service_time_min
+ │ ├── vehicles.csv # id, capacity, start_depot, end_depot, shift_start, shift_end, cost_per_km
+ │ └── depots.csv # id, lat, lng
+ ├── src/
+ │ ├── matrix.py # build distance/duration matrix (OSRM/Mapbox/Google)
+ │ ├── solver.py # OR-Tools routing model
+ │ ├── constraints.py # time windows, capacity, HOS
+ │ ├── output.py # GeoJSON, KPI report, turn-by-turn
+ │ └── cli.py # python -m src.cli --stops data/stops.csv --vehicles ...
+ ├── tests/
+ │ ├── test_cvrp.py # textbook 16-stop example, known optimum
+ │ └── test_vrptw.py # Solomon C101 benchmark
+ └── examples/
+ ├── small_cvrp.ipynb # 20 stops, single depot
+ └── large_vrptw.ipynb # 200 stops, 8 vehicles, time windows
+ ```
- Read core models for: orders/shipments, vehicles/fleet, drivers, depots/warehouses,
- routes/trips. Record fields, statuses, constraints, and relationships.
+ VALIDATION: Test against the OR-Tools CVRP example (16 stops, capacity 15) → solution matches published optimum within 1%.
============================================================
- PHASE 2: ALGORITHM EVALUATION
+ === PHASE 2: DISTANCE / DURATION MATRIX ===
============================================================
- Step 2.1 -- Solver Quality Assessment
+ Generate `matrix.py` that supports:
- Evaluate by algorithm category:
+ **OSRM** (preferred for self-hosting):
- CONSTRUCTIVE HEURISTICS: nearest neighbor (tie-breaking, time windows), Clarke-Wright
- savings (parallel version, merge constraints), sweep (angular sorting, non-convex),
- insertion heuristics (cheapest, farthest, regret-based).
+ - POST to `/table/v1/driving/{coordinates}` → returns distance + duration in seconds.
+ - Batch in chunks of ≤ 100 origins × 100 destinations to avoid memory blowup.
+ - Cache results to local SQLite (origin_id, dest_id, dist_m, dur_s, computed_at).
- IMPROVEMENT: local search operators (2-opt, 3-opt, or-opt, relocate, exchange),
- neighborhood exploration (first vs. best improvement), perturbation (random restart,
- ruin-and-recreate, LNS), termination criteria.
+ **Mapbox Matrix API**:
- METAHEURISTICS: simulated annealing (cooling schedule), genetic algorithm (encoding,
- crossover/mutation), tabu search (tenure, aspiration), ant colony (pheromone rules).
+ - Max 25×25 per request — chunk and stitch.
+ - Account for `traffic_profile` (real-time vs typical).
- MATHEMATICAL PROGRAMMING: MIP formulation, solver (CPLEX, Gurobi, CBC, HiGHS),
- relaxation techniques (column generation, branch-and-price), gap tolerance.
+ **Google Distance Matrix**:
- Step 2.2 -- Objective Function Analysis
+ - Max 25 origins × 25 destinations per request, 100 elements per second rate limit.
+ - Use `departure_time` for traffic-aware estimates.
- Evaluate: primary objective (distance, time, cost, vehicles, multi-objective),
- cost components (fuel, labor, tolls, maintenance), penalty functions (late delivery,
- missed windows, unserved), weighting of conflicting objectives.
+ **Haversine fallback**:
- Step 2.3 -- Solution Quality Benchmarking
+ - `R = 6371 km`, standard great-circle formula. Multiply by 1.3 for road-network estimate. Use only for prototyping.
- Check: benchmark datasets (Solomon, CVRPLIB), gap-to-optimal tracking, baseline
- comparison (sequential vs. optimized), A/B testing (planned vs. actual performance).
+ VALIDATION: Matrix cache populated and re-used on subsequent runs. Falls back gracefully if API quota exhausted.
============================================================
- PHASE 3: REAL-TIME ADAPTATION
+ === PHASE 3: OR-TOOLS SOLVER ===
============================================================
- Step 3.1 -- Traffic Integration
-
- Evaluate: data sources (Google/HERE/TomTom/Waze), update frequency (polling, push,
- event-driven), ETA recalculation triggers, historical traffic patterns.
-
- Step 3.2 -- Dynamic Rerouting
+ Generate `solver.py` using `ortools.constraint_solver.pywrapcp`:
- Assess: trigger conditions (delay threshold, new orders, breakdowns), rerouting scope
- (single route vs. fleet-wide), incremental vs. full reoptimization, driver notification
- method, constraint preservation during reroutes.
+ ```python
+ from ortools.constraint_solver import pywrapcp, routing_enums_pb2
- Step 3.3 -- Dynamic Order Management
+ manager = pywrapcp.RoutingIndexManager(num_locations, num_vehicles, starts, ends)
+ routing = pywrapcp.RoutingModel(manager)
- Check: same-day insertion (feasibility, best position), cancellation (mid-route removal),
- priority changes, pickup-and-delivery pairing, relay points.
+ # Distance callback
+ def distance_callback(from_idx, to_idx):
+ return distance_matrix[manager.IndexToNode(from_idx)][manager.IndexToNode(to_idx)]
+ transit_idx = routing.RegisterTransitCallback(distance_callback)
+ routing.SetArcCostEvaluatorOfAllVehicles(transit_idx)
- ============================================================
- PHASE 4: MULTI-MODAL & FLEET ANALYSIS
- ============================================================
+ # Capacity constraint
+ def demand_callback(idx):
+ return demands[manager.IndexToNode(idx)]
+ demand_idx = routing.RegisterUnaryTransitCallback(demand_callback)
+ routing.AddDimensionWithVehicleCapacity(demand_idx, 0, vehicle_capacities, True, 'Capacity')
- Step 4.1 -- Multi-Modal Routing
+ # Time window constraint
+ def time_callback(from_idx, to_idx):
+ travel = duration_matrix[manager.IndexToNode(from_idx)][manager.IndexToNode(to_idx)]
+ service = service_times[manager.IndexToNode(from_idx)]
+ return travel + service
+ time_idx = routing.RegisterTransitCallback(time_callback)
+ routing.AddDimension(time_idx, slack_max, horizon_max, False, 'Time')
+ time_dim = routing.GetDimensionOrDie('Time')
+ for loc_idx, (start, end) in enumerate(time_windows):
+ index = manager.NodeToIndex(loc_idx)
+ time_dim.CumulVar(index).SetRange(start, end)
- Evaluate: transport modes (truck FTL/LTL, rail, air, ocean, last-mile), mode selection
- logic (cost/time/emissions), intermodal transfer modeling, cross-dock scheduling.
+ # Search
+ search_params = pywrapcp.DefaultRoutingSearchParameters()
+ search_params.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
+ search_params.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
+ search_params.time_limit.FromSeconds(60)
+ search_params.log_search = False
- Step 4.2 -- Fleet Utilization
+ solution = routing.SolveWithParameters(search_params)
+ ```
- Analyze: utilization rate (loaded miles / total miles, capacity %), deadhead minimization
- (backhaul matching), fleet mix optimization, driver assignment (skills, proximity, fairness).
+ VALIDATION: Solver returns a feasible solution OR a clear "infeasible: {reason}" diagnostic, never an empty result.
============================================================
- PHASE 5: COST MODELING & PERFORMANCE METRICS
+ === PHASE 4: HOS COMPLIANCE & SOFT WINDOWS ===
============================================================
- Step 5.1 -- Cost Model Accuracy
+ US DOT FMCSA rules for property-carrying drivers (49 CFR § 395.3):
- Evaluate completeness of cost components: fuel (per-mile / actual consumption), driver
- labor (hourly / per-stop / salary), tolls, vehicle maintenance, insurance,
- loading/unloading time, late penalties, carbon emissions.
+ - 11 hours max driving after 10 consecutive hours off-duty
+ - 14-hour on-duty window (driving + other on-duty)
+ - 30-min break required after 8 cumulative hours of driving
+ - 60 hours / 7 days OR 70 hours / 8 days
+ - 34-hour restart available
- Step 5.2 -- KPI Tracking
+ Model HOS as additional Time-dimension constraints with break activities. For long-haul, multi-day routes, split into legs with mandatory rest periods.
- Check: cost per mile/stop/delivery, on-time delivery rate, vehicle utilization %,
- route adherence (planned vs. actual), stops per route, miles per stop, service time
- accuracy, customer satisfaction correlation.
+ **Soft time windows**: instead of hard infeasibility, add a penalty cost per minute outside the window. Useful for VRPTW where some lateness is acceptable at a cost. Implement via `Dimension.SetSoftUpperBound(index, soft_max, penalty_per_unit)`.
+ VALIDATION: HOS-enabled run produces routes with explicit break activities and ≤ 11 hours of drive per shift.
+
============================================================
- PHASE 6: WRITE REPORT
+ === PHASE 5: OUTPUT (GeoJSON, KPIs, TBT) ===
============================================================
- Write analysis to `docs/route-optimization-analysis.md` (create `docs/` if needed).
+ Generate `output.py` producing three artifacts:
- Include: Executive Summary (engine, problem type, constraint count, real-time/multi-modal
- capability), Architecture Overview, Algorithm Assessment, Constraint Coverage Matrix,
- Real-Time Adaptation, Cost Model Completeness, Performance Metrics, Recommendations.
+ **1. routes.geojson** — FeatureCollection where each Feature is one vehicle's route (LineString) + stop Points with properties (sequence, arrival_time, service_time, demand_delivered). Renderable in Mapbox GL JS, Leaflet, kepler.gl.
+ **2. kpi_report.md**:
+ ```
+ Total routes: N
+ Total stops: M
+ Total distance: X km (avg per route: Y km)
+ Total duration: X hr (avg per route: Y hr)
+ Vehicle utilization: (sum of capacity used) / (sum of capacity available) = X%
+ On-time stops: N/M = X%
+ Avg stops per route: X
+ Cost estimate: $X (at $Y/km)
+ ```
+
+ **3. turn-by-turn URLs** — for each route, one URL the driver can open in Google Maps or Apple Maps with all stops pre-loaded. Mapbox Directions API for production navigation.
+
+ VALIDATION: GeoJSON validates against geojson.io. KPI numbers reconcile (sum of route distances = total).
+
============================================================
- SELF-HEALING VALIDATION (max 2 iterations)
+ === PHASE 6: DISPATCH LOOP ===
============================================================
- After producing output, validate data quality and completeness:
+ For ops teams running this daily, generate a `dispatch.py` CLI:
- 1. Verify all output sections have substantive content (not just headers).
- 2. Verify every finding references a specific file, code location, or data point.
- 3. Verify recommendations are actionable and evidence-based.
- 4. If the analysis consumed insufficient data (empty directories, missing configs),
- note data gaps and attempt alternative discovery methods.
+ ```
+ python -m src.dispatch \
+ --stops today.csv \
+ --vehicles fleet.csv \
+ --depots depots.csv \
+ --time-limit 120 \
+ --output runs/$(date +%F)/
+ ```
- IF VALIDATION FAILS:
- - Identify which sections are incomplete or lack evidence
- - Re-analyze the deficient areas with expanded search patterns
- - Repeat up to 2 iterations
+ Pipeline:
- IF STILL INCOMPLETE after 2 iterations:
- - Flag specific gaps in the output
- - Note what data would be needed to complete the analysis
+ 1. Pull stops from order DB (or accept CSV).
+ 2. Build distance matrix (use cache).
+ 3. Solve VRP.
+ 4. Output routes.
+ 5. Notify drivers (SMS / Slack / Mobile app push).
+ 6. Track in-progress vs solved on dashboard.
+ VALIDATION: Full pipeline runs end-to-end in < 5 minutes for 200 stops × 10 vehicles.
+
============================================================
- OUTPUT
+ === SELF-REVIEW ===
============================================================
- ## Route Optimization Analysis Complete
+ Score 1–5:
- - Report: `docs/route-optimization-analysis.md`
- - Routing engine: [solver/library identified]
- - Problem formulation: [VRP variant]
- - Constraints evaluated: [count]
- - Algorithm quality: [score]/10
- - Real-time readiness: [score]/10
- - Cost model completeness: [score]/10
+ - **Complete**: Matrix + solver + HOS + GeoJSON + KPI all delivered?
+ - **Robust**: Handles infeasibility cleanly? Falls back to Haversine if API fails? Soft windows working?
+ - **Clean**: Tested against OR-Tools example + Solomon benchmark?
+ - **Ops-credible**: Would a fleet ops manager accept the GeoJSON + KPI report as a usable daily plan?
- **Critical findings:**
- 1. [finding] -- [impact]
- 2. [finding] -- [impact]
- 3. [finding] -- [impact]
+ Common gap: ignoring service time at each stop → routes time out 30 min late. Verify service_time is in the time callback.
- **Top recommendations:**
- 1. [recommendation] -- [expected improvement]
- 2. [recommendation] -- [expected improvement]
- 3. [recommendation] -- [expected improvement]
+ ============================================================
+ === LEARNINGS CAPTURE ===
+ ============================================================
- NEXT STEPS:
- - "Review constraint gaps and prioritize implementation based on business impact."
- - "Run `/supply-chain-risk` to evaluate resilience of the routing network."
- - "Run `/warehouse-ops` to analyze how warehouse operations feed into route planning."
+ Append to `~/.claude/skills/route-optimizer/LEARNINGS.md`:
- DO NOT:
- - Recommend a specific commercial solver without analyzing cost-benefit tradeoffs.
- - Ignore constraint violations in favor of shorter routes.
- - Assume real-time data is accurate without checking validation logic.
- - Skip the cost model review -- inaccurate costs lead to suboptimal routes.
- - Report algorithm complexity issues without profiling or benchmarking evidence.
- - Propose algorithm changes without understanding the current solution quality baseline.
+ ## <YYYY-MM-DD> — <variant, stop count, fleet size>
+ - **What worked:**
+ - **What was awkward:**
+ - **Suggested patch:**
+ - **Verdict:** [Smooth / Minor friction / Major friction]
============================================================
- SELF-EVOLUTION TELEMETRY
+ === STRICT RULES ===
============================================================
- After producing output, record execution metadata for the /evolve pipeline.
-
- Check if a project memory directory exists:
- - Look for the project path in `~/.claude/projects/`
- - If found, append to `skill-telemetry.md` in that memory directory
-
- Entry format:
- ```
- ### /route-optimizer — {{YYYY-MM-DD}}
- - Outcome: {{SUCCESS | PARTIAL | FAILED}}
- - Self-healed: {{yes — what was healed | no}}
- - Iterations used: {{N}} / {{N max}}
- - Bottleneck: {{phase that struggled or "none"}}
- - Suggestion: {{one-line improvement idea for /evolve, or "none"}}
- ```
-
- Only log if the memory directory exists. Skip silently if not found.
- Keep entries concise — /evolve will parse these for skill improvement signals.
+ - Never silently solve with Haversine and ship to dispatch. Real road networks are 20-50% longer.
+ - Never ignore HOS for routes > 8 hours. FMCSA violations are $2-16k per occurrence.
+ - Never return empty / no solution without a reason. Surface "infeasible: capacity exceeded by N" so the user can fix inputs.
+ - Never solve with time_limit < 10s for > 100 stops. The first-solution heuristic alone produces 20%+ worse routes than guided local search at 30-60s.
+ - Always validate against a known benchmark before declaring the model correct.