solverforge_solver/phase/construction/
forager.rs1use std::fmt::Debug;
13use std::marker::PhantomData;
14
15use solverforge_config::ConstructionObligation;
16use solverforge_core::domain::PlanningSolution;
17use solverforge_scoring::Director;
18
19use crate::heuristic::r#move::Move;
20use crate::scope::{ProgressCallback, StepScope};
21
22use super::Placement;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum ConstructionChoice {
27 KeepCurrent,
28 Select(usize),
29}
30
31pub trait ConstructionForager<S, M>: Send + Debug
40where
41 S: PlanningSolution,
42 M: Move<S>,
43{
44 fn pick_move_index<D: Director<S>>(
47 &self,
48 placement: &Placement<S, M>,
49 score_director: &mut D,
50 ) -> ConstructionChoice;
51
52 fn select_move_index<D, BestCb>(
53 &self,
54 placement: &Placement<S, M>,
55 _construction_obligation: ConstructionObligation,
56 step_scope: &mut StepScope<'_, '_, '_, S, D, BestCb>,
57 ) -> Option<ConstructionChoice>
58 where
59 D: Director<S>,
60 BestCb: ProgressCallback<S>,
61 {
62 Some(self.pick_move_index(placement, step_scope.score_director_mut()))
63 }
64}
65
66pub struct FirstFitForager<S, M> {
71 _phantom: PhantomData<fn() -> (S, M)>,
72}
73
74impl<S, M> Clone for FirstFitForager<S, M> {
75 fn clone(&self) -> Self {
76 *self
77 }
78}
79
80impl<S, M> Copy for FirstFitForager<S, M> {}
81
82impl<S, M> Default for FirstFitForager<S, M> {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl<S, M> Debug for FirstFitForager<S, M> {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 f.debug_struct("FirstFitForager").finish()
91 }
92}
93
94impl<S, M> FirstFitForager<S, M> {
95 pub fn new() -> Self {
96 Self {
97 _phantom: PhantomData,
98 }
99 }
100}
101
102pub struct BestFitForager<S, M> {
108 _phantom: PhantomData<fn() -> (S, M)>,
109}
110
111impl<S, M> Clone for BestFitForager<S, M> {
112 fn clone(&self) -> Self {
113 *self
114 }
115}
116
117impl<S, M> Copy for BestFitForager<S, M> {}
118
119impl<S, M> Default for BestFitForager<S, M> {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124
125impl<S, M> Debug for BestFitForager<S, M> {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 f.debug_struct("BestFitForager").finish()
128 }
129}
130
131impl<S, M> BestFitForager<S, M> {
132 pub fn new() -> Self {
133 Self {
134 _phantom: PhantomData,
135 }
136 }
137}
138
139pub struct FirstFeasibleForager<S, M> {
144 _phantom: PhantomData<fn() -> (S, M)>,
145}
146
147impl<S, M> Clone for FirstFeasibleForager<S, M> {
148 fn clone(&self) -> Self {
149 *self
150 }
151}
152
153impl<S, M> Copy for FirstFeasibleForager<S, M> {}
154
155impl<S, M> Default for FirstFeasibleForager<S, M> {
156 fn default() -> Self {
157 Self::new()
158 }
159}
160
161impl<S, M> Debug for FirstFeasibleForager<S, M> {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 f.debug_struct("FirstFeasibleForager").finish()
164 }
165}
166
167impl<S, M> FirstFeasibleForager<S, M> {
168 pub fn new() -> Self {
169 Self {
170 _phantom: PhantomData,
171 }
172 }
173}
174
175pub struct WeakestFitForager<S, M> {
181 strength_fn: fn(&M, &S) -> i64,
183 _phantom: PhantomData<fn() -> S>,
184}
185
186impl<S, M> Clone for WeakestFitForager<S, M> {
187 fn clone(&self) -> Self {
188 *self
189 }
190}
191
192impl<S, M> Copy for WeakestFitForager<S, M> {}
193
194impl<S, M> Debug for WeakestFitForager<S, M> {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 f.debug_struct("WeakestFitForager").finish()
197 }
198}
199
200impl<S, M> WeakestFitForager<S, M> {
201 pub fn new(strength_fn: fn(&M, &S) -> i64) -> Self {
206 Self {
207 strength_fn,
208 _phantom: PhantomData,
209 }
210 }
211
212 pub(crate) fn strength(&self, mov: &M, solution: &S) -> i64 {
213 (self.strength_fn)(mov, solution)
214 }
215}
216
217pub struct StrongestFitForager<S, M> {
223 strength_fn: fn(&M, &S) -> i64,
225 _phantom: PhantomData<fn() -> S>,
226}
227
228impl<S, M> Clone for StrongestFitForager<S, M> {
229 fn clone(&self) -> Self {
230 *self
231 }
232}
233
234impl<S, M> Copy for StrongestFitForager<S, M> {}
235
236impl<S, M> Debug for StrongestFitForager<S, M> {
237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238 f.debug_struct("StrongestFitForager").finish()
239 }
240}
241
242impl<S, M> StrongestFitForager<S, M> {
243 pub fn new(strength_fn: fn(&M, &S) -> i64) -> Self {
248 Self {
249 strength_fn,
250 _phantom: PhantomData,
251 }
252 }
253
254 pub(crate) fn strength(&self, mov: &M, solution: &S) -> i64 {
255 (self.strength_fn)(mov, solution)
256 }
257}
258
259#[cfg(test)]
260mod tests;