1use std::fmt;
2use std::ops::{Index, IndexMut};
3
4pub struct CompleteGraph<T> {
10 num_nodes: usize,
12 distances: Vec<T>,
15}
16
17impl<T: Clone + Default + PartialEq + fmt::Debug> CompleteGraph<T> {
18 pub fn new(num_nodes: usize) -> Self {
28 let size = num_nodes * num_nodes;
31 Self {
32 num_nodes,
33 distances: vec![T::default(); size],
34 }
35 }
36
37 pub fn from_vec(num_nodes: usize, distances: Vec<T>) -> Self {
53 let expected_size = num_nodes * num_nodes;
54 assert_eq!(
55 distances.len(),
56 expected_size,
57 "Vector length {} doesn't match expected size {} for {} nodes. For a complete graph with n nodes including diagonal elements, we need n*n distances.",
58 distances.len(),
59 expected_size,
60 num_nodes
61 );
62
63 Self {
64 num_nodes,
65 distances,
66 }
67 }
68
69 pub fn num_nodes(&self) -> usize {
71 self.num_nodes
72 }
73
74 #[inline(always)]
85 fn get_index(&self, i: usize, j: usize) -> usize {
86 i * self.num_nodes + j
87 }
88
89 pub fn get(&self, i: usize, j: usize) -> &T {
100 debug_assert!(
101 i < self.num_nodes && j < self.num_nodes,
102 "Node indices out of bounds"
103 );
104
105 let idx = self.get_index(i, j);
106 &self.distances[idx]
107 }
108
109 pub fn get_mut(&mut self, i: usize, j: usize) -> &mut T {
120 debug_assert!(
121 i < self.num_nodes && j < self.num_nodes,
122 "Node indices out of bounds"
123 );
124
125 let idx = self.get_index(i, j);
126 &mut self.distances[idx]
127 }
128}
129
130impl<T: Clone + Default + PartialEq + fmt::Debug> Index<(usize, usize)> for CompleteGraph<T> {
132 type Output = T;
133
134 fn index(&self, index: (usize, usize)) -> &Self::Output {
135 self.get(index.0, index.1)
136 }
137}
138
139impl<T: Clone + Default + PartialEq + fmt::Debug> IndexMut<(usize, usize)> for CompleteGraph<T> {
140 fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
141 if index.0 == index.1 {
142 panic!("Cannot modify diagonal");
143 }
144 self.get_mut(index.0, index.1)
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_complete_graph_creation() {
155 let graph: CompleteGraph<f32> = CompleteGraph::new(5);
156 assert_eq!(graph.num_nodes(), 5);
157 }
158
159 #[test]
160 fn test_diagonal_elements() {
161 let graph: CompleteGraph<i32> = CompleteGraph::new(4);
162
163 assert_eq!(graph[(0, 0)], 0);
165 assert_eq!(graph[(1, 1)], 0);
166 assert_eq!(graph[(2, 2)], 0);
167 assert_eq!(graph[(3, 3)], 0);
168 }
169
170 #[test]
171 fn test_get_set_distance() {
172 let mut graph: CompleteGraph<i32> = CompleteGraph::new(4);
173
174 *graph.get_mut(0, 1) = 10;
176 *graph.get_mut(1, 2) = 20;
177 *graph.get_mut(2, 3) = 30;
178
179 assert_eq!(*graph.get(0, 1), 10);
181 assert_eq!(*graph.get(1, 2), 20);
182 assert_eq!(*graph.get(2, 3), 30);
183
184 assert_eq!(*graph.get(0, 0), 0);
186 assert_eq!(*graph.get(1, 1), 0);
187 }
188
189 #[test]
190 fn test_index_syntax() {
191 let mut graph: CompleteGraph<i32> = CompleteGraph::new(4);
192
193 graph[(0, 1)] = 10;
195 graph[(1, 2)] = 20;
196
197 assert_eq!(graph[(0, 1)], 10);
199 assert_eq!(graph[(1, 2)], 20);
200 assert_eq!(graph[(0, 0)], 0);
201 }
202
203 #[test]
204 fn test_from_vec_constructor() {
205 let distances = &[0, 10, 20, 30, 0, 40, 50, 60, 0];
208 let graph = CompleteGraph::from_vec(3, distances.to_vec());
209
210 assert_eq!(graph.num_nodes(), 3);
211 assert_eq!(graph[(0, 0)], 0);
212 assert_eq!(graph[(0, 1)], 10);
213 assert_eq!(graph[(0, 2)], 20);
214 assert_eq!(graph[(1, 0)], 30);
215 assert_eq!(graph[(1, 1)], 0);
216 assert_eq!(graph[(1, 2)], 40);
217 assert_eq!(graph[(2, 0)], 50);
218 assert_eq!(graph[(2, 1)], 60);
219 assert_eq!(graph[(2, 2)], 0);
220 }
221
222 #[test]
223 #[should_panic(expected = "Cannot modify diagonal")]
224 fn test_modify_diagonal() {
225 let mut graph: CompleteGraph<i32> = CompleteGraph::new(4);
226 graph[(0, 0)] = 5; }
228
229 #[test]
230 #[should_panic(expected = "Vector length")]
231 fn test_from_vec_wrong_size() {
232 let distances = vec![0, 10, 20, 30, 0, 40, 50, 0, 60];
234 let _graph = CompleteGraph::<i32>::from_vec(4, distances);
235 }
236
237 #[test]
238 #[should_panic]
239 fn test_get_index_out_of_bounds() {
240 let graph: CompleteGraph<i32> = CompleteGraph::new(3);
241
242 let _ = graph[(3, 0)]; }
247
248 #[test]
249 #[should_panic]
250 fn test_get_mut_index_out_of_bounds() {
251 let mut graph: CompleteGraph<i32> = CompleteGraph::new(3);
252
253 *graph.get_mut(0, 4) = 10; }
258}