problemreductions/topology/
graph.rs1use petgraph::graph::{NodeIndex, UnGraph};
12use petgraph::visit::EdgeRef;
13use serde::{Deserialize, Serialize};
14
15pub trait Graph: Clone + Send + Sync {
42 fn num_vertices(&self) -> usize;
44
45 fn num_edges(&self) -> usize;
47
48 fn edges(&self) -> Vec<(usize, usize)>;
52
53 fn has_edge(&self, u: usize, v: usize) -> bool;
55
56 fn neighbors(&self, v: usize) -> Vec<usize>;
58
59 fn degree(&self, v: usize) -> usize {
61 self.neighbors(v).len()
62 }
63
64 fn is_empty(&self) -> bool {
66 self.num_vertices() == 0
67 }
68
69 fn for_each_edge<F>(&self, mut f: F)
73 where
74 F: FnMut(usize, usize),
75 {
76 for (u, v) in self.edges() {
77 f(u, v);
78 }
79 }
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct SimpleGraph {
101 inner: UnGraph<(), ()>,
102}
103
104impl SimpleGraph {
105 pub fn new(num_vertices: usize, edges: Vec<(usize, usize)>) -> Self {
116 let mut inner = UnGraph::new_undirected();
117 for _ in 0..num_vertices {
118 inner.add_node(());
119 }
120 for (u, v) in edges {
121 assert!(
122 u < num_vertices && v < num_vertices,
123 "edge ({}, {}) references vertex >= num_vertices ({})",
124 u,
125 v,
126 num_vertices
127 );
128 inner.add_edge(NodeIndex::new(u), NodeIndex::new(v), ());
129 }
130 Self { inner }
131 }
132
133 pub fn empty(num_vertices: usize) -> Self {
135 Self::new(num_vertices, vec![])
136 }
137
138 pub fn complete(num_vertices: usize) -> Self {
140 let mut edges = Vec::new();
141 for i in 0..num_vertices {
142 for j in (i + 1)..num_vertices {
143 edges.push((i, j));
144 }
145 }
146 Self::new(num_vertices, edges)
147 }
148
149 pub fn path(num_vertices: usize) -> Self {
151 let edges: Vec<_> = (0..num_vertices.saturating_sub(1))
152 .map(|i| (i, i + 1))
153 .collect();
154 Self::new(num_vertices, edges)
155 }
156
157 pub fn cycle(num_vertices: usize) -> Self {
159 if num_vertices < 3 {
160 return Self::path(num_vertices);
161 }
162 let mut edges: Vec<_> = (0..num_vertices - 1).map(|i| (i, i + 1)).collect();
163 edges.push((num_vertices - 1, 0));
164 Self::new(num_vertices, edges)
165 }
166
167 pub fn star(num_vertices: usize) -> Self {
169 let edges: Vec<_> = (1..num_vertices).map(|i| (0, i)).collect();
170 Self::new(num_vertices, edges)
171 }
172
173 pub fn grid(rows: usize, cols: usize) -> Self {
177 let num_vertices = rows * cols;
178 let mut edges = Vec::new();
179
180 for r in 0..rows {
181 for c in 0..cols {
182 let v = r * cols + c;
183 if c + 1 < cols {
185 edges.push((v, v + 1));
186 }
187 if r + 1 < rows {
189 edges.push((v, v + cols));
190 }
191 }
192 }
193
194 Self::new(num_vertices, edges)
195 }
196}
197
198impl Graph for SimpleGraph {
199 fn num_vertices(&self) -> usize {
200 self.inner.node_count()
201 }
202
203 fn num_edges(&self) -> usize {
204 self.inner.edge_count()
205 }
206
207 fn edges(&self) -> Vec<(usize, usize)> {
208 self.inner
209 .edge_references()
210 .map(|e| (e.source().index(), e.target().index()))
211 .collect()
212 }
213
214 fn has_edge(&self, u: usize, v: usize) -> bool {
215 self.inner
216 .find_edge(NodeIndex::new(u), NodeIndex::new(v))
217 .is_some()
218 }
219
220 fn neighbors(&self, v: usize) -> Vec<usize> {
221 self.inner
222 .neighbors(NodeIndex::new(v))
223 .map(|n| n.index())
224 .collect()
225 }
226}
227
228impl PartialEq for SimpleGraph {
229 fn eq(&self, other: &Self) -> bool {
230 if self.num_vertices() != other.num_vertices() {
231 return false;
232 }
233 if self.num_edges() != other.num_edges() {
234 return false;
235 }
236 let mut self_edges: Vec<_> = self.edges();
238 let mut other_edges: Vec<_> = other.edges();
239 for e in &mut self_edges {
241 if e.0 > e.1 {
242 *e = (e.1, e.0);
243 }
244 }
245 for e in &mut other_edges {
246 if e.0 > e.1 {
247 *e = (e.1, e.0);
248 }
249 }
250 self_edges.sort();
251 other_edges.sort();
252 self_edges == other_edges
253 }
254}
255
256impl Eq for SimpleGraph {}
257
258#[cfg(test)]
259mod tests {
260 use super::*;
261
262 #[test]
263 fn test_simple_graph_new() {
264 let graph = SimpleGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]);
265 assert_eq!(graph.num_vertices(), 4);
266 assert_eq!(graph.num_edges(), 3);
267 }
268
269 #[test]
270 fn test_simple_graph_empty() {
271 let graph = SimpleGraph::empty(5);
272 assert_eq!(graph.num_vertices(), 5);
273 assert_eq!(graph.num_edges(), 0);
274 }
275
276 #[test]
277 fn test_simple_graph_complete() {
278 let graph = SimpleGraph::complete(4);
279 assert_eq!(graph.num_vertices(), 4);
280 assert_eq!(graph.num_edges(), 6); }
282
283 #[test]
284 fn test_simple_graph_path() {
285 let graph = SimpleGraph::path(5);
286 assert_eq!(graph.num_vertices(), 5);
287 assert_eq!(graph.num_edges(), 4);
288 assert!(graph.has_edge(0, 1));
289 assert!(graph.has_edge(3, 4));
290 assert!(!graph.has_edge(0, 4));
291 }
292
293 #[test]
294 fn test_simple_graph_cycle() {
295 let graph = SimpleGraph::cycle(4);
296 assert_eq!(graph.num_vertices(), 4);
297 assert_eq!(graph.num_edges(), 4);
298 assert!(graph.has_edge(0, 1));
299 assert!(graph.has_edge(3, 0)); }
301
302 #[test]
303 fn test_simple_graph_star() {
304 let graph = SimpleGraph::star(5);
305 assert_eq!(graph.num_vertices(), 5);
306 assert_eq!(graph.num_edges(), 4);
307 assert!(graph.has_edge(0, 1));
308 assert!(graph.has_edge(0, 4));
309 assert!(!graph.has_edge(1, 2));
310 }
311
312 #[test]
313 fn test_simple_graph_grid() {
314 let graph = SimpleGraph::grid(2, 3);
315 assert_eq!(graph.num_vertices(), 6);
316 assert_eq!(graph.num_edges(), 7);
319 }
320
321 #[test]
322 fn test_simple_graph_has_edge() {
323 let graph = SimpleGraph::new(3, vec![(0, 1), (1, 2)]);
324 assert!(graph.has_edge(0, 1));
325 assert!(graph.has_edge(1, 0)); assert!(graph.has_edge(1, 2));
327 assert!(!graph.has_edge(0, 2));
328 }
329
330 #[test]
331 fn test_simple_graph_neighbors() {
332 let graph = SimpleGraph::new(4, vec![(0, 1), (0, 2), (0, 3)]);
333 let mut neighbors = graph.neighbors(0);
334 neighbors.sort();
335 assert_eq!(neighbors, vec![1, 2, 3]);
336 assert_eq!(graph.neighbors(1), vec![0]);
337 }
338
339 #[test]
340 fn test_simple_graph_degree() {
341 let graph = SimpleGraph::new(4, vec![(0, 1), (0, 2), (0, 3)]);
342 assert_eq!(graph.degree(0), 3);
343 assert_eq!(graph.degree(1), 1);
344 }
345
346 #[test]
347 fn test_simple_graph_is_empty() {
348 let empty = SimpleGraph::empty(0);
349 assert!(empty.is_empty());
350
351 let non_empty = SimpleGraph::empty(1);
352 assert!(!non_empty.is_empty());
353 }
354
355 #[test]
356 fn test_simple_graph_for_each_edge() {
357 let graph = SimpleGraph::new(3, vec![(0, 1), (1, 2)]);
358 let mut count = 0;
359 graph.for_each_edge(|_, _| count += 1);
360 assert_eq!(count, 2);
361 }
362
363 #[test]
364 fn test_simple_graph_eq() {
365 let g1 = SimpleGraph::new(3, vec![(0, 1), (1, 2)]);
366 let g2 = SimpleGraph::new(3, vec![(1, 2), (0, 1)]); let g3 = SimpleGraph::new(3, vec![(0, 1)]);
368
369 assert_eq!(g1, g2);
370 assert_ne!(g1, g3);
371 }
372
373 #[test]
374 #[should_panic(expected = "edge (0, 5) references vertex >= num_vertices")]
375 fn test_simple_graph_invalid_edge() {
376 SimpleGraph::new(3, vec![(0, 5)]);
377 }
378}