solverforge_solver/heuristic/selector/
entity.rs1use std::fmt::Debug;
4
5use solverforge_core::domain::PlanningSolution;
6use solverforge_scoring::Director;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub struct EntityReference {
11 pub descriptor_index: usize,
13 pub entity_index: usize,
15}
16
17impl EntityReference {
18 pub fn new(descriptor_index: usize, entity_index: usize) -> Self {
19 Self {
20 descriptor_index,
21 entity_index,
22 }
23 }
24}
25
26pub trait EntitySelector<S: PlanningSolution>: Send + Debug {
34 fn iter<'a, D: Director<S>>(
40 &'a self,
41 score_director: &'a D,
42 ) -> impl Iterator<Item = EntityReference> + 'a;
43
44 fn size<D: Director<S>>(&self, score_director: &D) -> usize;
45
46 fn is_never_ending(&self) -> bool {
48 false
49 }
50}
51
52#[derive(Clone, Debug)]
54pub struct FromSolutionEntitySelector {
55 descriptor_index: usize,
57}
58
59impl FromSolutionEntitySelector {
60 pub fn new(descriptor_index: usize) -> Self {
61 Self { descriptor_index }
62 }
63}
64
65impl<S: PlanningSolution> EntitySelector<S> for FromSolutionEntitySelector {
66 fn iter<'a, D: Director<S>>(
67 &'a self,
68 score_director: &'a D,
69 ) -> impl Iterator<Item = EntityReference> + 'a {
70 let count = score_director
71 .entity_count(self.descriptor_index)
72 .unwrap_or(0);
73 let desc_idx = self.descriptor_index;
74 (0..count).map(move |i| EntityReference::new(desc_idx, i))
75 }
76
77 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
78 score_director
79 .entity_count(self.descriptor_index)
80 .unwrap_or(0)
81 }
82}
83
84#[derive(Debug, Clone, Default)]
86pub struct AllEntitiesSelector;
87
88impl AllEntitiesSelector {
89 pub fn new() -> Self {
90 Self
91 }
92}
93
94impl<S: PlanningSolution> EntitySelector<S> for AllEntitiesSelector {
95 fn iter<'a, D: Director<S>>(
96 &'a self,
97 score_director: &'a D,
98 ) -> impl Iterator<Item = EntityReference> + 'a {
99 let desc = score_director.solution_descriptor();
100 let descriptor_count = desc.entity_descriptors.len();
101
102 let mut refs = Vec::new();
103 for desc_idx in 0..descriptor_count {
104 let count = score_director.entity_count(desc_idx).unwrap_or(0);
105 for entity_idx in 0..count {
106 refs.push(EntityReference::new(desc_idx, entity_idx));
107 }
108 }
109
110 refs.into_iter()
111 }
112
113 fn size<D: Director<S>>(&self, score_director: &D) -> usize {
114 score_director.total_entity_count().unwrap_or(0)
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use crate::test_utils::create_simple_nqueens_director;
122
123 #[test]
124 fn test_from_solution_entity_selector() {
125 let director = create_simple_nqueens_director(4);
126
127 let solution = director.working_solution();
129 for (i, queen) in solution.queens.iter().enumerate() {
130 assert_eq!(queen.column, i as i64);
131 }
132
133 let selector = FromSolutionEntitySelector::new(0);
134
135 let refs: Vec<_> = selector.iter(&director).collect();
136 assert_eq!(refs.len(), 4);
137 assert_eq!(refs[0], EntityReference::new(0, 0));
138 assert_eq!(refs[1], EntityReference::new(0, 1));
139 assert_eq!(refs[2], EntityReference::new(0, 2));
140 assert_eq!(refs[3], EntityReference::new(0, 3));
141
142 assert_eq!(selector.size(&director), 4);
143 }
144
145 #[test]
146 fn test_all_entities_selector() {
147 let director = create_simple_nqueens_director(3);
148
149 let selector = AllEntitiesSelector::new();
150
151 let refs: Vec<_> = selector.iter(&director).collect();
152 assert_eq!(refs.len(), 3);
153
154 assert_eq!(selector.size(&director), 3);
155 }
156}