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