This is a complete implementation of the Fleet Optimization algorithms for LSP Group's Predictive Fleet Swap AI system. The system optimizes vehicle-to-route assignments for a fleet of 180+ trucks across 100,000+ routes over 12 months.
- Purpose: Determines initial location for each vehicle
- Strategy: Analyzes demand in first 14 days and distributes vehicles proportionally
- Key Features:
- Demand-driven clustering
- Avoids over-concentration (max 30% at one location)
- Minimizes early relocation costs
- Purpose: Assigns vehicles to routes day-by-day
- Strategy: Greedy selection with future route chain evaluation
- Key Features:
- 7-day look-ahead window
- Chain depth of 3 routes
- Respects all constraints (time, service, contract limits, swap policy)
- Cost minimization (relocation + overage)
fleet-backend/
βββ algorithm_config.json # Algorithm configuration
βββ data/ # Input CSV files
β βββ vehicles.csv
β βββ locations.csv
β βββ locations_relations.csv
β βββ routes.csv
β βββ segments.csv
βββ src/
β βββ main.py # CLI entry point
β βββ models.py # Data structures
β βββ data_loader.py # CSV loading
β βββ costs.py # Cost calculations
β βββ constraints.py # Constraint validation
β βββ placement.py # Placement algorithm
β βββ assignment.py # Assignment algorithm
β βββ optimizer.py # Main orchestration
β βββ output.py # Result generation
βββ output/ # Generated results
βββ assignments_*.csv
βββ vehicle_states_*.csv
βββ placement_report_*.json
βββ summary_*.json
# Ensure Python 3.13+ is installed
python --version
# Install packages (if needed)
pip install -e .cd /home/rio/wrk/proj/fleet-backend
python src/main.py test 1000python src/main.py fullEach run generates timestamped files:
-
assignments_{timestamp}.csv- Route-to-vehicle assignments
- Columns: route_id, vehicle_id, date, distances, costs, relocations, etc.
-
vehicle_states_{timestamp}.csv- Final state of each vehicle
- Columns: odometer, annual km, overage, relocations, costs
-
placement_report_{timestamp}.json- Placement algorithm analysis
- Demand distribution, vehicle clustering
-
summary_{timestamp}.json- Overall statistics and KPIs
- Total costs, performance metrics, constraint violations
Edit algorithm_config.json to adjust parameters:
{
"placement": {
"lookahead_days": 14, // Days to analyze for demand
"max_concentration": 0.30 // Max % of fleet at one location
},
"assignment": {
"look_ahead_days": 7, // Look-ahead window
"chain_depth": 3 // Future routes to evaluate
},
"swap_policy": {
"max_swaps_per_period": 1, // Max swaps per period
"swap_period_days": 90 // Period length (3 months)
},
"service_policy": {
"service_tolerance_km": 1000, // Tolerance before service
"service_duration_hours": 48 // Service duration
},
"costs": {
"relocation_base_cost_pln": 1000.0, // Base relocation cost
"relocation_per_km_pln": 1.0, // Cost per km
"relocation_per_hour_pln": 150.0, // Cost per hour
"overage_per_km_pln": 0.92 // Overage penalty
}
}- Analyze Demand: Count routes starting at each location (first 14 days)
- Sort Locations: Order by demand (highest first)
- Distribute Vehicles: Proportionally allocate vehicles to high-demand locations
- Validate: Ensure good clustering, reasonable estimated costs
Example Output:
Top location: 18 vehicles (10% of fleet)
Total locations used: 25
Vehicles at zero-demand locations: 0
Estimated early relocation cost: 850,000 PLN
For each route (chronologically):
-
Find Feasible Vehicles:
- Check time feasibility (can reach on time?)
- Check contract limits (won't exceed lifetime limit?)
- Check swap policy (hasn't swapped too recently?)
-
Evaluate with Look-Ahead:
- Calculate immediate assignment cost (relocation + overage)
- Build future route chain (next 7 days, depth 3)
- Score based on future opportunities
- Select vehicle with best combined score
-
Update State:
- Update vehicle location, odometer, availability
- Track relocations, costs, service needs
- Record assignment
Example Output:
Progress: Day 30 (2024-01-30) - 5,240 routes assigned
Progress: Day 60 (2024-02-29) - 10,580 routes assigned
...
Routes assigned: 100,303
Total relocations: 3,420
Total cost: 10,550,000 PLN
- β 100% route completion
- β Total cost < 50M PLN (target: 10-30M)
- β < 50% routes require relocation
- β < 20% vehicles exceed annual limit
Total cost: 10-20M PLN
- Relocation: 60-70%
- Overage: 30-40%
Relocations: 3,000-5,000 (3-5%)
Vehicles over limit: 15-30 (8-17%)
Avg cost per route: ~100-200 PLN
Runtime: 15-45 minutes
# 500 routes
python src/main.py test 500
# 5000 routes
python src/main.py test 5000# In algorithm_config.json, try different parameters:
# Stricter swap policy (60 days instead of 90)
"swap_period_days": 60
# More aggressive look-ahead (10 days, depth 5)
"look_ahead_days": 10
"chain_depth": 5
# Tighter service tolerance
"service_tolerance_km": 500import json
import pandas as pd
# Load summary
with open('output/summary_20241030_143022.json') as f:
summary = json.load(f)
print(f"Total cost: {summary['costs']['total_cost_pln']:,.2f} PLN")
# Load assignments
df = pd.read_csv('output/assignments_20241030_143022.csv')
# Analyze relocations
relocations = df[df['requires_relocation'] == True]
print(f"Relocation rate: {len(relocations)/len(df)*100:.1f}%")
# Top vehicles by overage
vehicle_df = pd.read_csv('output/vehicle_states_20241030_143022.csv')
top_overage = vehicle_df.nlargest(10, 'overage_km')
print(top_overage[['vehicle_id', 'overage_km', 'overage_ratio']])- Cause: All vehicles violate constraints (time, swap policy, contract limit)
- Solution: Check if swap_period_days is too strict, or if routes are too dense
- Cause: Poor placement or over-relocation
- Solution: Increase placement_lookahead_days, check demand distribution
- Cause: Unbalanced route distribution
- Solution: Adjust annual limits in vehicles.csv, or increase fleet size
- Cause: Look-ahead too aggressive
- Solution: Reduce look_ahead_days or chain_depth
- Simplicity: Greedy heuristics over complex optimization
- Fail-safe: Always assign all routes, even if costly
- Fast feedback: Progress reports every 30 days
- Maintainable: Clear, documented code
- β HARD: Time feasibility (can reach route on time)
- β HARD: Contract limits (lifetime km)
- β HARD: Swap policy (max 1 per 90 days)
β οΈ SOFT: Service intervals (penalty cost)β οΈ SOFT: Annual limits (overage cost)
Assignment Cost = Relocation Cost + Overage Cost + Service Penalty
Relocation Cost = 1000 + (km Γ 1.0) + (hours Γ 150)
Overage Cost = (km_over_annual_limit) Γ 0.92
Service Penalty = 500 PLN (if service needed)
For each candidate vehicle, the system:
- Simulates completing current route
- Identifies next feasible routes (within 7 days)
- Calculates cost of each future route
- Assigns scores (lower cost = higher score)
- Weights future scores with decay (0.5^n)
- Combines immediate cost with future opportunity
Result: Vehicles that enable good future assignments are preferred.
Chains are built recursively:
- Depth 1: Immediate next route
- Depth 2: Route after that
- Depth 3: Third route ahead
Each level has diminishing weight:
- Level 1: weight = 1.0
- Level 2: weight = 0.5
- Level 3: weight = 0.25
Result: Near-term opportunities matter more than distant ones.
During execution, watch for:
- β Green checkmarks: Success
β οΈ Yellow warnings: Non-critical issues- β Red X: Errors requiring attention
For questions or issues, refer to:
ALGORITHM_SPEC_V2.md- Detailed algorithm specificationmessage.txt- Original problem statement- Code comments in each module
Implementation Status: β
Production Ready
Last Updated: October 30, 2025
Version: 2.0