Skip to main content

solverforge_solver/heuristic/selector/move_selector/
either.rs

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