/*
  * Reinitialises part of, or the whole, population
  * @param topology The population to be reinitialised
  */
 private void reinitialisePosition(fj.data.List<ClusterParticle> topology) {
   int index = 0;
   for (int i = index; i < topology.length(); i += reinitialisationInterval) {
     ClusterParticle c = topology.index(i);
     c.reinitialise();
     c.calculateFitness();
   }
 }
  public void performIteration(final TuningAlgorithm alg) {
    final List<Vector> parameterList = alg.getParameterList();

    // TODO: deal with maximisation problems
    results =
        results.snoc(
            parameterList.map(
                new F<Vector, OptimisationSolution>() {
                  @Override
                  public OptimisationSolution f(Vector a) {
                    return new OptimisationSolution(a, alg.evaluate(a));
                  }
                }));

    // (+1 because iterations start at 0)
    if (alg.getIterations() + 1 >= minProblems.getParameter() && parameterList.length() != 1) {
      List<List<Double>> data =
          results.map(
              List.<OptimisationSolution, Double>map_().f(getFitness().andThen(getValue())));
      P2<Double, Double> friedman = StatsTests.friedman(0.05, data);

      if (friedman._1() > friedman._2()) {
        final List<Integer> indexes = StatsTests.postHoc(0.05, friedman._1(), data);
        alg.setParameterList(indexes.map(flip(Utils.<Vector>index()).f(parameterList)));

        results =
            results.map(
                new F<List<OptimisationSolution>, List<OptimisationSolution>>() {
                  @Override
                  public List<OptimisationSolution> f(final List<OptimisationSolution> a) {
                    return indexes.map(flip(Utils.<OptimisationSolution>index()).f(a));
                  }
                });
      }
    }
  }