/**
  * Write report on eveluation to the given stream.
  *
  * @param a_fitnessFunction p_SupergeneChangeFitnessFunction
  * @param a_population Genotype
  * @return Chromosome
  */
 public IChromosome report(
     SupergeneChangeFitnessFunction a_fitnessFunction, Genotype a_population) {
   IChromosome bestSolutionSoFar = a_population.getFittestChromosome();
   if (!REPORT_ENABLED) {
     return bestSolutionSoFar;
   }
   System.out.println(
       "\nThe best solution has a fitness value of " + bestSolutionSoFar.getFitnessValue());
   System.out.println("It contained the following: ");
   System.out.println(
       "\t"
           + a_fitnessFunction.getNumberOfCoinsAtGene(bestSolutionSoFar, QUARTERS)
           + " quarters.");
   System.out.println(
       "\t" + a_fitnessFunction.getNumberOfCoinsAtGene(bestSolutionSoFar, DIMES) + " dimes.");
   System.out.println(
       "\t" + a_fitnessFunction.getNumberOfCoinsAtGene(bestSolutionSoFar, NICKELS) + " nickels.");
   System.out.println(
       "\t" + a_fitnessFunction.getNumberOfCoinsAtGene(bestSolutionSoFar, PENNIES) + " pennies.");
   System.out.println(
       "For a total of "
           + a_fitnessFunction.amountOfChange(bestSolutionSoFar)
           + " cents in "
           + a_fitnessFunction.getTotalNumberOfCoins(bestSolutionSoFar)
           + " coins.");
   return bestSolutionSoFar;
 }
 /**
  * Find and print the solution, return the solution error.
  *
  * @param a_conf the configuration to use
  * @return absolute difference between the required and computed change
  */
 protected int solve(
     Configuration a_conf,
     int a_targetChangeAmount,
     SupergeneChangeFitnessFunction a_fitnessFunction,
     Gene[] a_sampleGenes)
     throws InvalidConfigurationException {
   IChromosome sampleChromosome = new Chromosome(a_conf, a_sampleGenes);
   a_conf.setSampleChromosome(sampleChromosome);
   // Finally, we need to tell the Configuration object how many
   // Chromosomes we want in our population. The more Chromosomes,
   // the larger number of potential solutions (which is good for
   // finding the answer), but the longer it will take to evolve
   // the population (which could be seen as bad). We'll just set
   // the population size to 500 here.
   // ------------------------------------------------------------
   a_conf.setPopulationSize(POPULATION_SIZE);
   // Create random initial population of Chromosomes.
   // ------------------------------------------------
   Genotype population = Genotype.randomInitialGenotype(a_conf);
   int s;
   Evolution:
   // Evolve the population, break if the the change solution is found.
   // -----------------------------------------------------------------
   for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
     population.evolve();
     s =
         Math.abs(
             a_fitnessFunction.amountOfChange(population.getFittestChromosome())
                 - a_targetChangeAmount);
     if (s == 0) {
       break Evolution;
     }
   }
   // Display the best solution we found.
   // -----------------------------------
   IChromosome bestSolutionSoFar = report(a_fitnessFunction, population);
   return Math.abs(a_fitnessFunction.amountOfChange(bestSolutionSoFar) - a_targetChangeAmount);
 }