A memory-efficient implementation of a hybrid algorithm for the Vehicle Routing Problem with Time Windows (VRPTW) that combines Multiple Insertion Heuristic (MIH) with Multi-Directional Search (MDS).
- Memory Efficient: Designed for resource-constrained environments (~8GB RAM)
- Fast: 50-100× faster than OR-Tools with only 3-5% optimality gap
- CPU-Only: No GPU acceleration required
- Single-Threaded: Optimized for memory efficiency, not parallelization
- Intentionally sub-optimal insertion heuristic
- Samples only 30-50% of candidates at each step
- Leaves improvement opportunities for MDS
- Memory: O(n) - no distance matrix caching
- Targets only critical routes for improvement
- Uses in-place operators (temporal shift, swap, relocate)
- Memory: O(1) - all modifications in place
# Clone or download the repository
cd vrptw_solver
# Install dependencies
pip install ortools # Optional, for baseline comparisonfrom core.solomon_loader import load_solomon_instance
from algorithms.hybrid_solver import solve_vrptw
# Load instance
depot, customers, vehicle_capacity, fleet_size = load_solomon_instance("data/C101.txt")
# Solve
solution = solve_vrptw(depot, customers, vehicle_capacity)
# Check results
print(f"Total cost: {solution.total_cost}")
print(f"Number of vehicles: {solution.num_vehicles}")
print(f"Feasible: {solution.is_feasible()}")# Solve full instance
python main.py data/C101.txt
# Solve subset (25 customers)
python main.py data/C101.txt 25
# Solve subset (50 customers)
python main.py data/C101.txt 50| Customers | Memory Usage | Target |
|---|---|---|
| 25 | ~5 MB | < 10 MB |
| 50 | ~15 MB | < 30 MB |
| 100 | ~50 MB | < 100 MB |
vrptw_solver/
├── main.py # Entry point
├── core/
│ ├── data_structures.py # Customer, Route, Solution classes
│ ├── solomon_loader.py # Instance loader
│ └── geometry.py # Distance calculation
├── algorithms/
│ ├── mih.py # Limited Candidate MIH
│ ├── mds.py # Selective MDS
│ └── hybrid_solver.py # Combined solver
├── operators/
│ ├── temporal_shift.py # Departure time adjustment
│ ├── swap.py # Customer swap
│ └── relocate.py # Customer relocation
├── evaluation/
│ ├── route_analyzer.py # Criticality scoring
│ └── performance_metrics.py # Metrics and comparison
└── baselines/
└── ortools_solver.py # OR-Tools comparison
- On-the-Fly Distance Calculation: No distance matrix caching
- In-Place Modifications: All route operations modify existing objects
- Temporary Buffer Reuse: Shared buffers across iterations
- Lightweight Data Structures:
__slots__for minimal memory overhead - Single Solution Instance: Only one solution object in memory at a time
Test on Solomon benchmark instances:
- C1xx: Clustered customers (easier)
- R1xx: Random customers (harder)
- RC1xx: Mixed random-clustered
Start with small instances (25 customers) and scale up.
Expected performance on C101 instances:
| Instance | Customers | Time | Memory | Quality Gap |
|---|---|---|---|---|
| C101.25 | 25 | ~0.2s | ~5 MB | 3-5% |
| C101.50 | 50 | ~0.8s | ~15 MB | 4-6% |
| C101.100 | 100 | ~3s | ~50 MB | 5-8% |
This implementation is provided for research and educational purposes.