#![allow(non_snake_case)] use std::fmt; use text_io::{read}; mod generation; use generation::Generation; mod gene; use gene::Gene; mod chromosome; impl fmt::Display for Generation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let best = self.population .iter() .min_by(|a, b| a.fitness.partial_cmp(&b.fitness).unwrap()) .unwrap(); for cityi in &best.genes[..best.genes.len()-1] { let curr = &self.map[*cityi]; if curr.name.is_empty() { write!(f, "({},{}) -> ", curr.x, curr.y)?; } else { write!(f, "{} -> ", curr.name)?; } } let last = &self.map[*best.genes.last().unwrap()]; if last.name.is_empty() { writeln!(f, "({},{})", last.x, last.y)?; } else { writeln!(f, "{}", last.name)?; } writeln!(f, "{}", best.fitness) } } fn main() { let mut G: Generation; let input: String = read!(); let N = input.parse::(); if N.is_ok() { let N = N.unwrap(); G = Generation::new_from_random(N); } else { let names: Vec = std::fs::read_to_string([input.clone(), "_name.csv".to_string()].concat()) .expect("Couldn't open points file: ..._name.csv") .lines() .map(|x| x.to_string()) .collect(); let points: Vec = std::fs::read_to_string([input, "_xy.csv".to_string()].concat()) .expect("Couldn't open points file: ..._xy.csv") .lines() .enumerate() .map(|(i, l)| { let coords: Vec<&str> = l.split(',').collect(); Gene { x: coords[0].parse::().unwrap(), y: coords[1].parse::().unwrap(), name: names[i].clone(), } }) .collect(); G = Generation::new_from_map(points); } println!("{}", G.best_fitness()); let mut i = 0; while ! G.terminated() { if i < 8 { println!("{}", G.best_fitness()); i += 1; } G.selection_crossover(); G.mutate(); G = G.next_generation(); } println!(""); println!("{}", G); /* For debugging */ // let best = G.population // .iter() // .min_by(|a, b| a.fitness.partial_cmp(&b.fitness).unwrap()) // .unwrap(); // println!("{} {}", best.genes.first().unwrap(), best.genes.last().unwrap()); }