1mod bfs_visit;
16mod dfs_edges;
17mod dfs_visit;
18mod dijkstra_visit;
19mod random_walk;
20
21use petgraph::prelude::*;
22use petgraph::visit::GraphRef;
23use petgraph::visit::IntoNeighborsDirected;
24use petgraph::visit::Reversed;
25use petgraph::visit::VisitMap;
26use petgraph::visit::Visitable;
27
28pub use bfs_visit::{BfsEvent, bfs_layers, breadth_first_search};
29pub use dfs_edges::dfs_edges;
30pub use dfs_visit::{DfsEvent, depth_first_search};
31pub use dijkstra_visit::{DijkstraEvent, dijkstra_search};
32pub use random_walk::generate_random_path;
33
34macro_rules! try_control {
38 ($e:expr, $p:stmt) => {
39 try_control!($e, $p, ());
40 };
41 ($e:expr, $p:stmt, $q:stmt) => {
42 match $e {
43 x => {
44 if x.should_break() {
45 return x;
46 } else if x.should_prune() {
47 $p
48 } else {
49 $q
50 }
51 }
52 }
53 };
54}
55
56use try_control;
57
58struct AncestryWalker<G, N, VM> {
59 graph: G,
60 walker: Bfs<N, VM>,
61}
62
63impl<
64 G: GraphRef + Visitable + IntoNeighborsDirected<NodeId = N>,
65 N: Copy + Clone + PartialEq,
66 VM: VisitMap<N>,
67> Iterator for AncestryWalker<G, N, VM>
68{
69 type Item = N;
70 fn next(&mut self) -> Option<Self::Item> {
71 self.walker.next(self.graph)
72 }
73}
74
75pub fn ancestors<G>(graph: G, node: G::NodeId) -> impl Iterator<Item = G::NodeId>
101where
102 G: GraphRef + Visitable + IntoNeighborsDirected,
103{
104 let reversed = Reversed(graph);
105 AncestryWalker {
106 graph: reversed,
107 walker: Bfs::new(reversed, node),
108 }
109}
110
111pub fn descendants<G>(graph: G, node: G::NodeId) -> impl Iterator<Item = G::NodeId>
136where
137 G: GraphRef + Visitable + IntoNeighborsDirected,
138{
139 AncestryWalker {
140 graph,
141 walker: Bfs::new(graph, node),
142 }
143}
144
145struct BFSAncestryWalker<G, N, VM> {
146 graph: G,
147 walker: Bfs<N, VM>,
148}
149
150impl<
151 G: GraphRef + Visitable + IntoNeighborsDirected<NodeId = N>,
152 N: Copy + Clone + PartialEq,
153 VM: VisitMap<N>,
154> Iterator for BFSAncestryWalker<G, N, VM>
155{
156 type Item = (N, Vec<N>);
157
158 fn next(&mut self) -> Option<Self::Item> {
159 self.walker.next(self.graph).map(|nx| {
160 (
161 nx,
162 self.graph
163 .neighbors_directed(nx, petgraph::Direction::Outgoing)
164 .collect(),
165 )
166 })
167 }
168}
169
170pub fn bfs_successors<G>(
204 graph: G,
205 node: G::NodeId,
206) -> impl Iterator<Item = (G::NodeId, Vec<G::NodeId>)>
207where
208 G: GraphRef + Visitable + IntoNeighborsDirected,
209{
210 BFSAncestryWalker {
211 graph,
212 walker: Bfs::new(graph, node),
213 }
214}
215
216pub fn bfs_predecessors<G>(
250 graph: G,
251 node: G::NodeId,
252) -> impl Iterator<Item = (G::NodeId, Vec<G::NodeId>)>
253where
254 G: GraphRef + Visitable + IntoNeighborsDirected,
255{
256 let reversed = Reversed(graph);
257 BFSAncestryWalker {
258 graph: reversed,
259 walker: Bfs::new(reversed, node),
260 }
261}
262
263#[cfg(test)]
264mod test_bfs_ancestry {
265 use super::{bfs_predecessors, bfs_successors};
266 use crate::petgraph::graph::DiGraph;
267 use crate::petgraph::stable_graph::{NodeIndex, StableDiGraph};
268
269 #[test]
270 fn test_bfs_predecessors_digraph() {
271 let graph: DiGraph<(), ()> =
272 DiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
273 let predecessors: Vec<(usize, Vec<usize>)> = bfs_predecessors(&graph, NodeIndex::new(3))
274 .map(|(x, succ)| (x.index(), succ.iter().map(|y| y.index()).collect()))
275 .collect();
276 assert_eq!(
277 vec![(3_usize, vec![1_usize]), (1, vec![0]), (0, vec![])],
278 predecessors
279 );
280 }
281
282 #[test]
283 fn test_bfs_successors() {
284 let graph: DiGraph<(), ()> =
285 DiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
286 let successors: Vec<(usize, Vec<usize>)> = bfs_successors(&graph, NodeIndex::new(3))
287 .map(|(x, succ)| (x.index(), succ.iter().map(|y| y.index()).collect()))
288 .collect();
289 assert_eq!(
290 vec![(3_usize, vec![4_usize]), (4, vec![5]), (5, vec![])],
291 successors
292 );
293 }
294
295 #[test]
296 fn test_no_predecessors() {
297 let graph: StableDiGraph<(), ()> =
298 StableDiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
299 let predecessors: Vec<(usize, Vec<usize>)> = bfs_predecessors(&graph, NodeIndex::new(0))
300 .map(|(x, succ)| (x.index(), succ.iter().map(|y| y.index()).collect()))
301 .collect();
302 assert_eq!(vec![(0_usize, vec![])], predecessors);
303 }
304
305 #[test]
306 fn test_no_successors() {
307 let graph: StableDiGraph<(), ()> =
308 StableDiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
309 let successors: Vec<(usize, Vec<usize>)> = bfs_successors(&graph, NodeIndex::new(5))
310 .map(|(x, succ)| (x.index(), succ.iter().map(|y| y.index()).collect()))
311 .collect();
312 assert_eq!(vec![(5_usize, vec![])], successors);
313 }
314}
315
316#[cfg(test)]
317mod test_ancestry {
318 use super::{ancestors, descendants};
319 use crate::petgraph::graph::DiGraph;
320 use crate::petgraph::stable_graph::{NodeIndex, StableDiGraph};
321
322 #[test]
323 fn test_ancestors_digraph() {
324 let graph: DiGraph<(), ()> =
325 DiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
326 let ancestors: Vec<usize> = ancestors(&graph, NodeIndex::new(3))
327 .map(|x| x.index())
328 .collect();
329 assert_eq!(vec![3_usize, 1, 0], ancestors);
330 }
331
332 #[test]
333 fn test_descendants() {
334 let graph: DiGraph<(), ()> =
335 DiGraph::from_edges([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]);
336 let descendants: Vec<usize> = descendants(&graph, NodeIndex::new(3))
337 .map(|x| x.index())
338 .collect();
339 assert_eq!(vec![3_usize, 4, 5], descendants);
340 }
341
342 #[test]
343 fn test_no_ancestors() {
344 let mut graph: StableDiGraph<(), ()> = StableDiGraph::new();
345 let index = graph.add_node(());
346 let res = ancestors(&graph, index);
347 assert_eq!(vec![index], res.collect::<Vec<NodeIndex>>())
348 }
349
350 #[test]
351 fn test_no_descendants() {
352 let mut graph: StableDiGraph<(), ()> = StableDiGraph::new();
353 let index = graph.add_node(());
354 let res = descendants(&graph, index);
355 assert_eq!(vec![index], res.collect::<Vec<NodeIndex>>())
356 }
357}