fera_graph/graphs/adaptors/
spanning_subgraph.rs1use choose::Choose;
6use graphs::OutNeighborFromOutEdge;
7use params::IntoOwned;
8use prelude::*;
9use props::{DelegateEdgeProp, DelegateVertexProp};
10
11use std::iter::Cloned;
12use std::slice;
13
14use fera_fun::position_of;
15use rand::Rng;
16
17pub struct SpanningSubgraph<'a, G>
19where
20 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
21{
22 g: &'a G,
23 edges: Vec<Edge<G>>,
24 out_edges: DefaultVertexPropMut<G, Vec<Edge<G>>>,
25}
26
27impl<'a, G> SpanningSubgraph<'a, G>
28where
29 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
30{
31 #[doc(hidden)]
32 pub fn new(g: &'a G) -> Self {
33 SpanningSubgraph {
34 g: g,
35 edges: vec![],
36 out_edges: g.vertex_prop(vec![]),
37 }
38 }
39
40 pub fn add_edge(&mut self, e: Edge<G>) {
41 let (u, v) = self.g.ends(e);
42 self.edges.push(e);
43 self.out_edges[u].push(e);
44 if self.g.orientation(e).is_undirected() {
45 self.out_edges[v].push(self.g.get_reverse(e).unwrap());
46 }
47 }
48
49 pub fn set_edges<I>(&mut self, iter: I)
50 where
51 G: VertexList,
52 I: IntoIterator,
53 I::Item: IntoOwned<Edge<G>>,
54 {
55 self.clear_edges();
56 for e in iter {
57 self.add_edge(e.into_owned());
58 }
59 }
60
61 pub fn add_edges<I>(&mut self, iter: I)
62 where
63 I: IntoIterator,
64 I::Item: IntoOwned<Edge<G>>,
65 {
66 for e in iter {
67 self.add_edge(e.into_owned());
68 }
69 }
70
71 pub fn clear_edges(&mut self)
72 where
73 G: VertexList,
74 {
75 self.edges.clear();
77 for u in self.g.vertices() {
78 self.out_edges[u].clear();
79 }
80 }
81
82 pub fn replace_edge(&mut self, old: Edge<G>, new: Edge<G>) {
83 self.remove_edge(old);
84 self.add_edge(new);
85 }
86
87 pub fn remove_edge(&mut self, e: Edge<G>) {
88 let (u, v) = self.g.ends(e);
89 assert!(vec_find_swap_remove(&mut self.edges, &e));
90 assert!(vec_find_swap_remove(&mut self.out_edges[u], &e));
91 if self.g.orientation(e).is_undirected() {
92 assert!(vec_find_swap_remove(&mut self.out_edges[v], &e));
93 }
94 }
95}
96
97#[inline]
98fn vec_find_swap_remove<T: PartialEq>(vec: &mut Vec<T>, value: &T) -> bool {
99 if let Some(i) = position_of(&*vec, value) {
100 vec.swap_remove(i);
101 true
102 } else {
103 false
104 }
105}
106
107impl<'a, G> AsRef<G> for SpanningSubgraph<'a, G>
110where
111 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
112{
113 #[inline]
114 fn as_ref(&self) -> &G {
115 self.g
116 }
117}
118
119impl<'a, 'b, G> VertexTypes<'a, SpanningSubgraph<'b, G>> for SpanningSubgraph<'b, G>
120where
121 G: 'b + WithEdge + WithVertexProp<Vec<Edge<G>>>,
122{
123 type VertexIter = VertexIter<'b, G>;
124 type OutNeighborIter = OutNeighborFromOutEdge<'b, G, OutEdgeIter<'a, Self>>;
125}
126
127impl<'a, G> WithVertex for SpanningSubgraph<'a, G>
128where
129 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
130{
131 type Vertex = Vertex<G>;
132 type OptionVertex = OptionVertex<G>;
133}
134
135impl<'a, 'b, G> EdgeTypes<'a, SpanningSubgraph<'b, G>> for SpanningSubgraph<'b, G>
136where
137 G: 'b + WithEdge + WithVertexProp<Vec<Edge<G>>>,
138{
139 type EdgeIter = Cloned<slice::Iter<'a, Edge<G>>>;
140 type OutEdgeIter = Cloned<slice::Iter<'a, Edge<G>>>;
141}
142
143impl<'a, G> WithEdge for SpanningSubgraph<'a, G>
144where
145 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
146{
147 type Kind = G::Kind;
148 type Edge = Edge<G>;
149 type OptionEdge = OptionEdge<G>;
150
151 fn source(&self, e: Edge<Self>) -> Vertex<Self> {
152 self.g.source(e)
153 }
154
155 fn target(&self, e: Edge<Self>) -> Vertex<Self> {
156 self.g.target(e)
157 }
158
159 fn orientation(&self, e: Edge<Self>) -> Orientation {
160 self.g.orientation(e)
161 }
162
163 fn end_vertices(&self, e: Edge<Self>) -> (Vertex<Self>, Vertex<Self>) {
164 self.g.end_vertices(e)
165 }
166
167 fn opposite(&self, u: Vertex<Self>, e: Edge<Self>) -> Vertex<Self> {
168 self.g.opposite(u, e)
169 }
170
171 fn get_reverse(&self, e: Edge<Self>) -> Option<Edge<Self>> {
179 self.g.get_reverse(e)
180 }
181}
182
183impl<'a, G> VertexList for SpanningSubgraph<'a, G>
184where
185 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + VertexList,
186{
187 fn num_vertices(&self) -> usize {
188 self.g.num_vertices()
189 }
190
191 fn vertices(&self) -> VertexIter<Self> {
192 self.g.vertices()
193 }
194}
195
196impl<'a, G> EdgeList for SpanningSubgraph<'a, G>
197where
198 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
199{
200 fn num_edges(&self) -> usize {
201 self.edges.len()
202 }
203
204 fn edges(&self) -> EdgeIter<Self> {
205 self.edges.iter().cloned()
206 }
207
208 fn get_edge_by_ends(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Edge<Self>> {
209 self.out_edges(u).find(|e| (u, v) == self.ends(*e))
210 }
211}
212
213impl<'a, G> Adjacency for SpanningSubgraph<'a, G>
214where
215 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
216{
217 fn out_neighbors(&self, v: Vertex<Self>) -> OutNeighborIter<Self> {
218 OutNeighborFromOutEdge::new(self.g, self.out_edges(v))
219 }
220
221 fn out_degree(&self, v: Vertex<Self>) -> usize {
222 self.out_edges[v].len()
223 }
224}
225
226impl<'a, G> Incidence for SpanningSubgraph<'a, G>
227where
228 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>>,
229{
230 fn out_edges(&self, v: Vertex<Self>) -> OutEdgeIter<Self> {
231 self.out_edges[v].iter().cloned()
232 }
233}
234
235impl<'a, G, T> WithVertexProp<T> for SpanningSubgraph<'a, G>
236where
237 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + WithVertexProp<T>,
238{
239 type VertexProp = DelegateVertexProp<G, T>;
240}
241
242impl<'a, G, T> WithEdgeProp<T> for SpanningSubgraph<'a, G>
243where
244 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + WithEdgeProp<T>,
245{
246 type EdgeProp = DelegateEdgeProp<G, T>;
247}
248
249impl<'a, G> BasicVertexProps for SpanningSubgraph<'a, G>
250where
251 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + BasicVertexProps,
252{
253}
254
255impl<'a, G> BasicEdgeProps for SpanningSubgraph<'a, G>
256where
257 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + BasicEdgeProps,
258{
259}
260
261impl<'a, G> BasicProps for SpanningSubgraph<'a, G>
262where
263 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + BasicProps,
264{
265}
266
267impl<'a, G> Choose for SpanningSubgraph<'a, G>
268where
269 G: 'a + WithEdge + WithVertexProp<Vec<Edge<G>>> + Choose,
270{
271 fn choose_vertex<R: Rng>(&self, rng: R) -> Option<Vertex<Self>> {
272 self.g.choose_vertex(rng)
273 }
274
275 fn choose_out_neighbor<R: Rng>(&self, v: Vertex<Self>, rng: R) -> Option<Vertex<Self>> {
276 self.g.choose_out_edge(v, rng).map(|e| self.target(e))
277 }
278
279 fn choose_edge<R: Rng>(&self, rng: R) -> Option<Edge<Self>> {
280 use graphs::common::gen_range_bool;
281 if let Some((i, rev)) = gen_range_bool(self.num_edges(), rng) {
282 let e = self.edges[i];
283 if rev && self.orientation(e).is_undirected() {
284 let e = self.get_reverse(e);
285 debug_assert!(e.is_some());
286 e
287 } else {
288 Some(e)
289 }
290 } else {
291 None
292 }
293 }
294
295 fn choose_out_edge<R: Rng>(&self, v: Vertex<Self>, mut rng: R) -> Option<Edge<Self>> {
296 if self.out_degree(v) == 0 {
297 None
298 } else {
299 self.out_edges[v]
300 .get(rng.gen_range(0, self.out_degree(v)))
301 .cloned()
302 }
303 }
304}