solverforge_solver/phase/localsearch/acceptor/
great_deluge.rs1use std::fmt::Debug;
4
5use solverforge_core::domain::PlanningSolution;
6use solverforge_core::score::Score;
7
8use super::Acceptor;
9use crate::heuristic::r#move::MoveTabuSignature;
10
11pub struct GreatDelugeAcceptor<S: PlanningSolution> {
42 rain_speed: f64,
44 water_level: Option<S::Score>,
46 initial_abs_score: Option<S::Score>,
48}
49
50impl<S: PlanningSolution> Debug for GreatDelugeAcceptor<S> {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 f.debug_struct("GreatDelugeAcceptor")
53 .field("rain_speed", &self.rain_speed)
54 .finish()
55 }
56}
57
58impl<S: PlanningSolution> Clone for GreatDelugeAcceptor<S> {
59 fn clone(&self) -> Self {
60 Self {
61 rain_speed: self.rain_speed,
62 water_level: self.water_level,
63 initial_abs_score: self.initial_abs_score,
64 }
65 }
66}
67
68impl<S: PlanningSolution> GreatDelugeAcceptor<S> {
69 pub fn new(rain_speed: f64) -> Self {
75 Self {
76 rain_speed,
77 water_level: None,
78 initial_abs_score: None,
79 }
80 }
81}
82
83impl<S: PlanningSolution> Default for GreatDelugeAcceptor<S> {
84 fn default() -> Self {
85 Self::new(0.001)
86 }
87}
88
89impl<S: PlanningSolution> Acceptor<S> for GreatDelugeAcceptor<S> {
90 fn is_accepted(
91 &mut self,
92 last_step_score: &S::Score,
93 move_score: &S::Score,
94 _move_signature: Option<&MoveTabuSignature>,
95 ) -> bool {
96 if move_score > last_step_score {
98 return true;
99 }
100
101 match &self.water_level {
103 Some(water_level) => move_score >= water_level,
104 None => true, }
106 }
107
108 fn phase_started(&mut self, initial_score: &S::Score) {
109 self.water_level = Some(*initial_score);
110 self.initial_abs_score = Some(initial_score.abs());
111 }
112
113 fn step_ended(
114 &mut self,
115 _step_score: &S::Score,
116 _accepted_move_signature: Option<&MoveTabuSignature>,
117 ) {
118 if let (Some(water), Some(abs_score)) = (&self.water_level, &self.initial_abs_score) {
120 let increment = abs_score.multiply(self.rain_speed);
121 self.water_level = Some(*water + increment);
122 }
123 }
124
125 fn phase_ended(&mut self) {
126 self.water_level = None;
127 self.initial_abs_score = None;
128 }
129}
130
131#[cfg(test)]
132mod tests;