view release on metacpan or search on metacpan
Samples/PSOPlatTest.pl view on Meta::CPAN
23242526272829303132333435363738my
(
$fit
,
@values
) =
$pso
->getParticleBestPos (
$best
);
my
$iters
=
$pso
->getIterationCount ();
$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
123456789101112131415161718192021222324252627282930313233343536#!/usr/bin/perl
use
strict;
use
warnings;
++$|;
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
;
return
$sum
;
}
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
13141516171819202122232425262728293031323334353637sub
new {
my
(
$class
,
%params
) =
@_
;
my
$self
=
bless
{},
$class
;
$self
->setParams (
%params
);
return
$self
;
}
sub
setParams {
my
(
$self
,
%params
) =
@_
;
if
(
defined
$params
{-fitFunc}) {
# Process required parameters - -fitFunc and -dimensions
if
(
'ARRAY'
eq
ref
$params
{-fitFunc}) {
(
$self
->{fitFunc}, @{
$self
->{fitParams}}) = @{
$params
{-fitFunc}};
}
else
{
$self
->{fitFunc} =
$params
{-fitFunc};
}
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
96979899100101102103104105106107108109110111112113114115116117118119
$self
->{inertia} ||= 0.9;
$self
->{verbose} ||= 0;
return
1;
}
sub
init {
my
(
$self
) =
@_
;
die
"-fitFunc must be set before init or optimize is called"
unless
$self
->{fitFunc} and
'CODE'
eq
ref
$self
->{fitFunc};
die
"-dimensions must be set to 1 or greater before init or optimize is called"
unless
$self
->{dimensions} and
$self
->{dimensions} >= 1;
my
$seed
=
int
(
exists
$self
->{randSeed} ?
$self
->{randSeed} :
rand
(0xffffffff));
$self
->{rndGen} = Math::Random::MT->new (
$seed
);
$self
->{usedRandSeed} =
$seed
;
$self
->{prtcls} = [];
$self
->{bestBest} =
undef
;
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
290291292293294295296297298299300301302303304305306307308309310
"\n"
;
}
return
undef
;
}
sub
_saveBest {
my
(
$self
,
$prtcl
,
$fit
,
$iter
) =
@_
;
# for each dimension, set the best position as the current position
@{
$prtcl
->{bestPos}} = @{
$prtcl
->{currPos}};
$prtcl
->{bestFit} =
$fit
;
return
if
!
$self
->_betterFit (
$fit
,
$self
->{bestBest});
if
(
$self
->{verbose} & kLogBetter) {
my
$velSq
;
$velSq
+=
$_
**2
for
@{
$prtcl
->{velocity}};
printf
"#%05d: Particle $prtcl->{id} best: %.4f (vel: %.3f)\n"
,
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
418419420421422423424425426427428429430431432433434435436437438439440441
my
$fitValue
=
$pso
->optimize ();
my
(
$best
) =
$pso
->getBestParticles (1);
my
(
$fit
,
@values
) =
$pso
->getParticleBestPos (
$best
);
printf
"Fit %.4f at (%s)\n"
,
$fit
,
join
', '
,
map
{
sprintf
'%.4f'
,
$_
}
@values
;
sub
calcFit {
my
@values
=
@_
;
my
$offset
=
int
(-
@values
/ 2);
my
$sum
;
$sum
+= (
$_
-
$offset
++) ** 2
for
@values
;
return
$sum
;
}
=head1 Description
The Particle Swarm Optimization technique uses communication of the current best
position found between a number of particles moving over a hyper surface as a
technique for locating the best location on the surface (where 'best' is the
minimum of some fitness function). For a Wikipedia discussion of PSO see
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554Number of particles in the swarm. Defaults to 10
times
the number of dimensions.
=item I<-posMax>: number, optional
Maximum coordinate value for any dimension in the hyper space. Defaults to 100.
=item I<-posMin>: number, optional
Minimum coordinate value for any dimension in the hyper space. Defaults to
-I<-posMax> (if I<-posMax> is negative I<-posMin> should be set more negative).
=item I<-randSeed>: number, optional
Seed for the random number generator. Useful if you want to rerun an
optimization, perhaps for benchmarking or test purposes.
=item I<-randStartVelocity>: boolean, optional
Set true to initialize particles with a random velocity. Otherwise particle
velocity is set to 0 on initalization.
A range based on 1/100th of -I<-posMax> - I<-posMin> is used for the initial
speed in each dimension of the velocity vector if a random start velocity is
used.
=item I<-stallSpeed>: positive number, optional
Speed below which a particle is considered to be stalled and is repositioned to
a new random location with a new initial speed.
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
587588589590591592593594595596597598599600601602603604605606607608609610Defaults 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
=item * kLogBetter
prints particle details when its fit becomes bebtter than its previous best.
=item * kLogStall
prints particle details when its velocity reaches 0 or falls below the stall
lib/AI/ParticleSwarmOptimization.pm view on Meta::CPAN
619620621622623624625626627628629630631632633634635636637638639Shows additional details
for
some of the other logging options.
=item * kLogIterDetail
Shorthand for C<kLogIter | kLogIterDetail>
=back
=back
=item B<setParams (%parameters)>
Set or change optimization parameters. See I<-new> above for a description of
the parameters that may be supplied.
=item B<init ()>
Reinitialize the optimization. B<init ()> will be called during the first call
to B<optimize ()> if it hasn't already been called.
=item B<optimize ()>
t/01_pso_oo.t view on Meta::CPAN
1112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263=head1 DESCRIPTION
Test AI::ParticleSwarmOptimization
=cut
plan (
tests
=> 27);
ok (
my
$pso
= AI::ParticleSwarmOptimization->new (),
'Constructor'
);
mustDie (
'$pso->setParams (-fitFunc => 1)'
,
'Bad -fitFunc'
);
ok (
$pso
->setParams (
-fitFunc
=> \
&fitFunc
,),
'Good -fitFunc (setParams)'
);
ok (
$pso
= AI::ParticleSwarmOptimization->new (
-fitFunc
=> \
&fitFunc
,),
'Good -fitFunc (new)'
);
ok (
$pso
->setParams (
-fitFunc
=> [\
&fitFunc
, 1]),
'Good -fitFunc (array)'
);
mustDie (
'$pso->setParams (-dimensions => 0)'
,
'-dimensions 0'
);
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,
t/01_pso_oo.t view on Meta::CPAN
697071727374757677787980818283848586878889909192my
$iters
=
$pso
->getIterationCount ();
ok (
$iters
> 100 &&
$iters
< 350,
'Low plateau ok'
);
sub
fitFunc {
}
sub
calcFit {
my
@values
=
@_
;
my
$offset
=
int
(-
@values
/ 2);
my
$sum
;
$sum
+= (
$_
-
$offset
++)**2
for
@values
;
return
$sum
;
}
sub
mustDie {
my
(
$test
,
$name
) =
@_
;
eval
$test
;
ok (
defined
$@,
$name
);
}