optimize method

Map<String, dynamic> optimize({
  1. int iterations = 200,
})

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};
}