Particle swarm optimization: Difference between revisions
m
→{{header|Wren}}: Minor tidy
(→{{header|Kotlin}}: Fixed bug though results unaffected) |
m (→{{header|Wren}}: Minor tidy) |
||
(34 intermediate revisions by 9 users not shown) | |||
Line 4:
</p>
<p>
The goal of parameter selection is to ensure that the global minimum is discriminated from any local minima, and that the minimum is accurately determined, and that convergence is achieved with
<ul>
<li> McCormick function - bowl-shaped, with a single minimum
Line 39:
</ul>
</p>
<br><br>
=={{header|C sharp|C#}}==
{{trans|java}}
<syntaxhighlight 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 }));
}
}
}</syntaxhighlight>
{{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++}}==
{{trans|D}}
<syntaxhighlight lang="cpp">#include <algorithm>
#include <functional>
#include <iostream>
#include <random>
#include <vector>
const auto PI = std::atan2(0, -1);
bool double_equals(double a, double b, double epsilon = 0.001) {
return std::abs(a - b) < epsilon;
}
template <typename T>
bool vector_equals(const std::vector<T> & lhs, const std::vector<T> & rhs) {
if (lhs.size() != rhs.size()) {
return false;
}
for (size_t i = 0; i < lhs.size(); i++) {
if (!vector_equals(lhs[i], rhs[i])) {
return false;
}
}
return true;
}
template <typename T>
bool vector_equals(const T & lhs, const T & rhs) {
return lhs == rhs;
}
template <>
bool vector_equals(const std::vector<double> & lhs, const std::vector<double> & rhs) {
if (lhs.size() != rhs.size()) {
return false;
}
for (size_t i = 0; i < lhs.size(); i++) {
if (!double_equals(lhs[i], rhs[i])) {
return false;
}
}
return true;
}
template <typename T>
std::ostream& operator<<(std::ostream & os, const std::vector<T> & v) {
auto it = v.cbegin();
auto end = v.cend();
os << '[';
if (it != end) {
os << *it;
it = std::next(it);
}
while (it != end) {
os << ", " << *it;
it = std::next(it);
}
return os << ']';
}
double uniform01() {
static std::default_random_engine generator;
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
return distribution(generator);
}
struct Parameters {
double omega, phip, phig;
bool operator==(const Parameters& rhs) {
return double_equals(omega, rhs.omega)
&& double_equals(phip, rhs.phip)
&& double_equals(phig, rhs.phig);
}
};
struct State {
int iter;
std::vector<double> gbpos;
double gbval;
std::vector<double> min;
std::vector<double> max;
Parameters parameters;
std::vector<std::vector<double>> pos;
std::vector<std::vector<double>> vel;
std::vector<std::vector<double>> bpos;
std::vector<double> bval;
int nParticles;
int nDims;
bool operator==(const State& rhs) {
return iter == rhs.iter
&& vector_equals(gbpos, rhs.gbpos)
&& double_equals(gbval, rhs.gbval)
&& vector_equals(min, rhs.min)
&& vector_equals(max, rhs.max)
&& parameters == rhs.parameters
&& vector_equals(pos, rhs.pos)
&& vector_equals(vel, rhs.vel)
&& vector_equals(bpos, rhs.bpos)
&& vector_equals(bval, rhs.bval)
&& nParticles == rhs.nParticles
&& nDims == rhs.nDims;
}
void report(const std::string& testFunc) {
std::cout << "Test Function : " << testFunc << '\n';
std::cout << "Iterations : " << iter << '\n';
std::cout << "Global Best Position : " << gbpos << '\n';
std::cout << "Global Best Value : " << gbval << '\n';
}
};
State psoInit(const std::vector<double> & min, const std::vector<double> & max, const Parameters & parameters, int nParticles) {
int nDims = min.size();
std::vector<std::vector<double>> pos(nParticles);
for (int i = 0; i < nParticles; i++) {
std::copy(min.cbegin(), min.cend(), std::back_inserter(pos[i]));
}
std::vector<std::vector<double>> vel(nParticles);
for (int i = 0; i < nParticles; i++) {
vel[i].resize(nDims);
}
std::vector<std::vector<double>> bpos(nParticles);
for (int i = 0; i < nParticles; i++) {
std::copy(min.cbegin(), min.cend(), std::back_inserter(bpos[i]));
}
std::vector<double> bval(nParticles, HUGE_VAL);
auto iter = 0;
std::vector<double> gbpos(nDims, HUGE_VAL);
auto gbval = HUGE_VAL;
return{ iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims };
}
State pso(const std::function<double(const std::vector<double>&)> & fn, const State & y) {
auto p = y.parameters;
std::vector<double> v(y.nParticles);
std::vector<std::vector<double>> bpos(y.nParticles);
for (int i = 0; i < y.nParticles; i++) {
std::copy(y.min.cbegin(), y.min.cend(), std::back_inserter(bpos[i]));
}
std::vector<double> bval(y.nParticles);
std::vector<double> gbpos(y.nDims);
auto gbval = HUGE_VAL;
for (int j = 0; j < y.nParticles; j++) {
// evaluate
v[j] = fn(y.pos[j]);
// 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];
}
}
auto rg = uniform01();
std::vector<std::vector<double>> pos(y.nParticles);
for (size_t i = 0; i < pos.size(); i++) {
pos[i].resize(y.nDims);
}
std::vector<std::vector<double>> vel(y.nParticles);
for (size_t i = 0; i < vel.size(); i++) {
vel[i].resize(y.nDims);
}
for (size_t j = 0; j < y.nParticles; j++) {
// migrate
auto rp = uniform01();
bool ok = true;
std::fill(vel[j].begin(), vel[j].end(), 0);
std::fill(pos[j].begin(), pos[j].end(), 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]) * uniform01();
}
}
}
auto iter = 1 + y.iter;
return { iter, gbpos, gbval, y.min, y.max, y.parameters, pos, vel, bpos, bval, y.nParticles, y.nDims };
}
State iterate(const std::function<double(const std::vector<double>&)> & fn, int n, const State & y) {
State r(y);
if (n == INT32_MAX) {
State old(y);
while (true) {
r = pso(fn, r);
if (r == old) {
break;
}
old = r;
}
} else {
for (int i = 0; i < n; i++) {
r = pso(fn, r);
}
}
return r;
}
double mccormick(const std::vector<double> & x) {
auto a = x[0];
auto b = x[1];
return sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a;
}
double michalewicz(const std::vector<double> & x) {
auto m = 10;
auto d = x.size();
auto sum = 0.0;
for (int i = 1; i < d; ++i) {
auto j = x[i - 1];
auto k = sin(i * j * j / PI);
sum += sin(j) * pow(k, (2.0 * m));
}
return -sum;
}
int main() {
auto state = psoInit(
{ -1.5, -3.0 },
{ 4.0, 4.0 },
{ 0.0, 0.6, 0.3 },
100
);
state = iterate(mccormick, 40, state);
state.report("McCormick");
std::cout << "f(-0.54719, -1.54719) : " << mccormick({ -0.54719, -1.54719 }) << '\n';
std::cout << '\n';
state = psoInit(
{ 0.0, 0.0 },
{PI, PI},
{ 0.3, 0.3, 0.3 },
1000
);
state = iterate(michalewicz, 30, state);
state.report("Michalewicz (2D)");
std::cout << "f(2.20, 1.57) : " << michalewicz({ 2.2, 1.57 }) << '\n';
}</syntaxhighlight>
{{out}}
<pre>Test Function : McCormick
Iterations : 40
Global Best Position : [-0.547284, -1.54737]
Global Best Value : -1.91322
f(-0.54719, -1.54719) : -1.91322
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.20291, 1.2939]
Global Best Value : -0.801303
f(2.20, 1.57) : -0.801166</pre>
=={{header|D}}==
{{trans|Kotlin}}
<syntaxhighlight lang="d">import std.math;
import std.random;
import std.stdio;
alias Func = double function(double[]);
struct Parameters {
double omega, phip, phig;
}
struct 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;
void report(string testfunc) {
writeln("Test Function : ", testfunc);
writeln("Iterations : ", iter);
writefln("Global Best Position : [%(%.16f, %)]", gbpos);
writefln("Global Best Value : %.16f", gbval);
}
}
State psoInit(double[] min, double[] max, Parameters parameters, int nParticles) {
auto nDims = min.length;
double[][] pos;
pos.length = nParticles;
pos[] = min;
double[][] vel;
vel.length = nParticles;
for (int i; i<nParticles; i++) vel[i].length = nDims;
double[][] bpos;
bpos.length = nParticles;
bpos[] = min;
double[] bval;
bval.length = nParticles;
bval[] = double.infinity;
auto iter = 0;
double[] gbpos;
gbpos.length = nDims;
gbpos[] = double.infinity;
auto gbval = double.infinity;
return State(iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims);
}
State pso(Func fn, State y) {
auto p = y.parameters;
double[] v;
v.length = y.nParticles;
double[][] bpos;
bpos.length = y.nParticles;
bpos[] = y.min;
double[] bval;
bval.length = y.nParticles;
double[] gbpos;
gbpos.length = y.nDims;
auto gbval = double.infinity;
foreach (j; 0..y.nParticles) {
// evaluate
v[j] = fn(y.pos[j]);
// 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];
}
}
auto rg = uniform01();
double[][] pos;
pos.length = y.nParticles;
for (int i; i<pos.length; i++) pos[i].length = y.nDims;
double[][] vel;
vel.length = y.nParticles;
for (int i; i<vel.length; i++) vel[i].length = y.nDims;
foreach (j; 0..y.nParticles) {
// migrate
auto rp = uniform01();
bool ok = true;
vel[j][] = 0;
pos[j][] = 0;
foreach (k; 0..y.nDims) {
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) {
foreach (k; 0..y.nDims) {
pos[j][k] = y.min[k] + (y.max[k] - y.min[k]) * uniform01();
}
}
}
auto iter = 1 + y.iter;
return State(iter, gbpos, gbval, y.min, y.max, y.parameters, pos, vel, bpos, bval, y.nParticles, y.nDims);
}
State iterate(Func fn, int n, State y) {
auto r = y;
auto old = y;
if (n == int.max) {
while (true) {
r = pso(fn, r);
if (r == old) break;
old = r;
}
} else {
foreach (_; 0..n) r = pso(fn, r);
}
return r;
}
double mccormick(double[] x) {
auto a = x[0];
auto b = x[1];
return sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a;
}
double michalewicz(double[] x) {
auto m = 10;
auto d = x.length;
auto sum = 0.0;
foreach (i; 1..d) {
auto j = x[i - 1];
auto k = sin(i * j * j / PI);
sum += sin(j) * k^^(2.0*m);
}
return -sum;
}
void main() {
auto state = psoInit(
[-1.5, -3.0],
[4.0, 4.0],
Parameters(0.0, 0.6, 0.3),
100
);
state = iterate(&mccormick, 40, state);
state.report("McCormick");
writefln("f(-.54719, -1.54719) : %.16f", mccormick([-.54719, -1.54719]));
writeln;
state = psoInit(
[0.0, 0.0],
[PI, PI],
Parameters(0.3, 0.3, 0.3),
1000
);
state = iterate(&michalewicz, 30, state);
state.report("Michalewicz (2D)");
writefln("f(2.20, 1.57) : %.16f", michalewicz([2.2, 1.57]));
}</syntaxhighlight>
{{out}}
<pre>Test Function : McCormick
Iterations : 40
Global Best Position : [-0.5673174452967942, -1.5373177402652800]
Global Best Value : -1.9122776571457756
f(-.54719, -1.54719) : -1.9132229548822735
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.1907380816516597, 1.5608474620076016]
Global Best Value : -1.7949374368688056
f(2.20, 1.57) : -1.8011407184738251</pre>
=={{header|Go}}==
{{trans|Kotlin}}
<syntaxhighlight lang="go">package main
import (
"fmt"
"math"
"math/rand"
"time"
)
type ff = func([]float64) float64
type parameters struct{ omega, phip, phig float64 }
type state struct {
iter int
gbpos []float64
gbval float64
min []float64
max []float64
params parameters
pos [][]float64
vel [][]float64
bpos [][]float64
bval []float64
nParticles int
nDims int
}
func (s state) report(testfunc string) {
fmt.Println("Test Function :", testfunc)
fmt.Println("Iterations :", s.iter)
fmt.Println("Global Best Position :", s.gbpos)
fmt.Println("Global Best Value :", s.gbval)
}
func psoInit(min, max []float64, params parameters, nParticles int) *state {
nDims := len(min)
pos := make([][]float64, nParticles)
vel := make([][]float64, nParticles)
bpos := make([][]float64, nParticles)
bval := make([]float64, nParticles)
for i := 0; i < nParticles; i++ {
pos[i] = min
vel[i] = make([]float64, nDims)
bpos[i] = min
bval[i] = math.Inf(1)
}
iter := 0
gbpos := make([]float64, nDims)
for i := 0; i < nDims; i++ {
gbpos[i] = math.Inf(1)
}
gbval := math.Inf(1)
return &state{iter, gbpos, gbval, min, max, params,
pos, vel, bpos, bval, nParticles, nDims}
}
func pso(fn ff, y *state) *state {
p := y.params
v := make([]float64, y.nParticles)
bpos := make([][]float64, y.nParticles)
bval := make([]float64, y.nParticles)
gbpos := make([]float64, y.nDims)
gbval := math.Inf(1)
for j := 0; j < y.nParticles; j++ {
// evaluate
v[j] = fn(y.pos[j])
// 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]
}
}
rg := rand.Float64()
pos := make([][]float64, y.nParticles)
vel := make([][]float64, y.nParticles)
for j := 0; j < y.nParticles; j++ {
pos[j] = make([]float64, y.nDims)
vel[j] = make([]float64, y.nDims)
// migrate
rp := rand.Float64()
ok := true
for z := 0; z < y.nDims; z++ {
pos[j][z] = 0
vel[j][z] = 0
}
for 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 k := 0; k < y.nDims; k++ {
pos[j][k] = y.min[k] + (y.max[k]-y.min[k])*rand.Float64()
}
}
}
iter := 1 + y.iter
return &state{iter, gbpos, gbval, y.min, y.max, y.params,
pos, vel, bpos, bval, y.nParticles, y.nDims}
}
func iterate(fn ff, n int, y *state) *state {
r := y
for i := 0; i < n; i++ {
r = pso(fn, r)
}
return r
}
func mccormick(x []float64) float64 {
a, b := x[0], x[1]
return math.Sin(a+b) + (a-b)*(a-b) + 1.0 + 2.5*b - 1.5*a
}
func michalewicz(x []float64) float64 {
m := 10.0
sum := 0.0
for i := 1; i <= len(x); i++ {
j := x[i-1]
k := math.Sin(float64(i) * j * j / math.Pi)
sum += math.Sin(j) * math.Pow(k, 2*m)
}
return -sum
}
func main() {
rand.Seed(time.Now().UnixNano())
st := psoInit(
[]float64{-1.5, -3.0},
[]float64{4.0, 4.0},
parameters{0.0, 0.6, 0.3},
100,
)
st = iterate(mccormick, 40, st)
st.report("McCormick")
fmt.Println("f(-.54719, -1.54719) :", mccormick([]float64{-.54719, -1.54719}))
fmt.Println()
st = psoInit(
[]float64{0.0, 0.0},
[]float64{math.Pi, math.Pi},
parameters{0.3, 0.3, 0.3},
1000,
)
st = iterate(michalewicz, 30, st)
st.report("Michalewicz (2D)")
fmt.Println("f(2.20, 1.57) :", michalewicz([]float64{2.2, 1.57}))
</syntaxhighlight>
{{out}}
Sample output:
<pre>
Test Function : McCormick
Iterations : 40
Global Best Position : [-0.5473437041724806 -1.5464923165739348]
Global Best Value : -1.9132220947578635
f(-.54719, -1.54719) : -1.913222954882274
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.2029051150895165 1.570796212894911]
Global Best Value : -1.8013034100953598
f(2.20, 1.57) : -1.8011407184738253
</pre>
=={{header|J}}==
<
pso_init =: verb define
Line 85 ⟶ 951:
)
reportState=: 'Iteration: %j\nGlobalBestPosition: %j\nGlobalBestValue: %j\n' printf 3&{.</
Apply to McCormick Function:<
mccormick =: sin@(+/) + *:@(-/) + 1 + _1.5 2.5 +/@:* ]
Line 99 ⟶ 965:
Iteration: 40
GlobalBestPosition: _0.547399 _1.54698
GlobalBestValue: _1.91322</
Apply to Michalewicz Function:
<
michalewicz =: [: -@(+/) sin * 20 ^~ sin@(pi %~ >:@i.@# * *:) NB. tacit equivalent
Line 114 ⟶ 980:
Iteration: 30
GlobalBestPosition: 2.20296 1.57083
GlobalBestValue: _1.8013</
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.util.Arrays;
import java.util.Objects;
import java.util.Random;
import java.util.function.Function;
public class App {
static class Parameters {
double omega;
double phip;
double phig;
Parameters(double omega, double phip, double phig) {
this.omega = omega;
this.phip = phip;
this.phig = phig;
}
}
static class 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;
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.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;
}
void report(String testfunc) {
System.out.printf("Test Function : %s\n", testfunc);
System.out.printf("Iterations : %d\n", iter);
System.out.printf("Global Best Position : %s\n", Arrays.toString(gbpos));
System.out.printf("Global Best value : %.15f\n", gbval);
}
}
private static State psoInit(double[] min, double[] max, Parameters parameters, int nParticles) {
int nDims = min.length;
double[][] pos = new double[nParticles][];
for (int i = 0; i < nParticles; ++i) {
pos[i] = min.clone();
}
double[][] vel = new double[nParticles][nDims];
double[][] bpos = new double[nParticles][];
for (int i = 0; i < nParticles; ++i) {
bpos[i] = min.clone();
}
double[] bval = new double[nParticles];
for (int i = 0; i < bval.length; ++i) {
bval[i] = Double.POSITIVE_INFINITY;
}
int iter = 0;
double[] gbpos = new double[nDims];
for (int i = 0; i < gbpos.length; ++i) {
gbpos[i] = Double.POSITIVE_INFINITY;
}
double gbval = Double.POSITIVE_INFINITY;
return new State(iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims);
}
private static Random r = new Random();
private static State pso(Function<double[], Double> fn, State y) {
Parameters 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] = y.min.clone();
}
double[] bval = new double[y.nParticles];
double[] gbpos = new double[y.nDims];
double gbval = Double.POSITIVE_INFINITY;
for (int j = 0; j < y.nParticles; ++j) {
// evaluate
v[j] = fn.apply(y.pos[j]);
// 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];
}
}
double rg = r.nextDouble();
double[][] pos = new double[y.nParticles][y.nDims];
double[][] vel = new double[y.nParticles][y.nDims];
for (int j = 0; j < y.nParticles; ++j) {
// migrate
double rp = r.nextDouble();
boolean ok = true;
Arrays.fill(vel[j], 0.0);
Arrays.fill(pos[j], 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();
}
}
}
int iter = 1 + y.iter;
return new State(
iter, gbpos, gbval, y.min, y.max, y.parameters,
pos, vel, bpos, bval, y.nParticles, y.nDims
);
}
private static State iterate(Function<double[], Double> fn, int n, State y) {
State r = y;
if (n == Integer.MAX_VALUE) {
State old = y;
while (true) {
r = pso(fn, r);
if (Objects.equals(r, old)) break;
old = r;
}
} else {
for (int i = 0; i < n; ++i) {
r = pso(fn, r);
}
}
return r;
}
private static double mccormick(double[] x) {
double a = x[0];
double b = x[1];
return Math.sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a;
}
private static double michalewicz(double[] x) {
int m = 10;
int d = x.length;
double sum = 0.0;
for (int i = 1; i < d; ++i) {
double j = x[i - 1];
double k = Math.sin(i * j * j / Math.PI);
sum += Math.sin(j) * Math.pow(k, 2.0 * m);
}
return -sum;
}
public static void main(String[] args) {
State 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(App::mccormick, 40, state);
state.report("McCormick");
System.out.printf("f(-.54719, -1.54719) : %.15f\n", mccormick(new double[]{-.54719, -1.54719}));
System.out.println();
state = psoInit(
new double[]{0.0, 0.0},
new double[]{Math.PI, Math.PI},
new Parameters(0.3, 3.0, 0.3),
1000
);
state = iterate(App::michalewicz, 30, state);
state.report("Michalewicz (2D)");
System.out.printf("f(2.20, 1.57) : %.15f\n", michalewicz(new double[]{2.20, 1.57}));
}
}</syntaxhighlight>
{{out}}
<pre>Test Function : McCormick
Iterations : 40
Global Best Position : [-0.5468738679864172, -1.547048532862534]
Global Best value : -1.913222827709136
f(-.54719, -1.54719) : -1.913222954882274
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.2029055320517994, 1.832848319327826]
Global Best value : -0.801303410098550
f(2.20, 1.57) : -0.801166387820286</pre>
=={{header|JavaScript}}==
Line 120 ⟶ 1,195:
Translation of [[Particle_Swarm_Optimization#J|J]].
<
var nDims= y.min.length;
var pos=[], vel=[], bpos=[], bval=[];
Line 231 ⟶ 1,306:
state= repeat(function(y){return pso(mccormick,y)}, 40, state);
reportState(state);</
Example displayed result (random numbers are involved so there will be a bit of variance between repeated runs:
<syntaxhighlight lang="javascript">
Iteration: 0
GlobalBestPosition: Infinity
Line 242 ⟶ 1,317:
Iteration: 40
GlobalBestPosition: -0.5134004259016365,-1.5512442672625184
GlobalBestValue: -1.9114053788600853</
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Optim
const mcclow = [-1.5, -3.0]
const mccupp = [4.0, 4.0]
const miclow = [0.0, 0.0]
const micupp = Float64.([pi, pi])
const npar = [100, 1000]
const x0 = [0.0, 0.0]
michalewicz(x, m=10) = -sum(i -> sin(x[i]) * (i * sin( x[i]^2/pi))^(2*m), 1:length(x))
mccormick(x) = sin(x[1] + x[2]) + (x[1] - x[2])^2 - 1.5 * x[1] + 2.5 * x[2] + 1
println(optimize(mccormick, x0, ParticleSwarm(;lower=mcclow, upper=mccupp, n_particles=npar[1])))
@time optimize(mccormick, x0, ParticleSwarm(;lower=mcclow, upper=mccupp, n_particles=npar[1]))
println(optimize(michalewicz, x0, ParticleSwarm(;lower=miclow, upper=micupp, n_particles=npar[2])))
@time optimize(michalewicz, x0, ParticleSwarm(;lower=miclow, upper=micupp, n_particles=npar[2]))
</syntaxhighlight>{{out}}
<pre>
Results of Optimization Algorithm
* Algorithm: Particle Swarm
* Starting Point: [0.0,0.0]
* Minimizer: [-0.5471975503990738,-1.5471975447742121]
* Minimum: -1.913223e+00
* Iterations: 1000
* Convergence: false
* |x - x'| ≤ 0.0e+00: false
|x - x'| = NaN
* |f(x) - f(x')| ≤ 0.0e+00 |f(x)|: false
|f(x) - f(x')| = NaN |f(x)|
* |g(x)| ≤ 1.0e-08: false
|g(x)| = NaN
* Stopped by an increasing objective: false
* Reached Maximum Number of Iterations: true
* Objective Calls: 101001
* Gradient Calls: 0
0.087319 seconds (228.91 k allocations: 12.098 MiB, 59.41% gc time)
Results of Optimization Algorithm
* Algorithm: Particle Swarm
* Starting Point: [0.0,0.0]
* Minimizer: [2.202905520771759,1.5707963264041795]
* Minimum: -1.801303e+00
* Iterations: 1000
* Convergence: false
* |x - x'| ≤ 0.0e+00: false
|x - x'| = NaN
* |f(x) - f(x')| ≤ 0.0e+00 |f(x)|: false
|f(x) - f(x')| = NaN |f(x)|
* |g(x)| ≤ 1.0e-08: false
|g(x)| = NaN
* Stopped by an increasing objective: false
* Reached Maximum Number of Iterations: true
* Objective Calls: 1001001
* Gradient Calls: 0
2.312291 seconds (3.52 M allocations: 153.253 MiB, 0.49% gc time)
</pre>
=={{header|Kotlin}}==
{{trans|JavaScript}}
<
import java.util.Random
Line 402 ⟶ 1,538:
state.report("Michalewicz (2D)")
println("f(2.20, 1.57) : ${michalewicz(doubleArrayOf(2.2, 1.57))}")
}</
Sample output:
Line 418 ⟶ 1,554:
f(2.20, 1.57) : -1.801140718473825
</pre>
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import math, random, sequtils, sugar
type
Func = seq[float] -> float
Parameters = tuple[omega, phip, phig: float]
State = object
iter: int
gbpos: seq[float]
gbval: float
min, max: seq[float]
parameters: Parameters
pos, vel, bpos: seq[seq[float]]
bval: seq[float]
nParticles, nDims: int
func initState(min, max: seq[float]; parameters: Parameters; nParticles: int): State =
let nDims = min.len
State(iter: 0,
gbpos: repeat(Inf, nDims),
gbval: Inf,
min: min,
max: max,
parameters: parameters,
pos: repeat(min, nParticles),
vel: newSeqWith(nParticles,
newSeq[float](nDims)),
bpos: repeat(min, nParticles),
bval: repeat(Inf, nParticles),
nParticles: nParticles,
nDims: nDims)
proc report(state: State; testFunc: string) =
echo "Test Function: ", testfunc
echo "Iterations: ", state.iter
echo "Global Best Position: ", state.gbpos
echo "Global Best Value: ", state.gbval
proc pso(fn: Func; y: State): State =
let p = y.parameters
var v = newSeq[float](y.nParticles)
var bpos = repeat(y.min, y.nParticles)
var bval = newSeq[float](y.nParticles)
var gbpos = newSeq[float](y.nDims)
var gbval = Inf
for j in 0..<y.nParticles:
# evaluate.
v[j] = fn(y.pos[j])
# 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]
let rg = rand(1.0)
var pos = newSeqWith(y.nParticles, newSeq[float](y.nDims))
var vel = newSeqWith(y.nParticles, newSeq[float](y.nDims))
for j in 0..<y.nParticles:
# migrate.
let rp = rand(1.0)
var ok = true
for k in 0..<y.nDims:
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 and y.min[k] < pos[j][k] and y.max[k] > pos[j][k]
if not ok:
for k in 0..<y.nDims:
pos[j][k]= y.min[k] + (y.max[k] - y.min[k]) * rand(1.0)
result = State(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)
proc iterate(fn: Func; n: int; y: State): State =
result = y
if n == int.high:
while true:
let old = result
result = pso(fn, result)
if result == old: break
else:
for _ in 1..n:
result = pso(fn, result)
func mccormick(x: seq[float]): float =
let a = x[0]
let b = x[1]
result = sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a
func michalewicz(x: seq[float]): float =
const M = 10
for i in 1..x.len:
let j = x[i - 1]
let k = sin(i.toFloat * j * j / PI)
result -= sin(j) * k^(2 * M)
randomize()
var state = initState(min = @[-1.5, -3],
max = @[4.0, 4.0],
parameters = (0.0, 0.6, 0.3),
nParticles = 100)
state = iterate(mccormick, 40, state)
state.report("McCormick")
echo "f(-.54719, -1.54719): ", mccormick(@[-0.54719, -1.54719])
echo()
state = initState(min = @[0.0, 0.0],
max = @[PI, PI],
parameters = (0.3, 0.3, 0.3),
nParticles = 1000)
state = iterate(michalewicz, 30, state)
state.report("Michalewicz (2D)")
echo "f(2.20, 1.57): ", michalewicz(@[2.2, 1.57])</syntaxhighlight>
{{out}}
<pre>Test Function: McCormick
Iterations: 40
Global Best Position: @[-0.5470347980396687, -1.547176688676891]
Global Best Value: -1.913222920248667
f(-.54719, -1.54719): -1.913222954882274
Test Function: Michalewicz (2D)
Iterations: 30
Global Best Position: @[2.202898715299719, 1.570804023976923]
Global Best Value: -1.801303406946448
f(2.20, 1.57): -1.801140718473825</pre>
=={{header|ooRexx}}==
<
* Test for McCormick function
*--------------------------------------------------------------------*/
Line 455 ⟶ 1,747:
res=rxcalcsin(x+y,16,'R')+(x-y)**2-1.5*x+2.5*y+1
Return res
::requires rxmath library</
{{out}}
<pre>-1.5 -2.5 -1.243197504692072
Line 472 ⟶ 1,764:
f(-.54719,-1.54719)=-1.913222954882273
and differs from published -1.9133</pre>
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use constant PI => 2 * atan2(1, 0);
use constant Inf => 1e10;
sub pso_init {
my(%y) = @_;
my $d = @{$y{'min'}};
my $n = $y{'n'};
$y{'gbval'} = Inf;
$y{'gbpos'} = [(Inf) x $d];
$y{'bval'} = [(Inf) x $n];
$y{'bpos'} = [($y{'min'}) x $n];
$y{'pos'} = [($y{'min'}) x $n];
$y{'vel'} = [([(0) x $d]) x $n];
%y
}
sub pso {
my($fn, %y) = @_;
my $p = $y{'p'};
my $n = $y{'n'};
my $d = @{$y{'min'}};
my @bpos = ($y{'min'}) x $n;
my $gbval = Inf;
my $rand_g = rand;
my (@pos, @vel, @v, @gbpos, @bval);
for my $j (0 .. $n-1) {
$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) {
@gbpos = @{$bpos[$j]};
$gbval = $bval[$j];
}
}
# migrate
for my $j (0 .. $n-1) {
my $rand_p = rand;
my $ok = 1;
for my $k (0 .. $d-1) {
$vel[$j][$k] = $$p{'omega'} * $y{'vel'}[$j][$k]
+ $$p{'phi_p'} * $rand_p * ($bpos[$j][$k] - $y{'pos'}[$j][$k])
+ $$p{'phi_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]) && ($pos[$j][$k] < $y{'max'}[$k]) && $ok;
}
next if $ok;
$pos[$j][$_] = $y{'min'}[$_] + ($y{'max'}[$_] - $y{'min'}[$_]) * rand for 0 .. $d-1;
}
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 {
my($function_name, %state) = @_;
say $function_name;
say 'Global best position: ' . sprintf "%.5f %.5f", @{$state{'gbpos'}};
say 'Global best value: ' . sprintf "%.5f", $state{'gbval'};
say '';
}
# McCormick
sub mccormick {
my($a,$b) = @_;
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 => {omega => 0, phi_p => 0.6, phi_g => 0.3},
) );
%state = %{pso(\&mccormick, %state)} for 1 .. 40;
report('McCormick', %state);
# Michalewicz
sub michalewicz {
my(@x) = @_;
my $sum;
my $m = 10;
for my $i (1..@x) {
my $j = $x[$i - 1];
my $k = sin($i * $j**2/PI);
$sum += sin($j) * $k**(2*$m)
}
-$sum
}
%state = pso_init( (
min => [0, 0],
max => [PI, PI],
n => 1000,
p => {omega => 0.3, phi_p => 0.3, phi_g => 0.3},
) );
%state = %{pso(\&michalewicz, %state)} for 1 .. 30;
report('Michalewicz', %state);</syntaxhighlight>
{{out}}
<pre>McCormick
Global best position: -0.54675 -1.54665
Global best value: -1.91322
Michalewicz
Global best position: 2.20293 1.57080
Global best value: -1.80130</pre>
=={{header|Phix}}==
{{trans|Kotlin}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">OMEGA</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">PHIP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">PHIG</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">ITER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">GBPOS</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">GBVAL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MIN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MAX</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">PARAMS</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">POS</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">VEL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BPOS</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BVAL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NPARTICLES</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NDIMS</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">inf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1e308</span><span style="color: #0000FF;">*</span><span style="color: #000000;">1e308</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
Test Function : %s
Iterations : %d
Global Best Position : %s
Global Best Value : %f
"""</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">testfunc</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">testfunc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ITER</span><span style="color: #0000FF;">],</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">GBPOS</span><span style="color: #0000FF;">]),</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">GBVAL</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">psoInit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">maxs</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">params</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">nParticles</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nDims</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">iter</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">gbval</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">inf</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">gbpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">inf</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nDims</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">vel</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nDims</span><span style="color: #0000FF;">),</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bval</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">inf</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">iter</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gbpos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gbval</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">params</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vel</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bpos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bval</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nDims</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">pso</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">particles</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">NPARTICLES</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">dims</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">NDIMS</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PARAMS</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">particles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MIN</span><span style="color: #0000FF;">],</span><span style="color: #000000;">particles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bval</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">particles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">gbpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dims</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">gbval</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">inf</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">particles</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- evaluate</span>
<span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">POS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
<span style="color: #000080;font-style:italic;">-- update</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BVAL</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">bpos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">POS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">bval</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">bpos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BPOS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">bval</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BVAL</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bval</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">gbval</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">gbval</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bval</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">gbpos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bpos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">rg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dims</span><span style="color: #0000FF;">),</span><span style="color: #000000;">particles</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">vel</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dims</span><span style="color: #0000FF;">),</span><span style="color: #000000;">particles</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">particles</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- migrate</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">rp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #000000;">vel</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dims</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dims</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">dims</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">vel</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">OMEGA</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">VEL</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span>
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PHIP</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">rp</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">bpos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">POS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">+</span>
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PHIG</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">rg</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">gbpos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">POS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">POS</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">vel</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ok</span> <span style="color: #008080;">and</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MIN</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">and</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MAX</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">ok</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">dims</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MIN</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MAX</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MIN</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">*</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">iter</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ITER</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">iter</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gbpos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gbval</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MIN</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">MAX</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PARAMS</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vel</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bpos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bval</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">particles</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dims</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">iterate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">old</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pso</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">r</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">old</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">old</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pso</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mccormick</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">a</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">a</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1.0</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">2.5</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">1.5</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">a</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">michalewicz</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0.0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">d</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">/</span> <span style="color: #004600;">PI</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.0</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">total</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mins</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">1.5</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3.0</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">maxs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">4.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.0</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">params</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nParticles</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">psoInit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">params</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">iterate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mccormick</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">40</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"McCormick"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">GBPOS</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f(%.4f, %.4f) : %f\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mccormick</span><span style="color: #0000FF;">({</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">})})</span>
<span style="color: #000000;">mins</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">maxs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">PI</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">params</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">nParticles</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000</span>
<span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">psoInit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">params</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nParticles</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">iterate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">michalewicz</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">report</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Michalewicz (2D)"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">[</span><span style="color: #000000;">GBPOS</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f(%.5f, %.5f) : %f\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">michalewicz</span><span style="color: #0000FF;">({</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">})})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Test Function : McCormick
Iterations : 40
Global Best Position : {-0.5471808566,-1.547021879}
Global Best Value : -1.913223
f(-0.5472, -1.5470) : -1.913223
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : {2.202905614,1.570796293}
Global Best Value : -1.801303
f(2.20291, 1.57080) : -1.801303
</pre>
=={{header|Python}}==
{{trans|D}}
<syntaxhighlight lang="python">import math
import random
INFINITY = 1 << 127
MAX_INT = 1 << 31
class Parameters:
def __init__(self, omega, phip, phig):
self.omega = omega
self.phip = phip
self.phig = phig
class State:
def __init__(self, iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims):
self.iter = iter
self.gbpos = gbpos
self.gbval = gbval
self.min = min
self.max = max
self.parameters = parameters
self.pos = pos
self.vel = vel
self.bpos = bpos
self.bval = bval
self.nParticles = nParticles
self.nDims = nDims
def report(self, testfunc):
print "Test Function :", testfunc
print "Iterations :", self.iter
print "Global Best Position :", self.gbpos
print "Global Best Value : %.16f" % self.gbval
def uniform01():
v = random.random()
assert 0.0 <= v and v < 1.0
return v
def psoInit(min, max, parameters, nParticles):
nDims = len(min)
pos = [min[:]] * nParticles
vel = [[0.0] * nDims] * nParticles
bpos = [min[:]] * nParticles
bval = [INFINITY] * nParticles
iter = 0
gbpos = [INFINITY] * nDims
gbval = INFINITY
return State(iter, gbpos, gbval, min, max, parameters, pos, vel, bpos, bval, nParticles, nDims);
def pso(fn, y):
p = y.parameters
v = [0.0] * (y.nParticles)
bpos = [y.min[:]] * (y.nParticles)
bval = [0.0] * (y.nParticles)
gbpos = [0.0] * (y.nDims)
gbval = INFINITY
for j in xrange(0, y.nParticles):
# evaluate
v[j] = fn(y.pos[j])
# 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][:]
rg = uniform01()
pos = [[None] * (y.nDims)] * (y.nParticles)
vel = [[None] * (y.nDims)] * (y.nParticles)
for j in xrange(0, y.nParticles):
# migrate
rp = uniform01()
ok = True
vel[j] = [0.0] * (len(vel[j]))
pos[j] = [0.0] * (len(pos[j]))
for k in xrange(0, y.nDims):
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 and y.min[k] < pos[j][k] and y.max[k] > pos[j][k]
if not ok:
for k in xrange(0, y.nDims):
pos[j][k] = y.min[k] + (y.max[k] - y.min[k]) * uniform01()
iter = 1 + y.iter
return State(iter, gbpos, gbval, y.min, y.max, y.parameters, pos, vel, bpos, bval, y.nParticles, y.nDims);
def iterate(fn, n, y):
r = y
old = y
if n == MAX_INT:
while True:
r = pso(fn, r)
if r == old:
break
old = r
else:
for _ in xrange(0, n):
r = pso(fn, r)
return r
def mccormick(x):
(a, b) = x
return math.sin(a + b) + (a - b) * (a - b) + 1.0 + 2.5 * b - 1.5 * a
def michalewicz(x):
m = 10
d = len(x)
sum = 0.0
for i in xrange(1, d):
j = x[i - 1]
k = math.sin(i * j * j / math.pi)
sum += math.sin(j) * k ** (2.0 * m)
return -sum
def main():
state = psoInit([-1.5, -3.0], [4.0, 4.0], Parameters(0.0, 0.6, 0.3), 100)
state = iterate(mccormick, 40, state)
state.report("McCormick")
print "f(-.54719, -1.54719) : %.16f" % (mccormick([-.54719, -1.54719]))
print
state = psoInit([0.0, 0.0], [math.pi, math.pi], Parameters(0.3, 0.3, 0.3), 1000)
state = iterate(michalewicz, 30, state)
state.report("Michalewicz (2D)")
print "f(2.20, 1.57) : %.16f" % (michalewicz([2.2, 1.57]))
main()</syntaxhighlight>
{{out}}
<pre>Test Function : McCormick
Iterations : 40
Global Best Position : [-0.5471069930124911, -1.5471582891466962]
Global Best Value : -1.9132229450518705
f(-.54719, -1.54719) : -1.9132229548822739
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.2029052187108036, 0.9404640520657541]
Global Best Value : -0.8013034100970750
f(2.20, 1.57) : -0.8011663878202856</pre>
=={{header|Racket}}==
<
(require racket/list racket/math)
Line 552 ⟶ 2,269:
(PSO (Michalewitz 5) 1000 30 (box 0) (box pi) #:ω 0.3 #:φ_p 0.3 #:φ_g 0.3 #:> <)
(displayln "Michalewitz 10d [-9.66015]")
(PSO (Michalewitz 10) 1000 30 (box 0) (box pi) #:ω 0.3 #:φ_p 0.3 #:φ_g 0.3 #:> <)</
{{out}}
Line 584 ⟶ 2,301:
1.8558804696523914)
-6.432092623300999</pre>
=={{header|Raku}}==
(formerly Perl 6)
{{trans|J (via Javascript, Kotlin, D, Python)}}
<syntaxhighlight lang="raku" line>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;</syntaxhighlight>
{{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}}==
{{trans|ooRexx}}
This REXX version supports the specifying of '''X''', '''Y''', and '''D''', as well as the number of particles, and the number of
<br>decimal digits to be displayed. A little extra code was added to show a title and align the output columns.
The refinement loop is stopped when the calculation of the function value stabilizes.
Note that REXX uses decimal floating point, not binary.
<syntaxhighlight lang="rexx">/*REXX program calculates Particle Swarm Optimization as it migrates through a solution.*/
if
if
if
old= /*#part: 1e12 ≡ is one trillion. */
minF= #part
show= sDigs + 3
say "══iteration══" center('X',show,"═") center('Y',show,"═") center('D',show,"═")
do until refine(minX, minY) /*perform until the mix is "refined". */
end /*until*/ /* [↑] stop refining if no difference.*/
$= 15 + show*2; say /*compute the indentation for alignment*/
say right('The global minimum for f(-.54719, -1.54719) ───► ', $) fmt(f(-.54719, -1.54719))
say right('The published global minimum is:' , $) fmt( -1.9133 )
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
refine: parse arg xx,yy; h= d * .5 /*compute ½ distance. */
#= # + 1; say center(#,13) new
minF= f;
end /*x*/
return 0
/*──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/
f: procedure: parse arg a,b;
fmt:
pi: pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865; return pi
r2r: return arg(1) // ( pi() * 2) /*normalize radians ───► a unit circle.*/
sin: procedure;
<pre>
══iteration══ ═════════════X══════════════ ═════════════Y══════════════ ═════════════D══════════════
1 -1.5 -2.5 -1.2431975046920717486273609
2 -1 -2 -1.6411200080598672221007448
3 -0.5 -1.5 -1.9092974268256816953960199
4 -0.54 -1.54 -1.9131329795075164948766768
5 -0.548 -1.548 -1.9132218400165267634506035
6 -0.548 -1.5472 -1.9132220344928294065568196
7 -0.5472 -1.5472 -1.9132229549706499208388746
8 -0.5472 -1.54719872 -1.9132229549737311254290577
9 -0.54719872 -1.54719872 -1.9132229549786702369612333
10 -0.54719872 -1.54719744 -1.91322295497891365438682
11 -0.54719744 -1.54719744 -1.9132229549810149766572388
12 -0.5471975424 -1.5471975424 -1.9132229549810362588916172
13 -0.54719755264 -1.54719755264 -1.9132229549810363893093655
14 -0.547197550592 -1.547197550592 -1.9132229549810363922848065
15 -0.5471975514112 -1.5471975514112 -1.9132229549810363928381695
16 -0.5471975510016 -1.5471975510016 -1.9132229549810363928520779
17 -0.54719755116544 -1.54719755116544 -1.9132229549810363929162561
18 -0.547197551198208 -1.547197551198208 -1.9132229549810363929179331
19 -0.547197551198208 -1.54719755119755264 -1.9132229549810363929179344
20 -0.54719755119755264 -1.54719755119755264 -1.9132229549810363929179361
21 -0.54719755119755264 -1.54719755119689728 -1.9132229549810363929179365
22 -0.54719755119689728 -1.54719755119689728 -1.9132229549810363929179375
23 -0.54719755119689728 -1.547197551196766208 -1.9132229549810363929179375
24 -0.547197551196766208 -1.547197551196766208 -1.9132229549810363929179376
25 -0.547197551196766208 -1.547197551196635136 -1.9132229549810363929179376
26 -0.547197551196635136 -1.547197551196635136 -1.9132229549810363929179376
27 -0.547197551196635136 -1.5471975511966089216 -1.9132229549810363929179376
28 -0.5471975511966089216 -1.5471975511966089216 -1.9132229549810363929179376
29 -0.5471975511966089216 -1.54719755119660367872 -1.9132229549810363929179376
30 -0.54719755119660367872 -1.54719755119660367872 -1.9132229549810363929179376
31 -0.54719755119660367872 -1.54719755119659843584 -1.9132229549810363929179376
32 -0.54719755119659843584 -1.54719755119659843584 -1.9132229549810363929179376
33 -0.547197551196597387264 -1.547197551196597387264 -1.9132229549810363929179376
34 -0.5471975511965978066944 -1.5471975511965978066944 -1.9132229549810363929179376
35 -0.5471975511965978066944 -1.54719755119659776475136 -1.9132229549810363929179376
36 -0.54719755119659776475136 -1.54719755119659776475136 -1.9132229549810363929179376
37 -0.54719755119659776475136 -1.547197551196597756362752 -1.9132229549810363929179376
38 -0.547197551196597756362752 -1.547197551196597756362752 -1.9132229549810363929179376
39 -0.547197551196597756362752 -1.547197551196597747974144 -1.9132229549810363929179376
40 -0.547197551196597747974144 -1.547197551196597747974144 -1.9132229549810363929179376
41 -0.547197551196597747974144 -1.5471975511965977462964224 -1.9132229549810363929179376
42 -0.5471975511965977462964224 -1.5471975511965977462964224 -1.9132229549810363929179376
43 -0.5471975511965977462964224 -1.5471975511965977462293135 -1.9132229549810363929179376
44 -0.5471975511965977462293135 -1.5471975511965977462293135 -1.9132229549810363929179376
45 -0.5471975511965977462293135 -1.5471975511965977461622047 -1.9132229549810363929179376
46 -0.5471975511965977461622047 -1.5471975511965977461622047 -1.9132229549810363929179376
47 -0.5471975511965977461487829 -1.5471975511965977461487829 -1.9132229549810363929179376
48 -0.5471975511965977461541516 -1.5471975511965977461541516 -1.9132229549810363929179376
49 -0.547197551196597746154259 -1.547197551196597746154259 -1.9132229549810363929179376
50 -0.547197551196597746154259 -1.5471975511965977461542375 -1.9132229549810363929179376
51 -0.5471975511965977461542375 -1.5471975511965977461542375 -1.9132229549810363929179376
52 -0.5471975511965977461542375 -1.547197551196597746154216 -1.9132229549810363929179376
53 -0.547197551196597746154216 -1.547197551196597746154216 -1.9132229549810363929179376
54 -0.547197551196597746154216 -1.5471975511965977461542152 -1.9132229549810363929179376
55 -0.5471975511965977461542152 -1.5471975511965977461542152 -1.9132229549810363929179376
56 -0.5471975511965977461542152 -1.5471975511965977461542143 -1.9132229549810363929179376
57 -0.5471975511965977461542143 -1.5471975511965977461542143 -1.9132229549810363929179376
58 -0.5471975511965977461542145 -1.5471975511965977461542145 -1.9132229549810363929179376
The global minimum for f(-.54719, -1.54719) ───► -1.9132229548822735814541188
The published global minimum is: -1.9133
</pre>
Output note: the published global minimum (referenced above, as well as the function's arguments) can be found at:
::::: <u>[http://www.sfu.ca/~ssurjano/mccorm.html http://www.sfu.ca/~ssurjano/mccorm.html]</u>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="wren">import "random" for Random
import "./dynamic" for Tuple
var Parameters = Tuple.create("Parameters", ["omega", "phip", "phig"])
var fields = [
"iter", "gbpos", "gbval", "min", "max", "parameters",
"pos", "vel", "bpos", "bval", "nParticles", "nDims"
]
var State = Tuple.create("State", fields)
var report = Fn.new { |state, testfunc|
System.print("Test Function : %(testfunc)")
System.print("Iterations : %(state.iter)")
System.print("Global Best Position : %(state.gbpos)")
System.print("Global Best Value : %(state.gbval)")
}
var psoInit = Fn.new { |min, max, parameters, nParticles|
var nDims = min.count
var pos = List.filled(nParticles, null)
var vel = List.filled(nParticles, null)
var bpos = List.filled(nParticles, null)
var bval = List.filled(nParticles, 1/0)
for (i in 0...nParticles) {
pos[i] = min.toList
vel[i] = List.filled(nDims, 0)
bpos[i] = min.toList
}
var iter = 0
var gbpos = List.filled(nDims, 1/0 )
var gbval = 1/0
return State.new(iter, gbpos, gbval, min, max, parameters,
pos, vel, bpos, bval, nParticles, nDims)
}
var r = Random.new()
var pso = Fn.new { |fn, y|
var p = y.parameters
var v = List.filled(y.nParticles, 0)
var bpos = List.filled(y.nParticles, null)
for (i in 0...y.nParticles) bpos[i] = y.min.toList
var bval = List.filled(y.nParticles, 0)
var gbpos = List.filled(y.nDims, 0)
var gbval = 1/0
for (j in 0...y.nParticles) {
// evaluate
v[j] = fn.call(y.pos[j])
// 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]
}
}
var rg = r.float()
var pos = List.filled(y.nParticles, null)
var vel = List.filled(y.nParticles, null)
for (i in 0...y.nParticles) {
pos[i] = List.filled(y.nDims, 0)
vel[i] = List.filled(y.nDims, 0)
}
for (j in 0...y.nParticles) {
// migrate
var rp = r.float()
var ok = true
for (k in 0...y.nDims) {
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 (k in 0...y.nDims) {
pos[j][k]= y.min[k] + (y.max[k] - y.min[k]) * r.float()
}
}
}
var iter = 1 + y.iter
return State.new(
iter, gbpos, gbval, y.min, y.max, y.parameters,
pos, vel, bpos, bval, y.nParticles, y.nDims
)
}
var iterate = Fn.new { |fn, n, y|
var r = y
var old = y
if (n == 2147483647) {
while (true) {
r = pso.call(fn, r)
if (r == old) break
old = r
}
} else {
for (i in 1..n) r = pso.call(fn, r)
}
return r
}
var mccormick = Fn.new { |x|
var a = x[0]
var b = x[1]
return (a + b).sin + (a - b) * (a - b) + 1 + 2.5 * b - 1.5 * a
}
var michalewicz = Fn.new { |x|
var m = 10
var d = x.count
var sum = 0
for (i in 1..d) {
var j = x[i - 1]
var k = (i * j * j / Num.pi).sin
sum = sum + j.sin * k.pow(2 * m)
}
return -sum
}
var state = psoInit.call([-1.5, -3], [4, 4], Parameters.new(0, 0.6, 0.3), 100)
state = iterate.call(mccormick, 40, state)
report.call(state, "McCormick")
System.print("f(-0.54719, -1.54719) : %(mccormick.call([-0.54719, -1.54719]))")
System.print()
state = psoInit.call([0, 0], [Num.pi, Num.pi], Parameters.new(0.3, 0.3, 0.3), 1000)
state = iterate.call(michalewicz, 30, state)
report.call(state, "Michalewicz (2D)")
System.print("f(2.20, 1.57) : %(michalewicz.call([2.2, 1.57]))")</syntaxhighlight>
{{out}}
Sample run:
<pre>
Test Function : McCormick
Iterations : 40
Global Best Position : [-0.54763537556709, -1.5469760587453]
Global Best Value : -1.9132225000184
f(-0.54719, -1.54719) : -1.9132229548823
Test Function : Michalewicz (2D)
Iterations : 30
Global Best Position : [2.2029075565418, 1.570796180786]
Global Best Value : -1.8013034100303
f(2.20, 1.57) : -1.8011407184738
</pre>
|