@Override
  public double getPercentageCompleted(PSO algorithm) {
    DiameterVisitor diameterVisitor = new DiameterVisitor();
    algorithm.accept(diameterVisitor);
    double diameter = diameterVisitor.getResult();

    if (diameter <= minimumSwarmDiameter) {
      return 1;
    }
    return minimumSwarmDiameter / diameter;
  }
  /** {@inheritDoc} */
  public Real getValue(Algorithm algorithm) {
    PSO pso = (PSO) algorithm;

    int numberParticles = pso.getTopology().size();

    Iterator<Particle> k = pso.getTopology().iterator();
    Particle particle = k.next();
    Vector averageParticlePosition = (Vector) particle.getPosition().getClone();
    while (k.hasNext()) {
      particle = k.next();
      Vector v = (Vector) particle.getPosition();
      for (int j = 0; j < averageParticlePosition.size(); ++j) {
        averageParticlePosition.setReal(
            j, averageParticlePosition.doubleValueOf(j) + v.doubleValueOf(j));
      }
    }
    for (int j = 0; j < averageParticlePosition.size(); ++j) {
      averageParticlePosition.setReal(
          j, averageParticlePosition.doubleValueOf(j) / numberParticles);
    }

    Iterator<Particle> i = pso.getTopology().iterator();
    double particleSum = 0.0;
    while (i.hasNext()) {
      particle = i.next();

      double dimensionSum = 0.0;
      Vector v = (Vector) particle.getPosition();
      for (int j = 0; j < particle.getDimension(); ++j) {
        dimensionSum +=
            (v.doubleValueOf(j) - averageParticlePosition.doubleValueOf(j))
                * (v.doubleValueOf(j) - averageParticlePosition.doubleValueOf(j));
      }
      particleSum += Math.sqrt(dimensionSum);
    }

    double diversity = particleSum / numberParticles;

    DiameterVisitor diameterVisitor = new DiameterVisitor();
    pso.accept(diameterVisitor);
    double diameter = diameterVisitor.getResult();

    return Real.valueOf(diversity / diameter);
  }
 @Override
 public boolean apply(PSO input) {
   DiameterVisitor diameterVisitor = new DiameterVisitor();
   input.accept(diameterVisitor);
   return (diameterVisitor.getResult() <= minimumSwarmDiameter);
 }