solverforge_solver/heuristic/selector/move_selector/
either.rs1use std::fmt::Debug;
2
3use solverforge_core::domain::PlanningSolution;
4use solverforge_scoring::Director;
5
6use crate::heuristic::r#move::EitherMove;
7
8use super::super::entity::{EntitySelector, FromSolutionEntitySelector};
9use super::super::value_selector::{StaticValueSelector, ValueSelector};
10use super::{ChangeMoveSelector, MoveSelector, SwapMoveSelector};
11
12pub struct EitherChangeMoveSelector<S, V, ES, VS> {
13 inner: ChangeMoveSelector<S, V, ES, VS>,
14}
15
16impl<S, V: Debug, ES: Debug, VS: Debug> Debug for EitherChangeMoveSelector<S, V, ES, VS> {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 f.debug_struct("EitherChangeMoveSelector")
19 .field("inner", &self.inner)
20 .finish()
21 }
22}
23
24impl<S: PlanningSolution, V: Clone + Send + Sync + Debug + 'static>
25 EitherChangeMoveSelector<S, V, FromSolutionEntitySelector, StaticValueSelector<S, V>>
26{
27 pub fn simple(
28 getter: fn(&S, usize) -> Option<V>,
29 setter: fn(&mut S, usize, Option<V>),
30 descriptor_index: usize,
31 variable_name: &'static str,
32 values: Vec<V>,
33 ) -> Self {
34 Self {
35 inner: ChangeMoveSelector::simple(
36 getter,
37 setter,
38 descriptor_index,
39 variable_name,
40 values,
41 ),
42 }
43 }
44}
45
46impl<S, V, ES, VS> MoveSelector<S, EitherMove<S, V>> for EitherChangeMoveSelector<S, V, ES, VS>
47where
48 S: PlanningSolution,
49 V: Clone + PartialEq + Send + Sync + Debug + 'static,
50 ES: EntitySelector<S>,
51 VS: ValueSelector<S, V>,
52{
53 fn iter_moves<'a, D: Director<S>>(
54 &'a self,
55 score_director: &'a D,
56 ) -> impl Iterator<Item = EitherMove<S, V>> + 'a {
57 self.inner
58 .iter_moves(score_director)
59 .map(EitherMove::Change)
60 }
61
62 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
63 self.inner.size(score_director)
64 }
65}
66
67pub struct EitherSwapMoveSelector<S, V, LES, RES> {
68 inner: SwapMoveSelector<S, V, LES, RES>,
69}
70
71impl<S, V: Debug, LES: Debug, RES: Debug> Debug for EitherSwapMoveSelector<S, V, LES, RES> {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 f.debug_struct("EitherSwapMoveSelector")
74 .field("inner", &self.inner)
75 .finish()
76 }
77}
78
79impl<S: PlanningSolution, V>
80 EitherSwapMoveSelector<S, V, FromSolutionEntitySelector, FromSolutionEntitySelector>
81{
82 pub fn simple(
83 getter: fn(&S, usize) -> Option<V>,
84 setter: fn(&mut S, usize, Option<V>),
85 descriptor_index: usize,
86 variable_name: &'static str,
87 ) -> Self {
88 Self {
89 inner: SwapMoveSelector::simple(getter, setter, descriptor_index, variable_name),
90 }
91 }
92}
93
94impl<S, V, LES, RES> MoveSelector<S, EitherMove<S, V>> for EitherSwapMoveSelector<S, V, LES, RES>
95where
96 S: PlanningSolution,
97 V: Clone + PartialEq + Send + Sync + Debug + 'static,
98 LES: EntitySelector<S>,
99 RES: EntitySelector<S>,
100{
101 fn iter_moves<'a, D: Director<S>>(
102 &'a self,
103 score_director: &'a D,
104 ) -> impl Iterator<Item = EitherMove<S, V>> + 'a {
105 self.inner.iter_moves(score_director).map(EitherMove::Swap)
106 }
107
108 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
109 self.inner.size(score_director)
110 }
111}