File Coverage

blib/lib/AI/Genetic/Pro/Chromosome.pm
Criterion Covered Total %
statement 61 62 98.3
branch 25 36 69.4
condition 9 15 60.0
subroutine 11 11 100.0
pod 0 3 0.0
total 106 127 83.4


line stmt bran cond sub pod time code
1             package AI::Genetic::Pro::Chromosome;
2              
3 15     15   110 use warnings;
  15         33  
  15         609  
4 15     15   84 use strict;
  15         38  
  15         769  
5 15     15   89 use List::Util qw(shuffle first);
  15         29  
  15         1353  
6 15     15   89 use List::MoreUtils qw(first_index);
  15         28  
  15         701  
7 15     15   83 use Tie::Array::Packed;
  15         30  
  15         150  
8             #use Math::Random qw(random_uniform_integer);
9             #=======================================================================
10             sub new {
11 1320     1320 0 7079 my ($class, $data, $type, $package, $length) = @_;
12              
13 1320         1508 my @genes;
14 1320 50       6648 tie @genes, $package if $package;
15            
16 1320 100       16806 if($type eq q/bitvector/){
    100          
    100          
17             #@genes = random_uniform_integer(scalar @$data, 0, 1); # this is fastest, but uses more memory
18 620 100       1553 @genes = map { rand > 0.5 ? 1 : 0 } 0..$length; # this is faster
  16925         49133  
19             #@genes = split(q//, unpack("b*", rand 99999), $#$data + 1); # slow
20             }elsif($type eq q/combination/){
21             #@genes = shuffle 0..$#{$data->[0]};
22 100         1980 @genes = shuffle 0..$length;
23             }elsif($type eq q/rangevector/){
24 300         610 @genes = map { $_->[1] + int rand($_->[2] - $_->[1] + 1) } @$data[0..$length];
  1836         9090  
25             }else{
26 300         532 @genes = map { 1 + int(rand( $#{ $data->[$_] })) } 0..$length;
  1808         1757  
  1808         6958  
27             }
28              
29 1320         12590 return bless \@genes, $class;
30             }
31             #=======================================================================
32             sub new_from_data {
33 8783     8783 0 22693 my ($class, $data, $type, $package, $values, $fix_range) = @_;
34              
35 8783 50       56088 die qq/\nToo many elements in the injected chromosome of type "$type": @$values\n/ if $#$values > $#$data;
36              
37 8783         22853 my @genes;
38 8783 50       60113 tie @genes, $package if $package;
39            
40 8783 100       176626 if($type eq q/bitvector/){
    100          
    100          
41             die qq/\nInproper value in the injected chromosome of type "$type": @$values\n/
42 79 50 66 2528   2862 if first { not defined $_ or ($_ != 0 and $_ != 1) } @$values;
  2528 50       9635  
43 79         3108 @genes = @$values;
44             }elsif($type eq q/combination/){
45 1024         7985 die qq/\nToo few elements in the injected chromosome of type "$type": @$values\n/
46 1024 50       2589 if $#$values != $#{$data->[0]};
47 1024         4879 for my $idx(0..$#$values){
48 8192     36864   42035 my $id = first_index { $_ eq $values->[$idx] } @{$data->[0]}; # pomijamy poczatkowy undef
  36864         83078  
  8192         69929  
49 8192 50       70916 die qq/\nInproper element in the injected chromosome of type "$type": @$values\n/ if $id == -1;
50 8192         49564 push @genes, $id;
51             }
52             }elsif($type eq q/rangevector/){
53 3840         20682 for my $idx(0..$#$values){
54 30720 50       91086 if(defined $values->[$idx]){
55 30720         54290 my $min = $data->[$idx]->[1] - $fix_range->[$idx];
56 30720         52134 my $max = $data->[$idx]->[2] - $fix_range->[$idx];
57 30720 50 33     164873 die qq/\nValue out of scope in the injected chromosome of type "$type": @$values\n/
58             if $values->[$idx] > $max or $values->[$idx] < $min;
59 30720         126035 push @genes, $values->[$idx] + $fix_range->[$idx];
60 0         0 }else{ push @genes, 0; }
61             }
62             }else{
63 3840         9358 for my $idx(0..$#$values){
64             my $id = first_index {
65 245760 50 66 245760   1739684 not defined $values->[$idx] and not defined $_ or
      100        
      33        
66             defined $_ and defined $values->[$idx] and $_ eq $values->[$idx]
67 30720         109179 } @{$data->[$idx]}; # pomijamy poczatkowy undef
  30720         99166  
68 30720 50       123946 die qq/\nInproper element in the injected chromosome of type "$type": @$values\n/ if $id == -1;
69 30720         93995 push @genes, $id;
70             }
71             }
72            
73 8783         70404 return bless \@genes, $class;
74             }
75              
76             sub clone
77             {
78 24609     24609 0 57347 my ($self) = @_;
79 24609         26363 my $genes = tied(@{$self})->make_clone;
  24609         91891  
80 24609         530189 return bless($genes);
81             }
82              
83             #=======================================================================
84             1;