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