3 use std
::collections
::HashSet
;
6 use petgraph
::prelude
::*;
18 is_isomorphic_matching
,
21 use petgraph
::graph
::node_index
as n
;
22 use petgraph
::graph
::{
26 use petgraph
::visit
::{
45 fn set
<I
>(iter
: I
) -> HashSet
<I
::Item
>
46 where I
: IntoIterator
,
49 iter
.into_iter().collect()
55 let mut og
= Graph
::new_undirected();
56 let a
= og
.add_node(0);
57 let b
= og
.add_node(1);
58 let c
= og
.add_node(2);
59 let d
= og
.add_node(3);
60 let _
= og
.add_edge(a
, b
, 0);
61 let _
= og
.add_edge(a
, c
, 1);
67 assert_eq
!(og
.node_count(), 4);
68 assert_eq
!(og
.edge_count(), 7);
70 assert
!(og
.find_edge(a
, b
).is_some());
71 assert
!(og
.find_edge(d
, a
).is_some());
72 assert
!(og
.find_edge(a
, a
).is_some());
74 for edge
in og
.raw_edges() {
75 assert
!(og
.find_edge(edge
.source(), edge
.target()).is_some());
76 assert
!(og
.find_edge(edge
.target(), edge
.source()).is_some());
79 assert_eq
!(og
.neighbors(b
).collect
::<Vec
<_
>>(), vec
![a
, c
, a
]);
82 assert_eq
!(og
.neighbors(b
).collect
::<Vec
<_
>>(), vec
![c
]);
83 assert_eq
!(og
.node_count(), 3);
84 assert_eq
!(og
.edge_count(), 1);
85 assert
!(og
.find_edge(a
, b
).is_none());
86 assert
!(og
.find_edge(d
, a
).is_none());
87 assert
!(og
.find_edge(a
, a
).is_none());
88 assert
!(og
.find_edge(b
, c
).is_some());
89 assert_graph_consistent(&og
);
95 let mut gr
= Graph
::new();
96 let h
= gr
.add_node("H");
97 let i
= gr
.add_node("I");
98 let j
= gr
.add_node("J");
99 let k
= gr
.add_node("K");
100 // Z is disconnected.
101 let _
= gr
.add_node("Z");
102 gr
.add_edge(h
, i
, 1.);
103 gr
.add_edge(h
, j
, 3.);
104 gr
.add_edge(i
, j
, 1.);
105 gr
.add_edge(i
, k
, 2.);
107 println
!("{}", Dot
::new(&gr
));
109 assert_eq
!(Dfs
::new(&gr
, h
).iter(&gr
).count(), 4);
110 assert_eq
!(Dfs
::new(&gr
, h
).iter(&gr
).clone().count(), 4);
112 assert_eq
!(Dfs
::new(&gr
, h
).iter(Reversed(&gr
)).count(), 1);
114 assert_eq
!(Dfs
::new(&gr
, k
).iter(Reversed(&gr
)).count(), 3);
116 assert_eq
!(Dfs
::new(&gr
, i
).iter(&gr
).count(), 3);
122 let mut gr
= Graph
::new();
123 let h
= gr
.add_node("H");
124 let i
= gr
.add_node("I");
125 let j
= gr
.add_node("J");
126 let k
= gr
.add_node("K");
127 // Z is disconnected.
128 let _
= gr
.add_node("Z");
129 gr
.add_edge(h
, i
, 1.);
130 gr
.add_edge(h
, j
, 3.);
131 gr
.add_edge(i
, j
, 1.);
132 gr
.add_edge(i
, k
, 2.);
134 assert_eq
!(Bfs
::new(&gr
, h
).iter(&gr
).count(), 4);
135 assert_eq
!(Bfs
::new(&gr
, h
).iter(&gr
).clone().count(), 4);
137 assert_eq
!(Bfs
::new(&gr
, h
).iter(Reversed(&gr
)).count(), 1);
139 assert_eq
!(Bfs
::new(&gr
, k
).iter(Reversed(&gr
)).count(), 3);
141 assert_eq
!(Bfs
::new(&gr
, i
).iter(&gr
).count(), 3);
143 let mut bfs
= Bfs
::new(&gr
, h
);
144 let nx
= bfs
.next(&gr
);
145 assert_eq
!(nx
, Some(h
));
147 let nx1
= bfs
.next(&gr
);
148 assert
!(nx1
== Some(i
) || nx1
== Some(j
));
150 let nx2
= bfs
.next(&gr
);
151 assert
!(nx2
== Some(i
) || nx2
== Some(j
));
154 let nx
= bfs
.next(&gr
);
155 assert_eq
!(nx
, Some(k
));
156 assert_eq
!(bfs
.next(&gr
), None
);
163 use petgraph
::data
::FromElements
;
165 let mut gr
= Graph
::<_
,_
>::new();
166 let a
= gr
.add_node("A");
167 let b
= gr
.add_node("B");
168 let c
= gr
.add_node("C");
169 let d
= gr
.add_node("D");
170 let e
= gr
.add_node("E");
171 let f
= gr
.add_node("F");
172 let g
= gr
.add_node("G");
173 gr
.add_edge(a
, b
, 7.);
174 gr
.add_edge(a
, d
, 5.);
175 gr
.add_edge(d
, b
, 9.);
176 gr
.add_edge(b
, c
, 8.);
177 gr
.add_edge(b
, e
, 7.);
178 gr
.add_edge(c
, e
, 5.);
179 gr
.add_edge(d
, e
, 15.);
180 gr
.add_edge(d
, f
, 6.);
181 gr
.add_edge(f
, e
, 8.);
182 gr
.add_edge(f
, g
, 11.);
183 gr
.add_edge(e
, g
, 9.);
185 // add a disjoint part
186 let h
= gr
.add_node("H");
187 let i
= gr
.add_node("I");
188 let j
= gr
.add_node("J");
189 gr
.add_edge(h
, i
, 1.);
190 gr
.add_edge(h
, j
, 3.);
191 gr
.add_edge(i
, j
, 1.);
193 println
!("{}", Dot
::new(&gr
));
195 let mst
= UnGraph
::from_elements(min_spanning_tree(&gr
));
197 println
!("{}", Dot
::new(&mst
));
198 println
!("{:?}", Dot
::new(&mst
));
199 println
!("MST is:\n{:#?}", mst
);
200 assert
!(mst
.node_count() == gr
.node_count());
201 // |E| = |N| - 2 because there are two disconnected components.
202 assert
!(mst
.edge_count() == gr
.node_count() - 2);
204 // check the exact edges are there
205 assert
!(mst
.find_edge(a
, b
).is_some());
206 assert
!(mst
.find_edge(a
, d
).is_some());
207 assert
!(mst
.find_edge(b
, e
).is_some());
208 assert
!(mst
.find_edge(e
, c
).is_some());
209 assert
!(mst
.find_edge(e
, g
).is_some());
210 assert
!(mst
.find_edge(d
, f
).is_some());
212 assert
!(mst
.find_edge(h
, i
).is_some());
213 assert
!(mst
.find_edge(i
, j
).is_some());
215 assert
!(mst
.find_edge(d
, b
).is_none());
216 assert
!(mst
.find_edge(b
, c
).is_none());
222 let mut gr
= Graph
::new();
223 let a
= gr
.add_node("A");
224 let b
= gr
.add_node("B");
225 let c
= gr
.add_node("C");
226 gr
.add_edge(a
, b
, 7.);
227 gr
.add_edge(c
, a
, 6.);
228 let sed
= gr
.add_edge(a
, a
, 2.);
230 assert
!(gr
.find_edge(a
, b
).is_some());
231 assert
!(gr
.find_edge(b
, a
).is_none());
232 assert
!(gr
.find_edge_undirected(b
, a
).is_some());
233 assert
!(gr
.find_edge(a
, a
).is_some());
234 println
!("{:?}", gr
);
237 assert
!(gr
.find_edge(a
, a
).is_none());
238 println
!("{:?}", gr
);
243 let mut gr
= Graph
::new();
244 let a
= gr
.add_node("A");
245 let b
= gr
.add_node("B");
246 let c
= gr
.add_node("C");
248 assert
!(!is_cyclic_undirected(&gr
));
249 gr
.add_edge(a
, b
, 7.);
250 gr
.add_edge(c
, a
, 6.);
251 assert
!(!is_cyclic_undirected(&gr
));
253 let e
= gr
.add_edge(a
, a
, 0.);
254 assert
!(is_cyclic_undirected(&gr
));
256 assert
!(!is_cyclic_undirected(&gr
));
260 let e
= gr
.add_edge(b
, c
, 0.);
261 assert
!(is_cyclic_undirected(&gr
));
263 assert
!(!is_cyclic_undirected(&gr
));
266 let d
= gr
.add_node("D");
267 let e
= gr
.add_node("E");
268 gr
.add_edge(b
, d
, 0.);
269 gr
.add_edge(d
, e
, 0.);
270 assert
!(!is_cyclic_undirected(&gr
));
271 gr
.add_edge(c
, e
, 0.);
272 assert
!(is_cyclic_undirected(&gr
));
273 assert_graph_consistent(&gr
);
278 let mut gr
= Graph
::new();
279 let a
= gr
.add_node("a");
280 let b
= gr
.add_node("b");
281 gr
.add_edge(a
, b
, ());
282 gr
.add_edge(a
, b
, ());
283 assert_eq
!(gr
.edge_count(), 2);
290 let mut gr
= Graph
::new();
291 let a
= gr
.add_node("a");
292 let b
= gr
.add_node("b");
293 let e
= gr
.update_edge(a
, b
, 1);
294 let f
= gr
.update_edge(a
, b
, 2);
295 let _
= gr
.update_edge(b
, a
, 3);
296 assert_eq
!(gr
.edge_count(), 2);
298 assert_eq
!(*gr
.edge_weight(f
).unwrap(), 2);
302 let mut gr
= Graph
::new_undirected();
303 let a
= gr
.add_node("a");
304 let b
= gr
.add_node("b");
305 let e
= gr
.update_edge(a
, b
, 1);
306 let f
= gr
.update_edge(b
, a
, 2);
307 assert_eq
!(gr
.edge_count(), 1);
309 assert_eq
!(*gr
.edge_weight(f
).unwrap(), 2);
315 let mut g
= Graph
::new_undirected();
316 let a
= g
.add_node("A");
317 let b
= g
.add_node("B");
318 let c
= g
.add_node("C");
319 let d
= g
.add_node("D");
320 let e
= g
.add_node("E");
321 let f
= g
.add_node("F");
324 g
.add_edge(a
, d
, 14);
325 g
.add_edge(b
, c
, 10);
328 g
.add_edge(b
, f
, 15);
329 g
.add_edge(c
, f
, 11);
332 for no
in Bfs
::new(&g
, a
).iter(&g
) {
333 println
!("Visit {:?} = {:?}", no
, g
.node_weight(no
));
336 let scores
= dijkstra(&g
, a
, None
, |e
| *e
.weight());
337 let mut scores
: Vec
<_
> = scores
.into_iter().map(|(n
, s
)| (g
[n
], s
)).collect();
340 vec
![("A", 0), ("B", 7), ("C", 9), ("D", 11), ("E", 20), ("F", 20)]);
342 let scores
= dijkstra(&g
, a
, Some(c
), |e
| *e
.weight());
343 assert_eq
!(scores
[&c
], 9);
347 fn test_astar_null_heuristic() {
348 let mut g
= Graph
::new();
349 let a
= g
.add_node("A");
350 let b
= g
.add_node("B");
351 let c
= g
.add_node("C");
352 let d
= g
.add_node("D");
353 let e
= g
.add_node("E");
354 let f
= g
.add_node("F");
357 g
.add_edge(a
, d
, 14);
358 g
.add_edge(b
, c
, 10);
361 g
.add_edge(b
, f
, 15);
362 g
.add_edge(c
, f
, 11);
365 let path
= astar(&g
, a
, |finish
| finish
== e
, |e
| *e
.weight(), |_
| 0);
366 assert_eq
!(path
, Some((23, vec
![a
, d
, e
])));
368 // check against dijkstra
369 let dijkstra_run
= dijkstra(&g
, a
, Some(e
), |e
| *e
.weight());
370 assert_eq
!(dijkstra_run
[&e
], 23);
372 let path
= astar(&g
, e
, |finish
| finish
== b
, |e
| *e
.weight(), |_
| 0);
373 assert_eq
!(path
, None
);
377 fn test_astar_manhattan_heuristic() {
378 let mut g
= Graph
::new();
379 let a
= g
.add_node((0., 0.));
380 let b
= g
.add_node((2., 0.));
381 let c
= g
.add_node((1., 1.));
382 let d
= g
.add_node((0., 2.));
383 let e
= g
.add_node((3., 3.));
384 let f
= g
.add_node((4., 2.));
385 let _
= g
.add_node((5., 5.)); // no path to node
386 g
.add_edge(a
, b
, 2.);
387 g
.add_edge(a
, d
, 4.);
388 g
.add_edge(b
, c
, 1.);
389 g
.add_edge(b
, f
, 7.);
390 g
.add_edge(c
, e
, 5.);
391 g
.add_edge(e
, f
, 1.);
392 g
.add_edge(d
, e
, 1.);
394 let heuristic_for
= |f
: NodeIndex
| {
396 move |node
: NodeIndex
| -> f32 {
397 let (x1
, y1
): (f32, f32) = g
[node
];
398 let (x2
, y2
): (f32, f32) = g
[f
];
400 (x2
- x1
).abs() + (y2
- y1
).abs()
403 let path
= astar(&g
, a
, |finish
| finish
== f
, |e
| *e
.weight(), heuristic_for(f
));
405 assert_eq
!(path
, Some((6., vec
![a
, d
, e
, f
])));
407 // check against dijkstra
408 let dijkstra_run
= dijkstra(&g
, a
, None
, |e
| *e
.weight());
410 for end
in g
.node_indices() {
411 let astar_path
= astar(&g
, a
, |finish
| finish
== end
, |e
| *e
.weight(),
413 assert_eq
!(dijkstra_run
.get(&end
).cloned(),
414 astar_path
.map(|t
| t
.0));
418 #[cfg(feature = "generate")]
420 fn test_generate_undirected() {
422 let mut gen
= pg
::generate
::Generator
::<Undirected
>::all(size
, true);
423 let nedges
= (size
* size
- size
) / 2 + size
;
425 while let Some(g
) = gen
.next_ref() {
430 assert_eq
!(n
, 1 << nedges
);
434 #[cfg(feature = "generate")]
436 fn test_generate_directed() {
437 // Number of DAG out of all graphs (all permutations) per node size
438 // 0, 1, 2, 3, 4, 5 ..
439 let n_dag
= &[1, 1, 3, 25, 543, 29281, 3781503];
440 for (size
, &dags_exp
) in (0..4).zip(n_dag
) {
441 let mut gen
= pg
::generate
::Generator
::<Directed
>::all(size
, true);
442 let nedges
= size
* size
;
445 while let Some(g
) = gen
.next_ref() {
447 if !pg
::algo
::is_cyclic_directed(g
) {
453 // check that all generated graphs have unique adjacency matrices
454 let mut adjmats = graphs.iter().map(Graph::adjacency_matrix).collect::<Vec<_>>();
455 adjmats.sort(); adjmats.dedup();
456 assert_eq!(adjmats.len(), n);
458 assert_eq
!(dags_exp
, dags
);
459 assert_eq
!(n
, 1 << nedges
);
463 #[cfg(feature = "generate")]
465 fn test_generate_dag() {
466 use petgraph
::visit
::GetAdjacencyMatrix
;
468 let gen
= pg
::generate
::Generator
::directed_acyclic(size
);
469 let nedges
= (size
- 1) * size
/ 2;
470 let graphs
= gen
.collect
::<Vec
<_
>>();
472 assert_eq
!(graphs
.len(), 1 << nedges
);
474 // check that all generated graphs have unique adjacency matrices
475 let mut adjmats
= graphs
.iter().map(Graph
::adjacency_matrix
).collect
::<Vec
<_
>>();
478 assert_eq
!(adjmats
.len(), graphs
.len());
480 assert
!(!petgraph
::algo
::is_cyclic_directed(gr
),
481 "Assertion failed: {:?} acyclic", gr
);
489 let mut og
= Graph
::new_undirected();
490 let a
= og
.add_node(0);
491 let b
= og
.add_node(1);
492 let c
= og
.add_node(2);
493 let d
= og
.add_node(3);
494 let _
= og
.add_edge(a
, b
, 0);
495 let _
= og
.add_edge(a
, c
, 1);
496 let v
: Vec
<NodeIndex
> = og
.externals(Outgoing
).collect();
497 assert_eq
!(v
, vec
![d
]);
499 let mut og
= Graph
::new();
500 let a
= og
.add_node(0);
501 let b
= og
.add_node(1);
502 let c
= og
.add_node(2);
503 let d
= og
.add_node(3);
504 let _
= og
.add_edge(a
, b
, 0);
505 let _
= og
.add_edge(a
, c
, 1);
506 let init
: Vec
<NodeIndex
> = og
.externals(Incoming
).collect();
507 let term
: Vec
<NodeIndex
> = og
.externals(Outgoing
).collect();
508 assert_eq
!(init
, vec
![a
, d
]);
509 assert_eq
!(term
, vec
![b
, c
, d
]);
512 fn assert_is_topo_order
<N
, E
>(gr
: &Graph
<N
, E
, Directed
>, order
: &[NodeIndex
])
514 assert_eq
!(gr
.node_count(), order
.len());
515 // check all the edges of the graph
516 for edge
in gr
.raw_edges() {
517 let a
= edge
.source();
518 let b
= edge
.target();
519 let ai
= order
.iter().position(|x
| *x
== a
).unwrap();
520 let bi
= order
.iter().position(|x
| *x
== b
).unwrap();
521 println
!("Check that {:?} is before {:?}", a
, b
);
522 assert
!(ai
< bi
, "Topo order: assertion that node {:?} is before {:?} failed",
529 let mut gr
= Graph
::<_
,_
>::new();
530 let a
= gr
.add_node("A");
531 let b
= gr
.add_node("B");
532 let c
= gr
.add_node("C");
533 let d
= gr
.add_node("D");
534 let e
= gr
.add_node("E");
535 let f
= gr
.add_node("F");
536 let g
= gr
.add_node("G");
537 gr
.extend_with_edges(&[
551 // add a disjoint part
552 let h
= gr
.add_node("H");
553 let i
= gr
.add_node("I");
554 let j
= gr
.add_node("J");
555 gr
.add_edge(h
, i
, 1.);
556 gr
.add_edge(h
, j
, 3.);
557 gr
.add_edge(i
, j
, 1.);
559 let order
= petgraph
::algo
::toposort(&gr
, None
).unwrap();
560 println
!("{:?}", order
);
561 assert_eq
!(order
.len(), gr
.node_count());
563 assert_is_topo_order(&gr
, &order
);
567 fn test_toposort_eq() {
568 let mut g
= Graph
::<_
,_
>::new();
569 let a
= g
.add_node("A");
570 let b
= g
.add_node("B");
571 g
.add_edge(a
, b
, ());
573 assert_eq
!(petgraph
::algo
::toposort(&g
, None
), Ok(vec
![a
, b
]));
577 fn is_cyclic_directed() {
578 let mut gr
= Graph
::<_
,_
>::new();
579 let a
= gr
.add_node("A");
580 let b
= gr
.add_node("B");
581 let c
= gr
.add_node("C");
582 let d
= gr
.add_node("D");
583 let e
= gr
.add_node("E");
584 let f
= gr
.add_node("F");
585 let g
= gr
.add_node("G");
586 gr
.add_edge(a
, b
, 7.0);
587 gr
.add_edge(a
, d
, 5.);
588 gr
.add_edge(d
, b
, 9.);
589 gr
.add_edge(b
, c
, 8.);
590 gr
.add_edge(b
, e
, 7.);
591 gr
.add_edge(c
, e
, 5.);
592 gr
.add_edge(d
, e
, 15.);
593 gr
.add_edge(d
, f
, 6.);
594 gr
.add_edge(f
, e
, 8.);
595 gr
.add_edge(f
, g
, 11.);
596 gr
.add_edge(e
, g
, 9.);
598 assert
!(!petgraph
::algo
::is_cyclic_directed(&gr
));
600 // add a disjoint part
601 let h
= gr
.add_node("H");
602 let i
= gr
.add_node("I");
603 let j
= gr
.add_node("J");
604 gr
.add_edge(h
, i
, 1.);
605 gr
.add_edge(h
, j
, 3.);
606 gr
.add_edge(i
, j
, 1.);
607 assert
!(!petgraph
::algo
::is_cyclic_directed(&gr
));
609 gr
.add_edge(g
, e
, 0.);
610 assert
!(petgraph
::algo
::is_cyclic_directed(&gr
));
613 /// Compare two scc sets. Inside each scc, the order does not matter,
614 /// but the order of the sccs is significant.
615 fn assert_sccs_eq(mut res
: Vec
<Vec
<NodeIndex
>>, mut answer
: Vec
<Vec
<NodeIndex
>>,
616 scc_order_matters
: bool
) {
617 // normalize the result and compare with the answer.
618 for scc
in &mut res
{
621 for scc
in &mut answer
{
624 if !scc_order_matters
{
628 assert_eq
!(res
, answer
);
633 let gr
: Graph
<(), ()> = Graph
::from_edges(&[
646 assert_sccs_eq(petgraph
::algo
::kosaraju_scc(&gr
), vec
![
647 vec
![n(0), n(3), n(6)],
648 vec
![n(2), n(5), n(8)],
649 vec
![n(1), n(4), n(7)],
651 // Reversed edges gives the same sccs (when sorted)
652 assert_sccs_eq(petgraph
::algo
::kosaraju_scc(Reversed(&gr
)), vec
![
653 vec
![n(1), n(4), n(7)],
654 vec
![n(2), n(5), n(8)],
655 vec
![n(0), n(3), n(6)],
659 // Test an undirected graph just for fun.
660 // Sccs are just connected components.
661 let mut hr
= gr
.into_edge_type
::<Undirected
>();
662 // Delete an edge to disconnect it
663 let ed
= hr
.find_edge(n(6), n(8)).unwrap();
664 assert
!(hr
.remove_edge(ed
).is_some());
666 assert_sccs_eq(petgraph
::algo
::kosaraju_scc(&hr
), vec
![
667 vec
![n(0), n(3), n(6)],
668 vec
![n(1), n(2), n(4), n(5), n(7), n(8)],
672 // acyclic non-tree, #14
673 let n
= NodeIndex
::new
;
674 let mut gr
= Graph
::new();
679 gr
.add_edge(n(3), n(2), ());
680 gr
.add_edge(n(3), n(1), ());
681 gr
.add_edge(n(2), n(0), ());
682 gr
.add_edge(n(1), n(0), ());
684 assert_sccs_eq(petgraph
::algo
::kosaraju_scc(&gr
), vec
![
685 vec
![n(0)], vec
![n(1)], vec
![n(2)], vec
![n(3)],
688 // Kosaraju bug from PR #60
689 let mut gr
= Graph
::<(), ()>::new();
690 gr
.extend_with_edges(&[
698 // no order for the disconnected one
699 assert_sccs_eq(petgraph
::algo
::kosaraju_scc(&gr
), vec
![
700 vec
![n(0)], vec
![n(1)], vec
![n(2)], vec
![n(3)],
707 let gr
: Graph
<(), ()> = Graph
::from_edges(&[
720 assert_sccs_eq(petgraph
::algo
::tarjan_scc(&gr
), vec
![
721 vec
![n(0), n(3), n(6)],
722 vec
![n(2), n(5), n(8)],
723 vec
![n(1), n(4), n(7)],
727 // Test an undirected graph just for fun.
728 // Sccs are just connected components.
729 let mut hr
= gr
.into_edge_type
::<Undirected
>();
730 // Delete an edge to disconnect it
731 let ed
= hr
.find_edge(n(6), n(8)).unwrap();
732 assert
!(hr
.remove_edge(ed
).is_some());
734 assert_sccs_eq(petgraph
::algo
::tarjan_scc(&hr
), vec
![
735 vec
![n(1), n(2), n(4), n(5), n(7), n(8)],
736 vec
![n(0), n(3), n(6)],
740 // acyclic non-tree, #14
741 let n
= NodeIndex
::new
;
742 let mut gr
= Graph
::new();
747 gr
.add_edge(n(3), n(2), ());
748 gr
.add_edge(n(3), n(1), ());
749 gr
.add_edge(n(2), n(0), ());
750 gr
.add_edge(n(1), n(0), ());
752 assert_sccs_eq(petgraph
::algo
::tarjan_scc(&gr
), vec
![
753 vec
![n(0)], vec
![n(1)], vec
![n(2)], vec
![n(3)],
756 // Kosaraju bug from PR #60
757 let mut gr
= Graph
::<(), ()>::new();
758 gr
.extend_with_edges(&[
766 // no order for the disconnected one
767 assert_sccs_eq(petgraph
::algo
::tarjan_scc(&gr
), vec
![
768 vec
![n(0)], vec
![n(1)], vec
![n(2)], vec
![n(3)],
776 let gr
: Graph
<(), ()> = Graph
::from_edges(&[
791 // make_acyclic = true
793 let cond
= petgraph
::algo
::condensation(gr
.clone(), true);
795 assert
!(cond
.node_count() == 3);
796 assert
!(cond
.edge_count() == 2);
797 assert
!(!petgraph
::algo
::is_cyclic_directed(&cond
),
798 "Assertion failed: {:?} acyclic", cond
);
801 // make_acyclic = false
803 let cond
= petgraph
::algo
::condensation(gr
.clone(), false);
805 assert
!(cond
.node_count() == 3);
806 assert
!(cond
.edge_count() == gr
.edge_count());
812 let n
= NodeIndex
::new
;
813 let mut gr
= Graph
::new();
823 gr
.add_edge(n(6), n(0), ());
824 gr
.add_edge(n(0), n(3), ());
825 gr
.add_edge(n(3), n(6), ());
826 gr
.add_edge(n(8), n(6), ());
827 gr
.add_edge(n(8), n(2), ());
828 gr
.add_edge(n(2), n(5), ());
829 gr
.add_edge(n(5), n(8), ());
830 gr
.add_edge(n(7), n(5), ());
831 gr
.add_edge(n(1), n(7), ());
832 gr
.add_edge(n(7), n(4), ());
833 gr
.add_edge(n(4), n(1), ());
834 assert_eq
!(petgraph
::algo
::connected_components(&gr
), 1);
838 assert_eq
!(petgraph
::algo
::connected_components(&gr
), 3);
840 gr
.add_edge(n(9), n(10), ());
841 assert_eq
!(petgraph
::algo
::connected_components(&gr
), 2);
843 let gr
= gr
.into_edge_type
::<Undirected
>();
844 assert_eq
!(petgraph
::algo
::connected_components(&gr
), 2);
851 let mut gr
= Graph
::<_
, ()>::new();
852 let a
= gr
.add_node(0);
853 let b
= gr
.add_node(1);
861 let mut gr
= Graph
::<_
, _
, Directed
, usize>::with_capacity(0, 0);
862 let a
= gr
.add_node(0);
863 let b
= gr
.add_node(1);
864 let e
= gr
.add_edge(a
, b
, 1.2);
865 let mut dfs
= Dfs
::new(&gr
, a
);
866 while let Some(nx
) = dfs
.next(&gr
) {
869 assert_eq
!(gr
[a
], 1);
870 assert_eq
!(gr
[b
], 2);
871 assert_eq
!(gr
[e
], 1.2);
877 let mut gr
= Graph
::<_
, (), Undirected
, u8>::with_capacity(0, 0);
885 fn u8_index_overflow()
887 let mut gr
= Graph
::<_
, (), Undirected
, u8>::with_capacity(0, 0);
895 fn u8_index_overflow_edges()
897 let mut gr
= Graph
::<_
, (), Undirected
, u8>::with_capacity(0, 0);
898 let a
= gr
.add_node('a'
);
899 let b
= gr
.add_node('b'
);
901 gr
.add_edge(a
, b
, ());
906 fn test_weight_iterators() {
907 let mut gr
= Graph
::<_
,_
>::new();
908 let a
= gr
.add_node("A");
909 let b
= gr
.add_node("B");
910 let c
= gr
.add_node("C");
911 let d
= gr
.add_node("D");
912 let e
= gr
.add_node("E");
913 let f
= gr
.add_node("F");
914 let g
= gr
.add_node("G");
915 gr
.add_edge(a
, b
, 7.0);
916 gr
.add_edge(a
, d
, 5.);
917 gr
.add_edge(d
, b
, 9.);
918 gr
.add_edge(b
, c
, 8.);
919 gr
.add_edge(b
, e
, 7.);
920 gr
.add_edge(c
, e
, 5.);
921 gr
.add_edge(d
, e
, 15.);
922 gr
.add_edge(d
, f
, 6.);
923 gr
.add_edge(f
, e
, 8.);
924 gr
.add_edge(f
, g
, 11.);
925 gr
.add_edge(e
, g
, 9.);
927 assert_eq
!(gr
.node_weights_mut().count(), gr
.node_count());
928 assert_eq
!(gr
.edge_weights_mut().count(), gr
.edge_count());
930 // add a disjoint part
931 let h
= gr
.add_node("H");
932 let i
= gr
.add_node("I");
933 let j
= gr
.add_node("J");
934 gr
.add_edge(h
, i
, 1.);
935 gr
.add_edge(h
, j
, 3.);
936 gr
.add_edge(i
, j
, 1.);
938 assert_eq
!(gr
.node_weights_mut().count(), gr
.node_count());
939 assert_eq
!(gr
.edge_weights_mut().count(), gr
.edge_count());
941 for nw
in gr
.node_weights_mut() {
944 for node
in gr
.raw_nodes() {
945 assert_eq
!(node
.weight
, "x");
948 let old
= gr
.clone();
949 for (index
, ew
) in gr
.edge_weights_mut().enumerate() {
950 assert_eq
!(old
[EdgeIndex
::new(index
)], *ew
);
953 for (index
, edge
) in gr
.raw_edges().iter().enumerate() {
954 assert_eq
!(edge
.weight
, -1. * old
[EdgeIndex
::new(index
)]);
960 let mut gr
= Graph
::<_
,_
>::new();
961 let a
= gr
.add_node(0.);
962 let b
= gr
.add_node(1.);
963 let c
= gr
.add_node(2.);
964 let d
= gr
.add_node(3.);
965 let e0
= gr
.add_edge(a
, b
, 0.);
966 let e1
= gr
.add_edge(a
, d
, 0.);
967 let e2
= gr
.add_edge(b
, c
, 0.);
968 let e3
= gr
.add_edge(c
, a
, 0.);
970 // Set edge weights to difference: target - source.
971 let mut dfs
= Dfs
::new(&gr
, a
);
972 while let Some(source
) = dfs
.next(&gr
) {
973 let mut edges
= gr
.neighbors_directed(source
, Outgoing
).detach();
974 while let Some((edge
, target
)) = edges
.next(&gr
) {
975 gr
[edge
] = gr
[target
] - gr
[source
];
978 assert_eq
!(gr
[e0
], 1.);
979 assert_eq
!(gr
[e1
], 3.);
980 assert_eq
!(gr
[e2
], 1.);
981 assert_eq
!(gr
[e3
], -2.);
984 let mut dfs
= Dfs
::new(&gr
, a
);
985 while let Some(node
) = dfs
.next(&gr
) {
986 let mut edges
= gr
.neighbors_directed(node
, Incoming
).detach();
987 while let Some((edge
, source
)) = edges
.next(&gr
) {
988 assert_eq
!(gr
.find_edge(source
, node
), Some(edge
));
992 let mut edges
= gr
.neighbors_directed(node
, Outgoing
).detach();
993 while let Some((edge
, target
)) = edges
.next(&gr
) {
994 assert_eq
!(gr
.find_edge(node
, target
), Some(edge
));
998 assert_eq
!(nedges
, 8);
1002 fn index_twice_mut() {
1003 let mut gr
= Graph
::<_
,_
>::new();
1004 let a
= gr
.add_node(0.);
1005 let b
= gr
.add_node(0.);
1006 let c
= gr
.add_node(0.);
1007 let d
= gr
.add_node(0.);
1008 let e
= gr
.add_node(0.);
1009 let f
= gr
.add_node(0.);
1010 let g
= gr
.add_node(0.);
1011 gr
.add_edge(a
, b
, 7.0);
1012 gr
.add_edge(a
, d
, 5.);
1013 gr
.add_edge(d
, b
, 9.);
1014 gr
.add_edge(b
, c
, 8.);
1015 gr
.add_edge(b
, e
, 7.);
1016 gr
.add_edge(c
, e
, 5.);
1017 gr
.add_edge(d
, e
, 15.);
1018 gr
.add_edge(d
, f
, 6.);
1019 gr
.add_edge(f
, e
, 8.);
1020 gr
.add_edge(f
, g
, 11.);
1021 gr
.add_edge(e
, g
, 9.);
1023 for dir
in &[Incoming
, Outgoing
] {
1024 for nw
in gr
.node_weights_mut() { *nw = 0.; }
1026 // walk the graph and sum incoming edges
1027 let mut dfs
= Dfs
::new(&gr
, a
);
1028 while let Some(node
) = dfs
.next(&gr
) {
1029 let mut edges
= gr
.neighbors_directed(node
, *dir
).detach();
1030 while let Some(edge
) = edges
.next_edge(&gr
) {
1031 let (nw
, ew
) = gr
.index_twice_mut(node
, edge
);
1037 for i
in 0..gr
.node_count() {
1038 let ni
= NodeIndex
::new(i
);
1039 let s
= gr
.edges_directed(ni
, *dir
).map(|e
| *e
.weight()).fold(0., |a
, b
| a
+ b
);
1040 assert_eq
!(s
, gr
[ni
]);
1042 println
!("Sum {:?}: {:?}", dir
, gr
);
1047 fn toposort_generic() {
1048 // This is a DAG, visit it in order
1049 let mut gr
= Graph
::<_
,_
>::new();
1050 let b
= gr
.add_node(("B", 0.));
1051 let a
= gr
.add_node(("A", 0.));
1052 let c
= gr
.add_node(("C", 0.));
1053 let d
= gr
.add_node(("D", 0.));
1054 let e
= gr
.add_node(("E", 0.));
1055 let f
= gr
.add_node(("F", 0.));
1056 let g
= gr
.add_node(("G", 0.));
1057 gr
.add_edge(a
, b
, 7.0);
1058 gr
.add_edge(a
, d
, 5.);
1059 gr
.add_edge(d
, b
, 9.);
1060 gr
.add_edge(b
, c
, 8.);
1061 gr
.add_edge(b
, e
, 7.);
1062 gr
.add_edge(c
, e
, 5.);
1063 gr
.add_edge(d
, e
, 15.);
1064 gr
.add_edge(d
, f
, 6.);
1065 gr
.add_edge(f
, e
, 8.);
1066 gr
.add_edge(f
, g
, 11.);
1067 gr
.add_edge(e
, g
, 9.);
1069 assert
!(!pg
::algo
::is_cyclic_directed(&gr
));
1071 let mut topo
= Topo
::new(&gr
);
1072 while let Some(nx
) = topo
.next(&gr
) {
1077 let mut order
= Vec
::new();
1079 let mut topo
= Topo
::new(&gr
);
1080 while let Some(nx
) = topo
.next(&gr
) {
1082 assert_eq
!(gr
[nx
].1, index
);
1085 println
!("{:?}", gr
);
1086 assert_is_topo_order(&gr
, &order
);
1090 let mut topo
= Topo
::new(&gr
);
1091 while let Some(nx
) = topo
.next(&gr
) {
1094 println
!("{:?}", gr
);
1095 assert_is_topo_order(&gr
, &order
);
1097 let mut gr2
= gr
.clone();
1098 gr
.add_edge(e
, d
, -1.);
1099 assert
!(pg
::algo
::is_cyclic_directed(&gr
));
1100 assert
!(pg
::algo
::toposort(&gr
, None
).is_err());
1101 gr2
.add_edge(d
, d
, 0.);
1102 assert
!(pg
::algo
::is_cyclic_directed(&gr2
));
1103 assert
!(pg
::algo
::toposort(&gr2
, None
).is_err());
1107 fn test_has_path() {
1108 // This is a DAG, visit it in order
1109 let mut gr
= Graph
::<_
,_
>::new();
1110 let b
= gr
.add_node(("B", 0.));
1111 let a
= gr
.add_node(("A", 0.));
1112 let c
= gr
.add_node(("C", 0.));
1113 let d
= gr
.add_node(("D", 0.));
1114 let e
= gr
.add_node(("E", 0.));
1115 let f
= gr
.add_node(("F", 0.));
1116 let g
= gr
.add_node(("G", 0.));
1117 gr
.add_edge(a
, b
, 7.0);
1118 gr
.add_edge(a
, d
, 5.);
1119 gr
.add_edge(d
, b
, 9.);
1120 gr
.add_edge(b
, c
, 8.);
1121 gr
.add_edge(b
, e
, 7.);
1122 gr
.add_edge(c
, e
, 5.);
1123 gr
.add_edge(d
, e
, 15.);
1124 gr
.add_edge(d
, f
, 6.);
1125 gr
.add_edge(f
, e
, 8.);
1126 gr
.add_edge(f
, g
, 11.);
1127 gr
.add_edge(e
, g
, 9.);
1128 // disconnected island
1130 let h
= gr
.add_node(("H", 0.));
1131 let i
= gr
.add_node(("I", 0.));
1132 gr
.add_edge(h
, i
, 2.);
1133 gr
.add_edge(i
, h
, -2.);
1135 let mut state
= DfsSpace
::default();
1137 gr
.add_edge(b
, a
, 99.);
1139 assert
!(has_path_connecting(&gr
, c
, c
, None
));
1141 for edge
in gr
.edge_references() {
1142 assert
!(has_path_connecting(&gr
, edge
.source(), edge
.target(), None
));
1144 assert
!(has_path_connecting(&gr
, a
, g
, Some(&mut state
)));
1145 assert
!(!has_path_connecting(&gr
, a
, h
, Some(&mut state
)));
1146 assert
!(has_path_connecting(&gr
, a
, c
, None
));
1147 assert
!(has_path_connecting(&gr
, a
, c
, Some(&mut state
)));
1148 assert
!(!has_path_connecting(&gr
, h
, a
, Some(&mut state
)));
1152 fn map_filter_map() {
1153 let mut g
= Graph
::new_undirected();
1154 let a
= g
.add_node("A");
1155 let b
= g
.add_node("B");
1156 let c
= g
.add_node("C");
1157 let d
= g
.add_node("D");
1158 let e
= g
.add_node("E");
1159 let f
= g
.add_node("F");
1160 g
.add_edge(a
, b
, 7);
1161 g
.add_edge(c
, a
, 9);
1162 g
.add_edge(a
, d
, 14);
1163 g
.add_edge(b
, c
, 10);
1164 g
.add_edge(d
, c
, 2);
1165 g
.add_edge(d
, e
, 9);
1166 g
.add_edge(b
, f
, 15);
1167 g
.add_edge(c
, f
, 11);
1168 g
.add_edge(e
, f
, 6);
1169 println
!("{:?}", g
);
1171 let g2
= g
.filter_map(|_
, name
| Some(*name
), |_
, &weight
| if weight
>= 10 {
1174 assert_eq
!(g2
.edge_count(), 4);
1175 for edge
in g2
.raw_edges() {
1176 assert
!(edge
.weight
>= 10);
1179 let g3
= g
.filter_map(|i
, &name
| if i
== a
|| i
== e { None }
else { Some(name) }
,
1181 let (source
, target
) = g
.edge_endpoints(i
).unwrap();
1182 // don't map edges from a removed node
1183 assert
!(source
!= a
);
1184 assert
!(target
!= a
);
1185 assert
!(source
!= e
);
1186 assert
!(target
!= e
);
1189 assert_eq
!(g3
.node_count(), g
.node_count() - 2);
1190 assert_eq
!(g3
.edge_count(), g
.edge_count() - 5);
1191 assert_graph_consistent(&g3
);
1193 let mut g4
= g
.clone();
1194 g4
.retain_edges(|gr
, i
| {
1195 let (s
, t
) = gr
.edge_endpoints(i
).unwrap();
1196 !(s
== a
|| s
== e
|| t
== a
|| t
== e
)
1198 assert_eq
!(g4
.edge_count(), g
.edge_count() - 5);
1199 assert_graph_consistent(&g4
);
1204 let n
= NodeIndex
::new
;
1205 let gr
= Graph
::<(), (), Undirected
>::from_edges(&[
1206 (0, 1), (0, 2), (0, 3),
1210 assert_eq
!(gr
.node_count(), 4);
1211 assert_eq
!(gr
.edge_count(), 6);
1212 assert_eq
!(gr
.neighbors(n(0)).count(), 3);
1213 assert_eq
!(gr
.neighbors(n(1)).count(), 3);
1214 assert_eq
!(gr
.neighbors(n(2)).count(), 3);
1215 assert_eq
!(gr
.neighbors(n(3)).count(), 3);
1216 assert_graph_consistent(&gr
);
1221 let mut gr
= Graph
::<i32, i32, Undirected
>::from_edges(&[
1228 gr
.retain_edges(|mut gr
, i
| {
1229 if gr
[i
] <= 0 { false }
1232 let (s
, t
) = gr
.edge_endpoints(i
).unwrap();
1240 assert_eq
!(gr
.edge_count(), 3);
1241 assert_eq
!(gr
[n(0)], 1);
1242 assert_eq
!(gr
[n(1)], 4);
1243 assert_eq
!(gr
[n(2)], 2);
1244 assert_eq
!(gr
[n(3)], 1);
1245 assert
!(gr
.find_edge(n(1), n(1)).is_none());
1246 assert
!(gr
.find_edge(n(0), n(2)).is_none());
1247 assert_graph_consistent(&gr
);
1250 fn assert_graph_consistent
<N
, E
, Ty
, Ix
>(g
: &Graph
<N
, E
, Ty
, Ix
>)
1254 assert_eq
!(g
.node_count(), g
.node_indices().count());
1255 assert_eq
!(g
.edge_count(), g
.edge_indices().count());
1256 for edge
in g
.raw_edges() {
1257 assert
!(g
.find_edge(edge
.source(), edge
.target()).is_some(),
1258 "Edge not in graph! {:?} to {:?}", edge
.source(), edge
.target());
1263 fn neighbors_selfloops() {
1265 let mut gr
= Graph
::<_
,()>::new();
1266 let a
= gr
.add_node("a");
1267 let b
= gr
.add_node("b");
1268 let c
= gr
.add_node("c");
1269 gr
.extend_with_edges(&[
1276 let out_edges
= [a
, a
, b
];
1277 let in_edges
= [a
, a
, c
];
1278 let undir_edges
= [a
, a
, b
, c
];
1279 let mut seen_out
= gr
.neighbors(a
).collect
::<Vec
<_
>>();
1281 assert_eq
!(&seen_out
, &out_edges
);
1282 let mut seen_in
= gr
.neighbors_directed(a
, Incoming
).collect
::<Vec
<_
>>();
1284 assert_eq
!(&seen_in
, &in_edges
);
1286 let mut seen_undir
= gr
.neighbors_undirected(a
).collect
::<Vec
<_
>>();
1288 assert_eq
!(&seen_undir
, &undir_edges
);
1290 let mut seen_out
= gr
.edges(a
).map(|e
| e
.target()).collect
::<Vec
<_
>>();
1292 assert_eq
!(&seen_out
, &out_edges
);
1294 let mut seen_walk
= Vec
::new();
1295 let mut walk
= gr
.neighbors(a
).detach();
1296 while let Some(n
) = walk
.next_node(&gr
) { seen_walk.push(n); }
1298 assert_eq
!(&seen_walk
, &out_edges
);
1301 let mut walk
= gr
.neighbors_directed(a
, Incoming
).detach();
1302 while let Some(n
) = walk
.next_node(&gr
) { seen_walk.push(n); }
1304 assert_eq
!(&seen_walk
, &in_edges
);
1307 let mut walk
= gr
.neighbors_undirected(a
).detach();
1308 while let Some(n
) = walk
.next_node(&gr
) { seen_walk.push(n); }
1310 assert_eq
!(&seen_walk
, &undir_edges
);
1313 let mut gr
: Graph
<_
, (), _
> = Graph
::new_undirected();
1314 let a
= gr
.add_node("a");
1315 let b
= gr
.add_node("b");
1316 let c
= gr
.add_node("c");
1317 gr
.extend_with_edges(&[
1323 let out_edges
= [a
, b
, c
];
1324 let in_edges
= [a
, b
, c
];
1325 let undir_edges
= [a
, b
, c
];
1326 let mut seen_out
= gr
.neighbors(a
).collect
::<Vec
<_
>>();
1328 assert_eq
!(&seen_out
, &out_edges
);
1330 let mut seen_out
= gr
.edges(a
).map(|e
| e
.target()).collect
::<Vec
<_
>>();
1332 assert_eq
!(&seen_out
, &out_edges
);
1334 let mut seen_in
= gr
.neighbors_directed(a
, Incoming
).collect
::<Vec
<_
>>();
1336 assert_eq
!(&seen_in
, &in_edges
);
1338 let mut seen_undir
= gr
.neighbors_undirected(a
).collect
::<Vec
<_
>>();
1340 assert_eq
!(&seen_undir
, &undir_edges
);
1344 fn degree
<'a
, G
>(g
: G
, node
: G
::NodeId
) -> usize
1345 where G
: IntoNeighbors
,
1346 G
::NodeId
: PartialEq
,
1348 // self loops count twice
1349 let original_node
= node
.clone();
1351 for v
in g
.neighbors(node
) {
1352 degree
+= if v
== original_node { 2 }
else { 1 }
;
1357 #[cfg(feature = "graphmap")]
1359 fn degree_sequence() {
1360 let mut gr
= Graph
::<usize, (), Undirected
>::from_edges(&[
1367 gr
.add_node(0); // add isolated node
1368 let mut degree_sequence
= gr
.node_indices()
1369 .map(|i
| degree(&gr
, i
))
1370 .collect
::<Vec
<_
>>();
1372 degree_sequence
.sort_by(|x
, y
| Ord
::cmp(y
, x
));
1373 assert_eq
!(°ree_sequence
, &[5, 3, 3, 2, 2, 1, 0]);
1375 let mut gr
= GraphMap
::<_
, (), Undirected
>::from_edges(&[
1382 gr
.add_node(6); // add isolated node
1383 let mut degree_sequence
= gr
.nodes()
1384 .map(|i
| degree(&gr
, i
))
1385 .collect
::<Vec
<_
>>();
1387 degree_sequence
.sort_by(|x
, y
| Ord
::cmp(y
, x
));
1388 assert_eq
!(°ree_sequence
, &[5, 3, 3, 2, 2, 1, 0]);
1392 fn neighbor_order() {
1393 let mut gr
= Graph
::new();
1394 let a
= gr
.add_node("a");
1395 let b
= gr
.add_node("b");
1396 let c
= gr
.add_node("c");
1397 gr
.add_edge(a
, b
, 0);
1398 gr
.add_edge(a
, a
, 1);
1400 gr
.add_edge(c
, a
, 2);
1402 gr
.add_edge(a
, c
, 3);
1404 gr
.add_edge(c
, a
, 4);
1405 gr
.add_edge(b
, a
, 5);
1407 // neighbors (edges) are in lifo order, if it's a directed graph
1408 assert_eq
!(gr
.neighbors(a
).collect
::<Vec
<_
>>(),
1410 assert_eq
!(gr
.neighbors_directed(a
, Incoming
).collect
::<Vec
<_
>>(),
1416 // test alternate formatting
1422 let mut gr
= Graph
::new();
1423 let a
= gr
.add_node(Record { a: 1, b: "abc" }
);
1424 gr
.add_edge(a
, a
, (1, 2));
1425 let dot_output
= format
!("{:#?}", Dot
::new(&gr
));
1426 assert_eq
!(dot_output
,
1428 0 [label="Record {\l a: 1,\l b: \"abc\"\l}\l"]
1429 0 -> 0 [label="(\l 1,\l 2\l)\l"]
1436 let mut g
= Graph
::new();
1437 let a
= g
.add_node("A");
1438 let b
= g
.add_node("B");
1439 let c
= g
.add_node("C");
1440 let d
= g
.add_node("D");
1441 let e
= g
.add_node("E");
1442 let f
= g
.add_node("F");
1443 g
.add_edge(a
, b
, 7);
1444 g
.add_edge(c
, a
, 9);
1445 g
.add_edge(a
, d
, 14);
1446 g
.add_edge(b
, c
, 10);
1447 g
.add_edge(d
, c
, 2);
1448 g
.add_edge(d
, e
, 9);
1449 g
.add_edge(b
, f
, 15);
1450 g
.add_edge(c
, f
, 11);
1451 g
.add_edge(e
, f
, 6);
1452 println
!("{:?}", g
);
1454 let filt
= NodeFiltered(&g
, |n
: NodeIndex
| n
!= c
&& n
!= e
);
1456 let mut dfs
= DfsPostOrder
::new(&filt
, a
);
1457 let mut po
= Vec
::new();
1458 while let Some(nx
) = dfs
.next(&filt
) {
1459 println
!("Next: {:?}", nx
);
1462 assert_eq
!(set(po
), set(g
.node_identifiers().filter(|n
| (filt
.1)(*n
))));
1469 use petgraph
::visit
::{Visitable, VisitMap}
;
1470 use petgraph
::visit
::DfsEvent
::*;
1471 use petgraph
::visit
::{Time, depth_first_search}
;
1472 use petgraph
::visit
::Control
;
1473 let gr
: Graph
<(), ()> = Graph
::from_edges(&[
1474 (0, 5), (0, 2), (0, 3), (0, 1),
1480 let invalid_time
= Time(!0);
1481 let mut discover_time
= vec
![invalid_time
; gr
.node_count()];
1482 let mut finish_time
= vec
![invalid_time
; gr
.node_count()];
1483 let mut has_tree_edge
= gr
.visit_map();
1484 let mut edges
= HashSet
::new();
1485 depth_first_search(&gr
, Some(n(0)), |evt
| {
1486 println
!("Event: {:?}", evt
);
1488 Discover(n
, t
) => discover_time
[n
.index()] = t
,
1489 Finish(n
, t
) => finish_time
[n
.index()] = t
,
1491 // v is an ancestor of u
1492 assert
!(has_tree_edge
.visit(v
), "Two tree edges to {:?}!", v
);
1493 assert
!(discover_time
[v
.index()] == invalid_time
);
1494 assert
!(discover_time
[u
.index()] != invalid_time
);
1495 assert
!(finish_time
[u
.index()] == invalid_time
);
1496 edges
.insert((u
, v
));
1499 // u is an ancestor of v
1500 assert
!(discover_time
[v
.index()] != invalid_time
);
1501 assert
!(finish_time
[v
.index()] == invalid_time
);
1502 edges
.insert((u
, v
));
1504 CrossForwardEdge(u
, v
) => {
1505 edges
.insert((u
, v
));
1509 assert
!(discover_time
.iter().all(|x
| *x
!= invalid_time
));
1510 assert
!(finish_time
.iter().all(|x
| *x
!= invalid_time
));
1511 assert_eq
!(edges
.len(), gr
.edge_count());
1512 assert_eq
!(edges
, set(gr
.edge_references().map(|e
| (e
.source(), e
.target()))));
1513 println
!("{:?}", discover_time
);
1514 println
!("{:?}", finish_time
);
1516 // find path from 0 to 4
1517 let mut predecessor
= vec
![NodeIndex
::end(); gr
.node_count()];
1520 let ret
= depth_first_search(&gr
, Some(start
), |event
| {
1521 if let TreeEdge(u
, v
) = event
{
1522 predecessor
[v
.index()] = u
;
1524 return Control
::Break(u
);
1529 // assert we did terminate early
1530 assert
!(ret
.break_value().is_some());
1531 assert
!(predecessor
.iter().any(|x
| *x
== NodeIndex
::end()));
1533 let mut next
= goal
;
1534 let mut path
= vec
![next
];
1535 while next
!= start
{
1536 let pred
= predecessor
[next
.index()];
1541 assert_eq
!(&path
, &[n(0), n(2), n(4)]);
1546 fn filtered_post_order() {
1547 use petgraph
::visit
::NodeFiltered
;
1549 let mut gr
: Graph
<(), ()> = Graph
::from_edges(&[
1558 // map reachable nodes
1559 let mut dfs
= Dfs
::new(&gr
, n(0));
1560 while let Some(_
) = dfs
.next(&gr
) { }
1562 let map
= dfs
.discovered
;
1563 gr
.add_edge(n(0), n(1), ());
1564 let mut po
= Vec
::new();
1565 let mut dfs
= DfsPostOrder
::new(&gr
, n(0));
1566 let f
= NodeFiltered(&gr
, map
);
1567 while let Some(n
) = dfs
.next(&f
) {
1570 assert
!(!po
.contains(&n(1)));
1574 fn filter_elements() {
1575 use petgraph
::data
::Element
::{Node, Edge}
;
1576 use petgraph
::data
::FromElements
;
1577 use petgraph
::data
::ElementIterator
;
1578 let elements
= vec
![
1579 Node { weight: "A"}
,
1580 Node { weight: "B"}
,
1581 Node { weight: "C"}
,
1582 Node { weight: "D"}
,
1583 Node { weight: "E"}
,
1584 Node { weight: "F"}
,
1586 Edge { source: 0, target: 1, weight: 7 }
,
1587 Edge { source: 2, target: 0, weight: 9 }
,
1588 Edge { source: 0, target: 3, weight: 14 }
,
1589 Edge { source: 1, target: 2, weight: 10 }
,
1590 Edge { source: 3, target: 2, weight: 2 }
,
1591 Edge { source: 3, target: 4, weight: 9 }
,
1592 Edge { source: 1, target: 5, weight: 15 }
,
1593 Edge { source: 2, target: 5, weight: 11 }
,
1594 Edge { source: 4, target: 5, weight: 6 }
,
1596 let mut g
= DiGraph
::<_
, _
>::from_elements(elements
.iter().cloned());
1597 println
!("{:#?}", g
);
1598 assert
!(g
.contains_edge(n(1), n(5)));
1599 let g2
= DiGraph
::<_
, _
>::from_elements(elements
.iter().cloned().filter_elements(|elt
| {
1601 Node { ref weight }
if **weight
== "B" => false,
1605 println
!("{:#?}", g2
);
1606 g
.remove_node(n(1));
1607 assert
!(is_isomorphic_matching(&g
, &g2
, PartialEq
::eq
, PartialEq
::eq
));
1611 fn test_edge_filtered() {
1612 use petgraph
::algo
::connected_components
;
1613 use petgraph
::visit
::EdgeFiltered
;
1614 use petgraph
::visit
::IntoEdgeReferences
;
1616 let gr
= UnGraph
::<(), _
>::from_edges(&[
1632 assert_eq
!(connected_components(&gr
), 1);
1633 let positive_edges
= EdgeFiltered
::from_fn(&gr
, |edge
| *edge
.weight() >= 0);
1634 assert_eq
!(positive_edges
.edge_references().count(), 6);
1635 assert
!(positive_edges
.edge_references().all(|edge
| *edge
.weight() >= 0));
1636 assert_eq
!(connected_components(&positive_edges
), 2);
1638 let mut dfs
= DfsPostOrder
::new(&positive_edges
, n(0));
1639 while let Some(_
) = dfs
.next(&positive_edges
) { }
1642 for node
in &[n(0), n(1), n(2)] {
1643 assert
!(dfs
.discovered
.is_visited(node
));
1645 for node
in &[n(3), n(4), n(5)] {
1646 assert
!(!dfs
.discovered
.is_visited(node
));
1651 fn test_dominators_simple_fast() {
1652 // Construct the following graph:
1655 // | <--------------------------------.
1656 // .--------+--------------| r |--------------. |
1659 // | .--V--. .--V--. |
1661 // | | b | | c |--------. |
1663 // | '-----' '-----' | |
1664 // .--V--. | | .--V--. |
1666 // | a <-----+ | .----| g | |
1667 // | | | .----' | | | |
1668 // '-----' | | | '-----' |
1670 // .--V--. | .-----. .--V--. | | |
1671 // | | | | | | | | | |
1672 // | d <-----+----> e <----. | f | | | |
1673 // | | | | | | | | | |
1674 // '-----' '-----' | '-----' | | |
1675 // | .-----. | | | | .--V--. |
1676 // | | | | | | .-' | | |
1677 // '-----> l | | | | | | j | |
1678 // | | '--. | | | | | |
1679 // '-----' | | | | '-----' |
1680 // | .--V--. | | .--V--. | |
1681 // | | | | | | | | |
1682 // '-------> h |-' '---> i <------' |
1683 // | | .---------> | |
1684 // '-----' | '-----' |
1687 // '----------> k <---------' |
1691 // '----------------------------'
1693 // This graph has the following dominator tree:
1709 // This graph and dominator tree are taken from figures 1 and 2 of "A Fast
1710 // Algorithm for Finding Dominators in a Flowgraph" by Lengauer et al:
1711 // http://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf.
1713 let mut graph
= DiGraph
::<_
, _
>::new();
1715 let r
= graph
.add_node("r");
1716 let a
= graph
.add_node("a");
1717 let b
= graph
.add_node("b");
1718 let c
= graph
.add_node("c");
1719 let d
= graph
.add_node("d");
1720 let e
= graph
.add_node("e");
1721 let f
= graph
.add_node("f");
1722 let g
= graph
.add_node("g");
1723 let h
= graph
.add_node("h");
1724 let i
= graph
.add_node("i");
1725 let j
= graph
.add_node("j");
1726 let k
= graph
.add_node("k");
1727 let l
= graph
.add_node("l");
1729 graph
.add_edge(r
, a
, ());
1730 graph
.add_edge(r
, b
, ());
1731 graph
.add_edge(r
, c
, ());
1732 graph
.add_edge(a
, d
, ());
1733 graph
.add_edge(b
, a
, ());
1734 graph
.add_edge(b
, d
, ());
1735 graph
.add_edge(b
, e
, ());
1736 graph
.add_edge(c
, f
, ());
1737 graph
.add_edge(c
, g
, ());
1738 graph
.add_edge(d
, l
, ());
1739 graph
.add_edge(e
, h
, ());
1740 graph
.add_edge(f
, i
, ());
1741 graph
.add_edge(g
, i
, ());
1742 graph
.add_edge(g
, j
, ());
1743 graph
.add_edge(h
, e
, ());
1744 graph
.add_edge(h
, k
, ());
1745 graph
.add_edge(i
, k
, ());
1746 graph
.add_edge(j
, i
, ());
1747 graph
.add_edge(k
, r
, ());
1748 graph
.add_edge(k
, i
, ());
1749 graph
.add_edge(l
, h
, ());
1751 let doms
= dominators
::simple_fast(&graph
, r
);
1753 assert_eq
!(doms
.root(), r
);
1754 assert_eq
!(doms
.immediate_dominator(r
), None
,
1755 "The root node has no idom");
1757 assert_eq
!(doms
.immediate_dominator(a
), Some(r
),
1758 "r is the immediate dominator of a");
1759 assert_eq
!(doms
.immediate_dominator(b
), Some(r
),
1760 "r is the immediate dominator of b");
1761 assert_eq
!(doms
.immediate_dominator(c
), Some(r
),
1762 "r is the immediate dominator of c");
1763 assert_eq
!(doms
.immediate_dominator(f
), Some(c
),
1764 "c is the immediate dominator of f");
1765 assert_eq
!(doms
.immediate_dominator(g
), Some(c
),
1766 "c is the immediate dominator of g");
1767 assert_eq
!(doms
.immediate_dominator(j
), Some(g
),
1768 "g is the immediate dominator of j");
1769 assert_eq
!(doms
.immediate_dominator(d
), Some(r
),
1770 "r is the immediate dominator of d");
1771 assert_eq
!(doms
.immediate_dominator(l
), Some(d
),
1772 "d is the immediate dominator of l");
1773 assert_eq
!(doms
.immediate_dominator(e
), Some(r
),
1774 "r is the immediate dominator of e");
1775 assert_eq
!(doms
.immediate_dominator(i
), Some(r
),
1776 "r is the immediate dominator of i");
1777 assert_eq
!(doms
.immediate_dominator(k
), Some(r
),
1778 "r is the immediate dominator of k");
1779 assert_eq
!(doms
.immediate_dominator(h
), Some(r
),
1780 "r is the immediate dominator of h");
1782 let mut graph
= graph
.clone();
1783 let z
= graph
.add_node("z");
1784 let doms
= dominators
::simple_fast(&graph
, r
);
1785 assert_eq
!(doms
.immediate_dominator(z
), None
,
1786 "nodes that aren't reachable from the root do not have an idom");