1use crate::error::{MinCutError, Result};
10use dashmap::DashMap;
11use serde::{Deserialize, Serialize};
12use std::collections::{HashSet, VecDeque};
13use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
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
191 .edge_index
192 .remove(&key)
193 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?
194 .1;
195
196 let (_, edge) = self
198 .edges
199 .remove(&edge_id)
200 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?;
201
202 if let Some(mut neighbors) = self.adjacency.get_mut(&u) {
204 neighbors.retain(|(neighbor, eid)| !(*neighbor == v && *eid == edge_id));
205 }
206 if let Some(mut neighbors) = self.adjacency.get_mut(&v) {
207 neighbors.retain(|(neighbor, eid)| !(*neighbor == u && *eid == edge_id));
208 }
209
210 Ok(edge)
211 }
212
213 pub fn has_edge(&self, u: VertexId, v: VertexId) -> bool {
215 let key = Self::canonical_key(u, v);
216 self.edge_index.contains_key(&key)
217 }
218
219 pub fn get_edge(&self, u: VertexId, v: VertexId) -> Option<Edge> {
221 let key = Self::canonical_key(u, v);
222 self.edge_index
223 .get(&key)
224 .and_then(|edge_id| self.edges.get(edge_id.value()).map(|e| *e.value()))
225 }
226
227 pub fn neighbors(&self, v: VertexId) -> Vec<(VertexId, EdgeId)> {
229 self.adjacency
230 .get(&v)
231 .map(|neighbors| neighbors.iter().copied().collect())
232 .unwrap_or_default()
233 }
234
235 pub fn degree(&self, v: VertexId) -> usize {
237 self.adjacency
238 .get(&v)
239 .map(|neighbors| neighbors.len())
240 .unwrap_or(0)
241 }
242
243 pub fn num_vertices(&self) -> usize {
245 self.num_vertices.load(Ordering::SeqCst)
246 }
247
248 pub fn num_edges(&self) -> usize {
250 self.edges.len()
251 }
252
253 pub fn vertices(&self) -> Vec<VertexId> {
255 self.adjacency.iter().map(|entry| *entry.key()).collect()
256 }
257
258 pub fn edges(&self) -> Vec<Edge> {
260 self.edges.iter().map(|entry| *entry.value()).collect()
261 }
262
263 pub fn stats(&self) -> GraphStats {
265 let num_vertices = self.num_vertices();
266 let num_edges = self.num_edges();
267
268 if num_vertices == 0 {
269 return GraphStats::default();
270 }
271
272 let mut degrees: Vec<usize> = self
273 .adjacency
274 .iter()
275 .map(|entry| entry.value().len())
276 .collect();
277
278 degrees.sort_unstable();
279
280 let min_degree = degrees.first().copied().unwrap_or(0);
281 let max_degree = degrees.last().copied().unwrap_or(0);
282 let total_degree: usize = degrees.iter().sum();
283 let avg_degree = total_degree as f64 / num_vertices as f64;
284
285 let total_weight: f64 = self.edges.iter().map(|entry| entry.value().weight).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
411 .edge_index
412 .get(&key)
413 .ok_or_else(|| MinCutError::EdgeNotFound(u, v))?;
414
415 let edge_id = *edge_id.value();
416
417 if let Some(mut edge_ref) = self.edges.get_mut(&edge_id) {
418 edge_ref.weight = new_weight;
419 Ok(())
420 } else {
421 Err(MinCutError::EdgeNotFound(u, v))
422 }
423 }
424}
425
426impl Default for DynamicGraph {
427 fn default() -> Self {
428 Self::new()
429 }
430}
431
432impl Clone for DynamicGraph {
433 fn clone(&self) -> Self {
434 let new_graph = Self::with_capacity(self.num_vertices(), self.num_edges());
435
436 for entry in self.adjacency.iter() {
438 new_graph.add_vertex(*entry.key());
439 }
440
441 for entry in self.edges.iter() {
443 let edge = entry.value();
444 let _ = new_graph.insert_edge(edge.source, edge.target, edge.weight);
445 }
446
447 new_graph
448 }
449}
450
451#[cfg(test)]
452mod tests {
453 use super::*;
454
455 #[test]
456 fn test_empty_graph() {
457 let g = DynamicGraph::new();
458 assert_eq!(g.num_vertices(), 0);
459 assert_eq!(g.num_edges(), 0);
460 assert!(g.is_connected());
461 }
462
463 #[test]
464 fn test_add_vertex() {
465 let g = DynamicGraph::new();
466 assert!(g.add_vertex(1));
467 assert!(!g.add_vertex(1)); assert_eq!(g.num_vertices(), 1);
469 assert!(g.has_vertex(1));
470 assert!(!g.has_vertex(2));
471 }
472
473 #[test]
474 fn test_insert_edge() {
475 let g = DynamicGraph::new();
476 let edge_id = g.insert_edge(1, 2, 1.0).unwrap();
477 assert_eq!(g.num_edges(), 1);
478 assert_eq!(g.num_vertices(), 2);
479 assert!(g.has_edge(1, 2));
480 assert!(g.has_edge(2, 1)); assert_eq!(edge_id, 0);
484 }
485
486 #[test]
487 fn test_insert_duplicate_edge() {
488 let g = DynamicGraph::new();
489 g.insert_edge(1, 2, 1.0).unwrap();
490 let result = g.insert_edge(1, 2, 2.0);
491 assert!(matches!(result, Err(MinCutError::EdgeExists(1, 2))));
492 }
493
494 #[test]
495 fn test_insert_self_loop() {
496 let g = DynamicGraph::new();
497 let result = g.insert_edge(1, 1, 1.0);
498 assert!(matches!(result, Err(MinCutError::InvalidEdge(1, 1))));
499 }
500
501 #[test]
502 fn test_delete_edge() {
503 let g = DynamicGraph::new();
504 g.insert_edge(1, 2, 1.5).unwrap();
505 assert_eq!(g.num_edges(), 1);
506
507 let edge = g.delete_edge(1, 2).unwrap();
508 assert_eq!(edge.weight, 1.5);
509 assert_eq!(g.num_edges(), 0);
510 assert!(!g.has_edge(1, 2));
511 }
512
513 #[test]
514 fn test_delete_nonexistent_edge() {
515 let g = DynamicGraph::new();
516 let result = g.delete_edge(1, 2);
517 assert!(matches!(result, Err(MinCutError::EdgeNotFound(1, 2))));
518 }
519
520 #[test]
521 fn test_neighbors() {
522 let g = DynamicGraph::new();
523 g.insert_edge(1, 2, 1.0).unwrap();
524 g.insert_edge(1, 3, 1.0).unwrap();
525 g.insert_edge(1, 4, 1.0).unwrap();
526
527 let neighbors = g.neighbors(1);
528 assert_eq!(neighbors.len(), 3);
529
530 let neighbor_ids: HashSet<VertexId> = neighbors.iter().map(|(v, _)| *v).collect();
531 assert!(neighbor_ids.contains(&2));
532 assert!(neighbor_ids.contains(&3));
533 assert!(neighbor_ids.contains(&4));
534 }
535
536 #[test]
537 fn test_degree() {
538 let g = DynamicGraph::new();
539 g.insert_edge(1, 2, 1.0).unwrap();
540 g.insert_edge(1, 3, 1.0).unwrap();
541
542 assert_eq!(g.degree(1), 2);
543 assert_eq!(g.degree(2), 1);
544 assert_eq!(g.degree(3), 1);
545 assert_eq!(g.degree(4), 0); }
547
548 #[test]
549 fn test_get_edge() {
550 let g = DynamicGraph::new();
551 g.insert_edge(1, 2, 2.5).unwrap();
552
553 let edge = g.get_edge(1, 2).unwrap();
554 assert_eq!(edge.weight, 2.5);
555 assert_eq!(edge.source, 1);
556 assert_eq!(edge.target, 2);
557
558 let edge = g.get_edge(2, 1).unwrap();
560 assert_eq!(edge.weight, 2.5);
561
562 assert!(g.get_edge(1, 3).is_none());
563 }
564
565 #[test]
566 fn test_stats() {
567 let g = DynamicGraph::new();
568 g.insert_edge(1, 2, 1.0).unwrap();
569 g.insert_edge(2, 3, 2.0).unwrap();
570 g.insert_edge(3, 1, 3.0).unwrap();
571
572 let stats = g.stats();
573 assert_eq!(stats.num_vertices, 3);
574 assert_eq!(stats.num_edges, 3);
575 assert_eq!(stats.total_weight, 6.0);
576 assert_eq!(stats.min_degree, 2);
577 assert_eq!(stats.max_degree, 2);
578 assert_eq!(stats.avg_degree, 2.0);
579 }
580
581 #[test]
582 fn test_is_connected_single_component() {
583 let g = DynamicGraph::new();
584 g.insert_edge(1, 2, 1.0).unwrap();
585 g.insert_edge(2, 3, 1.0).unwrap();
586 g.insert_edge(3, 4, 1.0).unwrap();
587
588 assert!(g.is_connected());
589 }
590
591 #[test]
592 fn test_is_connected_disconnected() {
593 let g = DynamicGraph::new();
594 g.insert_edge(1, 2, 1.0).unwrap();
595 g.insert_edge(3, 4, 1.0).unwrap();
596
597 assert!(!g.is_connected());
598 }
599
600 #[test]
601 fn test_connected_components() {
602 let g = DynamicGraph::new();
603 g.insert_edge(1, 2, 1.0).unwrap();
604 g.insert_edge(2, 3, 1.0).unwrap();
605 g.insert_edge(4, 5, 1.0).unwrap();
606 g.insert_edge(6, 7, 1.0).unwrap();
607 g.insert_edge(7, 8, 1.0).unwrap();
608
609 let components = g.connected_components();
610 assert_eq!(components.len(), 3);
611
612 let mut sizes: Vec<usize> = components.iter().map(|c| c.len()).collect();
614 sizes.sort_unstable();
615 assert_eq!(sizes, vec![2, 3, 3]);
616 }
617
618 #[test]
619 fn test_clear() {
620 let g = DynamicGraph::new();
621 g.insert_edge(1, 2, 1.0).unwrap();
622 g.insert_edge(2, 3, 1.0).unwrap();
623
624 assert_eq!(g.num_vertices(), 3);
625 assert_eq!(g.num_edges(), 2);
626
627 g.clear();
628
629 assert_eq!(g.num_vertices(), 0);
630 assert_eq!(g.num_edges(), 0);
631 }
632
633 #[test]
634 fn test_remove_vertex() {
635 let g = DynamicGraph::new();
636 g.insert_edge(1, 2, 1.0).unwrap();
637 g.insert_edge(2, 3, 1.0).unwrap();
638 g.insert_edge(1, 3, 1.0).unwrap();
639
640 assert_eq!(g.num_vertices(), 3);
641 assert_eq!(g.num_edges(), 3);
642
643 g.remove_vertex(2).unwrap();
644
645 assert_eq!(g.num_vertices(), 2);
646 assert_eq!(g.num_edges(), 1);
647 assert!(!g.has_vertex(2));
648 assert!(g.has_edge(1, 3));
649 assert!(!g.has_edge(1, 2));
650 assert!(!g.has_edge(2, 3));
651 }
652
653 #[test]
654 fn test_edge_weight() {
655 let g = DynamicGraph::new();
656 g.insert_edge(1, 2, 3.5).unwrap();
657
658 assert_eq!(g.edge_weight(1, 2), Some(3.5));
659 assert_eq!(g.edge_weight(2, 1), Some(3.5));
660 assert_eq!(g.edge_weight(1, 3), None);
661 }
662
663 #[test]
664 fn test_update_edge_weight() {
665 let g = DynamicGraph::new();
666 g.insert_edge(1, 2, 1.0).unwrap();
667
668 g.update_edge_weight(1, 2, 5.0).unwrap();
669 assert_eq!(g.edge_weight(1, 2), Some(5.0));
670
671 let result = g.update_edge_weight(1, 3, 2.0);
672 assert!(matches!(result, Err(MinCutError::EdgeNotFound(1, 3))));
673 }
674
675 #[test]
676 fn test_clone() {
677 let g = DynamicGraph::new();
678 g.insert_edge(1, 2, 1.0).unwrap();
679 g.insert_edge(2, 3, 2.0).unwrap();
680
681 let g2 = g.clone();
682
683 assert_eq!(g2.num_vertices(), 3);
684 assert_eq!(g2.num_edges(), 2);
685 assert!(g2.has_edge(1, 2));
686 assert!(g2.has_edge(2, 3));
687 assert_eq!(g2.edge_weight(1, 2), Some(1.0));
688 assert_eq!(g2.edge_weight(2, 3), Some(2.0));
689 }
690
691 #[test]
692 fn test_edge_canonical_endpoints() {
693 let edge = Edge::new(0, 5, 3, 1.0);
694 assert_eq!(edge.canonical_endpoints(), (3, 5));
695
696 let edge = Edge::new(0, 2, 7, 1.0);
697 assert_eq!(edge.canonical_endpoints(), (2, 7));
698 }
699
700 #[test]
701 fn test_edge_other() {
702 let edge = Edge::new(0, 1, 2, 1.0);
703 assert_eq!(edge.other(1), Some(2));
704 assert_eq!(edge.other(2), Some(1));
705 assert_eq!(edge.other(3), None);
706 }
707
708 #[test]
709 fn test_with_capacity() {
710 let g = DynamicGraph::with_capacity(100, 200);
711 assert_eq!(g.num_vertices(), 0);
712 assert_eq!(g.num_edges(), 0);
713
714 g.insert_edge(1, 2, 1.0).unwrap();
716 assert_eq!(g.num_edges(), 1);
717 }
718
719 #[test]
720 fn test_vertices_and_edges() {
721 let g = DynamicGraph::new();
722 g.insert_edge(1, 2, 1.0).unwrap();
723 g.insert_edge(2, 3, 2.0).unwrap();
724
725 let vertices = g.vertices();
726 assert_eq!(vertices.len(), 3);
727 assert!(vertices.contains(&1));
728 assert!(vertices.contains(&2));
729 assert!(vertices.contains(&3));
730
731 let edges = g.edges();
732 assert_eq!(edges.len(), 2);
733 }
734}