solverforge_solver/heuristic/selector/selection_order.rs
1/* Selection order configuration for selectors.
2
3Defines the order in which elements are selected from a selector.
4*/
5
6/* Defines the order in which elements are selected from a selector.
7
8This enum controls how entities, values, or moves are ordered when
9iterating through a selector.
10*/
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
12pub enum SelectionOrder {
13 /* Inherit the selection order from the parent configuration.
14
15 If the parent is cached, defaults to `Original`.
16 If there is no parent, defaults to `Random`.
17 */
18 #[default]
19 Inherit,
20
21 /* Select elements in their original order.
22
23 Elements are returned in the order they appear in the underlying
24 collection. This is deterministic and reproducible.
25 */
26 Original,
27
28 /* Select elements in random order without shuffling.
29
30 Elements are selected randomly from the pool on each call to next().
31 The same element may be selected multiple times.
32 This scales well because it does not require caching.
33 */
34 Random,
35
36 /* Select elements in random order by shuffling.
37
38 Elements are shuffled when a selection iterator is created.
39 Each element will be selected exactly once (if all elements are consumed).
40 Requires caching (at least step-level).
41 */
42 Shuffled,
43
44 /* Select elements in sorted order.
45
46 Elements are sorted according to a sorter before iteration.
47 Each element will be selected exactly once (if all elements are consumed).
48 Requires caching (at least step-level).
49 */
50 Sorted,
51
52 /* Select elements based on probability weights.
53
54 Elements with higher probability have a greater chance of being selected.
55 The same element may be selected multiple times.
56 Requires caching (at least step-level).
57 */
58 Probabilistic,
59}
60
61impl SelectionOrder {
62 /// Resolves the selection order by inheriting from a parent if necessary.
63 ///
64 /// # Arguments
65 ///
66 /// * `inherited` - The selection order to inherit from if this is `Inherit`
67 ///
68 /// # Returns
69 ///
70 /// The resolved selection order (never `Inherit`)
71 pub fn resolve(self, inherited: SelectionOrder) -> SelectionOrder {
72 match self {
73 SelectionOrder::Inherit => {
74 if inherited == SelectionOrder::Inherit {
75 SelectionOrder::Random
76 } else {
77 inherited
78 }
79 }
80 other => other,
81 }
82 }
83
84 /// Returns `true` if this selection order implies random selection.
85 ///
86 /// This is used to determine whether a selector should use random iteration
87 /// or deterministic iteration.
88 pub fn is_random(&self) -> bool {
89 matches!(
90 self,
91 SelectionOrder::Random | SelectionOrder::Shuffled | SelectionOrder::Probabilistic
92 )
93 }
94
95 /// Returns `true` if this selection order requires caching.
96 ///
97 /// Some selection orders need to collect all elements before iteration
98 /// can begin (e.g., Shuffled, Sorted, Probabilistic).
99 pub fn requires_caching(&self) -> bool {
100 matches!(
101 self,
102 SelectionOrder::Shuffled | SelectionOrder::Sorted | SelectionOrder::Probabilistic
103 )
104 }
105
106 /// Converts from a boolean random selection flag.
107 ///
108 /// # Arguments
109 ///
110 /// * `random` - `true` for `Random`, `false` for `Original`
111 pub fn from_random_selection(random: bool) -> Self {
112 if random {
113 SelectionOrder::Random
114 } else {
115 SelectionOrder::Original
116 }
117 }
118
119 /// Converts to a boolean random selection flag.
120 ///
121 /// # Panics
122 ///
123 /// Panics if this is not `Random` or `Original`.
124 pub fn to_random_selection(&self) -> bool {
125 match self {
126 SelectionOrder::Random => true,
127 SelectionOrder::Original => false,
128 _ => panic!(
129 "Selection order {:?} cannot be converted to a random selection boolean",
130 self
131 ),
132 }
133 }
134}
135
136#[cfg(test)]
137#[path = "selection_order_tests.rs"]
138mod tests;