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 {
40 let starting_score = solver_scope.best_score().cloned();
41 Self {
42 solver_scope,
43 phase_index,
44 starting_score,
45 step_count: 0,
46 start_time: Instant::now(),
47 stats: PhaseStats::new(phase_index, "Unknown"),
48 }
49 }
50
51 pub fn with_phase_type(
53 solver_scope: &'a mut SolverScope<'t, S, D, BestCb>,
54 phase_index: usize,
55 phase_type: &'static str,
56 ) -> Self {
57 let starting_score = solver_scope.best_score().cloned();
58 Self {
59 solver_scope,
60 phase_index,
61 starting_score,
62 step_count: 0,
63 start_time: Instant::now(),
64 stats: PhaseStats::new(phase_index, phase_type),
65 }
66 }
67
68 pub fn phase_index(&self) -> usize {
70 self.phase_index
71 }
72
73 pub fn starting_score(&self) -> Option<&S::Score> {
75 self.starting_score.as_ref()
76 }
77
78 pub fn elapsed(&self) -> std::time::Duration {
80 self.start_time.elapsed()
81 }
82
83 pub fn step_count(&self) -> u64 {
85 self.step_count
86 }
87
88 pub fn increment_step_count(&mut self) -> u64 {
90 self.step_count += 1;
91 self.solver_scope.increment_step_count();
92 self.step_count
93 }
94
95 pub fn solver_scope(&self) -> &SolverScope<'t, S, D, BestCb> {
97 self.solver_scope
98 }
99
100 pub fn solver_scope_mut(&mut self) -> &mut SolverScope<'t, S, D, BestCb> {
102 self.solver_scope
103 }
104
105 pub fn score_director(&self) -> &D {
107 self.solver_scope.score_director()
108 }
109
110 pub fn score_director_mut(&mut self) -> &mut D {
112 self.solver_scope.score_director_mut()
113 }
114
115 pub fn calculate_score(&mut self) -> S::Score {
117 self.solver_scope.calculate_score()
118 }
119
120 pub fn update_best_solution(&mut self) {
122 self.solver_scope.update_best_solution()
123 }
124
125 pub fn stats(&self) -> &PhaseStats {
127 &self.stats
128 }
129
130 pub fn stats_mut(&mut self) -> &mut PhaseStats {
132 &mut self.stats
133 }
134}