solverforge_solver/termination/
score_calculation_count.rs

1//! Score calculation count termination.
2
3use std::fmt::Debug;
4use std::marker::PhantomData;
5
6use solverforge_core::domain::PlanningSolution;
7use solverforge_scoring::ScoreDirector;
8
9use super::Termination;
10use crate::scope::SolverScope;
11
12/// Terminates when a maximum number of score calculations is reached.
13///
14/// # Example
15///
16/// ```
17/// use solverforge_solver::termination::ScoreCalculationCountTermination;
18/// use solverforge_core::score::SimpleScore;
19/// use solverforge_core::domain::PlanningSolution;
20///
21/// #[derive(Clone)]
22/// struct MySolution;
23/// impl PlanningSolution for MySolution {
24///     type Score = SimpleScore;
25///     fn score(&self) -> Option<Self::Score> { None }
26///     fn set_score(&mut self, _: Option<Self::Score>) {}
27/// }
28///
29/// // Terminate after 10,000 score calculations
30/// let termination = ScoreCalculationCountTermination::<MySolution>::new(10_000);
31/// ```
32#[derive(Clone)]
33pub struct ScoreCalculationCountTermination<S: PlanningSolution> {
34    limit: u64,
35    _phantom: PhantomData<fn() -> S>,
36}
37
38impl<S: PlanningSolution> Debug for ScoreCalculationCountTermination<S> {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        f.debug_struct("ScoreCalculationCountTermination")
41            .field("limit", &self.limit)
42            .finish()
43    }
44}
45
46impl<S: PlanningSolution> ScoreCalculationCountTermination<S> {
47    /// Creates a new score calculation count termination.
48    ///
49    /// # Arguments
50    /// * `limit` - Maximum score calculations before terminating
51    pub fn new(limit: u64) -> Self {
52        Self {
53            limit,
54            _phantom: PhantomData,
55        }
56    }
57}
58
59impl<S: PlanningSolution, D: ScoreDirector<S>> Termination<S, D>
60    for ScoreCalculationCountTermination<S>
61{
62    fn is_terminated(&self, solver_scope: &SolverScope<'_, S, D>) -> bool {
63        solver_scope.stats().score_calculations >= self.limit
64    }
65}