algograph/graph/undirected/
tree_backed.rs1use crate::graph::*;
2use std::collections::{BTreeMap, BTreeSet};
3
4#[derive(Clone)]
23pub struct TreeBackedGraph {
24 vid_factory: VertexIdFactory,
25 eid_factory: EdgeIdFactory,
26 vertices: BTreeSet<VertexId>,
27 edges: BTreeMap<EdgeId, (VertexId, VertexId)>,
28 adjacent_edges: BTreeSet<(VertexId, VertexId, EdgeId)>,
29}
30
31impl DirectedOrNot for TreeBackedGraph {
32 const DIRECTED_OR_NOT: bool = false;
33}
34
35impl std::fmt::Debug for TreeBackedGraph {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 writeln!(f, "TreeBackedGraph {{")?;
38 for v in self.vertices.iter() {
39 writeln!(f, "{:?}:", v)?;
40 for e in self.out_edges(v) {
41 writeln!(f, " -> {:?} by {:?}", e.sink, e.id)?;
42 }
43 }
44 writeln!(f, "}}")?;
45 Ok(())
46 }
47}
48
49impl GrowableGraph for TreeBackedGraph {
50 fn new() -> Self {
51 Self {
52 vid_factory: VertexIdFactory::new(),
53 eid_factory: EdgeIdFactory::new(),
54 vertices: BTreeSet::new(),
55 edges: BTreeMap::new(),
56 adjacent_edges: BTreeSet::new(),
57 }
58 }
59
60 fn add_vertex(&mut self) -> VertexId {
61 let vid = self.vid_factory.one_more();
62 self.vertices.insert(vid);
63 vid
64 }
65
66 fn add_edge(&mut self, source: VertexId, sink: VertexId) -> EdgeId {
67 debug_assert!(self.vertices.contains(&source));
68 debug_assert!(self.vertices.contains(&sink));
69 let eid = self.eid_factory.one_more();
70 self.edges.insert(eid, (source, sink));
71 self.adjacent_edges.insert((sink, source, eid));
72 self.adjacent_edges.insert((source, sink, eid));
73 eid
74 }
75}
76
77impl EdgeShrinkableGraph for TreeBackedGraph {
78 fn remove_edge(&mut self, edge: &EdgeId) -> Option<Edge> {
79 match self.edges.remove(edge) {
80 None => None,
81 Some((src, snk)) => {
82 self.adjacent_edges.remove(&(snk, src, *edge));
83 self.adjacent_edges.remove(&(src, snk, *edge));
84 Some(Edge {
85 id: *edge,
86 source: src,
87 sink: snk,
88 })
89 }
90 }
91 }
92}
93
94impl VertexShrinkableGraph for TreeBackedGraph {
95 fn remove_vertex(&mut self, vertex: &VertexId) -> Box<dyn Iterator<Item = Edge> + 'static> {
96 if !self.vertices.remove(vertex) {
97 return Box::new(std::iter::empty());
98 }
99 let start = (*vertex, VertexId::MIN, EdgeId::MIN);
100 let end = (vertex.next(), VertexId::MIN, EdgeId::MIN);
101 let res: BTreeSet<_> = self
102 .adjacent_edges
103 .range(start..end)
104 .map(|(snk, src, edge)| Edge {
105 id: *edge,
106 source: *src,
107 sink: *snk,
108 })
109 .collect();
110 for x in res.iter() {
111 self.remove_edge(&x.id);
112 }
113 Box::new(res.into_iter())
114 }
115}
116
117impl QueryableGraph for TreeBackedGraph {
118 fn vertex_size(&self) -> usize {
119 self.vertices.len()
120 }
121
122 fn iter_vertices(&self) -> Box<dyn Iterator<Item = VertexId> + '_> {
123 Box::new(self.vertices.iter().copied())
124 }
125
126 fn contains_vertex(&self, v: &VertexId) -> bool {
127 self.vertices.contains(v)
128 }
129
130 fn edge_size(&self) -> usize {
131 self.edges.len()
132 }
133
134 fn iter_edges(&self) -> Box<dyn Iterator<Item = Edge> + '_> {
135 Box::new(self.edges.iter().map(|(e, (src, snk))| Edge {
136 id: *e,
137 source: *src,
138 sink: *snk,
139 }))
140 }
141
142 fn contains_edge(&self, e: &EdgeId) -> bool {
143 self.edges.contains_key(e)
144 }
145
146 fn find_edge(&self, e: &EdgeId) -> Option<Edge> {
147 self.edges.get(e).map(|(src, snk)| Edge {
148 id: *e,
149 source: *src,
150 sink: *snk,
151 })
152 }
153
154 fn in_edges(&self, v: &VertexId) -> Box<dyn Iterator<Item = Edge> + '_> {
155 let start = (*v, VertexId::MIN, EdgeId::MIN);
156 let end = (v.next(), VertexId::MIN, EdgeId::MIN);
157 let it = self
158 .adjacent_edges
159 .range(start..end)
160 .map(|(snk, src, e)| Edge {
161 id: *e,
162 source: *src,
163 sink: *snk,
164 });
165 Box::new(it)
166 }
167
168 fn out_edges(&self, v: &VertexId) -> Box<dyn Iterator<Item = Edge> + '_> {
169 let it = self.in_edges(v).map(|e| Edge {
170 id: e.id,
171 source: e.sink,
172 sink: e.source,
173 });
174 Box::new(it)
175 }
176
177 fn edges_connecting<'a, 'b>(
178 &'a self,
179 source: &'b VertexId,
180 sink: &'b VertexId,
181 ) -> Box<dyn Iterator<Item = Edge> + 'a> {
182 let source = *source;
183 let sink = *sink;
184 let start = (source, sink, EdgeId::MIN);
185 let end = (source, sink, EdgeId::MAX);
186 let it = self
187 .adjacent_edges
188 .range(start..=end)
189 .map(move |(_, _, eid)| Edge {
190 id: *eid,
191 source,
192 sink,
193 });
194 Box::new(it)
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use crate::graph::*;
201 use quickcheck_macros::*;
202
203 #[quickcheck]
204 fn tree_backed_gen(ops: directed::Ops) {
205 let dig: MappedGraph<directed::AdjacentListGraph> = (&ops).into();
206 let oracle: MappedGraph<undirected::AdjacentListGraph> = dig.transform();
207 let trial: MappedGraph<undirected::TreeBackedGraph> = dig.transform();
208 assert_eq!(oracle, trial);
209 }
210}