view release on metacpan or search on metacpan
Samples/PSOPlatTest.pl view on Meta::CPAN
use strict;
use warnings;
use lib '..\lib'; # For development testing
use AI::ParticleSwarmOptimization;
use Math::Random::MT qw();
++$|;
my $pso = AI::ParticleSwarmOptimization->new (
-fitFunc => \&calcFit,
-dimensions => 3,
-iterations => 500,
-exitPlateau => 1,
-exitPlateauDP => 3,
-exitPlateauBurnin => 100,
-exitPlateauWindow => 60,
);
$pso->init ();
my $fitValue = $pso->optimize ();
my ($best) = $pso->getBestParticles (1);
my ($fit, @values) = $pso->getParticleBestPos ($best);
my $iters = $pso->getIterationCount ();
print $pso->getSeed();
printf ",# Fit %.5f at (%s) after %d iterations\n",
$fit, join (', ', map {sprintf '%.4f', $_} @values), $iters;
sub calcFit {
my @values = @_;
my $offset = int (-@values / 2);
my $sum;
$sum += ($_ - $offset++)**2 for @values;
return $sum;
Samples/PSOTest.pl view on Meta::CPAN
use warnings;
use lib '..\lib'; # For development testing
use AI::ParticleSwarmOptimization;
++$|;
my $pso = AI::ParticleSwarmOptimization->new ();
$pso->setParams (
-fitFunc => \&calcFit,
-dimensions => 3,
-iterations => 100,
);
for (0 .. 9) {
$pso->init () unless $_ % 5;
my $fitValue = $pso->optimize ();
my ($best) = $pso->getBestParticles (1);
my ($fit, @values) = $pso->getParticleBestPos ($best);
my $iters = $pso->getIterationCount();
printf "Fit %.4f at (%s) after %d iterations\n",
$fit, join (', ', map {sprintf '%.4f', $_} @values), $iters;
}
sub calcFit {
my @values = @_;
my $offset = int (-@values / 2);
my $sum;
$sum += ($_ - $offset++) ** 2 for @values;
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
and $params{-dimensions} != $self->{dimensions};
$self->{$_} = $params{"-$_"} for grep {exists $params{"-$_"}} qw/
dimensions
exitFit
exitPlateau
exitPlateauDP
exitPlateauWindow
exitPlateauBurnin
inertia
iterations
meWeight
numNeighbors
numParticles
posMax
posMin
randSeed
randStartVelocity
stallSpeed
themWeight
verbose
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
);
$self->{verbose} = 0;
exists $logTypes{$_} and $self->{verbose} |= $logTypes{$_} for @log;
}
$self->{numParticles} ||= $self->{dimensions} * 10
if defined $self->{dimensions};
$self->{numNeighbors} ||= int sqrt $self->{numParticles}
if defined $self->{numParticles};
$self->{iterations} ||= 1000;
$self->{exitPlateauDP} ||= 10;
$self->{exitPlateauWindow} ||= $self->{iterations} * 0.1;
$self->{exitPlateauBurnin} ||= $self->{iterations} * 0.5;
$self->{posMax} = 100 unless defined $self->{posMax};
$self->{posMin} = -$self->{posMax} unless defined $self->{posMin};
$self->{meWeight} ||= 0.5;
$self->{themWeight} ||= 0.5;
$self->{inertia} ||= 0.9;
$self->{verbose} ||= 0;
return 1;
}
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
unless $self->{posMax} > $self->{posMin};
$self->{$_} > 0 or die "-$_ must be greater then 0" for qw/numParticles/;
$self->{deltaMax} = ($self->{posMax} - $self->{posMin}) / 100.0;
return 1;
}
sub optimize {
my ($self, $iterations) = @_;
$iterations ||= $self->{iterations};
$self->init () unless $self->{prtcls};
return $self->_swarm ($iterations);
}
sub getBestParticles {
my ($self, $num) = @_;
my @bests = 0 .. $self->{numParticles} - 1;
my $prtcls = $self->{prtcls};
@bests = sort {$prtcls->[$a]{bestFit} <=> $prtcls->[$b]{bestFit}} @bests;
$num ||= 1;
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
sub _calcPosFit {
my ($self, $pos) = @_;
return $self->{fitFunc}->(@{$self->{fitParams}}, @$pos);
}
sub _swarm {
my ($self, $iterations) = @_;
for my $iter (1 .. $iterations) {
++$self->{iterCount};
last if defined $self->_moveParticles ($iter);
$self->_updateVelocities ($iter);
next if !$self->{exitPlateau} || !defined $self->{bestBest};
if ($iter >= $self->{exitPlateauBurnin} - $self->{exitPlateauWindow}) {
my $i = $iter % $self->{exitPlateauWindow};
$self->{bestsMean} -= $self->{bestBestByIter}[$i]
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
$self->{bestBest} / $self->{exitPlateauWindow};
}
next if $iter <= $self->{exitPlateauBurnin};
#Round to the specified number of d.p.
my $format = "%.$self->{exitPlateauDP}f";
my $mean = sprintf $format, $self->{bestsMean};
my $current = sprintf $format, $self->{bestBest};
#Check if there is a sufficient plateau - stopping iterations if so
last if $mean == $current;
}
return $self->{bestBest};
}
sub _moveParticles {
my ($self, $iter) = @_;
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
current particle position in the hyperspace is passed in. There is one value per
hyperspace dimension.
=item I<-inertia>: positive or zero number, optional
Determines what proportion of the previous velocity is carried forward to the
next iteration. Defaults to 0.9
See also I<-meWeight> and I<-themWeight>.
=item I<-iterations>: number, optional
Number of optimization iterations to perform. Defaults to 1000.
=item I<-meWeight>: number, optional
Coefficient determining the influence of the current local best position on the
next iterations velocity. Defaults to 0.5.
See also I<-inertia> and I<-themWeight>.
=item I<-numNeighbors>: positive number, optional
Number of local particles considered to be part of the neighbourhood of the
current particle. Defaults to the square root of the total number of particles.
=item I<-numParticles>: positive number, optional
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
Speed below which a particle is considered to be stalled and is repositioned to
a new random location with a new initial speed.
By default I<-stallSpeed> is undefined but particles with a speed of 0 will be
repositioned.
=item I<-themWeight>: number, optional
Coefficient determining the influence of the neighbourhod best position on the
next iterations velocity. Defaults to 0.5.
See also I<-inertia> and I<-meWeight>.
=item I<-exitPlateau>: boolean, optional
Set true to have the optimization check for plateaus (regions where the fit
hasn't improved much for a while) during the search. The optimization ends when
a suitable plateau is detected following the burn in period.
Defaults to undefined (option disabled).
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
function value and the mean of the previous I<-exitPlateauWindow> values.
Defaults to 10.
=item I<-exitPlateauWindow>: number, optional
Specify the size of the window used to calculate the mean for comparison to
the current output of the fitness function. Correlates to the minimum size of a
plateau needed to end the optimization.
Defaults to 10% of the number of iterations (I<-iterations>).
=item I<-exitPlateauBurnin>: number, optional
Determines how many iterations to run before checking for plateaus.
Defaults to 50% of the number of iterations (I<-iterations>).
=item I<-verbose>: flags, optional
If set to a non-zero value I<-verbose> determines the level of diagnostic print
reporting that is generated during optimization.
The following constants may be bitwise ored together to set logging options:
=over 4
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
=item B<getParticleBestPos ($particleNum)>
Returns a list containing the best value of the fit and the vector of its point
in hyper space.
my ($fit, @vector) = $pso->getParticleBestPos (3)
=item B<getIterationCount ()>
Return the number of iterations performed. This may be useful when the
I<-exitFit> criteria has been met or where multiple calls to I<optimize> have
been made.
=back
=head1 BUGS
Please report any bugs or feature requests to C<bug-AI-ParticleSwarmOptimization
at rt.cpan.org>, or through the web interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=AI-ParticleSwarmOptimization>.
t/01_pso_oo.t view on Meta::CPAN
mustDie ('$pso->setParams (-dimensions => -1)', '-dimensions -1');
ok ($pso->setParams (-dimensions => 1), '-dimensions good');
for my $param (qw/numParticles/) {
mustDie ("$pso->setParams (-$param => 0); $pso->init ()", "-$param zero");
mustDie ("$pso->setParams (-$param => -1); $pso->init ()", "-$param neg");
ok (($pso->setParams (-$param => 1), $pso->init ()), "-$param good");
}
for my $param (
qw/inertia iterations meWeight numNeighbors stallSpeed themWeight/)
{
mustDie ("$pso->setParams (-$param => -1); $pso->init ()", "-$param neg");
ok (($pso->setParams (-$param => 1), $pso->init ()), "-$param good");
}
mustDie (
'$pso->setParams (-posMax => 0); $pso->setParams (-posMin => 0); $pso->init ()',
'-posMax == -posMin'
);
mustDie (
'$pso->setParams (-posMax => -1); $pso->setParams (-posMin => 0); $pso->init ()',
'-posMax < -posMin'
);
ok (
'$pso->setParams (-posMax => -1); $pso->setParams (-posMin => -2); $pso->init ()',
'-posMax > -posMin'
);
# Calculation tests.
$pso = AI::ParticleSwarmOptimization->new (
-randSeed => 2626813951,# Fit 0.00006 at (-1.0051, -0.0005, 1.0058) after 258 iterations
-fitFunc => \&calcFit,
-dimensions => 3,
-iterations => 500,
-exitPlateau => 1,
-exitPlateauDP => 3,
-exitPlateauBurnin => 100,
-exitPlateauWindow => 60,
);
my $fitValue = $pso->optimize ();
my $iters = $pso->getIterationCount ();
ok ($iters > 100 && $iters < 350, 'Low plateau ok');