File Coverage

blib/lib/AI/ParticleSwarmOptimization/Pmap.pm
Criterion Covered Total %
statement 65 78 83.3
branch 7 18 38.8
condition 3 9 33.3
subroutine 10 10 100.0
pod n/a
total 85 115 73.9


line stmt bran cond sub pod time code
1             package AI::ParticleSwarmOptimization::Pmap;
2              
3 322     322   21433676 use strict;
  322         3212  
  322         9659  
4 322     322   1611 use warnings;
  322         644  
  322         9660  
5 322         175696 use base qw(
6             AI::ParticleSwarmOptimization
7 322     322   1611 );
  322         644  
8             #-----------------------------------------------------------------------
9 322     322   1471471 use List::Util qw( min );
  322         1286  
  322         30931  
10 322     322   131733 use Parallel::parallel_map;
  322         9060038  
  322         259555  
11             #-----------------------------------------------------------------------
12             $AI::ParticleSwarmOptimization::Pmap::VERSION = '1.004';
13             #=======================================================================
14             sub _initParticles {
15 321     321   332877 my ($self) = @_;
16              
17 321         27606 @{ $self->{ prtcls } } = map {
18 321000         689829 my %prt = ( id => $_ );
19 321000         1175181 $self->_initParticle( \%prt );
20 321000         97992954 \%prt;
21 321         16371 } 0 .. $self->{ numParticles } - 1;
22             }
23             #=======================================================================
24             sub _moveParticles {
25 1770     1770   123049 my ($self, $iter) = @_;
26              
27 1770 50       12227 print "Iter $iter\n" if $self->{verbose} & AI::ParticleSwarmOptimization::kLogIter;
28              
29 1610000         525503703 my @lst = grep { defined $_ } parallel_map {
30 10000     10000   68135250 my $prtcl = $_;
31             #---------------------------------------------------------------
32 10000         20383 @{$prtcl->{currPos}} = @{$prtcl->{nextPos}};
  10000         42967  
  10000         25483  
33 10000         31594 $prtcl->{currFit} = $prtcl->{nextFit};
34              
35 10000         21071 my $fit = $prtcl->{currFit};
36              
37 10000 100       62327 if ($self->_betterFit ($fit, $prtcl->{bestFit})) {
38             # Save position - best fit for this particle so far
39 2307         121087 $self->_saveBest ($prtcl, $fit, $iter);
40             }
41              
42 10000         243857 my $ret;
43 10000 50 33     59627 if( defined $self->{exitFit} and $fit < $self->{exitFit} ){
    50          
44 0         0 $ret = $fit;
45             }elsif( !($self->{verbose} & AI::ParticleSwarmOptimization::kLogIterDetail) ){
46 10000         21416 $ret = undef;
47             }else{
48             printf "Part %3d fit %8.2f", $prtcl->{id}, $fit
49 0 0       0 if $self->{verbose} >= 2;
50             printf " (%s @ %s)",
51 0         0 join (', ', map {sprintf '%5.3f', $_} @{$prtcl->{velocity}}),
  0         0  
52 0         0 join (', ', map {sprintf '%5.2f', $_} @{$prtcl->{currPos}})
  0         0  
53 0 0       0 if $self->{verbose} & AI::ParticleSwarmOptimization::kLogDetail;
54 0         0 print "\n";
55            
56 0         0 $ret = undef;
57             }
58             #---------------------------------------------------------------
59 10000         38217 [ $prtcl, $ret ]
60 1770         31347 } @{ $self->{ prtcls } };
  1770         53265  
61              
62 1610         119934 @{ $self->{ prtcls } } = map { $_->[ 0 ] } @lst;
  1610         1336741  
  1610000         2984693  
63            
64 1610         30231 $self->{ bestBest } = min map { $_->{ bestFit } } @{ $self->{ prtcls } };
  1610000         3108830  
  1610         13307  
65            
66 1610         51310 my @fit = map { $_->[ 1 ] } grep { defined $_->[ 1 ] } @lst;
  0         0  
  1610000         2839552  
67              
68 1610 50       58809 return scalar( @fit ) ? ( sort { $a <=> $b } @fit )[ 0 ] : undef;
  0         0  
69             }
70             #=======================================================================
71             sub _updateVelocities {
72 1610     1610   143317 my ($self, $iter) = @_;
73              
74 1450         460482287 @{ $self->{ prtcls } } = parallel_map {
75 10000     10000   77257014 my $prtcl = $_;
76             #---------------------------------------------------------------
77 10000         681543 my $bestN = $self->{prtcls}[$self->_getBestNeighbour ($prtcl)];
78 10000         1863698 my $velSq;
79              
80 10000         119700 for my $d (0 .. $self->{dimensions} - 1) {
81             my $meFactor =
82 100000         636146 $self->_randInRange (-$self->{meWeight}, $self->{meWeight});
83             my $themFactor =
84 100000         1310916 $self->_randInRange (-$self->{themWeight}, $self->{themWeight});
85 100000         1093485 my $meDelta = $prtcl->{bestPos}[$d] - $prtcl->{currPos}[$d];
86 100000         321676 my $themDelta = $bestN->{bestPos}[$d] - $prtcl->{currPos}[$d];
87              
88             $prtcl->{velocity}[$d] =
89             $prtcl->{velocity}[$d] * $self->{inertia} +
90 100000         237537 $meFactor * $meDelta +
91             $themFactor * $themDelta;
92 100000         275653 $velSq += $prtcl->{velocity}[$d]**2;
93             }
94              
95 10000         61853 my $vel = sqrt ($velSq);
96 10000 50 33     84854 if (!$vel or $self->{stallSpeed} and $vel <= $self->{stallSpeed}) {
      33        
97 0         0 $self->_initParticle ($prtcl);
98             printf "#%05d: Particle $prtcl->{id} stalled (%6f)\n", $iter, $vel
99 0 0       0 if $self->{verbose} & AI::ParticleSwarmOptimization::kLogStall;
100             }
101              
102 10000         75638 $self->_calcNextPos ($prtcl);
103             #---------------------------------------------------------------
104 10000         771109 $prtcl;
105 1610         41727 } @{ $self->{ prtcls } };
  1610         49752  
106             }
107             #=======================================================================
108             1;
109              
110             __END__