Skip to content

Commit 2cf4969

Browse files
Lucian-4a25ABorgna
andauthored
add Topo::with_initials API (petgraph#585)
* add Topo::with_initials API * filter nodes with incoming edges for Topo::with_initials API * Clear up the docs --------- Co-authored-by: Agustín Borgna <[email protected]>
1 parent e73fb54 commit 2cf4969

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

src/visit/traversal.rs

+17
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,23 @@ where
344344
topo
345345
}
346346

347+
/// Create a new `Topo` with initial nodes.
348+
///
349+
/// Nodes with incoming edges are ignored.
350+
pub fn with_initials<G, I>(graph: G, initials: I) -> Self
351+
where
352+
G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
353+
I: IntoIterator<Item = N>,
354+
{
355+
Topo {
356+
tovisit: initials
357+
.into_iter()
358+
.filter(|&n| graph.neighbors_directed(n, Incoming).next().is_none())
359+
.collect(),
360+
ordered: graph.visit_map(),
361+
}
362+
}
363+
347364
fn extend_with_initials<G>(&mut self, g: G)
348365
where
349366
G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,

tests/graph.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,30 @@ fn toposort_generic() {
15361536
println!("{:?}", gr);
15371537
assert_is_topo_order(&gr, &order);
15381538

1539+
{
1540+
order.clear();
1541+
let init_nodes = gr.node_identifiers().filter(|n| {
1542+
gr.neighbors_directed(n.clone(), Direction::Incoming)
1543+
.next()
1544+
.is_none()
1545+
});
1546+
let mut topo = Topo::with_initials(&gr, init_nodes);
1547+
while let Some(nx) = topo.next(&gr) {
1548+
order.push(nx);
1549+
}
1550+
assert_is_topo_order(&gr, &order);
1551+
}
1552+
1553+
{
1554+
// test `with_initials` API using nodes with incoming edges
1555+
order.clear();
1556+
let mut topo = Topo::with_initials(&gr, gr.node_identifiers());
1557+
while let Some(nx) = topo.next(&gr) {
1558+
order.push(nx);
1559+
}
1560+
assert_is_topo_order(&gr, &order);
1561+
}
1562+
15391563
{
15401564
order.clear();
15411565
let mut topo = Topo::new(&gr);

tests/quickcheck.rs

+29
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,35 @@ fn full_topo_generic() {
727727
return false;
728728
}
729729
}
730+
731+
{
732+
order.clear();
733+
let init_nodes = gr.node_identifiers().filter(|n| {
734+
gr.neighbors_directed(n.clone(), Direction::Incoming)
735+
.next()
736+
.is_none()
737+
});
738+
let mut topo = Topo::with_initials(&gr, init_nodes);
739+
while let Some(nx) = topo.next(&gr) {
740+
order.push(nx);
741+
}
742+
if !is_topo_order(&gr, &order) {
743+
println!("{:?}", gr);
744+
return false;
745+
}
746+
}
747+
748+
{
749+
order.clear();
750+
let mut topo = Topo::with_initials(&gr, gr.node_identifiers());
751+
while let Some(nx) = topo.next(&gr) {
752+
order.push(nx);
753+
}
754+
if !is_topo_order(&gr, &order) {
755+
println!("{:?}", gr);
756+
return false;
757+
}
758+
}
730759
true
731760
}
732761
quickcheck::quickcheck(prop_generic as fn(_) -> bool);

0 commit comments

Comments
 (0)