1use choose::Choose;
6use graphs::OutNeighborFromOutEdge;
7use params::IntoOwned;
8use prelude::*;
9use props::{DelegateEdgeProp, DelegateVertexProp};
10
11use fera_fun::vec;
12
13use std::iter::Cloned;
14use std::slice;
15
16use rand::Rng;
17
18pub struct Subgraph<'a, G>
22where
23 G: 'a + Graph,
24{
25 g: &'a G,
26 vertices: Vec<Vertex<G>>,
27 edges: Vec<Edge<G>>,
28 inc: DefaultVertexPropMut<G, Vec<Edge<G>>>,
29}
30
31impl<'a, G> AsRef<G> for Subgraph<'a, G>
34where
35 G: 'a + Graph,
36{
37 #[inline]
38 fn as_ref(&self) -> &G {
39 self.g
40 }
41}
42
43impl<'a, 'b, G> VertexTypes<'a, Subgraph<'b, G>> for Subgraph<'b, G>
44where
45 G: 'b + Graph,
46{
47 type VertexIter = Cloned<slice::Iter<'a, Vertex<G>>>;
48 type OutNeighborIter = OutNeighborFromOutEdge<'b, G, OutEdgeIter<'a, Self>>;
49}
50
51impl<'a, G> WithVertex for Subgraph<'a, G>
52where
53 G: 'a + Graph,
54{
55 type Vertex = Vertex<G>;
56 type OptionVertex = OptionVertex<G>;
57}
58
59impl<'a, 'b, G> EdgeTypes<'a, Subgraph<'b, G>> for Subgraph<'b, G>
60where
61 G: 'b + Graph,
62{
63 type EdgeIter = Cloned<slice::Iter<'a, Edge<G>>>;
64 type OutEdgeIter = Cloned<slice::Iter<'a, Edge<G>>>;
65}
66
67impl<'a, G> WithEdge for Subgraph<'a, G>
68where
69 G: 'a + Graph,
70{
71 type Kind = G::Kind;
72 type Edge = Edge<G>;
73 type OptionEdge = OptionEdge<G>;
74
75 fn source(&self, e: Edge<Self>) -> Vertex<Self> {
76 self.g.source(e)
77 }
78
79 fn target(&self, e: Edge<Self>) -> Vertex<Self> {
80 self.g.target(e)
81 }
82
83 fn orientation(&self, e: Edge<Self>) -> Orientation {
84 self.g.orientation(e)
85 }
86
87 fn end_vertices(&self, e: Edge<Self>) -> (Vertex<Self>, Vertex<Self>) {
88 self.g.end_vertices(e)
89 }
90
91 fn opposite(&self, u: Vertex<Self>, e: Edge<Self>) -> Vertex<Self> {
92 self.g.opposite(u, e)
93 }
94
95 fn reverse(&self, e: Edge<Self>) -> Edge<Self> {
96 self.g.reverse(e)
97 }
98
99 fn get_reverse(&self, e: Edge<Self>) -> Option<Edge<Self>> {
100 self.g.get_reverse(e)
101 }
102}
103
104impl<'a, G> VertexList for Subgraph<'a, G>
105where
106 G: 'a + Graph,
107{
108 fn num_vertices(&self) -> usize {
109 self.vertices.len()
110 }
111
112 fn vertices(&self) -> VertexIter<Self> {
113 self.vertices.iter().cloned()
114 }
115}
116
117impl<'a, G> EdgeList for Subgraph<'a, G>
118where
119 G: 'a + Graph,
120{
121 fn num_edges(&self) -> usize {
122 self.edges.len()
123 }
124
125 fn edges(&self) -> EdgeIter<Self> {
126 self.edges.iter().cloned()
127 }
128
129 fn get_edge_by_ends(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Edge<Self>> {
130 self.out_edges(u).find(|e| (u, v) == self.ends(*e))
131 }
132}
133
134impl<'a, G> Adjacency for Subgraph<'a, G>
135where
136 G: 'a + Graph,
137{
138 fn out_neighbors(&self, v: Vertex<Self>) -> OutNeighborIter<Self> {
139 OutNeighborFromOutEdge::new(self.g, self.out_edges(v))
140 }
141
142 fn out_degree(&self, v: Vertex<Self>) -> usize {
143 self.inc[v].len()
144 }
145}
146
147impl<'a, G> Incidence for Subgraph<'a, G>
148where
149 G: 'a + Graph,
150{
151 fn out_edges(&self, v: Vertex<Self>) -> OutEdgeIter<Self> {
152 self.inc[v].iter().cloned()
153 }
154}
155
156impl<'a, G, T> WithVertexProp<T> for Subgraph<'a, G>
157where
158 G: 'a + Graph + WithVertexProp<T>,
159{
160 type VertexProp = DelegateVertexProp<G, T>;
161}
162
163impl<'a, G, T> WithEdgeProp<T> for Subgraph<'a, G>
164where
165 G: 'a + Graph + WithEdgeProp<T>,
166{
167 type EdgeProp = DelegateEdgeProp<G, T>;
168}
169
170impl<'a, G> BasicVertexProps for Subgraph<'a, G>
171where
172 G: 'a + Graph,
173{
174}
175
176impl<'a, G> BasicEdgeProps for Subgraph<'a, G>
177where
178 G: 'a + Graph,
179{
180}
181
182impl<'a, G> BasicProps for Subgraph<'a, G>
183where
184 G: 'a + Graph,
185{
186}
187
188impl<'a, G> Choose for Subgraph<'a, G>
191where
192 G: 'a + IncidenceGraph,
193{
194 fn choose_vertex<R: Rng>(&self, mut rng: R) -> Option<Vertex<Self>> {
195 self.vertices
196 .get(rng.gen_range(0, self.num_vertices()))
197 .cloned()
198 }
199
200 fn choose_out_neighbor<R: Rng>(&self, v: Vertex<Self>, mut rng: R) -> Option<Vertex<Self>> {
201 self.inc[v]
202 .get(rng.gen_range(0, self.out_degree(v)))
203 .map(|e| self.target(*e))
204 }
205
206 fn choose_edge<R: Rng>(&self, rng: R) -> Option<Edge<Self>> {
207 use graphs::common::gen_range_bool;
208 if let Some((i, rev)) = gen_range_bool(self.num_edges(), rng) {
209 let e = self.edges[i];
210 if rev && self.orientation(e).is_undirected() {
211 let e = self.get_reverse(e);
212 debug_assert!(e.is_some());
213 e
214 } else {
215 Some(e)
216 }
217 } else {
218 None
219 }
220 }
221
222 fn choose_out_edge<R: Rng>(&self, v: Vertex<Self>, mut rng: R) -> Option<Edge<Self>> {
223 if self.out_degree(v) == 0 {
224 None
225 } else {
226 self.inc[v]
227 .get(rng.gen_range(0, self.out_degree(v)))
228 .cloned()
229 }
230 }
231}
232
233pub trait WithSubgraph<G: Graph> {
236 fn empty_spanning_subgraph(&self) -> SpanningSubgraph<G>;
237
238 fn spanning_subgraph<I>(&self, vertices: I) -> SpanningSubgraph<G>
239 where
240 I: IntoIterator,
241 I::Item: IntoOwned<Edge<G>>;
242
243 fn induced_subgraph<I>(&self, vertices: I) -> Subgraph<G>
244 where
245 G: Incidence,
246 I: IntoIterator,
247 I::Item: IntoOwned<Vertex<G>>;
248
249 fn edge_induced_subgraph<I>(&self, edges: I) -> Subgraph<G>
250 where
251 I: IntoIterator,
252 I::Item: IntoOwned<Edge<G>>;
253}
254
255impl<G: Graph> WithSubgraph<G> for G {
256 fn spanning_subgraph<I>(&self, iter: I) -> SpanningSubgraph<G>
257 where
258 I: IntoIterator,
259 I::Item: IntoOwned<Edge<G>>,
260 {
261 let mut sub = SpanningSubgraph::new(self);
262 sub.add_edges(iter);
263 sub
264 }
265
266 fn empty_spanning_subgraph(&self) -> SpanningSubgraph<G> {
267 SpanningSubgraph::new(self)
268 }
269
270 fn edge_induced_subgraph<I>(&self, edges: I) -> Subgraph<G>
271 where
272 I: IntoIterator,
273 I::Item: IntoOwned<Edge<G>>,
274 {
275 let edges = vec(edges.into_iter().map(IntoOwned::into_owned));
277 let mut vin = self.default_vertex_prop(false);
278 let mut vertices = vec![];
279 let mut inc = self.default_vertex_prop(Vec::<Edge<G>>::new());
280 for (e, u, v) in self.with_ends(&edges) {
281 if !vin[u] {
282 vin[u] = true;
283 vertices.push(u);
284 }
285 if !vin[v] {
286 vin[v] = true;
287 vertices.push(v);
288 }
289 inc[u].push(e);
290 inc[v].push(self.reverse(e));
291 }
292
293 Subgraph {
294 g: self,
295 vertices: vertices,
296 edges: edges,
297 inc: inc,
298 }
299 }
300
301 fn induced_subgraph<I>(&self, vertices: I) -> Subgraph<G>
302 where
303 G: Incidence,
304 I: IntoIterator,
305 I::Item: IntoOwned<Vertex<G>>,
306 {
307 let vertices = vec(vertices.into_iter().map(IntoOwned::into_owned));
308 let mut vs = self.default_vertex_prop(false);
309 let mut edges = vec![];
310 let mut inc = self.default_vertex_prop(Vec::<Edge<G>>::new());
311 for &v in &vertices {
312 vs[v] = true;
313 }
314 for (e, u, v) in self.edges_with_ends() {
315 if vs[u] && vs[v] {
316 edges.push(e);
317 inc[u].push(e);
318 inc[v].push(self.reverse(e));
319 }
320 }
321
322 Subgraph {
323 g: self,
324 vertices: vertices,
325 edges: edges,
326 inc: inc,
327 }
328 }
329}
330
331#[cfg(test)]
334mod tests {
335 use fera_fun::{set, vec};
336 use prelude::*;
337
338 fn new_graph() -> (
339 StaticGraph,
340 Edge<StaticGraph>,
341 Edge<StaticGraph>,
342 Edge<StaticGraph>,
343 Edge<StaticGraph>,
344 ) {
345 let g: StaticGraph = graph!(5, (0, 1), (0, 2), (1, 2), (3, 4));
346 let e = vec(g.edges());
347 (g, e[0], e[1], e[2], e[3])
348 }
349
350 #[test]
351 fn test_spanning_subgraph() {
352 let (g, _, e02, e12, _) = new_graph();
353 let s = g.spanning_subgraph(vec![e02, e12]);
354 assert_eq!(vec![0, 1, 2, 3, 4], vec(s.vertices()));
355 assert_eq!(set(vec![e02, e12]), set(s.edges()));
356 assert_eq!(set(vec![e02]), set(s.out_edges(0)));
357 assert_eq!(set(vec![e12]), set(s.out_edges(1)));
358 assert_eq!(set(vec![e02, e12]), set(s.out_edges(2)));
359 assert!(set(s.out_edges(3)).is_empty());
360 assert!(set(s.out_edges(4)).is_empty());
361 }
362
363 #[test]
364 fn test_edge_induced_subgraph() {
365 let (g, e01, e02, _, _) = new_graph();
366 let s = g.edge_induced_subgraph(vec![e01, e02]);
367 assert_eq!(set(vec![0, 1, 2]), set(s.vertices()));
368 assert_eq!(set(vec![e01, e02]), set(s.edges()));
369 assert_eq!(set(vec![e01, e02]), set(s.out_edges(0)));
370 assert_eq!(set(vec![1, 2]), set(s.out_neighbors(0)));
371 assert_eq!(set(vec![e01]), set(s.out_edges(1)));
372 assert_eq!(set(vec![0]), set(s.out_neighbors(1)));
373 assert_eq!(set(vec![e02]), set(s.out_edges(2)));
374 assert_eq!(set(vec![0]), set(s.out_neighbors(2)));
375 }
376
377 #[test]
378 fn test_induced_subgraph() {
379 let (g, e01, e02, e12, _) = new_graph();
380 let s = g.induced_subgraph(vec![0, 1, 2]);
381 assert_eq!(set(vec![0, 1, 2]), set(s.vertices()));
382 assert_eq!(set(vec![e01, e02, e12]), set(s.edges()));
383 assert_eq!(set(vec![e01, e02]), set(s.out_edges(0)));
384 assert_eq!(set(vec![e01, e12]), set(s.out_edges(1)));
385 assert_eq!(set(vec![e02, e12]), set(s.out_edges(2)));
386 }
387}