metalforge 0.1.2

forge: a deterministic metaheuristic optimization substrate in Rust. Unified Problem/MultiProblem/Anneal traits; DDS, SCE-UA, DE, PSO, NSGA-II and simulated annealing; reproducible by seed; optional Rayon parallelism.
Documentation
//! Stopping criteria shared by every optimizer.
//!
//! All forge algorithms count objective **evaluations** as their budget unit
//! (not iterations or generations), so runs are comparable across algorithms
//! with very different inner loops. An optional target value enables early exit
//! once a good-enough solution is reached.

use crate::solution::StopReason;

/// When an optimizer should stop.
#[derive(Debug, Clone, Copy)]
pub struct Termination {
    /// Maximum number of objective evaluations.
    pub max_evaluations: usize,
    /// Optional target: stop as soon as the minimized objective drops to or
    /// below this value. `None` disables early exit.
    pub target: Option<f64>,
}

impl Termination {
    /// A pure evaluation budget with no target.
    pub fn budget(max_evaluations: usize) -> Self {
        Termination {
            max_evaluations,
            target: None,
        }
    }

    /// Adds an early-exit target (minimized sense).
    pub fn with_target(mut self, target: f64) -> Self {
        self.target = Some(target);
        self
    }

    /// True once `best` meets the target, if any.
    #[inline]
    pub fn target_met(&self, best: f64) -> bool {
        matches!(self.target, Some(t) if best <= t)
    }

    /// The stop reason implied by the current state.
    #[inline]
    pub fn reason(&self, evaluations: usize, best: f64) -> Option<StopReason> {
        if self.target_met(best) {
            Some(StopReason::TargetReached)
        } else if evaluations >= self.max_evaluations {
            Some(StopReason::BudgetExhausted)
        } else {
            None
        }
    }
}

impl Default for Termination {
    fn default() -> Self {
        Termination::budget(1000)
    }
}