solverforge_solver/scope/
phase.rs1use std::time::Instant;
4
5use solverforge_core::domain::PlanningSolution;
6use solverforge_scoring::Director;
7
8use super::solver::BestSolutionCallback;
9use super::SolverScope;
10use crate::stats::PhaseStats;
11
12pub struct PhaseScope<'t, 'a, S: PlanningSolution, D: Director<S>, BestCb = ()> {
21 solver_scope: &'a mut SolverScope<'t, S, D, BestCb>,
23 phase_index: usize,
25 starting_score: Option<S::Score>,
27 step_count: u64,
29 start_time: Instant,
31 stats: PhaseStats,
33}
34
35impl<'t, 'a, S: PlanningSolution, D: Director<S>, BestCb: BestSolutionCallback<S>>
36 PhaseScope<'t, 'a, S, D, BestCb>
37{
38 pub fn new(solver_scope: &'a mut SolverScope<'t, S, D, BestCb>, phase_index: usize) -> Self {
39 let starting_score = solver_scope.best_score().cloned();
40 Self {
41 solver_scope,
42 phase_index,
43 starting_score,
44 step_count: 0,
45 start_time: Instant::now(),
46 stats: PhaseStats::new(phase_index, "Unknown"),
47 }
48 }
49
50 pub fn with_phase_type(
51 solver_scope: &'a mut SolverScope<'t, S, D, BestCb>,
52 phase_index: usize,
53 phase_type: &'static str,
54 ) -> Self {
55 let starting_score = solver_scope.best_score().cloned();
56 Self {
57 solver_scope,
58 phase_index,
59 starting_score,
60 step_count: 0,
61 start_time: Instant::now(),
62 stats: PhaseStats::new(phase_index, phase_type),
63 }
64 }
65
66 pub fn phase_index(&self) -> usize {
67 self.phase_index
68 }
69
70 pub fn starting_score(&self) -> Option<&S::Score> {
71 self.starting_score.as_ref()
72 }
73
74 pub fn elapsed(&self) -> std::time::Duration {
75 self.start_time.elapsed()
76 }
77
78 pub fn step_count(&self) -> u64 {
79 self.step_count
80 }
81
82 pub fn increment_step_count(&mut self) -> u64 {
84 self.step_count += 1;
85 self.solver_scope.increment_step_count();
86 self.step_count
87 }
88
89 pub fn solver_scope(&self) -> &SolverScope<'t, S, D, BestCb> {
90 self.solver_scope
91 }
92
93 pub fn solver_scope_mut(&mut self) -> &mut SolverScope<'t, S, D, BestCb> {
94 self.solver_scope
95 }
96
97 pub fn score_director(&self) -> &D {
98 self.solver_scope.score_director()
99 }
100
101 pub fn score_director_mut(&mut self) -> &mut D {
102 self.solver_scope.score_director_mut()
103 }
104
105 pub fn calculate_score(&mut self) -> S::Score {
107 self.solver_scope.calculate_score()
108 }
109
110 pub fn update_best_solution(&mut self) {
112 self.solver_scope.update_best_solution()
113 }
114
115 pub fn stats(&self) -> &PhaseStats {
116 &self.stats
117 }
118
119 pub fn stats_mut(&mut self) -> &mut PhaseStats {
120 &mut self.stats
121 }
122}