1
2
3#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct Edge {
6 pub src: usize,
7 pub dst: usize,
8 pub weight: f64,
9}
10
11impl Edge {
12 pub fn new(src: usize, dst: usize, weight: f64) -> Self {
13 Edge { src, dst, weight }
14 }
15}
16
17#[derive(Debug, Clone)]
19pub struct Graph {
20 pub n_vertices: usize,
21 pub n_edges: usize,
22 pub edges: Vec<Edge>,
23}
24
25impl Graph {
26 pub fn new(n_vertices: usize, edges: Vec<Edge>) -> Self {
27 let n_edges = edges.len();
28 Graph {
29 n_vertices,
30 n_edges,
31 edges,
32 }
33 }
34
35 pub fn cycle(n: usize) -> Self {
37 let edges: Vec<Edge> = (0..n)
38 .map(|i| Edge::new(i, (i + 1) % n, 1.0))
39 .collect();
40 Graph::new(n, edges)
41 }
42
43 pub fn path(n: usize) -> Self {
45 assert!(n >= 2, "path graph needs at least 2 vertices");
46 let edges: Vec<Edge> = (0..n - 1)
47 .map(|i| Edge::new(i, i + 1, 1.0))
48 .collect();
49 Graph::new(n, edges)
50 }
51
52 pub fn complete(n: usize) -> Self {
54 let mut edges = Vec::with_capacity(n * (n - 1) / 2);
55 for i in 0..n {
56 for j in (i + 1)..n {
57 edges.push(Edge::new(i, j, 1.0));
58 }
59 }
60 Graph::new(n, edges)
61 }
62
63 pub fn expander(n: usize) -> Self {
65 let max_edges = n * 3;
66 let mut edges = Vec::with_capacity(max_edges);
67 for i in 0..n {
68 let targets = [(i + 1) % n, (i + 2) % n, (i + n / 3) % n];
69 for &t in &targets {
70 let (a, b) = if i < t { (i, t) } else { (t, i) };
71 if !edges.iter().any(|e: &Edge| e.src == a && e.dst == b) {
72 edges.push(Edge::new(a, b, 1.0));
73 }
74 }
75 }
76 Graph::new(n, edges)
77 }
78
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_cycle_4_vertices() {
87 let g = Graph::cycle(4);
88 assert_eq!(g.n_vertices, 4);
89 assert_eq!(g.n_edges, 4);
90 for i in 0..4 {
91 assert_eq!(g.edges[i].src, i);
92 assert_eq!(g.edges[i].dst, (i + 1) % 4);
93 }
94 }
95
96 #[test]
97 fn test_path_5() {
98 let g = Graph::path(5);
99 assert_eq!(g.n_vertices, 5);
100 assert_eq!(g.n_edges, 4);
101 }
102
103 #[test]
104 fn test_complete_k4() {
105 let g = Graph::complete(4);
106 assert_eq!(g.n_vertices, 4);
107 assert_eq!(g.n_edges, 6);
108 }
109
110 #[test]
111 fn test_expander_10() {
112 let g = Graph::expander(10);
113 assert_eq!(g.n_vertices, 10);
114 assert!(g.n_edges >= 10);
115 }
116
117 #[test]
118 fn test_cycle_3() {
119 let g = Graph::cycle(3);
120 assert_eq!(g.n_vertices, 3);
121 assert_eq!(g.n_edges, 3);
122 }
123
124 #[test]
125 fn test_new_graph() {
126 let edges = vec![Edge::new(0, 1, 2.0)];
127 let g = Graph::new(2, edges);
128 assert_eq!(g.n_vertices, 2);
129 assert_eq!(g.n_edges, 1);
130 assert!((g.edges[0].weight - 2.0).abs() < 1e-12);
131 }
132}