newbio has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I am trying to create a graphical structure with four nodes with names a, b, c and d. (%parentchild in the code below shows the graphical structure).
The program is giving the desired output for $nodes[0] (in the first foreach loop of the code below - output for $nodes[0] is also shown below). The output must contain all possible combinations of values of the node and its parents.
However, all subsequent iterations of this foreach loop (for $nodes[1], $nodes[2], $nodes[3], $nodes[4], and $nodes[5])
give incorrect results. I am not being able to figure out what mistake I am making.

Please guide me where the fault is.

Thanks very much.

#!/usr/bin/perl use warnings; use strict; my $a=['a','p','q','r']; # a is the node name and p,q,r are the values + this node can assume. Likewise for other nodes. my $b=['b','t','f']; my $c=['c','nn','ny','yn','yy']; my $d=['d','abv','avb','vab']; my $values=[$b,$a,$c,$d]; my @nodes=('a','a','a','b','c','d'); foreach my $i (@nodes) { my $nodeparents=[parentchildrelationship($i)]; print "$i $nodeparents $values\n"; my $hash1=cpt($i,$nodeparents,$values); foreach my $i (keys %{$hash1}) { print "$i=>${$hash1}{$i}\n"; #print "$i\n"; } } sub cpt { my $node=$_[0]; my @parents=@{$_[1]}; my @nodevalues=@{$_[2]}; my %hash=(); my @nodeindex=(); my @temparray=(); my $string=""; my @temp=(); my $s; foreach my $i (@parents) { for (my $j=0;$j<=$#nodevalues;$j++) { if ($i eq ${$nodevalues[$j]}[0]) { push (@nodeindex, $j); } } } foreach my $i (reverse @nodeindex) { push (@temparray, $nodevalues[$i]); } for (my $i=0;$i<=$#temparray;$i++) { $string="$string"."${$temparray[$i]}[0] "; shift @{$temparray[$i]}; $temp[$i]=join (",",@{$temparray[$i]}); } $hash{$string}=1; #fill %hash with the header $s = join "\\ ", map "{$_}", @temp; #print "$s\n"; $hash{$_}=1 for glob $s; return {%hash}; $node=""; @parents=(); @nodevalues=(); %hash=(); @nodeindex=(); @temparray=(); $string=""; @temp=(); $s=""; } sub parentchildrelationship { my $node=$_[0]; #or use "shift" my %parentchild=(); my @nodeset=(); %parentchild=('b'=>['none'], 'a'=>['b','d'], 'd'=>['b'], 'c'=>['b' +]); #This is the structure of my graph, for example node 'b' has no p +arent; node 'a' has parents in 'b','d'; and node d and c have both b +as parent. push (@nodeset, $node, @{$parentchild{$node}}); return @nodeset; }

Replies are listed 'Best First'.
Re: Tree structure problem
by kyle (Abbot) on May 08, 2007 at 17:33 UTC

    Looking at your parentchildrelationship sub, I can't see how it's defining a tree of any kind. Either 'a' has two parents or 'b' has two parents.

    It would help us to know what kind of output you're expecting. One thing I notice is that you print $nodeparents, but that's an array reference. You might want to look at Data::Dumper to see the contents of it.

      Parent child relationship is defined in sub parentchildrelationship in hash %parentchild as 'a'=>['b','d'], where node 'a' has two parents, 'b','d'.

      Result for the first foreach iteration, ie for $nodes[\0] is shown below (and this result is correct). The first line is the header with names of the nodes (target node here is 'a' and its parents are 'd' and 'b'). All other remaining lines represent combinations of all different values that the nodes can assume. However, I am getting incorrect results for $nodes[\1], $nodes[\2], and others. Please remove backslash from the array elements because I cannot figure out how to correctly write $nodes[\0] without a backslash. Wow, formatting appears a huge task here...any reason to make it complex. I hope this formatting works out..:)

      Output:
      d b a =>1
      abv f r=>1
      abv t r=>1
      abv f q=>1
      avb t q=>1
      avb t p=>1
      avb f p=>1
      avb f r=>1
      abv t q=>1
      abv t p=>1
      avb t r=>1
      vab t r=>1
      vab f r=>1
      vab f q=>1
      vab t p=>1
      abv f p=>1
      avb f q=>1
      vab f p=>1
      vab t q=>1