math_audio_optimisation/
external_archive.rs1use ndarray::Array1;
7
8#[derive(Debug, Clone)]
10pub struct ExternalArchive {
11 solutions: Vec<Array1<f64>>,
13 max_size: usize,
15}
16
17impl ExternalArchive {
18 pub fn new(max_size: usize) -> Self {
20 Self {
21 solutions: Vec::with_capacity(max_size),
22 max_size,
23 }
24 }
25
26 pub fn with_population_size(np: usize, arc_rate: f64) -> Self {
28 let max_size = (arc_rate * np as f64).ceil() as usize;
29 Self::new(max_size.max(1))
30 }
31
32 pub fn add(&mut self, solution: Array1<f64>) {
35 if self.solutions.len() < self.max_size {
36 self.solutions.push(solution);
37 } else if self.max_size > 0 {
38 use rand::Rng;
39 let mut rng = rand::rng();
40 let idx = rng.random_range(0..self.max_size);
41 self.solutions[idx] = solution;
42 }
43 }
44
45 pub fn random_select<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Option<&Array1<f64>> {
48 if self.solutions.is_empty() {
49 None
50 } else {
51 let idx = rng.random_range(0..self.solutions.len());
52 Some(&self.solutions[idx])
53 }
54 }
55
56 pub fn random_index<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Option<usize> {
59 if self.solutions.is_empty() {
60 None
61 } else {
62 Some(rng.random_range(0..self.solutions.len()))
63 }
64 }
65
66 pub fn get(&self, idx: usize) -> Option<&Array1<f64>> {
68 self.solutions.get(idx)
69 }
70
71 pub fn len(&self) -> usize {
73 self.solutions.len()
74 }
75
76 pub fn is_empty(&self) -> bool {
78 self.solutions.is_empty()
79 }
80
81 pub fn clear(&mut self) {
83 self.solutions.clear();
84 }
85
86 pub fn resize(&mut self, new_max_size: usize) {
88 self.max_size = new_max_size;
89 if self.solutions.len() > new_max_size {
90 self.solutions.truncate(new_max_size);
91 }
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use ndarray::array;
99
100 #[test]
101 fn test_archive_basic() {
102 let mut archive = ExternalArchive::new(5);
103 assert!(archive.is_empty());
104
105 archive.add(array![1.0, 2.0]);
106 archive.add(array![3.0, 4.0]);
107 assert_eq!(archive.len(), 2);
108 }
109
110 #[test]
111 fn test_archive_full() {
112 let mut archive = ExternalArchive::new(2);
113 archive.add(array![1.0]);
114 archive.add(array![2.0]);
115 archive.add(array![3.0]);
116 assert_eq!(archive.len(), 2);
117 }
118
119 #[test]
120 fn test_archive_select() {
121 let mut archive = ExternalArchive::new(5);
122 archive.add(array![1.0, 2.0]);
123 archive.add(array![3.0, 4.0]);
124
125 let mut rng = rand::rng();
126 let selected = archive.random_select(&mut rng);
127 assert!(selected.is_some());
128 }
129}