public float computeFitness(Individual individual) {
    float fitness = 0;
    int three = 99; // Bogus value. Just to initialize.
    char[] levelString = individual.copyIndividual();
    int levelSize = Problem.n;
    int nLevels = (int) (Math.log(levelSize) / Math.log(3));
    float levelFit;

    float
        flow =
            (float) 1
                + (float) 0.1
                    / (float) nLevels, // Parameters for trap at all levels except the top one.
        fhigh = 1;
    float topFlow = (float) 0.9, // Parameters for topTrap
        topFhigh = 1;

    while (levelSize > 3) { // All levels except the top one.
      levelFit = 0; // Fitness contribution of each level.
      for (int i = 0; i < levelSize; ) { // Empty increment
        three = Integer.parseInt(String.valueOf(levelString[i++]));
        three += Integer.parseInt(String.valueOf(levelString[i++]));
        three += Integer.parseInt(String.valueOf(levelString[i++]));
        if (three == 3) {
          levelFit += fhigh; // fhigh = 1.
          levelString[i / 3 - 1] =
              '1'; // '111' -> 1. NOTE: rewriting over the leftmost part of levelString.
        } else if (three == 0) {
          levelFit += flow; // flow = 1 + 0.1/l.
          levelString[i / 3 - 1] =
              '0'; // '000' -> 0. NOTE: rewriting over the leftmost part of levelString.
        } else if (three < 3) {
          levelFit += flow - ((float) three) * flow / ((float) 2); // flow - u*flow/(k-1).
          levelString[i / 3 - 1] =
              '8'; // anything else -> 8 (NULL symbol). NOTE: rewriting over the leftmost part of
                   // levelString.
        } else if (three > 3) {
          // levelFit += 0									// NULL symbol present.
          levelString[i / 3 - 1] =
              '8'; // anything else -> 8 (NULL symbol). NOTE: rewriting over the leftmost part of
                   // levelString.
        }
      }
      levelSize /= 3; // Next levelSize. Each 3-string is collapsed in to a single symbol.
      fitness +=
          levelFit * Problem.n
              / levelSize; // Each level contribution is multiplied by the factor: 3^level =
                           // stringSize/(next levelSize).
    }

    levelFit =
        0; // We are at the top level. No need for mapping. Use topTrap as the contribution
           // function.
    for (int i = 0; i < 3; ) {
      three = Integer.parseInt(String.valueOf(levelString[i++]));
      three += Integer.parseInt(String.valueOf(levelString[i++]));
      three += Integer.parseInt(String.valueOf(levelString[i++]));
    }
    if (three == 3) levelFit += topFhigh; // topFhigh = 1.
    else if (three == 0) levelFit += topFlow; // topFlow = .9.
    else if (three < 3)
      levelFit += topFlow - ((float) three) * topFlow / ((float) 2); // flow - u*flow/(k-1).
    // else NULL symbol present, do nothing.
    fitness += levelFit * Problem.n; // At the top level the contribution factor is
    return fitness; // 3^nLevels = stringSize.
  } // END: computeFitness(...)