1

I am looking for the solution to a problem where Perl script could detect all the cyclic nodes in a directed graph? For example, I have following graph:

A<-N<-G<-L<- A<-B<-C<-D<-E<-F<-A Be a Graph with cyclic edges. 
use strict;
use warnings;
my @graphNodes=(A,N,G,L, A,B,C,D,E,F,A );
my depEdges= dependBy(); #Let dependBy be hypothetical function that return immediate dependents.

In rest of code, I need logical help to collect all the nodes which are involved in cyclic dependencies. For instance, in my case, on node 'A', there are cyclic dependencies. How can I recursively implement dependBy function to find cyclic edges or dependencies?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Analyzer
  • 79
  • 7
  • 1
    What exactly is your question? Are you expecting us to write this for you? – simbabque Sep 28 '15 at 12:12
  • @simbabque Not really. I have mentioned. I want to find cyclic dependency over the node in directed graph. Just a need logical help. – Analyzer Sep 28 '15 at 12:25
  • Not sure what you mean by dependent edges. Are all nodes in a circle "dependent"? Do you want to find the nodes in every directed circle that's present in the graph? So in your sample graph, you'd output 2 sets of nodes involved in the 2 circles? – hepcat72 Sep 28 '15 at 15:15
  • In any case, generally, you would have to do something like a recursive depth-first search, keeping track of(/sending along as a param) the seen-nodes. When you hit a node you've seen before, you can record the loop and return it. When you recurse back a step, you save the returned result and try a different path(/child) and see if it yields another circle. It ends when you get back to the starting node and there's no other paths to try. Not sure of the best place to start, but you could keep global track of any untouched nodes and cycle through those in an outer loop. – hepcat72 Sep 28 '15 at 18:53
  • @hepcat72 Thanks for your guidance. For you question, all nodes are directly are indirectly dependents on "A" or other node. And, they get back to A forming a cycle, however, in my case, dependby function would only yield BL as its dependent nodes. While, further recursion of dependy would yield corresponding adjacent or immediate edges of B and L. How should I proceed ahead to implment a logic in which "dependby" function list up all the nodes and find which are involved in a cycle. – Analyzer Sep 29 '15 at 02:27
  • I'm still unclear about the desired output from dependBy(). Can you give a discrete full example of what you want to be output by dependBy()? For example, if I attempt to infer the intended function by what you've said, it sounds like you want all the edges involved in junctions into and out of a circle. So would this be the desired output from dependBy() in your example?: `(A->F,B->A,A->L,N->A)` – hepcat72 Sep 29 '15 at 15:19

1 Answers1

1

While this is not conceptual help, it's the fastest solution: Check if someone has already found the solution. In this case, you can use the Graph module from CPAN to do that.

use strict;
use warnings;
use feature 'say';
use Graph;

my $g = Graph->new;

my @edges = qw(A B C D E F A);
for (my $i =0; $i < $#edges; $i++) {
  $g->add_edge($edges[$i], $edges[$i+1]);
}

say $g;
say "is cyclic" if $g->is_cyclic;
say $g->find_a_cycle;

This will output:

A-B,B-C,C-D,D-E,E-F,F-A
is cyclic
FABCDE
simbabque
  • 53,749
  • 8
  • 73
  • 136
  • How about without using graph module? In my case "dependby" function produces immediate dependent edges. – Analyzer Sep 28 '15 at 12:49
  • @Analyzer you should be able to build that with Graph. But for purely algorithmic help, SO is the wrong place to ask this question I'm afraid. We help with immediate problems. As is, this is not a Perl problem. – simbabque Sep 28 '15 at 12:52
  • I would prefer more concrete logic to built in functions :(. For instance , as I mentioned in question that I already have function "dependby" that produces immediate dependent edges. – Analyzer Sep 28 '15 at 12:54
  • I will wait for more help to come. – Analyzer Sep 28 '15 at 12:57