I want to find all paths from sources to sinks. Expected:
(3 11 17 24 32 39 45)
(3 11 18 26 33 39 45)
(3 11 18 26 33 40 46)
(3 11 18 26 33 40 47)
(3 11 19 27 33 39 45)
(3 11 19 27 33 40 46)
(3 11 19 27 33 40 47)
(3 11 19 27 34 40 46)
(3 11 19 27 34 40 47)
(6 12 20 27 33 39 45)
(6 12 20 27 33 40 46)
(6 12 20 27 33 40 47)
(6 12 20 27 34 40 46)
(6 12 20 27 34 40 47)
In my code, I know how to visit each vertex, but how do I properly remember and assemble the full paths?
use 5.028;
use feature 'signatures';
use strictures;
use Graph qw();
my $g = Graph->new(directed => 1);
for my $edge_tuple (qw(
3-11 6-12 11-17 11-18 11-19 12-20 17-24 18-26 19-27 20-27 24-32 26-33
27-33 27-34 32-39 33-39 33-40 34-40 39-45 40-46 40-47
)) {
my ($from, $to) = split '-', $edge_tuple;
$g->add_edge($from, $to);
}
say join ';', $g->source_vertices;
say join ';', $g->sink_vertices;
sub visit($g, $v, $p) {
push @$p, $v;
if ($g->is_sink_vertex($v)) {
return;
} else {
for my $s ($g->successors($v)) {
visit($g, $s, $p)
}
}
}
my $p = [];
for my $v ($g->source_vertices) {
visit($g, $v, $p);
}
use Data::Dumper; say Dumper $p;
Finding all the possible paths in any graph in Exponential. It can be solved by using Backtracking. For DAG's we can do it using Depth first search(DFS). In DFS code, Start at any node, Go to the extreme dead end path and note down all the nodes visited in that path using some array or list.
A node is considered a source in a graph if it has in-degree of 0 (no nodes have a source as their destination); likewise, a node is considered a sink in a graph if it has out-degree of 0 (no nodes have a sink as their source). A path is a sequence of nodes a1, a2, ... an, such that there is an edge from ai to ai+1.
A local sink is a node of a directed graph with no exiting edges, also called a terminal (Borowski and Borwein 1991, p. 401; left figure). A global sink (often simply called a sink) is a node in a directed graph which is reached by all directed edges (Harary 1994, p. 201; right figure).
(b) Which are source SCCs and which are sink SCCs? Ans: The source SCCs: E and B; sink SCC: CDFJ.
I modified your code to pass a partial path into visit()
and also to have visit()
return all possible complete paths from the supplied partial path:
sub visit($g, $path) {
my $v = $path->[-1];
if ($g->is_sink_vertex($v)) {
return $path;
} else {
my @more;
for my $s ($g->successors($v)) {
push @more, visit($g, [ @$path, $s ])
}
return @more;
}
}
my @p;
for my $v ($g->source_vertices) {
push @p, visit($g, [$v]);
}
use Data::Dumper; say Dumper @p;
The loops could then be reduced using map:
sub visit($g, $path) {
my $v = $path->[-1];
if ($g->is_sink_vertex($v)) {
return $path;
} else {
return map { visit($g, [ @$path, $_ ]) } $g->successors($v);
}
}
my @p = map { visit($g, [$_]) } $g->source_vertices;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With