Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find all paths from sources to sinks in a directed graph?

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;
like image 436
daxim Avatar asked Oct 21 '18 20:10

daxim


People also ask

How do you find all possible paths in a directed graph?

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.

What are the sources and sinks of the graph?

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.

What is a sink in a directed graph?

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).

Which are source SCCs and which are sink SCCs?

(b) Which are source SCCs and which are sink SCCs? Ans: The source SCCs: E and B; sink SCC: CDFJ.


1 Answers

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;
like image 117
Grant McLean Avatar answered Nov 07 '22 19:11

Grant McLean