problemreductions/topology/
graph.rs1use petgraph::graph::{NodeIndex, UnGraph};
12use petgraph::visit::EdgeRef;
13use serde::{Deserialize, Serialize};
14
15pub trait Graph: Clone + Send + Sync + 'static {
42 const NAME: &'static str;
44
45 fn num_vertices(&self) -> usize;
47
48 fn num_edges(&self) -> usize;
50
51 fn edges(&self) -> Vec<(usize, usize)>;
55
56 fn has_edge(&self, u: usize, v: usize) -> bool;
58
59 fn neighbors(&self, v: usize) -> Vec<usize>;
61
62 fn degree(&self, v: usize) -> usize {
64 self.neighbors(v).len()
65 }
66
67 fn is_empty(&self) -> bool {
69 self.num_vertices() == 0
70 }
71
72 fn for_each_edge<F>(&self, mut f: F)
76 where
77 F: FnMut(usize, usize),
78 {
79 for (u, v) in self.edges() {
80 f(u, v);
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
103pub struct SimpleGraph {
104 inner: UnGraph<(), ()>,
105}
106
107impl SimpleGraph {
108 pub fn new(num_vertices: usize, edges: Vec<(usize, usize)>) -> Self {
119 let mut inner = UnGraph::new_undirected();
120 for _ in 0..num_vertices {
121 inner.add_node(());
122 }
123 for (u, v) in edges {
124 assert!(
125 u < num_vertices && v < num_vertices,
126 "edge ({}, {}) references vertex >= num_vertices ({})",
127 u,
128 v,
129 num_vertices
130 );
131 inner.add_edge(NodeIndex::new(u), NodeIndex::new(v), ());
132 }
133 Self { inner }
134 }
135
136 pub fn empty(num_vertices: usize) -> Self {
138 Self::new(num_vertices, vec![])
139 }
140
141 pub fn complete(num_vertices: usize) -> Self {
143 let mut edges = Vec::new();
144 for i in 0..num_vertices {
145 for j in (i + 1)..num_vertices {
146 edges.push((i, j));
147 }
148 }
149 Self::new(num_vertices, edges)
150 }
151
152 pub fn path(num_vertices: usize) -> Self {
154 let edges: Vec<_> = (0..num_vertices.saturating_sub(1))
155 .map(|i| (i, i + 1))
156 .collect();
157 Self::new(num_vertices, edges)
158 }
159
160 pub fn cycle(num_vertices: usize) -> Self {
162 if num_vertices < 3 {
163 return Self::path(num_vertices);
164 }
165 let mut edges: Vec<_> = (0..num_vertices - 1).map(|i| (i, i + 1)).collect();
166 edges.push((num_vertices - 1, 0));
167 Self::new(num_vertices, edges)
168 }
169
170 pub fn star(num_vertices: usize) -> Self {
172 let edges: Vec<_> = (1..num_vertices).map(|i| (0, i)).collect();
173 Self::new(num_vertices, edges)
174 }
175
176 pub fn grid(rows: usize, cols: usize) -> Self {
180 let num_vertices = rows * cols;
181 let mut edges = Vec::new();
182
183 for r in 0..rows {
184 for c in 0..cols {
185 let v = r * cols + c;
186 if c + 1 < cols {
188 edges.push((v, v + 1));
189 }
190 if r + 1 < rows {
192 edges.push((v, v + cols));
193 }
194 }
195 }
196
197 Self::new(num_vertices, edges)
198 }
199}
200
201impl Graph for SimpleGraph {
202 const NAME: &'static str = "SimpleGraph";
203
204 fn num_vertices(&self) -> usize {
205 self.inner.node_count()
206 }
207
208 fn num_edges(&self) -> usize {
209 self.inner.edge_count()
210 }
211
212 fn edges(&self) -> Vec<(usize, usize)> {
213 self.inner
214 .edge_references()
215 .map(|e| (e.source().index(), e.target().index()))
216 .collect()
217 }
218
219 fn has_edge(&self, u: usize, v: usize) -> bool {
220 self.inner
221 .find_edge(NodeIndex::new(u), NodeIndex::new(v))
222 .is_some()
223 }
224
225 fn neighbors(&self, v: usize) -> Vec<usize> {
226 self.inner
227 .neighbors(NodeIndex::new(v))
228 .map(|n| n.index())
229 .collect()
230 }
231}
232
233impl PartialEq for SimpleGraph {
234 fn eq(&self, other: &Self) -> bool {
235 if self.num_vertices() != other.num_vertices() {
236 return false;
237 }
238 if self.num_edges() != other.num_edges() {
239 return false;
240 }
241 let mut self_edges: Vec<_> = self.edges();
243 let mut other_edges: Vec<_> = other.edges();
244 for e in &mut self_edges {
246 if e.0 > e.1 {
247 *e = (e.1, e.0);
248 }
249 }
250 for e in &mut other_edges {
251 if e.0 > e.1 {
252 *e = (e.1, e.0);
253 }
254 }
255 self_edges.sort();
256 other_edges.sort();
257 self_edges == other_edges
258 }
259}
260
261impl Eq for SimpleGraph {}
262
263impl Serialize for SimpleGraph {
264 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
265 use serde::ser::SerializeStruct;
266 let mut state = serializer.serialize_struct("SimpleGraph", 2)?;
267 state.serialize_field("num_vertices", &self.num_vertices())?;
268 let edges: Vec<(usize, usize)> = self.edges();
269 state.serialize_field("edges", &edges)?;
270 state.end()
271 }
272}
273
274impl<'de> Deserialize<'de> for SimpleGraph {
275 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
276 #[derive(Deserialize)]
277 struct GraphData {
278 num_vertices: usize,
279 edges: Vec<(usize, usize)>,
280 }
281 let data = GraphData::deserialize(deserializer)?;
282 Ok(SimpleGraph::new(data.num_vertices, data.edges))
283 }
284}
285
286use crate::impl_variant_param;
287impl_variant_param!(SimpleGraph, "graph");
288
289#[cfg(test)]
290#[path = "../unit_tests/topology/graph.rs"]
291mod tests;