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::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}