use pdp_lns::algorithm;
use pdp_lns::instance::Instance;
use pdp_lns::solution;
use std::path::Path;
use std::time::{Duration, Instant};
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
eprintln!(
"Usage: {} <instance_file> [time_limit_secs] [seed] [initial_method]",
args[0]
);
eprintln!(" instance_file: path to Li & Lim PDPTW instance file");
eprintln!(" time_limit_secs: time limit in seconds (default: 300)");
eprintln!(" seed: random seed (default: 42)");
eprintln!(
" initial_method: legacy|lu2006|ropke2006|cluster2004|hosny2012 (default: legacy)"
);
std::process::exit(1);
}
let instance_path = &args[1];
let time_limit_secs: u64 = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(300);
let seed: u64 = args.get(3).and_then(|s| s.parse().ok()).unwrap_or(42);
let initial_method = if let Some(raw) = args.get(4) {
if let Some(m) = algorithm::InitialSolutionMethod::from_str(raw) {
m
} else {
eprintln!(
"Unknown initial_method '{raw}'. Expected legacy|lu2006|ropke2006|cluster2004|hosny2012"
);
std::process::exit(2);
}
} else {
algorithm::InitialSolutionMethod::Legacy
};
let process_start = Instant::now();
eprintln!("Loading instance: {instance_path}");
let inst = Instance::from_file(Path::new(instance_path));
eprintln!(
" {} customers, {} PD pairs, capacity={}, max_vehicles={}",
inst.n, inst.m, inst.capacity, inst.num_vehicles
);
eprintln!(
"Solving with time_limit={time_limit_secs}s, seed={seed}, initial_method={}",
initial_method.as_str()
);
let best = algorithm::solve_with_initial_method(
&inst,
Duration::from_secs(time_limit_secs),
seed,
None,
initial_method,
Some(process_start),
);
println!("=== RESULT ===");
println!("Vehicles: {}", best.num_vehicles());
println!("Distance: {:.2}", best.total_distance(&inst));
println!("Routes:");
for (i, route) in best.routes.iter().enumerate() {
let route_str: Vec<String> = route.iter().map(std::string::ToString::to_string).collect();
println!(" Route {}: {}", i + 1, route_str.join(" -> "));
println!(
" Distance: {:.2}, Customers: {}",
solution::route_distance(&inst, route),
route.len() - 2
);
}
println!("Feasible: {}", best.is_feasible(&inst));
}