graphmind_graph_algorithms/
topology.rs1use super::common::GraphView;
6use std::collections::HashSet;
7
8pub fn count_triangles(view: &GraphView) -> usize {
14 let mut triangle_count = 0;
15
16 for u in 0..view.node_count {
20 let u_neighbors: HashSet<_> = view
21 .successors(u)
22 .iter()
23 .chain(view.predecessors(u).iter())
24 .cloned()
25 .collect();
26
27 for &v in &u_neighbors {
28 if v <= u {
29 continue;
30 } let v_neighbors: HashSet<_> = view
33 .successors(v)
34 .iter()
35 .chain(view.predecessors(v).iter())
36 .cloned()
37 .collect();
38
39 for &w in &v_neighbors {
40 if w <= v {
41 continue;
42 } if u_neighbors.contains(&w) {
46 triangle_count += 1;
47 }
48 }
49 }
50 }
51
52 triangle_count
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use std::collections::HashMap;
59
60 #[test]
61 fn test_triangle_counting() {
62 let node_count = 4;
66 let mut outgoing = vec![vec![]; 4];
67 let mut incoming = vec![vec![]; 4];
68
69 for i in 0..4 {
70 for j in (i + 1)..4 {
71 outgoing[i].push(j);
72 incoming[j].push(i);
73 }
74 }
75
76 let view = GraphView::from_adjacency_list(
77 node_count,
78 vec![0, 1, 2, 3],
79 HashMap::new(),
80 outgoing,
81 incoming,
82 None,
83 );
84
85 let count = count_triangles(&view);
86 assert_eq!(count, 4);
87 }
88}