use genetic_algorithm_traits::Population;
use genetic_algorithm_tsp::{distance_mat, route};
use std::time;
pub fn duration_to_ms(duration: time::Duration) -> u64 {
let nano_seconds = duration.subsec_nanos() as u64;
(1000 * 1000 * 1000 * duration.as_secs() + nano_seconds) / (1000 * 1000)
}
pub fn solve_tsp(
distance_matrix: &distance_mat::DistanceMat,
n_generations: usize,
n_routes: usize,
n_random_individuals_per_generation: usize,
top_n: usize,
) -> Vec<route::Route> {
let initial_population = distance_matrix.get_random_population(n_routes);
(0..10000)
.step_by(10000 / n_generations)
.fold(
initial_population,
|population, mutation_probability_int| {
population
.evolve(1.0 - (f64::from(mutation_probability_int) / 10000.0) as f32)
.add_n_random_nodes(n_random_individuals_per_generation)
.get_fittest_population(n_routes, distance_matrix)
},
)
.get_n_fittest(top_n, distance_matrix)
}
mod tests {
#[test]
fn test_duration() {
use super::duration_to_ms;
use std::thread;
use std::time;
let before = time::Instant::now();
thread::sleep(time::Duration::from_millis(12));
assert_eq!(duration_to_ms(before.elapsed()), 12);
}
#[test]
fn test_solve_tsp() {
use super::solve_tsp;
use genetic_algorithm_tsp::distance_mat;
use std::fs;
let distances = distance_mat::DistanceMat::new(
fs::read_to_string("tests/test-data/6_cities.txt")
.unwrap()
.lines()
.collect::<Vec<&str>>()
.iter()
.map(|line| {
line.split(";")
.map(|float_string| float_string.parse::<f64>().unwrap())
.collect::<Vec<f64>>()
})
.collect(),
);
let _ = solve_tsp(&distances, 20, 10, 10, 3);
}
}