Particle swarm optimization: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) m (→{{header|Perl}}: oops, print results *correctly*) |
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
||
Line 40: | Line 40: | ||
</p> |
</p> |
||
<br><br> |
<br><br> |
||
=={{header|C sharp|C#}}== |
|||
{{trans|java}} |
|||
<lang csharp>using System; |
|||
namespace ParticleSwarmOptimization { |
|||
public struct Parameters { |
|||
public double omega, phip, phig; |
|||
public Parameters(double omega, double phip, double phig) : this() { |
|||
this.omega = omega; |
|||
this.phip = phip; |
|||
this.phig = phig; |
|||
} |
|||
} |
|||
public struct State { |
|||
public int iter; |
|||
public double[] gbpos; |
|||
public double gbval; |
|||
public double[] min; |
|||
public double[] max; |
|||
public Parameters parameters; |
|||
public double[][] pos; |
|||
public double[][] vel; |
|||
public double[][] bpos; |
|||
public double[] bval; |
|||
public int nParticles; |
|||
public int nDims; |
|||
public State(int iter, double[] gbpos, double gbval, double[] min, double[] max, Parameters parameters, double[][] pos, double[][] vel, double[][] bpos, double[] bval, int nParticles, int nDims) : this() { |
|||
this.iter = iter; |
|||
this.gbpos = gbpos; |
|||
this.gbval = gbval; |
|||
this.min = min; |
|||
this.max = max; |
|||
this.parameters = parameters; |
|||
this.pos = pos; |
|||
this.vel = vel; |
|||
this.bpos = bpos; |
|||
this.bval = bval; |
|||
this.nParticles = nParticles; |
|||
this.nDims = nDims; |
|||
} |
|||
public void Report(string testfunc) { |
|||
Console.WriteLine("Test Function : {0}", testfunc); |
|||
Console.WriteLine("Iterations : {0}", iter); |
|||
Console.WriteLine("Global Best Position : {0}", string.Join(", ", gbpos)); |
|||
Console.WriteLine("Global Best Value : {0}", gbval); |
|||
} |
|||
} |
|||
class Program { |
|||
public static State PsoInit(double[] min, double[] max, Parameters parameters, int nParticles) { |
|||
var nDims = min.Length; |
|||
double[][] pos = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
pos[i] = new double[min.Length]; |
|||
min.CopyTo(pos[i], 0); |
|||
} |
|||
double[][] vel = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
vel[i] = new double[nDims]; |
|||
} |
|||
double[][] bpos = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
bpos[i] = new double[min.Length]; |
|||
min.CopyTo(bpos[i], 0); |
|||
} |
|||
double[] bval = new double[nParticles]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
bval[i] = double.PositiveInfinity; |
|||
} |
|||
int iter = 0; |
|||
double[] gbpos = new double[nDims]; |
|||
for (int i = 0; i < nDims; i++) { |
|||
gbpos[i] = double.PositiveInfinity; |
|||
} |
|||
double gbval = double.PositiveInfinity; |
|||
return new State(iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims); |
|||
} |
|||
static Random r = new Random(); |
|||
public static State Pso(Func<double[], double> fn, State y) { |
|||
var p = y.parameters; |
|||
double[] v = new double[y.nParticles]; |
|||
double[][] bpos = new double[y.nParticles][]; |
|||
for (int i = 0; i < y.nParticles; i++) { |
|||
bpos[i] = new double[y.min.Length]; |
|||
y.min.CopyTo(bpos[i], 0); |
|||
} |
|||
double[] bval = new double[y.nParticles]; |
|||
double[] gbpos = new double[y.nDims]; |
|||
double gbval = double.PositiveInfinity; |
|||
for (int j = 0; j < y.nParticles; j++) { |
|||
// evaluate |
|||
v[j] = fn.Invoke(y.pos[j]); |
|||
// update |
|||
if (v[j] < y.bval[j]) { |
|||
y.pos[j].CopyTo(bpos[j], 0); |
|||
bval[j] = v[j]; |
|||
} |
|||
else { |
|||
y.bpos[j].CopyTo(bpos[j], 0); |
|||
bval[j] = y.bval[j]; |
|||
} |
|||
if (bval[j] < gbval) { |
|||
gbval = bval[j]; |
|||
bpos[j].CopyTo(gbpos, 0); |
|||
} |
|||
} |
|||
double rg = r.NextDouble(); |
|||
double[][] pos = new double[y.nParticles][]; |
|||
double[][] vel = new double[y.nParticles][]; |
|||
for (int i = 0; i < y.nParticles; i++) { |
|||
pos[i] = new double[y.nDims]; |
|||
vel[i] = new double[y.nDims]; |
|||
} |
|||
for (int j = 0; j < y.nParticles; j++) { |
|||
// migrate |
|||
double rp = r.NextDouble(); |
|||
bool ok = true; |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
vel[j][k] = 0.0; |
|||
pos[j][k] = 0.0; |
|||
} |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
vel[j][k] = p.omega * y.vel[j][k] + |
|||
p.phip * rp * (bpos[j][k] - y.pos[j][k]) + |
|||
p.phig * rg * (gbpos[k] - y.pos[j][k]); |
|||
pos[j][k] = y.pos[j][k] + vel[j][k]; |
|||
ok = ok && y.min[k] < pos[j][k] && y.max[k] > pos[j][k]; |
|||
} |
|||
if (!ok) { |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
pos[j][k] = y.min[k] + (y.max[k] - y.min[k]) * r.NextDouble(); |
|||
} |
|||
} |
|||
} |
|||
var iter = 1 + y.iter; |
|||
return new State(iter, gbpos, gbval, y.min, y.max, y.parameters, pos, vel, bpos, bval, y.nParticles, y.nDims); |
|||
} |
|||
public static State Iterate(Func<double[], double> fn, int n, State y) { |
|||
State r = y; |
|||
if (n == int.MaxValue) { |
|||
State old = y; |
|||
while (true) { |
|||
r = Pso(fn, r); |
|||
if (r.Equals(old)) break; |
|||
old = r; |
|||
} |
|||
} |
|||
else { |
|||
for (int i = 0; i < n; i++) { |
|||
r = Pso(fn, r); |
|||
} |
|||
} |
|||
return r; |
|||
} |
|||
public static double Mccormick(double[] x) { |
|||
var a = x[0]; |
|||
var b = x[1]; |
|||
return Math.Sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a; |
|||
} |
|||
public static double Michalewicz(double[] x) { |
|||
int m = 10; |
|||
int d = x.Length; |
|||
double sum = 0.0; |
|||
for (int i = 1; i < d; i++) { |
|||
var j = x[i - 1]; |
|||
var k = Math.Sin(i * j * j / Math.PI); |
|||
sum += Math.Sin(j) * Math.Pow(k, 2.0 * m); |
|||
} |
|||
return -sum; |
|||
} |
|||
static void Main(string[] args) { |
|||
var state = PsoInit( |
|||
new double[] { -1.5, -3.0 }, |
|||
new double[] { 4.0, 4.0 }, |
|||
new Parameters(0.0, 0.6, 0.3), |
|||
100 |
|||
); |
|||
state = Iterate(Mccormick, 40, state); |
|||
state.Report("McCormick"); |
|||
Console.WriteLine("f(-.54719, -1.54719) : {0}", Mccormick(new double[] { -.54719, -1.54719 })); |
|||
Console.WriteLine(); |
|||
state = PsoInit( |
|||
new double[] { -0.0, -0.0 }, |
|||
new double[] { Math.PI, Math.PI }, |
|||
new Parameters(0.3, 0.3, 0.3), |
|||
1000 |
|||
); |
|||
state = Iterate(Michalewicz, 30, state); |
|||
state.Report("Michalewicz (2D)"); |
|||
Console.WriteLine("f(2.20, 1.57) : {0}", Michalewicz(new double[] { 2.20, 1.57 })); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Test Function : McCormick |
|||
Iterations : 40 |
|||
Global Best Position : -0.546850526417689, -1.54649614884518 |
|||
Global Best Value : -1.91322235333426 |
|||
f(-.54719, -1.54719) : -1.91322295488227 |
|||
Test Function : Michalewicz (2D) |
|||
Iterations : 30 |
|||
Global Best Position : 2.20290514143486, 2.20798457238775 |
|||
Global Best Value : -0.801303410096221 |
|||
f(2.20, 1.57) : -0.801166387820286</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 330: | Line 548: | ||
Global Best Value : -0.801303 |
Global Best Value : -0.801303 |
||
f(2.20, 1.57) : -0.801166</pre> |
f(2.20, 1.57) : -0.801166</pre> |
||
=={{header|C#|C sharp}}== |
|||
{{trans|java}} |
|||
<lang csharp>using System; |
|||
namespace ParticleSwarmOptimization { |
|||
public struct Parameters { |
|||
public double omega, phip, phig; |
|||
public Parameters(double omega, double phip, double phig) : this() { |
|||
this.omega = omega; |
|||
this.phip = phip; |
|||
this.phig = phig; |
|||
} |
|||
} |
|||
public struct State { |
|||
public int iter; |
|||
public double[] gbpos; |
|||
public double gbval; |
|||
public double[] min; |
|||
public double[] max; |
|||
public Parameters parameters; |
|||
public double[][] pos; |
|||
public double[][] vel; |
|||
public double[][] bpos; |
|||
public double[] bval; |
|||
public int nParticles; |
|||
public int nDims; |
|||
public State(int iter, double[] gbpos, double gbval, double[] min, double[] max, Parameters parameters, double[][] pos, double[][] vel, double[][] bpos, double[] bval, int nParticles, int nDims) : this() { |
|||
this.iter = iter; |
|||
this.gbpos = gbpos; |
|||
this.gbval = gbval; |
|||
this.min = min; |
|||
this.max = max; |
|||
this.parameters = parameters; |
|||
this.pos = pos; |
|||
this.vel = vel; |
|||
this.bpos = bpos; |
|||
this.bval = bval; |
|||
this.nParticles = nParticles; |
|||
this.nDims = nDims; |
|||
} |
|||
public void Report(string testfunc) { |
|||
Console.WriteLine("Test Function : {0}", testfunc); |
|||
Console.WriteLine("Iterations : {0}", iter); |
|||
Console.WriteLine("Global Best Position : {0}", string.Join(", ", gbpos)); |
|||
Console.WriteLine("Global Best Value : {0}", gbval); |
|||
} |
|||
} |
|||
class Program { |
|||
public static State PsoInit(double[] min, double[] max, Parameters parameters, int nParticles) { |
|||
var nDims = min.Length; |
|||
double[][] pos = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
pos[i] = new double[min.Length]; |
|||
min.CopyTo(pos[i], 0); |
|||
} |
|||
double[][] vel = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
vel[i] = new double[nDims]; |
|||
} |
|||
double[][] bpos = new double[nParticles][]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
bpos[i] = new double[min.Length]; |
|||
min.CopyTo(bpos[i], 0); |
|||
} |
|||
double[] bval = new double[nParticles]; |
|||
for (int i = 0; i < nParticles; i++) { |
|||
bval[i] = double.PositiveInfinity; |
|||
} |
|||
int iter = 0; |
|||
double[] gbpos = new double[nDims]; |
|||
for (int i = 0; i < nDims; i++) { |
|||
gbpos[i] = double.PositiveInfinity; |
|||
} |
|||
double gbval = double.PositiveInfinity; |
|||
return new State(iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims); |
|||
} |
|||
static Random r = new Random(); |
|||
public static State Pso(Func<double[], double> fn, State y) { |
|||
var p = y.parameters; |
|||
double[] v = new double[y.nParticles]; |
|||
double[][] bpos = new double[y.nParticles][]; |
|||
for (int i = 0; i < y.nParticles; i++) { |
|||
bpos[i] = new double[y.min.Length]; |
|||
y.min.CopyTo(bpos[i], 0); |
|||
} |
|||
double[] bval = new double[y.nParticles]; |
|||
double[] gbpos = new double[y.nDims]; |
|||
double gbval = double.PositiveInfinity; |
|||
for (int j = 0; j < y.nParticles; j++) { |
|||
// evaluate |
|||
v[j] = fn.Invoke(y.pos[j]); |
|||
// update |
|||
if (v[j] < y.bval[j]) { |
|||
y.pos[j].CopyTo(bpos[j], 0); |
|||
bval[j] = v[j]; |
|||
} |
|||
else { |
|||
y.bpos[j].CopyTo(bpos[j], 0); |
|||
bval[j] = y.bval[j]; |
|||
} |
|||
if (bval[j] < gbval) { |
|||
gbval = bval[j]; |
|||
bpos[j].CopyTo(gbpos, 0); |
|||
} |
|||
} |
|||
double rg = r.NextDouble(); |
|||
double[][] pos = new double[y.nParticles][]; |
|||
double[][] vel = new double[y.nParticles][]; |
|||
for (int i = 0; i < y.nParticles; i++) { |
|||
pos[i] = new double[y.nDims]; |
|||
vel[i] = new double[y.nDims]; |
|||
} |
|||
for (int j = 0; j < y.nParticles; j++) { |
|||
// migrate |
|||
double rp = r.NextDouble(); |
|||
bool ok = true; |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
vel[j][k] = 0.0; |
|||
pos[j][k] = 0.0; |
|||
} |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
vel[j][k] = p.omega * y.vel[j][k] + |
|||
p.phip * rp * (bpos[j][k] - y.pos[j][k]) + |
|||
p.phig * rg * (gbpos[k] - y.pos[j][k]); |
|||
pos[j][k] = y.pos[j][k] + vel[j][k]; |
|||
ok = ok && y.min[k] < pos[j][k] && y.max[k] > pos[j][k]; |
|||
} |
|||
if (!ok) { |
|||
for (int k = 0; k < y.nDims; k++) { |
|||
pos[j][k] = y.min[k] + (y.max[k] - y.min[k]) * r.NextDouble(); |
|||
} |
|||
} |
|||
} |
|||
var iter = 1 + y.iter; |
|||
return new State(iter, gbpos, gbval, y.min, y.max, y.parameters, pos, vel, bpos, bval, y.nParticles, y.nDims); |
|||
} |
|||
public static State Iterate(Func<double[], double> fn, int n, State y) { |
|||
State r = y; |
|||
if (n == int.MaxValue) { |
|||
State old = y; |
|||
while (true) { |
|||
r = Pso(fn, r); |
|||
if (r.Equals(old)) break; |
|||
old = r; |
|||
} |
|||
} |
|||
else { |
|||
for (int i = 0; i < n; i++) { |
|||
r = Pso(fn, r); |
|||
} |
|||
} |
|||
return r; |
|||
} |
|||
public static double Mccormick(double[] x) { |
|||
var a = x[0]; |
|||
var b = x[1]; |
|||
return Math.Sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a; |
|||
} |
|||
public static double Michalewicz(double[] x) { |
|||
int m = 10; |
|||
int d = x.Length; |
|||
double sum = 0.0; |
|||
for (int i = 1; i < d; i++) { |
|||
var j = x[i - 1]; |
|||
var k = Math.Sin(i * j * j / Math.PI); |
|||
sum += Math.Sin(j) * Math.Pow(k, 2.0 * m); |
|||
} |
|||
return -sum; |
|||
} |
|||
static void Main(string[] args) { |
|||
var state = PsoInit( |
|||
new double[] { -1.5, -3.0 }, |
|||
new double[] { 4.0, 4.0 }, |
|||
new Parameters(0.0, 0.6, 0.3), |
|||
100 |
|||
); |
|||
state = Iterate(Mccormick, 40, state); |
|||
state.Report("McCormick"); |
|||
Console.WriteLine("f(-.54719, -1.54719) : {0}", Mccormick(new double[] { -.54719, -1.54719 })); |
|||
Console.WriteLine(); |
|||
state = PsoInit( |
|||
new double[] { -0.0, -0.0 }, |
|||
new double[] { Math.PI, Math.PI }, |
|||
new Parameters(0.3, 0.3, 0.3), |
|||
1000 |
|||
); |
|||
state = Iterate(Michalewicz, 30, state); |
|||
state.Report("Michalewicz (2D)"); |
|||
Console.WriteLine("f(2.20, 1.57) : {0}", Michalewicz(new double[] { 2.20, 1.57 })); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Test Function : McCormick |
|||
Iterations : 40 |
|||
Global Best Position : -0.546850526417689, -1.54649614884518 |
|||
Global Best Value : -1.91322235333426 |
|||
f(-.54719, -1.54719) : -1.91322295488227 |
|||
Test Function : Michalewicz (2D) |
|||
Iterations : 30 |
|||
Global Best Position : 2.20290514143486, 2.20798457238775 |
|||
Global Best Value : -0.801303410096221 |
|||
f(2.20, 1.57) : -0.801166387820286</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
Line 981: | Line 981: | ||
GlobalBestPosition: 2.20296 1.57083 |
GlobalBestPosition: 2.20296 1.57083 |
||
GlobalBestValue: _1.8013</lang> |
GlobalBestValue: _1.8013</lang> |
||
=={{header|JavaScript}}== |
|||
Translation of [[Particle_Swarm_Optimization#J|J]]. |
|||
<lang JavaScript>function pso_init(y) { |
|||
var nDims= y.min.length; |
|||
var pos=[], vel=[], bpos=[], bval=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
pos[j]= bpos[j]= y.min; |
|||
var v= []; for (var k= 0; k<nDims; k++) v[k]= 0; |
|||
vel[j]= v; |
|||
bval[j]= Infinity} |
|||
return { |
|||
iter: 0, |
|||
gbpos: Infinity, |
|||
gbval: Infinity, |
|||
min: y.min, |
|||
max: y.max, |
|||
parameters: y.parameters, |
|||
pos: pos, |
|||
vel: vel, |
|||
bpos: bpos, |
|||
bval: bval, |
|||
nParticles: y.nParticles, |
|||
nDims: nDims} |
|||
} |
|||
function pso(fn, state) { |
|||
var y= state; |
|||
var p= y.parameters; |
|||
var val=[], bpos=[], bval=[], gbval= Infinity, gbpos=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
// evaluate |
|||
val[j]= fn.apply(null, y.pos[j]); |
|||
// update |
|||
if (val[j] < y.bval[j]) { |
|||
bpos[j]= y.pos[j]; |
|||
bval[j]= val[j]; |
|||
} else { |
|||
bpos[j]= y.bpos[j]; |
|||
bval[j]= y.bval[j]} |
|||
if (bval[j] < gbval) { |
|||
gbval= bval[j]; |
|||
gbpos= bpos[j]}} |
|||
var rg= Math.random(), vel=[], pos=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
// migrate |
|||
var rp= Math.random(), ok= true; |
|||
vel[j]= []; |
|||
pos[j]= []; |
|||
for (var k= 0; k < y.nDims; k++) { |
|||
vel[j][k]= p.omega*y.vel[j][k] + p.phip*rp*(bpos[j]-y.pos[j]) + p.phig*rg*(gbpos-y.pos[j]); |
|||
pos[j][k]= y.pos[j]+vel[j][k]; |
|||
ok= ok && y.min[k]<pos[j][k] && y.max>pos[j][k];} |
|||
if (!ok) |
|||
for (var k= 0; k < y.nDims; k++) |
|||
pos[j][k]= y.min[k] + (y.max[k]-y.min[k])*Math.random()} |
|||
return { |
|||
iter: 1+y.iter, |
|||
gbpos: gbpos, |
|||
gbval: gbval, |
|||
min: y.min, |
|||
max: y.max, |
|||
parameters: y.parameters, |
|||
pos: pos, |
|||
vel: vel, |
|||
bpos: bpos, |
|||
bval: bval, |
|||
nParticles: y.nParticles, |
|||
nDims: y.nDims} |
|||
} |
|||
function display(text) { |
|||
if (document) { |
|||
var o= document.getElementById('o'); |
|||
if (!o) { |
|||
o= document.createElement('pre'); |
|||
o.id= 'o'; |
|||
document.body.appendChild(o)} |
|||
o.innerHTML+= text+'\n'; |
|||
window.scrollTo(0,document.body.scrollHeight); |
|||
} |
|||
if (console.log) console.log(text) |
|||
} |
|||
function reportState(state) { |
|||
var y= state; |
|||
display(''); |
|||
display('Iteration: '+y.iter); |
|||
display('GlobalBestPosition: '+y.gbpos); |
|||
display('GlobalBestValue: '+y.gbval); |
|||
} |
|||
function repeat(fn, n, y) { |
|||
var r=y, old= y; |
|||
if (Infinity == n) |
|||
while ((r= fn(r)) != old) old= r; |
|||
else |
|||
for (var j= 0; j<n; j++) r= fn(r); |
|||
return r |
|||
} |
|||
function mccormick(a,b) { |
|||
return Math.sin(a+b) + Math.pow(a-b,2) + (1 + 2.5*b - 1.5*a) |
|||
} |
|||
state= pso_init({ |
|||
min: [-1.5,-3], max:[4,4], |
|||
parameters: {omega: 0, phip: 0.6, phig: 0.3}, |
|||
nParticles: 100}); |
|||
reportState(state); |
|||
state= repeat(function(y){return pso(mccormick,y)}, 40, state); |
|||
reportState(state);</lang> |
|||
Example displayed result (random numbers are involved so there will be a bit of variance between repeated runs: |
|||
<lang Javascript> |
|||
Iteration: 0 |
|||
GlobalBestPosition: Infinity |
|||
GlobalBestValue: Infinity |
|||
Iteration: 40 |
|||
GlobalBestPosition: -0.5134004259016365,-1.5512442672625184 |
|||
GlobalBestValue: -1.9114053788600853</lang> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,318: | Line 1,190: | ||
Global Best value : -0.801303410098550 |
Global Best value : -0.801303410098550 |
||
f(2.20, 1.57) : -0.801166387820286</pre> |
f(2.20, 1.57) : -0.801166387820286</pre> |
||
=={{header|JavaScript}}== |
|||
Translation of [[Particle_Swarm_Optimization#J|J]]. |
|||
<lang JavaScript>function pso_init(y) { |
|||
var nDims= y.min.length; |
|||
var pos=[], vel=[], bpos=[], bval=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
pos[j]= bpos[j]= y.min; |
|||
var v= []; for (var k= 0; k<nDims; k++) v[k]= 0; |
|||
vel[j]= v; |
|||
bval[j]= Infinity} |
|||
return { |
|||
iter: 0, |
|||
gbpos: Infinity, |
|||
gbval: Infinity, |
|||
min: y.min, |
|||
max: y.max, |
|||
parameters: y.parameters, |
|||
pos: pos, |
|||
vel: vel, |
|||
bpos: bpos, |
|||
bval: bval, |
|||
nParticles: y.nParticles, |
|||
nDims: nDims} |
|||
} |
|||
function pso(fn, state) { |
|||
var y= state; |
|||
var p= y.parameters; |
|||
var val=[], bpos=[], bval=[], gbval= Infinity, gbpos=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
// evaluate |
|||
val[j]= fn.apply(null, y.pos[j]); |
|||
// update |
|||
if (val[j] < y.bval[j]) { |
|||
bpos[j]= y.pos[j]; |
|||
bval[j]= val[j]; |
|||
} else { |
|||
bpos[j]= y.bpos[j]; |
|||
bval[j]= y.bval[j]} |
|||
if (bval[j] < gbval) { |
|||
gbval= bval[j]; |
|||
gbpos= bpos[j]}} |
|||
var rg= Math.random(), vel=[], pos=[]; |
|||
for (var j= 0; j<y.nParticles; j++) { |
|||
// migrate |
|||
var rp= Math.random(), ok= true; |
|||
vel[j]= []; |
|||
pos[j]= []; |
|||
for (var k= 0; k < y.nDims; k++) { |
|||
vel[j][k]= p.omega*y.vel[j][k] + p.phip*rp*(bpos[j]-y.pos[j]) + p.phig*rg*(gbpos-y.pos[j]); |
|||
pos[j][k]= y.pos[j]+vel[j][k]; |
|||
ok= ok && y.min[k]<pos[j][k] && y.max>pos[j][k];} |
|||
if (!ok) |
|||
for (var k= 0; k < y.nDims; k++) |
|||
pos[j][k]= y.min[k] + (y.max[k]-y.min[k])*Math.random()} |
|||
return { |
|||
iter: 1+y.iter, |
|||
gbpos: gbpos, |
|||
gbval: gbval, |
|||
min: y.min, |
|||
max: y.max, |
|||
parameters: y.parameters, |
|||
pos: pos, |
|||
vel: vel, |
|||
bpos: bpos, |
|||
bval: bval, |
|||
nParticles: y.nParticles, |
|||
nDims: y.nDims} |
|||
} |
|||
function display(text) { |
|||
if (document) { |
|||
var o= document.getElementById('o'); |
|||
if (!o) { |
|||
o= document.createElement('pre'); |
|||
o.id= 'o'; |
|||
document.body.appendChild(o)} |
|||
o.innerHTML+= text+'\n'; |
|||
window.scrollTo(0,document.body.scrollHeight); |
|||
} |
|||
if (console.log) console.log(text) |
|||
} |
|||
function reportState(state) { |
|||
var y= state; |
|||
display(''); |
|||
display('Iteration: '+y.iter); |
|||
display('GlobalBestPosition: '+y.gbpos); |
|||
display('GlobalBestValue: '+y.gbval); |
|||
} |
|||
function repeat(fn, n, y) { |
|||
var r=y, old= y; |
|||
if (Infinity == n) |
|||
while ((r= fn(r)) != old) old= r; |
|||
else |
|||
for (var j= 0; j<n; j++) r= fn(r); |
|||
return r |
|||
} |
|||
function mccormick(a,b) { |
|||
return Math.sin(a+b) + Math.pow(a-b,2) + (1 + 2.5*b - 1.5*a) |
|||
} |
|||
state= pso_init({ |
|||
min: [-1.5,-3], max:[4,4], |
|||
parameters: {omega: 0, phip: 0.6, phig: 0.3}, |
|||
nParticles: 100}); |
|||
reportState(state); |
|||
state= repeat(function(y){return pso(mccormick,y)}, 40, state); |
|||
reportState(state);</lang> |
|||
Example displayed result (random numbers are involved so there will be a bit of variance between repeated runs: |
|||
<lang Javascript> |
|||
Iteration: 0 |
|||
GlobalBestPosition: Infinity |
|||
GlobalBestValue: Infinity |
|||
Iteration: 40 |
|||
GlobalBestPosition: -0.5134004259016365,-1.5512442672625184 |
|||
GlobalBestValue: -1.9114053788600853</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 1,730: | Line 1,730: | ||
Global best position: 2.20293 1.57080 |
Global best position: 2.20293 1.57080 |
||
Global best value: -1.80130</pre> |
Global best value: -1.80130</pre> |
||
=={{header|Perl 6}}== |
|||
{{trans|J (via Javascript, Kotlin, D, Python)}} |
|||
<lang perl6>sub pso-init (%y) { |
|||
my $d = @(%y{'min'}); |
|||
my $n = %y{'n'}; |
|||
%y{'gbval'} = Inf; |
|||
%y{'gbpos'} = [Inf xx $d]; |
|||
%y{'bval'} = [Inf xx $n]; |
|||
%y{'bpos'} = [%y{'min'} xx $n]; |
|||
%y{'pos'} = [%y{'min'} xx $n]; |
|||
%y{'vel'} = [[0 xx $d] xx $n]; |
|||
%y; |
|||
} |
|||
sub pso (&fn, %y) { |
|||
my %p = %y{'p'}; |
|||
my $n = %y{'n'}; |
|||
my $d = @(%y{'min'}); |
|||
my @bpos = %y{'min'} xx $n; |
|||
my $gbval = Inf; |
|||
my $rand-g = rand; |
|||
my (@pos, @vel, @v, @gbpos, @bval); |
|||
for 0 ..^ $n -> \j { |
|||
@v[j] = &fn(%y{'pos'}[j]); # evaluate |
|||
# update |
|||
if @v[j] < %y{'bval'}[j] { |
|||
@bpos[j] = %y{'pos'}[j]; |
|||
@bval[j] = @v[j]; |
|||
} else { |
|||
@bpos[j] = %y{'bpos'}[j]; |
|||
@bval[j] = %y{'bval'}[j]; |
|||
} |
|||
if @bval[j] < $gbval { |
|||
$gbval = @bval[j]; |
|||
@gbpos = |@bpos[j]; |
|||
} |
|||
} |
|||
# migrate |
|||
for 0 ..^ $n -> \j { |
|||
my $rand-p = rand; |
|||
my $ok = True; |
|||
for 0 ..^ $d -> \k { |
|||
@vel[j;k] = %p{'ω'} × %y{'vel'}[j;k] |
|||
+ %p{'φ-p'} × $rand-p × (@bpos[j;k] - %y{'pos'}[j;k]) |
|||
+ %p{'φ-g'} × $rand-g × (@gbpos[k] - %y{'pos'}[j;k]); |
|||
@pos[j;k] = %y{'pos'}[j;k] + @vel[j;k]; |
|||
$ok = %y{'min'}[k] < @pos[j;k] < %y{'max'}[k] if $ok; |
|||
} |
|||
next if $ok; |
|||
@pos[j;$_] = %y{'min'}[$_] + (%y{'max'}[$_] - %y{'min'}[$_]) × rand for 0 ..^ $d; |
|||
} |
|||
return {gbpos => @gbpos, gbval => $gbval, bpos => @bpos, bval => @bval, pos => @pos, vel => @vel, |
|||
min => %y{'min'}, max => %y{'max'}, p=> %y{'p'}, n => $n} |
|||
} |
|||
sub report ($function-name, %state) { |
|||
say $function-name; |
|||
say '🌐 best position: ' ~ %state{'gbpos'}.fmt('%.5f'); |
|||
say '🌐 best value: ' ~ %state{'gbval'}.fmt('%.5f'); |
|||
say ''; |
|||
} |
|||
sub mccormick (@x) { |
|||
my ($a,$b) = @x; |
|||
sin($a+$b) + ($a-$b)**2 + (1 + 2.5×$b - 1.5×$a) |
|||
} |
|||
my %state = pso-init( { |
|||
min => [-1.5, -3], |
|||
max => [4, 4], |
|||
n => 100, |
|||
p => {ω=> 0, φ-p=> 0.6, φ-g=> 0.3}, |
|||
} ); |
|||
%state = pso(&mccormick, %state) for 1 .. 40; |
|||
report 'McCormick', %state; |
|||
sub michalewicz (@x) { |
|||
my $sum; |
|||
my $m = 10; |
|||
for 1..@x -> $i { |
|||
my $j = @x[$i-1]; |
|||
my $k = sin($i × $j**2/π); |
|||
$sum += sin($j) × $k**(2×$m) |
|||
} |
|||
-$sum |
|||
} |
|||
%state = pso-init( { |
|||
min => [0, 0], |
|||
max => [π, π], |
|||
n => 1000, |
|||
p => {ω=> 0.3, φ-p=> 0.3, φ-g=> 0.3}, |
|||
} ); |
|||
%state = pso(&michalewicz, %state) for 1 .. 30; |
|||
report 'Michalewicz', %state;</lang> |
|||
{{out}} |
|||
<pre>McCormick |
|||
🌐 best position: -0.54714 -1.54710 |
|||
🌐 best value: -1.91322 |
|||
Michalewicz |
|||
🌐 best position: 2.20291 1.57080 |
|||
🌐 best value: -1.80130</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 2,253: | Line 2,143: | ||
1.8558804696523914) |
1.8558804696523914) |
||
-6.432092623300999</pre> |
-6.432092623300999</pre> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{trans|J (via Javascript, Kotlin, D, Python)}} |
|||
<lang perl6>sub pso-init (%y) { |
|||
my $d = @(%y{'min'}); |
|||
my $n = %y{'n'}; |
|||
%y{'gbval'} = Inf; |
|||
%y{'gbpos'} = [Inf xx $d]; |
|||
%y{'bval'} = [Inf xx $n]; |
|||
%y{'bpos'} = [%y{'min'} xx $n]; |
|||
%y{'pos'} = [%y{'min'} xx $n]; |
|||
%y{'vel'} = [[0 xx $d] xx $n]; |
|||
%y; |
|||
} |
|||
sub pso (&fn, %y) { |
|||
my %p = %y{'p'}; |
|||
my $n = %y{'n'}; |
|||
my $d = @(%y{'min'}); |
|||
my @bpos = %y{'min'} xx $n; |
|||
my $gbval = Inf; |
|||
my $rand-g = rand; |
|||
my (@pos, @vel, @v, @gbpos, @bval); |
|||
for 0 ..^ $n -> \j { |
|||
@v[j] = &fn(%y{'pos'}[j]); # evaluate |
|||
# update |
|||
if @v[j] < %y{'bval'}[j] { |
|||
@bpos[j] = %y{'pos'}[j]; |
|||
@bval[j] = @v[j]; |
|||
} else { |
|||
@bpos[j] = %y{'bpos'}[j]; |
|||
@bval[j] = %y{'bval'}[j]; |
|||
} |
|||
if @bval[j] < $gbval { |
|||
$gbval = @bval[j]; |
|||
@gbpos = |@bpos[j]; |
|||
} |
|||
} |
|||
# migrate |
|||
for 0 ..^ $n -> \j { |
|||
my $rand-p = rand; |
|||
my $ok = True; |
|||
for 0 ..^ $d -> \k { |
|||
@vel[j;k] = %p{'ω'} × %y{'vel'}[j;k] |
|||
+ %p{'φ-p'} × $rand-p × (@bpos[j;k] - %y{'pos'}[j;k]) |
|||
+ %p{'φ-g'} × $rand-g × (@gbpos[k] - %y{'pos'}[j;k]); |
|||
@pos[j;k] = %y{'pos'}[j;k] + @vel[j;k]; |
|||
$ok = %y{'min'}[k] < @pos[j;k] < %y{'max'}[k] if $ok; |
|||
} |
|||
next if $ok; |
|||
@pos[j;$_] = %y{'min'}[$_] + (%y{'max'}[$_] - %y{'min'}[$_]) × rand for 0 ..^ $d; |
|||
} |
|||
return {gbpos => @gbpos, gbval => $gbval, bpos => @bpos, bval => @bval, pos => @pos, vel => @vel, |
|||
min => %y{'min'}, max => %y{'max'}, p=> %y{'p'}, n => $n} |
|||
} |
|||
sub report ($function-name, %state) { |
|||
say $function-name; |
|||
say '🌐 best position: ' ~ %state{'gbpos'}.fmt('%.5f'); |
|||
say '🌐 best value: ' ~ %state{'gbval'}.fmt('%.5f'); |
|||
say ''; |
|||
} |
|||
sub mccormick (@x) { |
|||
my ($a,$b) = @x; |
|||
sin($a+$b) + ($a-$b)**2 + (1 + 2.5×$b - 1.5×$a) |
|||
} |
|||
my %state = pso-init( { |
|||
min => [-1.5, -3], |
|||
max => [4, 4], |
|||
n => 100, |
|||
p => {ω=> 0, φ-p=> 0.6, φ-g=> 0.3}, |
|||
} ); |
|||
%state = pso(&mccormick, %state) for 1 .. 40; |
|||
report 'McCormick', %state; |
|||
sub michalewicz (@x) { |
|||
my $sum; |
|||
my $m = 10; |
|||
for 1..@x -> $i { |
|||
my $j = @x[$i-1]; |
|||
my $k = sin($i × $j**2/π); |
|||
$sum += sin($j) × $k**(2×$m) |
|||
} |
|||
-$sum |
|||
} |
|||
%state = pso-init( { |
|||
min => [0, 0], |
|||
max => [π, π], |
|||
n => 1000, |
|||
p => {ω=> 0.3, φ-p=> 0.3, φ-g=> 0.3}, |
|||
} ); |
|||
%state = pso(&michalewicz, %state) for 1 .. 30; |
|||
report 'Michalewicz', %state;</lang> |
|||
{{out}} |
|||
<pre>McCormick |
|||
🌐 best position: -0.54714 -1.54710 |
|||
🌐 best value: -1.91322 |
|||
Michalewicz |
|||
🌐 best position: 2.20291 1.57080 |
|||
🌐 best value: -1.80130</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |