File Coverage

blib/lib/AI/Genetic/Pro/Crossover/PMX.pm
Criterion Covered Total %
statement 60 62 96.7
branch 9 10 90.0
condition n/a
subroutine 8 8 100.0
pod 0 3 0.0
total 77 83 92.7


line stmt bran cond sub pod time code
1             package AI::Genetic::Pro::Crossover::PMX;
2              
3 1     1   7 use warnings;
  1         3  
  1         41  
4 1     1   6 use strict;
  1         3  
  1         42  
5 1     1   6 use List::MoreUtils qw(indexes);
  1         2  
  1         869  
6             #use Data::Dumper; $Data::Dumper::Sortkeys = 1;
7             #=======================================================================
8 1     1 0 9 sub new { bless \$_[0], $_[0]; }
9             #=======================================================================
10             sub dup {
11 3012     3012 0 26169 my ($ar) = @_;
12              
13 3012         3228 my %seen;
14 3012 100       47605 my @dup = grep { if($seen{$_}){ 1 }else{ $seen{$_} = 1; 0} } @$ar;
  24096         75050  
  1252         2168  
  22844         55770  
  22844         33349  
15 3012 100       36900 return \@dup if @dup;
16 1982         8121 return;
17             }
18             #=======================================================================
19             sub run {
20 1     1 0 3 my ($self, $ga) = @_;
21            
22 1         10 my ($chromosomes, $parents, $crossover) = ($ga->chromosomes, $ga->_parents, $ga->crossover);
23 1         9 my ($fitness, $_fitness) = ($ga->fitness, $ga->_fitness);
24 1         2 my @children;
25             #-------------------------------------------------------------------
26 1         7 while(my $elders = shift @$parents){
27 1124         3165 my @elders = unpack 'I*', $elders;
28            
29 1124 50       2671 unless(scalar @elders){
30 0         0 push @children, $chromosomes->[$elders[0]];
31 0         0 next;
32             }
33            
34 1124         5671 my @points = sort { $a <=> $b } map { 1 + int(rand $#{$chromosomes->[0]}) } 0..1;
  1124         2731  
  2248         2387  
  2248         12096  
35            
36 991         10628 @elders = sort {
37 991         2041 my @av = @{$a}[$points[0]..$points[1]-1];
  2115         7871  
38 991         10730 my @bv = splice @$b, $points[0], $points[1] - $points[0], @av;
39 991         2899 splice @$a, $points[0], $points[1] - $points[0], @bv;
40            
41 991         1184 my %av; @av{@av} = @bv;
  991         2803  
42 991         12525 my %bv; @bv{@bv} = @av;
  991         15859  
43              
44 991         1881 while(my $dup = dup($a)){
45 515         1027 foreach my $val (@$dup){
46 626 100   5008   9204 my ($ind) = grep { $_ < $points[0] or $_ >= $points[1] } indexes { $_ == $val } @$a;
  1252         5520  
  5008         5366  
47 626         14871 $a->[$ind] = $bv{$val};
48             }
49             }
50              
51 991         1870 while(my $dup = dup($b)){
52 515         928 foreach my $val (@$dup){
53 626 100   5008   8621 my ($ind) = grep { $_ < $points[0] or $_ >= $points[1] } indexes { $_ == $val } @$b;
  1252         15054  
  5008         15155  
54 626         6127 $b->[$ind] = $av{$val};
55             }
56             }
57            
58 991         4738 0;
59             } map {
60 1124         2036 $chromosomes->[$_]->clone
61             } @elders;
62            
63            
64 1124         2578 my %elders = map { $_ => $fitness->($ga, $elders[$_]) } 0..$#elders;
  2115         12034  
65 1124         4419 my $max = (sort { $elders{$a} <=> $elders{$b} } keys %elders)[-1];
  991         15983  
66 1124         3796 $_fitness->{scalar(@children)} = $elders{$max};
67            
68 1124         8146 push @children, $elders[$max];
69             }
70             #-------------------------------------------------------------------
71            
72 1         5 return \@children;
73             }
74             #=======================================================================
75             1;