1use std::collections::{HashSet, VecDeque};
10use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
11use dashmap::DashMap;
12use serde::{Deserialize, Serialize};
13use crate::error::{MinCutError, Result};
14
15pub type VertexId = u64;
17
18pub type EdgeId = u64;
20
21pub type Weight = f64;
23
24#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
26pub struct Edge {
27 pub id: EdgeId,
29 pub source: VertexId,
31 pub target: VertexId,
33 pub weight: Weight,
35}
36
37impl Edge {
38 pub fn new(id: EdgeId, source: VertexId, target: VertexId, weight: Weight) -> Self {
40 Self {
41 id,
42 source,
43 target,
44 weight,
45 }
46 }
47
48 pub fn canonical_endpoints(&self) -> (VertexId, VertexId) {
50 if self.source <= self.target {
51 (self.source, self.target)
52 } else {
53 (self.target, self.source)
54 }
55 }
56
57 pub fn other(&self, v: VertexId) -> Option<VertexId> {
59 if self.source == v {
60 Some(self.target)
61 } else if self.target == v {
62 Some(self.source)
63 } else {
64 None
65 }
66 }
67}
68
69#[derive(Debug, Clone, Default, Serialize, Deserialize)]
71pub struct GraphStats {
72 pub num_vertices: usize,
74 pub num_edges: usize,
76 pub total_weight: f64,
78 pub min_degree: usize,
80 pub max_degree: usize,
82 pub avg_degree: f64,
84}
85
86pub struct DynamicGraph {
88 adjacency: DashMap<VertexId, HashSet<(VertexId, EdgeId)>>,
90 edges: DashMap<EdgeId, Edge>,
92 edge_index: DashMap<(VertexId, VertexId), EdgeId>,
94 next_edge_id: AtomicU64,
96 num_vertices: AtomicUsize,
98}
99
100impl DynamicGraph {
101 pub fn new() -> Self {
103 Self {
104 adjacency: DashMap::new(),
105 edges: DashMap::new(),
106 edge_index: DashMap::new(),
107 next_edge_id: AtomicU64::new(0),
108 num_vertices: AtomicUsize::new(0),
109 }
110 }
111
112 pub fn with_capacity(vertices: usize, edges: usize) -> Self {
114 Self {
115 adjacency: DashMap::with_capacity(vertices),
116 edges: DashMap::with_capacity(edges),
117 edge_index: DashMap::with_capacity(edges),
118 next_edge_id: AtomicU64::new(0),
119 num_vertices: AtomicUsize::new(0),
120 }
121 }
122
123 pub fn add_vertex(&self, v: VertexId) -> bool {
125 if self.adjacency.contains_key(&v) {
126 false
127 } else {
128 self.adjacency.insert(v, HashSet::new());
129 self.num_vertices.fetch_add(1, Ordering::SeqCst);
130 true
131 }
132 }
133
134 pub fn has_vertex(&self, v: VertexId) -> bool {
136 self.adjacency.contains_key(&v)
137 }
138
139 fn canonical_key(u: VertexId, v: VertexId) -> (VertexId, VertexId) {
141 if u <= v {
142 (u, v)
143 } else {
144 (v, u)
145 }
146 }
147
148 pub fn insert_edge(&self, u: VertexId, v: VertexId, weight: Weight) -> Result<EdgeId> {
150 if u == v {
152 return Err(MinCutError::InvalidEdge(u, v));
153 }
154
155 self.add_vertex(u);
157 self.add_vertex(v);
158
159 let key = Self::canonical_key(u, v);
160
161 if self.edge_index.contains_key(&key) {
163 return Err(MinCutError::EdgeExists(u, v));
164 }
165
166 let edge_id = self.next_edge_id.fetch_add(1, Ordering::SeqCst);
168
169 let edge = Edge::new(edge_id, u, v, weight);
171
172 self.edges.insert(edge_id, edge);
174
175 self.edge_index.insert(key, edge_id);
177
178 self.adjacency.get_mut(&u).unwrap().insert((v, edge_id));
180 self.adjacency.get_mut(&v).unwrap().insert((u, edge_id));
181
182 Ok(edge_id)
183 }
184
185 pub fn delete_edge(&self, u: VertexId, v: VertexId) -> Result<Edge> {
187 let key = Self::canonical_key(u, v);
188
189 let edge_id = self.edge_index
191 .remove(&key)
192 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?
193 .1;
194
195 let (_, edge) = self.edges
197 .remove(&edge_id)
198 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?;
199
200 if let Some(mut neighbors) = self.adjacency.get_mut(&u) {
202 neighbors.retain(|(neighbor, eid)| !(*neighbor == v && *eid == edge_id));
203 }
204 if let Some(mut neighbors) = self.adjacency.get_mut(&v) {
205 neighbors.retain(|(neighbor, eid)| !(*neighbor == u && *eid == edge_id));
206 }
207
208 Ok(edge)
209 }
210
211 pub fn has_edge(&self, u: VertexId, v: VertexId) -> bool {
213 let key = Self::canonical_key(u, v);
214 self.edge_index.contains_key(&key)
215 }
216
217 pub fn get_edge(&self, u: VertexId, v: VertexId) -> Option<Edge> {
219 let key = Self::canonical_key(u, v);
220 self.edge_index.get(&key).and_then(|edge_id| {
221 self.edges.get(edge_id.value()).map(|e| *e.value())
222 })
223 }
224
225 pub fn neighbors(&self, v: VertexId) -> Vec<(VertexId, EdgeId)> {
227 self.adjacency
228 .get(&v)
229 .map(|neighbors| neighbors.iter().copied().collect())
230 .unwrap_or_default()
231 }
232
233 pub fn degree(&self, v: VertexId) -> usize {
235 self.adjacency
236 .get(&v)
237 .map(|neighbors| neighbors.len())
238 .unwrap_or(0)
239 }
240
241 pub fn num_vertices(&self) -> usize {
243 self.num_vertices.load(Ordering::SeqCst)
244 }
245
246 pub fn num_edges(&self) -> usize {
248 self.edges.len()
249 }
250
251 pub fn vertices(&self) -> Vec<VertexId> {
253 self.adjacency.iter().map(|entry| *entry.key()).collect()
254 }
255
256 pub fn edges(&self) -> Vec<Edge> {
258 self.edges.iter().map(|entry| *entry.value()).collect()
259 }
260
261 pub fn stats(&self) -> GraphStats {
263 let num_vertices = self.num_vertices();
264 let num_edges = self.num_edges();
265
266 if num_vertices == 0 {
267 return GraphStats::default();
268 }
269
270 let mut degrees: Vec<usize> = self.adjacency
271 .iter()
272 .map(|entry| entry.value().len())
273 .collect();
274
275 degrees.sort_unstable();
276
277 let min_degree = degrees.first().copied().unwrap_or(0);
278 let max_degree = degrees.last().copied().unwrap_or(0);
279 let total_degree: usize = degrees.iter().sum();
280 let avg_degree = total_degree as f64 / num_vertices as f64;
281
282 let total_weight: f64 = self.edges
283 .iter()
284 .map(|entry| entry.value().weight)
285 .sum();
286
287 GraphStats {
288 num_vertices,
289 num_edges,
290 total_weight,
291 min_degree,
292 max_degree,
293 avg_degree,
294 }
295 }
296
297 pub fn is_connected(&self) -> bool {
299 let num_vertices = self.num_vertices();
300
301 if num_vertices == 0 {
302 return true; }
304
305 if num_vertices == 1 {
306 return true;
307 }
308
309 let start = match self.adjacency.iter().next() {
311 Some(entry) => *entry.key(),
312 None => return true,
313 };
314
315 let mut visited = HashSet::new();
316 let mut queue = VecDeque::new();
317
318 queue.push_back(start);
319 visited.insert(start);
320
321 while let Some(v) = queue.pop_front() {
322 if let Some(neighbors) = self.adjacency.get(&v) {
323 for (neighbor, _) in neighbors.iter() {
324 if visited.insert(*neighbor) {
325 queue.push_back(*neighbor);
326 }
327 }
328 }
329 }
330
331 visited.len() == num_vertices
332 }
333
334 pub fn connected_components(&self) -> Vec<Vec<VertexId>> {
336 let mut visited = HashSet::new();
337 let mut components = Vec::new();
338
339 for entry in self.adjacency.iter() {
340 let start = *entry.key();
341
342 if visited.contains(&start) {
343 continue;
344 }
345
346 let mut component = Vec::new();
347 let mut queue = VecDeque::new();
348
349 queue.push_back(start);
350 visited.insert(start);
351
352 while let Some(v) = queue.pop_front() {
353 component.push(v);
354
355 if let Some(neighbors) = self.adjacency.get(&v) {
356 for (neighbor, _) in neighbors.iter() {
357 if visited.insert(*neighbor) {
358 queue.push_back(*neighbor);
359 }
360 }
361 }
362 }
363
364 components.push(component);
365 }
366
367 components
368 }
369
370 pub fn clear(&self) {
372 self.adjacency.clear();
373 self.edges.clear();
374 self.edge_index.clear();
375 self.next_edge_id.store(0, Ordering::SeqCst);
376 self.num_vertices.store(0, Ordering::SeqCst);
377 }
378
379 pub fn remove_vertex(&self, v: VertexId) -> Result<()> {
381 if !self.has_vertex(v) {
382 return Err(MinCutError::InvalidVertex(v));
383 }
384
385 let incident_edges: Vec<(VertexId, EdgeId)> = self.neighbors(v);
387
388 for (neighbor, _) in incident_edges {
390 let _ = self.delete_edge(v, neighbor);
392 }
393
394 self.adjacency.remove(&v);
396 self.num_vertices.fetch_sub(1, Ordering::SeqCst);
397
398 Ok(())
399 }
400
401 pub fn edge_weight(&self, u: VertexId, v: VertexId) -> Option<Weight> {
403 self.get_edge(u, v).map(|e| e.weight)
404 }
405
406 pub fn update_edge_weight(&self, u: VertexId, v: VertexId, new_weight: Weight) -> Result<()> {
408 let key = Self::canonical_key(u, v);
409
410 let edge_id = self.edge_index
411 .get(&key)
412 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?;
413
414 let edge_id = *edge_id.value();
415
416 if let Some(mut edge_ref) = self.edges.get_mut(&edge_id) {
417 edge_ref.weight = new_weight;
418 Ok(())
419 } else {
420 Err(MinCutError::EdgeNotFound(u, v))
421 }
422 }
423}
424
425impl Default for DynamicGraph {
426 fn default() -> Self {
427 Self::new()
428 }
429}
430
431impl Clone for DynamicGraph {
432 fn clone(&self) -> Self {
433 let new_graph = Self::with_capacity(self.num_vertices(), self.num_edges());
434
435 for entry in self.adjacency.iter() {
437 new_graph.add_vertex(*entry.key());
438 }
439
440 for entry in self.edges.iter() {
442 let edge = entry.value();
443 let _ = new_graph.insert_edge(edge.source, edge.target, edge.weight);
444 }
445
446 new_graph
447 }
448}
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453
454 #[test]
455 fn test_empty_graph() {
456 let g = DynamicGraph::new();
457 assert_eq!(g.num_vertices(), 0);
458 assert_eq!(g.num_edges(), 0);
459 assert!(g.is_connected());
460 }
461
462 #[test]
463 fn test_add_vertex() {
464 let g = DynamicGraph::new();
465 assert!(g.add_vertex(1));
466 assert!(!g.add_vertex(1)); assert_eq!(g.num_vertices(), 1);
468 assert!(g.has_vertex(1));
469 assert!(!g.has_vertex(2));
470 }
471
472 #[test]
473 fn test_insert_edge() {
474 let g = DynamicGraph::new();
475 let edge_id = g.insert_edge(1, 2, 1.0).unwrap();
476 assert_eq!(g.num_edges(), 1);
477 assert_eq!(g.num_vertices(), 2);
478 assert!(g.has_edge(1, 2));
479 assert!(g.has_edge(2, 1)); assert_eq!(edge_id, 0);
483 }
484
485 #[test]
486 fn test_insert_duplicate_edge() {
487 let g = DynamicGraph::new();
488 g.insert_edge(1, 2, 1.0).unwrap();
489 let result = g.insert_edge(1, 2, 2.0);
490 assert!(matches!(result, Err(MinCutError::EdgeExists(1, 2))));
491 }
492
493 #[test]
494 fn test_insert_self_loop() {
495 let g = DynamicGraph::new();
496 let result = g.insert_edge(1, 1, 1.0);
497 assert!(matches!(result, Err(MinCutError::InvalidEdge(1, 1))));
498 }
499
500 #[test]
501 fn test_delete_edge() {
502 let g = DynamicGraph::new();
503 g.insert_edge(1, 2, 1.5).unwrap();
504 assert_eq!(g.num_edges(), 1);
505
506 let edge = g.delete_edge(1, 2).unwrap();
507 assert_eq!(edge.weight, 1.5);
508 assert_eq!(g.num_edges(), 0);
509 assert!(!g.has_edge(1, 2));
510 }
511
512 #[test]
513 fn test_delete_nonexistent_edge() {
514 let g = DynamicGraph::new();
515 let result = g.delete_edge(1, 2);
516 assert!(matches!(result, Err(MinCutError::EdgeNotFound(1, 2))));
517 }
518
519 #[test]
520 fn test_neighbors() {
521 let g = DynamicGraph::new();
522 g.insert_edge(1, 2, 1.0).unwrap();
523 g.insert_edge(1, 3, 1.0).unwrap();
524 g.insert_edge(1, 4, 1.0).unwrap();
525
526 let neighbors = g.neighbors(1);
527 assert_eq!(neighbors.len(), 3);
528
529 let neighbor_ids: HashSet<VertexId> = neighbors.iter().map(|(v, _)| *v).collect();
530 assert!(neighbor_ids.contains(&2));
531 assert!(neighbor_ids.contains(&3));
532 assert!(neighbor_ids.contains(&4));
533 }
534
535 #[test]
536 fn test_degree() {
537 let g = DynamicGraph::new();
538 g.insert_edge(1, 2, 1.0).unwrap();
539 g.insert_edge(1, 3, 1.0).unwrap();
540
541 assert_eq!(g.degree(1), 2);
542 assert_eq!(g.degree(2), 1);
543 assert_eq!(g.degree(3), 1);
544 assert_eq!(g.degree(4), 0); }
546
547 #[test]
548 fn test_get_edge() {
549 let g = DynamicGraph::new();
550 g.insert_edge(1, 2, 2.5).unwrap();
551
552 let edge = g.get_edge(1, 2).unwrap();
553 assert_eq!(edge.weight, 2.5);
554 assert_eq!(edge.source, 1);
555 assert_eq!(edge.target, 2);
556
557 let edge = g.get_edge(2, 1).unwrap();
559 assert_eq!(edge.weight, 2.5);
560
561 assert!(g.get_edge(1, 3).is_none());
562 }
563
564 #[test]
565 fn test_stats() {
566 let g = DynamicGraph::new();
567 g.insert_edge(1, 2, 1.0).unwrap();
568 g.insert_edge(2, 3, 2.0).unwrap();
569 g.insert_edge(3, 1, 3.0).unwrap();
570
571 let stats = g.stats();
572 assert_eq!(stats.num_vertices, 3);
573 assert_eq!(stats.num_edges, 3);
574 assert_eq!(stats.total_weight, 6.0);
575 assert_eq!(stats.min_degree, 2);
576 assert_eq!(stats.max_degree, 2);
577 assert_eq!(stats.avg_degree, 2.0);
578 }
579
580 #[test]
581 fn test_is_connected_single_component() {
582 let g = DynamicGraph::new();
583 g.insert_edge(1, 2, 1.0).unwrap();
584 g.insert_edge(2, 3, 1.0).unwrap();
585 g.insert_edge(3, 4, 1.0).unwrap();
586
587 assert!(g.is_connected());
588 }
589
590 #[test]
591 fn test_is_connected_disconnected() {
592 let g = DynamicGraph::new();
593 g.insert_edge(1, 2, 1.0).unwrap();
594 g.insert_edge(3, 4, 1.0).unwrap();
595
596 assert!(!g.is_connected());
597 }
598
599 #[test]
600 fn test_connected_components() {
601 let g = DynamicGraph::new();
602 g.insert_edge(1, 2, 1.0).unwrap();
603 g.insert_edge(2, 3, 1.0).unwrap();
604 g.insert_edge(4, 5, 1.0).unwrap();
605 g.insert_edge(6, 7, 1.0).unwrap();
606 g.insert_edge(7, 8, 1.0).unwrap();
607
608 let components = g.connected_components();
609 assert_eq!(components.len(), 3);
610
611 let mut sizes: Vec<usize> = components.iter().map(|c| c.len()).collect();
613 sizes.sort_unstable();
614 assert_eq!(sizes, vec![2, 3, 3]);
615 }
616
617 #[test]
618 fn test_clear() {
619 let g = DynamicGraph::new();
620 g.insert_edge(1, 2, 1.0).unwrap();
621 g.insert_edge(2, 3, 1.0).unwrap();
622
623 assert_eq!(g.num_vertices(), 3);
624 assert_eq!(g.num_edges(), 2);
625
626 g.clear();
627
628 assert_eq!(g.num_vertices(), 0);
629 assert_eq!(g.num_edges(), 0);
630 }
631
632 #[test]
633 fn test_remove_vertex() {
634 let g = DynamicGraph::new();
635 g.insert_edge(1, 2, 1.0).unwrap();
636 g.insert_edge(2, 3, 1.0).unwrap();
637 g.insert_edge(1, 3, 1.0).unwrap();
638
639 assert_eq!(g.num_vertices(), 3);
640 assert_eq!(g.num_edges(), 3);
641
642 g.remove_vertex(2).unwrap();
643
644 assert_eq!(g.num_vertices(), 2);
645 assert_eq!(g.num_edges(), 1);
646 assert!(!g.has_vertex(2));
647 assert!(g.has_edge(1, 3));
648 assert!(!g.has_edge(1, 2));
649 assert!(!g.has_edge(2, 3));
650 }
651
652 #[test]
653 fn test_edge_weight() {
654 let g = DynamicGraph::new();
655 g.insert_edge(1, 2, 3.5).unwrap();
656
657 assert_eq!(g.edge_weight(1, 2), Some(3.5));
658 assert_eq!(g.edge_weight(2, 1), Some(3.5));
659 assert_eq!(g.edge_weight(1, 3), None);
660 }
661
662 #[test]
663 fn test_update_edge_weight() {
664 let g = DynamicGraph::new();
665 g.insert_edge(1, 2, 1.0).unwrap();
666
667 g.update_edge_weight(1, 2, 5.0).unwrap();
668 assert_eq!(g.edge_weight(1, 2), Some(5.0));
669
670 let result = g.update_edge_weight(1, 3, 2.0);
671 assert!(matches!(result, Err(MinCutError::EdgeNotFound(1, 3))));
672 }
673
674 #[test]
675 fn test_clone() {
676 let g = DynamicGraph::new();
677 g.insert_edge(1, 2, 1.0).unwrap();
678 g.insert_edge(2, 3, 2.0).unwrap();
679
680 let g2 = g.clone();
681
682 assert_eq!(g2.num_vertices(), 3);
683 assert_eq!(g2.num_edges(), 2);
684 assert!(g2.has_edge(1, 2));
685 assert!(g2.has_edge(2, 3));
686 assert_eq!(g2.edge_weight(1, 2), Some(1.0));
687 assert_eq!(g2.edge_weight(2, 3), Some(2.0));
688 }
689
690 #[test]
691 fn test_edge_canonical_endpoints() {
692 let edge = Edge::new(0, 5, 3, 1.0);
693 assert_eq!(edge.canonical_endpoints(), (3, 5));
694
695 let edge = Edge::new(0, 2, 7, 1.0);
696 assert_eq!(edge.canonical_endpoints(), (2, 7));
697 }
698
699 #[test]
700 fn test_edge_other() {
701 let edge = Edge::new(0, 1, 2, 1.0);
702 assert_eq!(edge.other(1), Some(2));
703 assert_eq!(edge.other(2), Some(1));
704 assert_eq!(edge.other(3), None);
705 }
706
707 #[test]
708 fn test_with_capacity() {
709 let g = DynamicGraph::with_capacity(100, 200);
710 assert_eq!(g.num_vertices(), 0);
711 assert_eq!(g.num_edges(), 0);
712
713 g.insert_edge(1, 2, 1.0).unwrap();
715 assert_eq!(g.num_edges(), 1);
716 }
717
718 #[test]
719 fn test_vertices_and_edges() {
720 let g = DynamicGraph::new();
721 g.insert_edge(1, 2, 1.0).unwrap();
722 g.insert_edge(2, 3, 2.0).unwrap();
723
724 let vertices = g.vertices();
725 assert_eq!(vertices.len(), 3);
726 assert!(vertices.contains(&1));
727 assert!(vertices.contains(&2));
728 assert!(vertices.contains(&3));
729
730 let edges = g.edges();
731 assert_eq!(edges.len(), 2);
732 }
733}