optimize method
Run optimization and return best particle and fitness.
Implementation
Map<String, dynamic> optimize({int iterations = 200}) {
var particles = initParticles();
if (particles.isEmpty) throw ArgumentError('empty particle set');
// convert particles to vector form
var vectors = particles.map(toVector).toList();
if (vectors.any((v) => v.length != dim)) {
throw ArgumentError('vector dimension mismatch');
}
// initialize velocities
final velocities = List.generate(
swarmSize,
(_) => List<double>.filled(dim, 0.0),
);
// ensure swarm size
if (vectors.length != swarmSize) {
final buf = <List<double>>[];
while (buf.length < swarmSize) {
buf.addAll(vectors);
}
vectors = buf.sublist(0, swarmSize);
}
final pBestVec = List.generate(
swarmSize,
(i) => List<double>.from(vectors[i]),
);
final pBestVal = List.generate(
swarmSize,
(i) => fitness(fromVector(vectors[i])),
);
var gBestVec = List<double>.from(pBestVec[0]);
var gBestVal = pBestVal[0];
for (var i = 1; i < swarmSize; i++) {
if (pBestVal[i] > gBestVal) {
gBestVal = pBestVal[i];
gBestVec = List<double>.from(pBestVec[i]);
}
}
for (var it = 0; it < iterations; it++) {
for (var i = 0; i < swarmSize; i++) {
final pos = vectors[i];
final vel = velocities[i];
for (var d = 0; d < dim; d++) {
final r1 = _rand.nextDouble();
final r2 = _rand.nextDouble();
vel[d] =
inertia * vel[d] +
cognitive * r1 * (pBestVec[i][d] - pos[d]) +
social * r2 * (gBestVec[d] - pos[d]);
pos[d] = pos[d] + vel[d];
}
final val = fitness(fromVector(pos));
if (val > pBestVal[i]) {
pBestVal[i] = val;
pBestVec[i] = List<double>.from(pos);
if (val > gBestVal) {
gBestVal = val;
gBestVec = List<double>.from(pos);
}
}
}
}
return {'best': fromVector(gBestVec), 'bestFitness': gBestVal};
}