1use crate::{GraphAlgorithm, GraphError};
2
3#[derive(Debug, Clone)]
5pub struct Edge {
6 pub source: usize,
8
9 pub destination: usize,
11
12 pub weight: i32,
14}
15
16#[derive(Debug, Clone)]
19pub struct BellmanFordAlgorithm {
20 pub total_vertices: usize,
22
23 pub edges: Vec<Edge>,
25}
26
27impl Default for BellmanFordAlgorithm {
28 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl BellmanFordAlgorithm {
39 pub fn new() -> Self {
45 BellmanFordAlgorithm {
46 total_vertices: 0,
47 edges: Vec::new(),
48 }
49 }
50
51 pub fn set_edge(&mut self, source: usize, edges: Vec<(usize, i32)>) {
58 if edges.is_empty() {
59 self.total_vertices = self.total_vertices.max(source + 1);
60 return;
61 }
62
63 for (destination, weight) in edges {
64 self.edges.push(Edge {
65 source,
66 weight,
67 destination,
68 });
69
70 self.total_vertices = self.total_vertices.max(source + 1).max(destination + 1);
71 }
72 }
73
74 pub fn set_edges(&mut self, nodes: Vec<(usize, Vec<(usize, i32)>)>) {
80 for (source, edges) in nodes {
81 self.set_edge(source, edges);
82 }
83 }
84}
85
86impl GraphAlgorithm for BellmanFordAlgorithm {
87 type Node = isize;
89
90 type Weight = Vec<i32>;
92
93 fn run(&self, start: Option<Self::Node>) -> Result<Self::Weight, GraphError> {
103 let start = start.ok_or(GraphError::MissingStartNode)?;
104
105 let mut distances = vec![i32::MAX; self.total_vertices];
106 distances[start as usize] = 0;
107
108 for _ in 0..self.total_vertices - 1 {
109 let mut is_distance_updated = false;
110
111 for edge in &self.edges {
112 if distances[edge.source] != i32::MAX {
113 let new_distance = distances[edge.source] + edge.weight;
114
115 if new_distance < distances[edge.destination] {
116 distances[edge.destination] = new_distance;
117 is_distance_updated = true;
118 }
119 }
120 }
121
122 if !is_distance_updated {
123 break;
124 }
125 }
126
127 for edge in &self.edges {
128 if distances[edge.source] != i32::MAX {
129 let new_distance = distances[edge.source] + edge.weight;
130
131 if new_distance < distances[edge.destination] {
132 return Err(GraphError::NegativeWeightCycle);
133 }
134 }
135 }
136
137 Ok(distances)
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn test_new() {
147 let algorithm = BellmanFordAlgorithm::new();
148 let algorithm_default = BellmanFordAlgorithm::default();
149
150 assert_eq!(algorithm.edges.len(), 0);
151 assert_eq!(algorithm_default.edges.len(), 0);
152 }
153
154 #[test]
155 fn test_missing_start_node() {
156 let algorithm = BellmanFordAlgorithm::new();
157
158 assert_eq!(algorithm.run(None), Err(GraphError::MissingStartNode));
159 }
160
161 #[test]
162 fn test_run() {
163 let mut algorithm = BellmanFordAlgorithm {
164 total_vertices: 50,
165 edges: Vec::new(),
166 };
167
168 let edges = vec![
169 (0, 1, 4),
170 (0, 2, 1),
171 (1, 2, 2),
172 (1, 3, 5),
173 (2, 3, 8),
174 (2, 4, 2),
175 (3, 5, 3),
176 (4, 5, 4),
177 (5, 6, 1),
178 (6, 7, 3),
179 (7, 8, 2),
180 (8, 9, 6),
181 (9, 10, 2),
182 (10, 11, 1),
183 (11, 12, 3),
184 (12, 13, 4),
185 (13, 14, 2),
186 (14, 15, 1),
187 (15, 16, 5),
188 (16, 17, 1),
189 (17, 18, 2),
190 (18, 19, 3),
191 (19, 20, 6),
192 (20, 21, 2),
193 (21, 22, 1),
194 (22, 23, 3),
195 (23, 24, 4),
196 (24, 25, 2),
197 (25, 26, 1),
198 (26, 27, 5),
199 (27, 28, 1),
200 (28, 29, 2),
201 (29, 30, 3),
202 (30, 31, 6),
203 (31, 32, 2),
204 (32, 33, 1),
205 (33, 34, 3),
206 (34, 35, 4),
207 (35, 36, 2),
208 (36, 37, 1),
209 (37, 38, 5),
210 (38, 39, 1),
211 (39, 40, 2),
212 (40, 41, 3),
213 (41, 42, 6),
214 (42, 43, 2),
215 (43, 44, 1),
216 (44, 45, 4),
217 (45, 46, 1),
218 (46, 47, 2),
219 (47, 48, 3),
220 (48, 49, 1),
221 ];
222
223 for (source, destination, weight) in edges {
224 algorithm.set_edge(source, vec![(destination, weight)]);
225 }
226
227 let result = algorithm.run(Some(0)).unwrap();
228
229 assert_eq!(result[0], 0);
230
231 for &distance in &result {
232 assert!(distance >= 0 || distance == i32::MAX);
233 }
234
235 for item in result.iter().take(10).skip(1) {
236 assert!(item < &i32::MAX);
237 }
238 }
239
240 #[test]
241 fn test_run_single_node_graph() {
242 let mut algorithm = BellmanFordAlgorithm::new();
243 algorithm.set_edge(0, vec![]);
244
245 assert_eq!(algorithm.run(Some(0)).unwrap(), vec![0]);
246 }
247
248 #[test]
249 fn test_run_simple_graph_no_negative_edges() {
250 let mut algorithm = BellmanFordAlgorithm::new();
251 algorithm.set_edge(0, vec![(1, 4), (2, 3)]);
252 algorithm.set_edge(1, vec![(2, 1), (3, 2)]);
253 algorithm.set_edge(2, vec![(3, 5)]);
254
255 assert_eq!(algorithm.run(Some(0)).unwrap(), vec![0, 4, 3, 6]);
256 }
257
258 #[test]
259 fn test_run_graph_with_negative_edge() {
260 let mut algorithm = BellmanFordAlgorithm::new();
261 algorithm.set_edge(0, vec![(1, 4), (2, 3)]);
262 algorithm.set_edge(1, vec![(2, -2), (3, 2)]);
263 algorithm.set_edge(2, vec![(3, 3)]);
264
265 assert_eq!(algorithm.run(Some(0)).unwrap(), vec![0, 4, 2, 5]);
266 }
267
268 #[test]
269 fn test_run_graph_with_no_edges() {
270 let mut algorithm = BellmanFordAlgorithm::new();
271 algorithm.set_edge(0, vec![]);
272 algorithm.set_edge(1, vec![]);
273 algorithm.set_edge(2, vec![]);
274 algorithm.set_edge(3, vec![]);
275
276 assert_eq!(
277 algorithm.run(Some(0)).unwrap(),
278 vec![0, i32::MAX, i32::MAX, i32::MAX]
279 );
280 }
281
282 #[test]
283 fn test_run_run_from_different_start_node() {
284 let mut algorithm = BellmanFordAlgorithm::new();
285 algorithm.set_edge(0, vec![(1, 4), (2, 3)]);
286 algorithm.set_edge(1, vec![(2, 1), (3, 2)]);
287 algorithm.set_edge(2, vec![(3, 5)]);
288
289 assert_eq!(algorithm.run(Some(1)).unwrap(), vec![i32::MAX, 0, 1, 2]);
290 }
291
292 #[test]
293 fn test_run_disconnected_graph() {
294 let mut algorithm = BellmanFordAlgorithm::new();
295 algorithm.set_edge(0, vec![(1, 4)]);
296 algorithm.set_edge(2, vec![(3, 5)]);
297
298 assert_eq!(
299 algorithm.run(Some(0)).unwrap(),
300 vec![0, 4, i32::MAX, i32::MAX]
301 );
302 }
303
304 #[test]
305 fn test_run_graph_with_negative_weight_cycle() {
306 let mut algorithm = BellmanFordAlgorithm::new();
307 algorithm.set_edges(vec![
308 (0, vec![(1, 1)]),
309 (1, vec![(2, -1)]),
310 (2, vec![(0, -1)]),
311 ]);
312
313 assert_eq!(algorithm.run(Some(0)), Err(GraphError::NegativeWeightCycle));
314 }
315
316 #[test]
317 fn test_run_early_exit_no_updates() {
318 let mut algorithm = BellmanFordAlgorithm::new();
319 algorithm.set_edge(0, vec![(1, 2)]);
320 algorithm.set_edge(1, vec![(2, 3)]);
321 algorithm.set_edge(2, vec![(3, 4)]);
322 algorithm.set_edge(3, vec![(4, 1)]);
323
324 let result = algorithm.run(Some(0)).unwrap();
325
326 assert_eq!(result[0], 0);
327 assert_eq!(result[1], 2);
328 assert_eq!(result[2], 5);
329 assert_eq!(result[3], 9);
330 assert_eq!(result[4], 10);
331 }
332
333 #[test]
334 fn test_run_early_exit_with_no_negative_cycle() {
335 let mut algorithm = BellmanFordAlgorithm::new();
336 algorithm.set_edge(0, vec![(1, 2)]);
337 algorithm.set_edge(1, vec![(2, 3)]);
338 algorithm.set_edge(2, vec![(3, -5)]);
339 algorithm.set_edge(3, vec![(4, 1)]);
340
341 let result = algorithm.run(Some(0)).unwrap();
342
343 assert_eq!(result[0], 0);
344 assert_eq!(result[1], 2);
345 assert_eq!(result[2], 5);
346 assert_eq!(result[3], 0);
347 assert_eq!(result[4], 1);
348 }
349
350 #[test]
351 fn test_run_early_exit_with_negative_cycle() {
352 let mut algorithm = BellmanFordAlgorithm::new();
353 algorithm.set_edge(0, vec![(1, 1)]);
354 algorithm.set_edge(1, vec![(2, -2)]);
355 algorithm.set_edge(2, vec![(0, -1)]); assert_eq!(algorithm.run(Some(0)), Err(GraphError::NegativeWeightCycle));
358 }
359}