1use std::fmt::Debug;
2
3use solverforge_core::domain::PlanningSolution;
4use solverforge_scoring::Director;
5
6use crate::heuristic::r#move::{ListMoveImpl, MoveArena};
7use crate::heuristic::selector::move_selector::{
8 ListMoveKOptSelector, ListMoveListChangeSelector, ListMoveListRuinSelector,
9 ListMoveNearbyKOptSelector, MoveSelector,
10};
11use crate::heuristic::selector::nearby_list_change::CrossEntityDistanceMeter;
12use crate::heuristic::selector::{
13 FromSolutionEntitySelector, ListMoveListReverseSelector, ListMoveListSwapSelector,
14 ListMoveNearbyListChangeSelector, ListMoveNearbyListSwapSelector,
15 ListMoveSubListChangeSelector, ListMoveSubListSwapSelector,
16};
17
18use super::super::context::IntraDistanceAdapter;
19
20pub enum ListLeafSelector<S, V, DM, IDM>
26where
27 S: PlanningSolution,
28 V: Clone + PartialEq + Send + Sync + Debug + 'static,
29 DM: CrossEntityDistanceMeter<S>,
30 IDM: CrossEntityDistanceMeter<S>,
31{
32 NearbyListChange(ListMoveNearbyListChangeSelector<S, V, DM, FromSolutionEntitySelector>),
33 NearbyListSwap(ListMoveNearbyListSwapSelector<S, V, DM, FromSolutionEntitySelector>),
34 ListReverse(ListMoveListReverseSelector<S, V, FromSolutionEntitySelector>),
35 SubListChange(ListMoveSubListChangeSelector<S, V, FromSolutionEntitySelector>),
36 KOpt(ListMoveKOptSelector<S, V, FromSolutionEntitySelector>),
37 NearbyKOpt(
38 ListMoveNearbyKOptSelector<S, V, IntraDistanceAdapter<IDM>, FromSolutionEntitySelector>,
39 ),
40 ListRuin(ListMoveListRuinSelector<S, V>),
41 ListChange(ListMoveListChangeSelector<S, V, FromSolutionEntitySelector>),
42 ListSwap(ListMoveListSwapSelector<S, V, FromSolutionEntitySelector>),
43 SubListSwap(ListMoveSubListSwapSelector<S, V, FromSolutionEntitySelector>),
44}
45
46impl<S, V, DM, IDM> Debug for ListLeafSelector<S, V, DM, IDM>
47where
48 S: PlanningSolution,
49 V: Clone + PartialEq + Send + Sync + Debug + 'static,
50 DM: CrossEntityDistanceMeter<S>,
51 IDM: CrossEntityDistanceMeter<S>,
52{
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 match self {
55 Self::NearbyListChange(s) => write!(f, "ListLeafSelector::NearbyListChange({s:?})"),
56 Self::NearbyListSwap(s) => write!(f, "ListLeafSelector::NearbyListSwap({s:?})"),
57 Self::ListReverse(s) => write!(f, "ListLeafSelector::ListReverse({s:?})"),
58 Self::SubListChange(s) => write!(f, "ListLeafSelector::SubListChange({s:?})"),
59 Self::KOpt(s) => write!(f, "ListLeafSelector::KOpt({s:?})"),
60 Self::NearbyKOpt(s) => write!(f, "ListLeafSelector::NearbyKOpt({s:?})"),
61 Self::ListRuin(s) => write!(f, "ListLeafSelector::ListRuin({s:?})"),
62 Self::ListChange(s) => write!(f, "ListLeafSelector::ListChange({s:?})"),
63 Self::ListSwap(s) => write!(f, "ListLeafSelector::ListSwap({s:?})"),
64 Self::SubListSwap(s) => write!(f, "ListLeafSelector::SubListSwap({s:?})"),
65 }
66 }
67}
68
69impl<S, V, DM, IDM> MoveSelector<S, ListMoveImpl<S, V>> for ListLeafSelector<S, V, DM, IDM>
70where
71 S: PlanningSolution,
72 V: Clone + PartialEq + Send + Sync + Debug + 'static,
73 DM: CrossEntityDistanceMeter<S>,
74 IDM: CrossEntityDistanceMeter<S> + 'static,
75{
76 fn iter_moves<'a, D: Director<S>>(
77 &'a self,
78 score_director: &'a D,
79 ) -> impl Iterator<Item = ListMoveImpl<S, V>> + 'a {
80 enum ListLeafIter<A, B, C, DIter, E, F, G, H, I, J> {
81 NearbyListChange(A),
82 NearbyListSwap(B),
83 ListReverse(C),
84 SubListChange(DIter),
85 KOpt(E),
86 NearbyKOpt(F),
87 ListRuin(G),
88 ListChange(H),
89 ListSwap(I),
90 SubListSwap(J),
91 }
92
93 impl<T, A, B, C, DIter, E, F, G, H, I, J> Iterator
94 for ListLeafIter<A, B, C, DIter, E, F, G, H, I, J>
95 where
96 A: Iterator<Item = T>,
97 B: Iterator<Item = T>,
98 C: Iterator<Item = T>,
99 DIter: Iterator<Item = T>,
100 E: Iterator<Item = T>,
101 F: Iterator<Item = T>,
102 G: Iterator<Item = T>,
103 H: Iterator<Item = T>,
104 I: Iterator<Item = T>,
105 J: Iterator<Item = T>,
106 {
107 type Item = T;
108
109 fn next(&mut self) -> Option<Self::Item> {
110 match self {
111 Self::NearbyListChange(iter) => iter.next(),
112 Self::NearbyListSwap(iter) => iter.next(),
113 Self::ListReverse(iter) => iter.next(),
114 Self::SubListChange(iter) => iter.next(),
115 Self::KOpt(iter) => iter.next(),
116 Self::NearbyKOpt(iter) => iter.next(),
117 Self::ListRuin(iter) => iter.next(),
118 Self::ListChange(iter) => iter.next(),
119 Self::ListSwap(iter) => iter.next(),
120 Self::SubListSwap(iter) => iter.next(),
121 }
122 }
123 }
124
125 match self {
126 Self::NearbyListChange(s) => {
127 ListLeafIter::NearbyListChange(s.iter_moves(score_director))
128 }
129 Self::NearbyListSwap(s) => ListLeafIter::NearbyListSwap(s.iter_moves(score_director)),
130 Self::ListReverse(s) => ListLeafIter::ListReverse(s.iter_moves(score_director)),
131 Self::SubListChange(s) => ListLeafIter::SubListChange(s.iter_moves(score_director)),
132 Self::KOpt(s) => ListLeafIter::KOpt(s.iter_moves(score_director)),
133 Self::NearbyKOpt(s) => ListLeafIter::NearbyKOpt(s.iter_moves(score_director)),
134 Self::ListRuin(s) => ListLeafIter::ListRuin(s.iter_moves(score_director)),
135 Self::ListChange(s) => ListLeafIter::ListChange(s.iter_moves(score_director)),
136 Self::ListSwap(s) => ListLeafIter::ListSwap(s.iter_moves(score_director)),
137 Self::SubListSwap(s) => ListLeafIter::SubListSwap(s.iter_moves(score_director)),
138 }
139 }
140
141 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
142 match self {
143 Self::NearbyListChange(s) => s.size(score_director),
144 Self::NearbyListSwap(s) => s.size(score_director),
145 Self::ListReverse(s) => s.size(score_director),
146 Self::SubListChange(s) => s.size(score_director),
147 Self::KOpt(s) => s.size(score_director),
148 Self::NearbyKOpt(s) => s.size(score_director),
149 Self::ListRuin(s) => s.size(score_director),
150 Self::ListChange(s) => s.size(score_director),
151 Self::ListSwap(s) => s.size(score_director),
152 Self::SubListSwap(s) => s.size(score_director),
153 }
154 }
155
156 fn append_moves<D: Director<S>>(
157 &self,
158 score_director: &D,
159 arena: &mut MoveArena<ListMoveImpl<S, V>>,
160 ) {
161 match self {
162 Self::NearbyListChange(s) => arena.extend(s.iter_moves(score_director)),
163 Self::NearbyListSwap(s) => arena.extend(s.iter_moves(score_director)),
164 Self::ListReverse(s) => arena.extend(s.iter_moves(score_director)),
165 Self::SubListChange(s) => arena.extend(s.iter_moves(score_director)),
166 Self::KOpt(s) => arena.extend(s.iter_moves(score_director)),
167 Self::NearbyKOpt(s) => arena.extend(s.iter_moves(score_director)),
168 Self::ListRuin(s) => arena.extend(s.iter_moves(score_director)),
169 Self::ListChange(s) => arena.extend(s.iter_moves(score_director)),
170 Self::ListSwap(s) => arena.extend(s.iter_moves(score_director)),
171 Self::SubListSwap(s) => arena.extend(s.iter_moves(score_director)),
172 }
173 }
174}