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
85pub trait GraphCast<Target: Graph>: Graph {
92 fn cast_graph(&self) -> Target;
94}
95
96impl<G: Graph> GraphCast<SimpleGraph> for G {
98 fn cast_graph(&self) -> SimpleGraph {
99 SimpleGraph::new(self.num_vertices(), self.edges())
100 }
101}
102
103#[derive(Debug, Clone)]
121pub struct SimpleGraph {
122 inner: UnGraph<(), ()>,
123}
124
125impl SimpleGraph {
126 pub fn new(num_vertices: usize, edges: Vec<(usize, usize)>) -> Self {
137 let mut inner = UnGraph::new_undirected();
138 for _ in 0..num_vertices {
139 inner.add_node(());
140 }
141 for (u, v) in edges {
142 assert!(
143 u < num_vertices && v < num_vertices,
144 "edge ({}, {}) references vertex >= num_vertices ({})",
145 u,
146 v,
147 num_vertices
148 );
149 inner.add_edge(NodeIndex::new(u), NodeIndex::new(v), ());
150 }
151 Self { inner }
152 }
153
154 pub fn empty(num_vertices: usize) -> Self {
156 Self::new(num_vertices, vec![])
157 }
158
159 pub fn complete(num_vertices: usize) -> Self {
161 let mut edges = Vec::new();
162 for i in 0..num_vertices {
163 for j in (i + 1)..num_vertices {
164 edges.push((i, j));
165 }
166 }
167 Self::new(num_vertices, edges)
168 }
169
170 pub fn path(num_vertices: usize) -> Self {
172 let edges: Vec<_> = (0..num_vertices.saturating_sub(1))
173 .map(|i| (i, i + 1))
174 .collect();
175 Self::new(num_vertices, edges)
176 }
177
178 pub fn cycle(num_vertices: usize) -> Self {
180 if num_vertices < 3 {
181 return Self::path(num_vertices);
182 }
183 let mut edges: Vec<_> = (0..num_vertices - 1).map(|i| (i, i + 1)).collect();
184 edges.push((num_vertices - 1, 0));
185 Self::new(num_vertices, edges)
186 }
187
188 pub fn star(num_vertices: usize) -> Self {
190 let edges: Vec<_> = (1..num_vertices).map(|i| (0, i)).collect();
191 Self::new(num_vertices, edges)
192 }
193
194 pub fn grid(rows: usize, cols: usize) -> Self {
198 let num_vertices = rows * cols;
199 let mut edges = Vec::new();
200
201 for r in 0..rows {
202 for c in 0..cols {
203 let v = r * cols + c;
204 if c + 1 < cols {
206 edges.push((v, v + 1));
207 }
208 if r + 1 < rows {
210 edges.push((v, v + cols));
211 }
212 }
213 }
214
215 Self::new(num_vertices, edges)
216 }
217}
218
219impl Graph for SimpleGraph {
220 const NAME: &'static str = "SimpleGraph";
221
222 fn num_vertices(&self) -> usize {
223 self.inner.node_count()
224 }
225
226 fn num_edges(&self) -> usize {
227 self.inner.edge_count()
228 }
229
230 fn edges(&self) -> Vec<(usize, usize)> {
231 self.inner
232 .edge_references()
233 .map(|e| (e.source().index(), e.target().index()))
234 .collect()
235 }
236
237 fn has_edge(&self, u: usize, v: usize) -> bool {
238 self.inner
239 .find_edge(NodeIndex::new(u), NodeIndex::new(v))
240 .is_some()
241 }
242
243 fn neighbors(&self, v: usize) -> Vec<usize> {
244 self.inner
245 .neighbors(NodeIndex::new(v))
246 .map(|n| n.index())
247 .collect()
248 }
249}
250
251impl PartialEq for SimpleGraph {
252 fn eq(&self, other: &Self) -> bool {
253 if self.num_vertices() != other.num_vertices() {
254 return false;
255 }
256 if self.num_edges() != other.num_edges() {
257 return false;
258 }
259 let mut self_edges: Vec<_> = self.edges();
261 let mut other_edges: Vec<_> = other.edges();
262 for e in &mut self_edges {
264 if e.0 > e.1 {
265 *e = (e.1, e.0);
266 }
267 }
268 for e in &mut other_edges {
269 if e.0 > e.1 {
270 *e = (e.1, e.0);
271 }
272 }
273 self_edges.sort();
274 other_edges.sort();
275 self_edges == other_edges
276 }
277}
278
279impl Eq for SimpleGraph {}
280
281impl Serialize for SimpleGraph {
282 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
283 use serde::ser::SerializeStruct;
284 let mut state = serializer.serialize_struct("SimpleGraph", 2)?;
285 state.serialize_field("num_vertices", &self.num_vertices())?;
286 let edges: Vec<(usize, usize)> = self.edges();
287 state.serialize_field("edges", &edges)?;
288 state.end()
289 }
290}
291
292impl<'de> Deserialize<'de> for SimpleGraph {
293 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
294 #[derive(Deserialize)]
295 struct GraphData {
296 num_vertices: usize,
297 edges: Vec<(usize, usize)>,
298 }
299 let data = GraphData::deserialize(deserializer)?;
300 Ok(SimpleGraph::new(data.num_vertices, data.edges))
301 }
302}
303
304use crate::impl_variant_param;
305impl_variant_param!(SimpleGraph, "graph");
306
307#[cfg(test)]
308#[path = "../unit_tests/topology/graph.rs"]
309mod tests;