use std::time::Duration;
use crate::ga::TerminationCause;
use crate::observer::{ExtensionEvent, GaObserver, IslandGaObserver, Nsga2Observer};
use crate::stats::GenerationStats;
use crate::traits::ChromosomeT;
pub struct LogObserver;
impl<U: ChromosomeT> GaObserver<U> for LogObserver {
fn on_run_start(&self) {
log::info!("Initialization started");
}
fn on_generation_start(&self, generation: usize) {
log::info!(target="ga_events", method="run"; "Generation number: {}", generation + 1);
}
fn on_selection_complete(&self, _generation: usize, _duration: Duration, _population_size: usize) {
log::debug!(target="ga_events", method="run"; "Parents selected for reproduction");
}
fn on_crossover_complete(&self, _generation: usize, _duration: Duration, _offspring_count: usize) {
log::debug!(target="ga_events", method="parent_crossover"; "Started the parent crossover");
log::debug!(target="ga_events", method="run"; "Offspring created");
log::debug!(target="ga_events", method="parent_crossover"; "Parent crossover finished");
}
fn on_mutation_complete(&self, _generation: usize, _duration: Duration, _population_size: usize) {
}
fn on_fitness_evaluation_complete(&self, _generation: usize, _duration: Duration, _population_size: usize) {
}
fn on_survivor_selection_complete(&self, _generation: usize, _duration: Duration, _population_size: usize) {
log::debug!(target="ga_events", method="run"; "Survivors selected");
}
fn on_new_best(&self, _generation: usize, _best: U) {
}
fn on_stagnation(&self, _generation: usize, _stagnation_count: usize) {
}
fn on_extension_triggered(&self, event: ExtensionEvent) {
log::info!(
target="extension_events",
method="run";
"Extension triggered: diversity={:.6} < threshold={:.6}",
event.diversity,
event.threshold
);
}
fn on_generation_end(&self, stats: &GenerationStats) {
log::debug!(target="ga_events", method="run"; "Best chromosome calculated - generation {}", stats.generation + 1);
if let Some(prob) = stats.dynamic_mutation_probability {
log::debug!(
target="ga_events",
method="run";
"Dynamic mutation: diversity={:.4}, probability={:.4}",
stats.diversity,
prob
);
}
log::debug!(target="ga_events", method="limit_reached"; "Started limit reached method");
log::trace!(target="ga_events", method="limit_reached"; "limit reached for minimization");
log::trace!(target="ga_events", method="limit_reached"; "limit reached for fixed fitness");
log::debug!(target="ga_events", method="limit_reached"; "Limit reached method finished");
}
fn on_run_end(&self, _cause: TerminationCause, _all_stats: &[GenerationStats]) {
}
}
impl<U: ChromosomeT> IslandGaObserver<U> for LogObserver {
fn on_island_run_start(&self, _island_id: usize) {
log::info!(target: "island_events", "Island model GA started");
}
fn on_island_run_end(&self, _island_id: usize) {
log::info!(target: "island_events", "Island model GA ended");
}
fn on_island_generation_end(&self, _island_id: usize, generation: usize, stats: &GenerationStats) {
log::debug!(target: "island_events", "Best chromosome calculated - generation {}", generation + 1);
if let Some(prob) = stats.dynamic_mutation_probability {
log::debug!(
target: "island_events",
"Dynamic mutation: diversity={:.4}, probability={:.4}",
stats.diversity,
prob
);
}
}
fn on_migration_triggered(&self, generation: usize, migration_count: usize) {
log::debug!(target: "island_events", "Migration performed at generation {} (count={})", generation, migration_count);
}
}
impl<U: ChromosomeT> Nsga2Observer<U> for LogObserver {
fn on_pareto_front_assigned(&self, generation: usize, front_count: usize, population_size: usize) {
log::debug!(target: "nsga2_events", "Generation {} complete, population size = {}, fronts = {}", generation, population_size, front_count);
}
fn on_non_dominated_sort_complete(&self, generation: usize, duration_ms: f64) {
log::debug!(target: "nsga2_events", "Non-dominated sort complete at generation {} ({:.2}ms)", generation, duration_ms);
}
fn on_crowding_distance_calculated(&self, generation: usize, duration_ms: f64) {
log::debug!(target: "nsga2_events", "Crowding distance calculated at generation {} ({:.2}ms)", generation, duration_ms);
}
}