in reply to Re^3: out of memory problem
in thread out of memory problem

The output of the program with the sample dataset I gave in the previous thread is:
cancer-1->breast cancer cancer-1->lung cancer cancer-1->heart cancer cancer-1->stomach cancer cancer-4->foot cancer cancer-1->blood cancer breast cancer-1->foot cancer breast cancer-1->some cancer lung cancer-1->foot cancer lung cancer-2->some cancer lung cancer-1->blood cancer heart cancer-1->foot cancer heart cancer-1->some cancer stomach cancer-1->foot cancer stomach cancer-1->some cancer foot cancer-1->some cancer blood cancer-1->some cancer
As you can see, I am trying to create transitive relationships, ie, If A->B, and B->C, then A->C. But I am also giving weight to the relationships, ie, if A->D, and D->C, then again A->C. So the relation [valueof{A}][valueof{C}]=2---->ie 1+1, because the relation was created twice.

Replies are listed 'Best First'.
Re^5: out of memory problem
by GrandFather (Saint) on Mar 16, 2006 at 07:05 UTC

    Now that I understand what you are doing, here's code that generates the output you are looking for, albeit in a different order:

    use strict; use warnings; my %mappings; while (<DATA>) { chomp; next if ! /\S/; s/^\s+//; s/\s+$//; my ($mainfile, $subfiles) = split /\s*,\s*/; my @subfiles = split /\s*;\s*/, $subfiles; @subfiles = grep /\S/, @subfiles; $mappings{$mainfile}{$_} = 1 for @subfiles; } # Generate transitive relationships. ie: if A->B and B->C, then A->C for my $A (keys %mappings) { for my $B (keys %{$mappings{$A}}) { ++$mappings{$A}{$_} for keys %{$mappings{$B}}; } } for my $key (keys %mappings) { print "$key - $mappings{$key}{$_} -> $_\n" for keys %{$mappings{$k +ey}}; } __DATA__ cancer,breast cancer; lung cancer; heart cancer; stomach cancer; breast cancer,foot cancer; foot cancer,some cancer; lung cancer,blood cancer; foot cancer; heart cancer,foot cancer; stomach cancer,foot cancer; blood cancer,some cancer;

    Prints:

    lung cancer - 2 -> some cancer lung cancer - 1 -> blood cancer lung cancer - 1 -> foot cancer cancer - 1 -> some cancer cancer - 1 -> lung cancer cancer - 1 -> blood cancer cancer - 1 -> breast cancer cancer - 4 -> foot cancer cancer - 1 -> heart cancer cancer - 1 -> stomach cancer blood cancer - 1 -> some cancer breast cancer - 1 -> some cancer breast cancer - 1 -> foot cancer heart cancer - 1 -> some cancer heart cancer - 1 -> foot cancer foot cancer - 1 -> some cancer stomach cancer - 1 -> some cancer stomach cancer - 1 -> foot cancer

    DWIM is Perl's answer to Gödel
      Hi GrandFather, Thank you very much for your code.
      Now I want to increase the weight of transitive relations from ++$mappings{$A}{$_} to $mappings{$A}{$_} = $mappings{$A}{$_} +5.
      But can you please tell me how to print just the values that are greater than 1?
      I tried the following:
      for my $key (keys %mappings) { if($mappings{$key}{$_} > 1 ) print "$key - $mappings{$key}{$_} -> $_\n" for keys %{$mapping +s{$key}} ; }
      But there is this error:
      Use of uninitialized value in numeric gt (>) at test.pl line 33, <$tes +tdataset> line 7.
      Thanks

        Changing the print loop to:

        for my $key (keys %mappings) { for (keys %{$mappings{$key}}) { next if $mappings{$key}{$_} < 2; print "$key - $mappings{$key}{$_} -> $_\n" ; } }

        Prints:

        lung cancer - 2 -> some cancer cancer - 4 -> foot cancer

        for the code I posted. Note that in the original code for keys %{$mappings{$key}} is a statement modifier and the if statement that you inserted is outside the inner loop so $_ is bogus. The code needed to be changed around into a full for loop so the condition can be checked inside the inner loop.


        DWIM is Perl's answer to Gödel