use std::fmt::Display;
use std::io;
use std::time;
use crate::AlgorithmState;
pub trait Logger<T> {
fn start(&mut self, _state: &dyn AlgorithmState<T>) {}
fn resume(&mut self, _state: &dyn AlgorithmState<T>) {}
fn next_iteration(&mut self, _state: &dyn AlgorithmState<T>) {}
fn finish(&mut self, _state: &dyn AlgorithmState<T>) {}
}
pub struct VerboseLogger<'a> {
writer: &'a mut dyn io::Write,
precision: usize,
}
impl<'a> VerboseLogger<'a> {
pub fn new(writer: &'a mut dyn io::Write, precision: usize) -> Self {
Self { writer, precision }
}
}
impl<'a, T: Display> Logger<Vec<T>> for VerboseLogger<'a> {
fn next_iteration(&mut self, state: &dyn AlgorithmState<Vec<T>>) {
if let Some((solution, goal)) = state.get_best_solution() {
let mut result = String::new();
result = result + &format!("{:<8}", state.get_iteration());
for x in solution {
result = result + &format!(" {:<20.*}", self.precision, x);
}
result = result + &format!(" {:20.*}", self.precision, goal);
writeln!(&mut self.writer, "{}", result).unwrap();
}
}
}
pub struct ResultOnlyLogger<'a> {
writer: &'a mut dyn io::Write,
precision: usize,
}
impl<'a> ResultOnlyLogger<'a> {
pub fn new(writer: &'a mut dyn io::Write, precision: usize) -> Self {
Self { writer, precision }
}
}
impl<'a, T: Display> Logger<Vec<T>> for ResultOnlyLogger<'a> {
fn start(&mut self, _state: &dyn AlgorithmState<Vec<T>>) {}
fn finish(&mut self, state: &dyn AlgorithmState<Vec<T>>) {
match state.get_best_solution() {
None => writeln!(&mut self.writer, "Solution not found").unwrap(),
Some((solution, goal)) => {
let mut result = String::new();
result = result + "Solution:\n";
for x in solution {
result = result + &format!(" {:.*}\n", self.precision, x);
}
result = result + "\n";
writeln!(&mut self.writer, "{}", result).unwrap();
writeln!(&mut self.writer, "Goal: {:.*}", self.precision, goal).unwrap();
}
}
writeln!(
&mut self.writer,
"Iterations count: {}",
state.get_iteration()
)
.unwrap();
}
}
pub struct TimeLogger<'a> {
writer: &'a mut dyn io::Write,
start_time: Option<time::Instant>,
}
impl<'a> TimeLogger<'a> {
pub fn new(writer: &'a mut dyn io::Write) -> Self {
Self {
writer,
start_time: None,
}
}
}
impl<'a, T: Display> Logger<Vec<T>> for TimeLogger<'a> {
fn resume(&mut self, _state: &dyn AlgorithmState<Vec<T>>) {
self.start_time = Some(time::Instant::now());
}
fn finish(&mut self, _state: &dyn AlgorithmState<Vec<T>>) {
let duration = self.start_time.unwrap().elapsed();
let time_ms = duration.as_secs() * 1000 + duration.subsec_millis() as u64;
writeln!(&mut self.writer, "Time elapsed: {} ms", time_ms).unwrap();
}
}