solverforge_solver/heuristic/selector/move_selector/
swap.rs1pub struct SwapMoveSelector<S, V, LES, RES> {
3 left_entity_selector: LES,
4 right_entity_selector: RES,
5 getter: fn(&S, usize, usize) -> Option<V>,
6 setter: fn(&mut S, usize, usize, Option<V>),
7 descriptor_index: usize,
8 variable_index: usize,
9 variable_name: &'static str,
10 _phantom: PhantomData<(fn() -> S, fn() -> V)>,
11}
12
13impl<S, V, LES: Debug, RES: Debug> Debug for SwapMoveSelector<S, V, LES, RES> {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 f.debug_struct("SwapMoveSelector")
16 .field("left_entity_selector", &self.left_entity_selector)
17 .field("right_entity_selector", &self.right_entity_selector)
18 .field("descriptor_index", &self.descriptor_index)
19 .field("variable_index", &self.variable_index)
20 .field("variable_name", &self.variable_name)
21 .finish()
22 }
23}
24
25impl<S: PlanningSolution, V, LES, RES> SwapMoveSelector<S, V, LES, RES> {
26 pub fn new(
27 left_entity_selector: LES,
28 right_entity_selector: RES,
29 getter: fn(&S, usize, usize) -> Option<V>,
30 setter: fn(&mut S, usize, usize, Option<V>),
31 descriptor_index: usize,
32 variable_index: usize,
33 variable_name: &'static str,
34 ) -> Self {
35 Self {
36 left_entity_selector,
37 right_entity_selector,
38 getter,
39 setter,
40 descriptor_index,
41 variable_index,
42 variable_name,
43 _phantom: PhantomData,
44 }
45 }
46}
47
48impl<S: PlanningSolution, V>
49 SwapMoveSelector<S, V, FromSolutionEntitySelector, FromSolutionEntitySelector>
50{
51 pub fn simple(
52 getter: fn(&S, usize, usize) -> Option<V>,
53 setter: fn(&mut S, usize, usize, Option<V>),
54 descriptor_index: usize,
55 variable_index: usize,
56 variable_name: &'static str,
57 ) -> Self {
58 Self {
59 left_entity_selector: FromSolutionEntitySelector::new(descriptor_index),
60 right_entity_selector: FromSolutionEntitySelector::new(descriptor_index),
61 getter,
62 setter,
63 descriptor_index,
64 variable_index,
65 variable_name,
66 _phantom: PhantomData,
67 }
68 }
69}
70
71impl<S, V, LES, RES> MoveSelector<S, SwapMove<S, V>> for SwapMoveSelector<S, V, LES, RES>
72where
73 S: PlanningSolution,
74 V: Clone + PartialEq + Send + Sync + Debug + 'static,
75 LES: EntitySelector<S>,
76 RES: EntitySelector<S>,
77{
78 type Cursor<'a>
79 = ArenaMoveCursor<S, SwapMove<S, V>>
80 where
81 Self: 'a;
82
83 fn open_cursor<'a, D: Director<S>>(&'a self, score_director: &D) -> Self::Cursor<'a> {
84 let getter = self.getter;
85 let setter = self.setter;
86 let variable_index = self.variable_index;
87 let variable_name = self.variable_name;
88 let descriptor_index = self.descriptor_index;
89 let right_entities: Vec<_> = self.right_entity_selector.iter(score_director).collect();
90 let mut moves = Vec::new();
91 for left_entity_ref in self.left_entity_selector.iter(score_director) {
92 for right_entity_ref in &right_entities {
93 if left_entity_ref.entity_index < right_entity_ref.entity_index {
94 moves.push(SwapMove::new(
95 left_entity_ref.entity_index,
96 right_entity_ref.entity_index,
97 getter,
98 setter,
99 variable_index,
100 variable_name,
101 descriptor_index,
102 ));
103 }
104 }
105 }
106 ArenaMoveCursor::from_moves(moves)
107 }
108
109 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
110 let left_count = self.left_entity_selector.iter(score_director).count();
111 let right_count = self.right_entity_selector.iter(score_director).count();
112 left_count.saturating_mul(right_count.saturating_sub(1)) / 2
113 }
114}