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 Self::try_new(num_vertices, edges).unwrap_or_else(|error| panic!("{error}"))
120 }
121
122 fn try_new(
123 num_vertices: usize,
124 edges: Vec<(usize, usize)>,
125 ) -> Result<Self, crate::registry::ConstructionError> {
126 let mut inner = UnGraph::new_undirected();
127 for _ in 0..num_vertices {
128 inner.add_node(());
129 }
130 for (u, v) in edges {
131 if !(u < num_vertices && v < num_vertices) {
132 return Err(format!(
133 "edge ({}, {}) references vertex >= num_vertices ({})",
134 u, v, num_vertices
135 )
136 .into());
137 }
138 inner.add_edge(NodeIndex::new(u), NodeIndex::new(v), ());
139 }
140 Ok(Self { inner })
141 }
142
143 pub fn empty(num_vertices: usize) -> Self {
145 Self::new(num_vertices, vec![])
146 }
147
148 pub fn complete(num_vertices: usize) -> Self {
150 let mut edges = Vec::new();
151 for i in 0..num_vertices {
152 for j in (i + 1)..num_vertices {
153 edges.push((i, j));
154 }
155 }
156 Self::new(num_vertices, edges)
157 }
158
159 pub fn path(num_vertices: usize) -> Self {
161 let edges: Vec<_> = (0..num_vertices.saturating_sub(1))
162 .map(|i| (i, i + 1))
163 .collect();
164 Self::new(num_vertices, edges)
165 }
166
167 pub fn cycle(num_vertices: usize) -> Self {
169 if num_vertices < 3 {
170 return Self::path(num_vertices);
171 }
172 let mut edges: Vec<_> = (0..num_vertices - 1).map(|i| (i, i + 1)).collect();
173 edges.push((num_vertices - 1, 0));
174 Self::new(num_vertices, edges)
175 }
176
177 pub fn star(num_vertices: usize) -> Self {
179 let edges: Vec<_> = (1..num_vertices).map(|i| (0, i)).collect();
180 Self::new(num_vertices, edges)
181 }
182
183 pub fn grid(rows: usize, cols: usize) -> Self {
187 let num_vertices = rows * cols;
188 let mut edges = Vec::new();
189
190 for r in 0..rows {
191 for c in 0..cols {
192 let v = r * cols + c;
193 if c + 1 < cols {
195 edges.push((v, v + 1));
196 }
197 if r + 1 < rows {
199 edges.push((v, v + cols));
200 }
201 }
202 }
203
204 Self::new(num_vertices, edges)
205 }
206}
207
208impl Graph for SimpleGraph {
209 const NAME: &'static str = "SimpleGraph";
210
211 fn num_vertices(&self) -> usize {
212 self.inner.node_count()
213 }
214
215 fn num_edges(&self) -> usize {
216 self.inner.edge_count()
217 }
218
219 fn edges(&self) -> Vec<(usize, usize)> {
220 self.inner
221 .edge_references()
222 .map(|e| (e.source().index(), e.target().index()))
223 .collect()
224 }
225
226 fn has_edge(&self, u: usize, v: usize) -> bool {
227 self.inner
228 .find_edge(NodeIndex::new(u), NodeIndex::new(v))
229 .is_some()
230 }
231
232 fn neighbors(&self, v: usize) -> Vec<usize> {
233 self.inner
234 .neighbors(NodeIndex::new(v))
235 .map(|n| n.index())
236 .collect()
237 }
238}
239
240impl PartialEq for SimpleGraph {
241 fn eq(&self, other: &Self) -> bool {
242 if self.num_vertices() != other.num_vertices() {
243 return false;
244 }
245 if self.num_edges() != other.num_edges() {
246 return false;
247 }
248 let mut self_edges: Vec<_> = self.edges();
250 let mut other_edges: Vec<_> = other.edges();
251 for e in &mut self_edges {
253 if e.0 > e.1 {
254 *e = (e.1, e.0);
255 }
256 }
257 for e in &mut other_edges {
258 if e.0 > e.1 {
259 *e = (e.1, e.0);
260 }
261 }
262 self_edges.sort();
263 other_edges.sort();
264 self_edges == other_edges
265 }
266}
267
268impl Eq for SimpleGraph {}
269
270impl Serialize for SimpleGraph {
271 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
272 use serde::ser::SerializeStruct;
273 let mut state = serializer.serialize_struct("SimpleGraph", 2)?;
274 state.serialize_field("num_vertices", &self.num_vertices())?;
275 let edges: Vec<(usize, usize)> = self.edges();
276 state.serialize_field("edges", &edges)?;
277 state.end()
278 }
279}
280
281impl<'de> Deserialize<'de> for SimpleGraph {
282 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
283 #[derive(Deserialize)]
284 struct GraphData {
285 num_vertices: usize,
286 edges: Vec<(usize, usize)>,
287 }
288 let data = GraphData::deserialize(deserializer)?;
289 SimpleGraph::try_new(data.num_vertices, data.edges).map_err(serde::de::Error::custom)
290 }
291}
292
293use crate::impl_variant_param;
294impl_variant_param!(SimpleGraph, "graph");
295
296#[cfg(test)]
297#[path = "../unit_tests/topology/graph.rs"]
298mod tests;